ARM: vGIC: rework gic_remove_from_queues()
authorAndre Przywara <andre.przywara@arm.com>
Thu, 25 May 2017 18:06:41 +0000 (19:06 +0100)
committerStefano Stabellini <sstabellini@kernel.org>
Wed, 14 Jun 2017 18:38:37 +0000 (11:38 -0700)
The function name gic_remove_from_queues() was a bit of a misnomer,
since it just removes an IRQ from the pending queue, not both queues.
Rename the function to make this more clear, also give it a pointer to
a struct pending_irq directly and rely on the VGIC VCPU lock to be
already taken, so this can be used in more places. This results in the
lock to be taken in the caller instead now.
Replace the list removal in gic_clear_pending_irqs() with a call to
this function.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
xen/arch/arm/gic.c
xen/arch/arm/vgic.c
xen/include/asm-arm/gic.h

index da191309b83a3626c190e23d140d87b0f475fc87..6c0c9c31b65e183fcc09b49cee48fd8a165cb456 100644 (file)
@@ -400,15 +400,11 @@ static inline void gic_add_to_lr_pending(struct vcpu *v, struct pending_irq *n)
     list_add_tail(&n->lr_queue, &v->arch.vgic.lr_pending);
 }
 
-void gic_remove_from_queues(struct vcpu *v, unsigned int virtual_irq)
+void gic_remove_from_lr_pending(struct vcpu *v, struct pending_irq *p)
 {
-    struct pending_irq *p = irq_to_pending(v, virtual_irq);
-    unsigned long flags;
+    ASSERT(spin_is_locked(&v->arch.vgic.lock));
 
-    spin_lock_irqsave(&v->arch.vgic.lock, flags);
-    if ( !list_empty(&p->lr_queue) )
-        list_del_init(&p->lr_queue);
-    spin_unlock_irqrestore(&v->arch.vgic.lock, flags);
+    list_del_init(&p->lr_queue);
 }
 
 void gic_raise_inflight_irq(struct vcpu *v, unsigned int virtual_irq)
@@ -609,7 +605,7 @@ void gic_clear_pending_irqs(struct vcpu *v)
 
     v->arch.lr_mask = 0;
     list_for_each_entry_safe ( p, t, &v->arch.vgic.lr_pending, lr_queue )
-        list_del_init(&p->lr_queue);
+        gic_remove_from_lr_pending(v, p);
 }
 
 int gic_events_need_delivery(void)
index 18fe420c736aa42b55b27d45456c80f44f03d2fa..04d821aabd2f170a72363d550f806057c8794ec1 100644 (file)
@@ -309,7 +309,10 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n)
         v_target = vgic_get_target_vcpu(v, irq);
         p = irq_to_pending(v_target, irq);
         clear_bit(GIC_IRQ_GUEST_ENABLED, &p->status);
-        gic_remove_from_queues(v_target, irq);
+        spin_lock_irqsave(&v_target->arch.vgic.lock, flags);
+        gic_remove_from_lr_pending(v_target, p);
+        spin_unlock_irqrestore(&v_target->arch.vgic.lock, flags);
+
         if ( p->desc != NULL )
         {
             spin_lock_irqsave(&p->desc->lock, flags);
index 836a103ceb9ff1737997626cb0ae18b7f7923f54..31306341c70e9a97d34df2812590ebf942121eac 100644 (file)
@@ -243,7 +243,7 @@ extern void init_maintenance_interrupt(void);
 extern void gic_raise_guest_irq(struct vcpu *v, unsigned int irq,
         unsigned int priority);
 extern void gic_raise_inflight_irq(struct vcpu *v, unsigned int virtual_irq);
-extern void gic_remove_from_queues(struct vcpu *v, unsigned int virtual_irq);
+extern void gic_remove_from_lr_pending(struct vcpu *v, struct pending_irq *p);
 
 /* Accept an interrupt from the GIC and dispatch its handler */
 extern void gic_interrupt(struct cpu_user_regs *regs, int is_fiq);