@@ -642,6 +642,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);
@@ -708,11 +709,15 @@ static void _gic_clear_lr(struct vcpu *v, int i, int vgic_locked)
{
if ( 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 ( !vgic_locked ) spin_lock(&v->arch.vgic.lock);
@@ -986,6 +991,8 @@ void gic_dump_info(struct vcpu *v)
struct pending_irq *p;
printk("GICH_LRs (vcpu %d) mask=%"PRIx64"\n", v->vcpu_id, v->arch.lr_mask);
+
+ spin_lock(&v->arch.vgic.lock);
if ( v == current )
{
for ( i = 0; i < nr_lrs; i++ )
@@ -997,14 +1004,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(&v->arch.vgic.lock);
}
void __cpuinit init_maintenance_interrupt(void)
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 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> --- xen/arch/arm/gic.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)