# HG changeset patch # Parent 3bc8894f281f3ee68406a565beb2f811c67c6b5e diff -r 3bc8894f281f xen/arch/x86/io_apic.c --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c @@ -1100,7 +1100,7 @@ static inline void UNEXPECTED_IO_APIC(vo { } -static void /*__init*/ __print_IO_APIC(void) +void /*__init*/ __print_IO_APIC(void) { int apic, i; union IO_APIC_reg_00 reg_00; diff -r 3bc8894f281f xen/arch/x86/irq.c --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -1115,6 +1115,8 @@ static void irq_guest_eoi_timer_fn(void spin_unlock_irqrestore(&desc->lock, flags); } +static void dump_irqs(unsigned char key); +void __print_IO_APIC(void); static void __do_IRQ_guest(int irq) { struct irq_desc *desc = irq_to_desc(irq); @@ -1137,7 +1139,36 @@ static void __do_IRQ_guest(int irq) if ( action->ack_type == ACKTYPE_EOI ) { sp = pending_eoi_sp(peoi); - ASSERT((sp == 0) || (peoi[sp-1].vector < vector)); + if ( unlikely( !((sp == 0) || (peoi[sp-1].vector < vector)) )) + { + printk("**Pending EOI error\n"); + printk(" irq %d, vector 0x%x\n", irq, vector); + + for ( i = sp-1; i >= 0; --i ) + { + printk(" s[%d] irq %d, vec 0x%x, ready %u, " + "ISR %u, TMR %u, IRR %u\n", + i, peoi[i].irq, peoi[i].vector, peoi[i].ready, + apic_isr_read(peoi[i].vector), + apic_tmr_read(peoi[i].vector), + apic_irr_read(peoi[i].vector) ); + } + + printk("All LAPIC state:\n"); + printk("[vector] %8s %8s %8s\n", "ISR", "TMR", "IRR"); + for ( i = 0; i < APIC_ISR_NR; ++i ) + printk("[%02x:%0x2x] %08"PRIu32" %08"PRIu32" %08"PRIu32"\n", + (i * 32)+31, i*32, + apic_read(APIC_ISR + i*0x10), + apic_read(APIC_TMR + i*0x10), + apic_read(APIC_IRR + i*0x10) ); + + spin_unlock(&desc->lock); + dump_irqs('i'); + __print_IO_APIC(); + + panic("CA-107844"); + } ASSERT(sp < (NR_DYNAMIC_VECTORS-1)); peoi[sp].irq = irq; peoi[sp].vector = vector; diff -r 3bc8894f281f xen/include/asm-x86/apic.h --- a/xen/include/asm-x86/apic.h +++ b/xen/include/asm-x86/apic.h @@ -152,6 +152,18 @@ static __inline bool_t apic_isr_read(u8 (vector & 0x1f)) & 1; } +static __inline bool_t apic_tmr_read(u8 vector) +{ + return (apic_read(APIC_TMR + ((vector & ~0x1f) >> 1)) >> + (vector & 0x1f)) & 1; +} + +static __inline bool_t apic_irr_read(u8 vector) +{ + return (apic_read(APIC_IRR + ((vector & ~0x1f) >> 1)) >> + (vector & 0x1f)) & 1; +} + static __inline u32 get_apic_id(void) /* Get the physical APIC id */ { u32 id = apic_read(APIC_ID);