[Xen-devel,PATCH-4.5,v3,12/12] xen/arm: print more info in gic_dump_info, keep gic_lr sync'ed

Message ID 1393439997-26936-12-git-send-email-stefano.stabellini@eu.citrix.com
State New
Headers show

Commit Message

Stefano Stabellini Feb. 26, 2014, 6:39 p.m.
For each inflight and pending irqs print GIC_IRQ_GUEST_ENABLED,
GIC_IRQ_GUEST_PENDING and GIC_IRQ_GUEST_VISIBLE.

In order to get consistent information from gic_dump_info, we need to
get the vgic.lock and disable interrupts before walking the inflight and
lr_pending lists.

We also need to keep v->arch.gic_lr in sync with GICH_LR registers.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

---
Changes in v3:
- use spin_lock_irqsave and spin_unlock_irqrestore in gic_dump_info.
---
 xen/arch/arm/gic.c |   20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

Patch

diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index aaba8b0..7de4443 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -639,6 +639,7 @@  static inline void gic_set_lr(struct vcpu *v, int lr, unsigned int irq,
             ((p->desc->irq & GICH_LR_PHYSICAL_MASK) << GICH_LR_PHYSICAL_SHIFT);
 
     GICH[GICH_LR + lr] = lr_reg;
+    v->arch.gic_lr[lr] = lr_reg;
 
     set_bit(GIC_IRQ_GUEST_VISIBLE, &p->status);
     clear_bit(GIC_IRQ_GUEST_PENDING, &p->status);
@@ -714,11 +715,15 @@  static void _gic_clear_lr(struct vcpu *v, int i)
         if ( p->desc == NULL &&
              test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) &&
              test_and_clear_bit(GIC_IRQ_GUEST_PENDING, &p->status) )
+        {
             GICH[GICH_LR + i] = lr | GICH_LR_PENDING;
+            v->arch.gic_lr[i] = lr | GICH_LR_PENDING;
+        }
     } else if ( lr & GICH_LR_PENDING ) {
         clear_bit(GIC_IRQ_GUEST_PENDING, &p->status);
     } else {
         GICH[GICH_LR + i] = 0;
+        v->arch.gic_lr[i] = 0;
         clear_bit(i, &this_cpu(lr_mask));
 
         if ( p->desc != NULL )
@@ -1006,8 +1011,11 @@  void gic_dump_info(struct vcpu *v)
 {
     int i;
     struct pending_irq *p;
+    unsigned long flags;
 
     printk("GICH_LRs (vcpu %d) mask=%"PRIx64"\n", v->vcpu_id, v->arch.lr_mask);
+
+    spin_lock_irqsave(&v->arch.vgic.lock, flags);
     if ( v == current )
     {
         for ( i = 0; i < nr_lrs; i++ )
@@ -1019,14 +1027,20 @@  void gic_dump_info(struct vcpu *v)
 
     list_for_each_entry ( p, &v->arch.vgic.inflight_irqs, inflight )
     {
-        printk("Inflight irq=%d lr=%u\n", p->irq, p->lr);
+        printk("Inflight irq=%d lr=%u enable=%d pending=%d visible=%d\n",
+                p->irq, p->lr, test_bit(GIC_IRQ_GUEST_ENABLED, &p->status),
+                test_bit(GIC_IRQ_GUEST_PENDING, &p->status),
+                test_bit(GIC_IRQ_GUEST_VISIBLE, &p->status));
     }
 
     list_for_each_entry( p, &v->arch.vgic.lr_pending, lr_queue )
     {
-        printk("Pending irq=%d lr=%u\n", p->irq, p->lr);
+        printk("Pending irq=%d lr=%u enable=%d pending=%d visible=%d\n",
+                p->irq, p->lr, test_bit(GIC_IRQ_GUEST_ENABLED, &p->status),
+                test_bit(GIC_IRQ_GUEST_PENDING, &p->status),
+                test_bit(GIC_IRQ_GUEST_VISIBLE, &p->status));
     }
-
+    spin_unlock_irqrestore(&v->arch.vgic.lock, flags);
 }
 
 void __cpuinit init_maintenance_interrupt(void)