[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: enable directed EOI
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1258959499 0 # Node ID 522ae754787d678ad64fcad7ee951bdce4fe28ce # Parent 3ca45272ff2cf8382d324d2ef767f1fe9e3022e3 x86: enable directed EOI This patch enables directed EOI on latest processor. With this, the broadcast of EOI would be suppressed upon LAPIC EOI, so VMM is required to perform a directed EOI to the IOxAPIC generating the interrupt by writting to its EOI register.(Pls. refer SDM 3A 10.5.5) This is useful for ioapic_ack_old to avoid the spurious interrupt storm, which is the reason why ioapic_ack_new is used. Signed-Off-By: Zhai Edwin <edwin.zhai@xxxxxxxxx> --- xen/arch/x86/apic.c | 25 +++++++++++++++++++++++++ xen/arch/x86/io_apic.c | 35 +++++++++++++++++++++++++++++++++-- xen/include/asm-x86/apic.h | 1 + xen/include/asm-x86/apicdef.h | 2 ++ xen/include/asm-x86/io_apic.h | 5 +++++ 5 files changed, 66 insertions(+), 2 deletions(-) diff -r 3ca45272ff2c -r 522ae754787d xen/arch/x86/apic.c --- a/xen/arch/x86/apic.c Mon Nov 23 06:56:01 2009 +0000 +++ b/xen/arch/x86/apic.c Mon Nov 23 06:58:19 2009 +0000 @@ -68,6 +68,7 @@ int apic_verbosity; int apic_verbosity; int x2apic_enabled __read_mostly = 0; +int directed_eoi_enabled __read_mostly = 0; /* * The following vectors are part of the Linux architecture, there @@ -348,6 +349,7 @@ void disable_local_APIC(void) } } +extern int ioapic_ack_new; /* * This is to verify that we're looking at a real local APIC. * Check these against your board if the CPUs aren't getting @@ -386,6 +388,18 @@ int __init verify_local_APIC(void) reg1 = get_maxlvt(); if (reg1 < 0x02 || reg1 == 0xff) return 0; + + /* + * Detecting directed EOI on BSP: + * If having directed EOI support in lapic, force to use ioapic_ack_old, + * and enable the directed EOI for intr handling. + */ + if ( reg0 & APIC_LVR_DIRECTED_EOI ) + { + ioapic_ack_new = 0; + directed_eoi_enabled = 1; + printk("Enabled directed EOI with ioapic_ack_old on!\n"); + } /* * The ID register is read/write in a real APIC. @@ -575,6 +589,17 @@ void __devinit setup_local_APIC(void) * Set spurious IRQ vector */ value |= SPURIOUS_APIC_VECTOR; + + /* + * Enable directed EOI + */ + if ( directed_eoi_enabled ) + { + value |= APIC_SPIV_DIRECTED_EOI; + apic_printk(APIC_VERBOSE, "Suppress EOI broadcast on CPU#%d\n", + smp_processor_id()); + } + apic_write_around(APIC_SPIV, value); /* diff -r 3ca45272ff2c -r 522ae754787d xen/arch/x86/io_apic.c --- a/xen/arch/x86/io_apic.c Mon Nov 23 06:56:01 2009 +0000 +++ b/xen/arch/x86/io_apic.c Mon Nov 23 06:58:19 2009 +0000 @@ -194,6 +194,30 @@ static void unmask_IO_APIC_irq (unsigned spin_lock_irqsave(&ioapic_lock, flags); __unmask_IO_APIC_irq(irq); + spin_unlock_irqrestore(&ioapic_lock, flags); +} + +static void __eoi_IO_APIC_irq(unsigned int irq) +{ + struct irq_pin_list *entry = irq_2_pin + irq; + unsigned int pin, vector = IO_APIC_VECTOR(irq); + + for (;;) { + pin = entry->pin; + if (pin == -1) + break; + io_apic_eoi(entry->apic, vector); + if (!entry->next) + break; + entry = irq_2_pin + entry->next; + } +} + +static void eoi_IO_APIC_irq(unsigned int irq) +{ + unsigned long flags; + spin_lock_irqsave(&ioapic_lock, flags); + __eoi_IO_APIC_irq(irq); spin_unlock_irqrestore(&ioapic_lock, flags); } @@ -1464,7 +1488,8 @@ static void mask_and_ack_level_ioapic_ir if ( ioapic_ack_new ) return; - mask_IO_APIC_irq(irq); + if ( !directed_eoi_enabled ) + mask_IO_APIC_irq(irq); /* * It appears there is an erratum which affects at least version 0x11 @@ -1511,8 +1536,14 @@ static void end_level_ioapic_irq (unsign if ( !ioapic_ack_new ) { - if ( !(irq_desc[irq].status & IRQ_DISABLED) ) + if ( irq_desc[irq].status & IRQ_DISABLED ) + return; + + if ( directed_eoi_enabled ) + eoi_IO_APIC_irq(irq); + else unmask_IO_APIC_irq(irq); + return; } diff -r 3ca45272ff2c -r 522ae754787d xen/include/asm-x86/apic.h --- a/xen/include/asm-x86/apic.h Mon Nov 23 06:56:01 2009 +0000 +++ b/xen/include/asm-x86/apic.h Mon Nov 23 06:58:19 2009 +0000 @@ -23,6 +23,7 @@ extern int apic_verbosity; extern int x2apic_enabled; +extern int directed_eoi_enabled; extern void enable_x2apic(void); diff -r 3ca45272ff2c -r 522ae754787d xen/include/asm-x86/apicdef.h --- a/xen/include/asm-x86/apicdef.h Mon Nov 23 06:56:01 2009 +0000 +++ b/xen/include/asm-x86/apicdef.h Mon Nov 23 06:58:19 2009 +0000 @@ -16,6 +16,7 @@ #define SET_xAPIC_ID(x) (((x)<<24)) #define APIC_LVR 0x30 #define APIC_LVR_MASK 0xFF00FF +#define APIC_LVR_DIRECTED_EOI (1 << 24) #define GET_APIC_VERSION(x) ((x)&0xFF) #define GET_APIC_MAXLVT(x) (((x)>>16)&0xFF) #define APIC_INTEGRATED(x) ((x)&0xF0) @@ -39,6 +40,7 @@ #define APIC_SPIV 0xF0 #define APIC_SPIV_FOCUS_DISABLED (1<<9) #define APIC_SPIV_APIC_ENABLED (1<<8) +#define APIC_SPIV_DIRECTED_EOI (1<<12) #define APIC_ISR 0x100 #define APIC_ISR_NR 0x8 /* Number of 32 bit ISR registers. */ #define APIC_TMR 0x180 diff -r 3ca45272ff2c -r 522ae754787d xen/include/asm-x86/io_apic.h --- a/xen/include/asm-x86/io_apic.h Mon Nov 23 06:56:01 2009 +0000 +++ b/xen/include/asm-x86/io_apic.h Mon Nov 23 06:58:19 2009 +0000 @@ -147,6 +147,11 @@ static inline void io_apic_write(unsigne *(IO_APIC_BASE(apic)+4) = value; } +static inline void io_apic_eoi(unsigned int apic, unsigned int vector) +{ + *(IO_APIC_BASE(apic)+16) = vector; +} + /* * Re-write a value: to be used for read-modify-write * cycles where the read already set up the index register. _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |