]> xenbits.xensource.com Git - xen.git/commitdiff
ARM: VGIC: rework events_need_delivery()
authorAndre Przywara <andre.przywara@linaro.org>
Tue, 6 Feb 2018 17:08:59 +0000 (17:08 +0000)
committerStefano Stabellini <sstabellini@kernel.org>
Thu, 8 Feb 2018 21:18:10 +0000 (13:18 -0800)
In event.h we very deeply dive into the VGIC to learn if an event for
a guest is pending.
Rework that function to abstract the VGIC specific part out. Also
reorder the queries there, as we only actually need to check for the
event channel if there are no other pending IRQs.

Signed-off-by: Andre Przywara <andre.przywara@linaro.org>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
xen/arch/arm/vgic.c
xen/include/asm-arm/event.h
xen/include/asm-arm/vgic.h

index 6e933a86d3607defc5a890d3022a295392aa4c43..9921769b15a71c253c32bf66455684d4dcd02bf8 100644 (file)
@@ -593,6 +593,17 @@ void arch_evtchn_inject(struct vcpu *v)
     vgic_vcpu_inject_irq(v, v->domain->arch.evtchn_irq);
 }
 
+bool vgic_evtchn_irq_pending(struct vcpu *v)
+{
+    struct pending_irq *p;
+
+    p = irq_to_pending(v, v->domain->arch.evtchn_irq);
+    /* Does not work for LPIs. */
+    ASSERT(!is_lpi(v->domain->arch.evtchn_irq));
+
+    return list_empty(&p->inflight);
+}
+
 bool vgic_emulate(struct cpu_user_regs *regs, union hsr hsr)
 {
     struct vcpu *v = current;
index 2b20d1aa15457a65d001cc66ca5d837830d76108..e8c2a6cb44cde776fa9884137b8c25facf39a821 100644 (file)
@@ -16,12 +16,6 @@ static inline int vcpu_event_delivery_is_enabled(struct vcpu *v)
 
 static inline int local_events_need_delivery_nomask(void)
 {
-    struct pending_irq *p = irq_to_pending(current,
-                                           current->domain->arch.evtchn_irq);
-
-    /* Does not work for LPIs. */
-    ASSERT(!is_lpi(current->domain->arch.evtchn_irq));
-
     /* XXX: if the first interrupt has already been delivered, we should
      * check whether any other interrupts with priority higher than the
      * one in GICV_IAR are in the lr_pending queue or in the LR
@@ -33,11 +27,10 @@ static inline int local_events_need_delivery_nomask(void)
     if ( gic_events_need_delivery() )
         return 1;
 
-    if ( vcpu_info(current, evtchn_upcall_pending) &&
-        list_empty(&p->inflight) )
-        return 1;
+    if ( !vcpu_info(current, evtchn_upcall_pending) )
+        return 0;
 
-    return 0;
+    return vgic_evtchn_irq_pending(current);
 }
 
 static inline int local_events_need_delivery(void)
index 2a93a7bef980b07f6a733932f3b76ba8f71d4e64..22c8502c95cdbeca7333d57df77cc2a49ae6d882 100644 (file)
@@ -218,6 +218,8 @@ extern void register_vgic_ops(struct domain *d, const struct vgic_ops *ops);
 int vgic_v2_init(struct domain *d, int *mmio_count);
 int vgic_v3_init(struct domain *d, int *mmio_count);
 
+bool vgic_evtchn_irq_pending(struct vcpu *v);
+
 extern int domain_vgic_register(struct domain *d, int *mmio_count);
 extern int vcpu_vgic_free(struct vcpu *v);
 extern bool vgic_to_sgi(struct vcpu *v, register_t sgir,