[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] x86/ioapic: sanitize IO-APIC pins before enabling the local APIC
The current logic to init the local APIC and the IO-APIC does init the former first before doing any kind of sanitation on the IO-APIC pin configuration. It's already noted on enable_IO_APIC() that Xen shouldn't trust the IO-APIC being empty at bootup. At XenServer we have a system where the IO-APIC 0 is handed to Xen with pin 0 unmasked, set to Fixed delivery mode, edge triggered and with a vector of 0 (all fields of the RTE are zeroed). Once the local APIC is enabled periodic injections from such pin cause a storm of errors: APIC error on CPU0: 00(40), Received illegal vector APIC error on CPU0: 40(40), Received illegal vector APIC error on CPU0: 40(40), Received illegal vector APIC error on CPU0: 40(40), Received illegal vector APIC error on CPU0: 40(40), Received illegal vector APIC error on CPU0: 40(40), Received illegal vector That prevents Xen from booting. Fix this by moving the masking of IO-APIC pins ahead of the enabling of the local APIC. Note that before doing such masking Xen attempts to detect the pin where the legacy i8259 is connected, and that logic relies on the pin being unmasked, hence the logic is also moved ahead of enabling the local APIC. Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- I've placed the sanitize_IO_APIC() declaration in irq.h with the rest of related IO-APIC setup functions declarations instead of placing it in io_apic.h. --- xen/arch/x86/apic.c | 4 ++++ xen/arch/x86/include/asm/irq.h | 1 + xen/arch/x86/io_apic.c | 4 +--- xen/arch/x86/smpboot.c | 4 ++++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c index f71474d47dd1..9197b9532480 100644 --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -1476,6 +1476,10 @@ int __init APIC_init_uniprocessor (void) return -1; } + if ( smp_found_config && !skip_ioapic_setup && nr_ioapics ) + /* Sanitize the IO-APIC pins before enabling the local APIC. */ + sanitize_IO_APIC(); + verify_local_APIC(); connect_bsp_APIC(); diff --git a/xen/arch/x86/include/asm/irq.h b/xen/arch/x86/include/asm/irq.h index 424b0e1af8f4..dfa681846255 100644 --- a/xen/arch/x86/include/asm/irq.h +++ b/xen/arch/x86/include/asm/irq.h @@ -118,6 +118,7 @@ bool bogus_8259A_irq(unsigned int irq); int i8259A_suspend(void); int i8259A_resume(void); +void sanitize_IO_APIC(void); void setup_IO_APIC(void); void disable_IO_APIC(void); void setup_ioapic_dest(void); diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c index 9b8a972cf570..120c231e0302 100644 --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c @@ -1273,7 +1273,7 @@ static void cf_check _print_IO_APIC_keyhandler(unsigned char key) __print_IO_APIC(0); } -static void __init enable_IO_APIC(void) +void __init sanitize_IO_APIC(void) { int i8259_apic, i8259_pin; int i, apic; @@ -2067,8 +2067,6 @@ static void __init ioapic_pm_state_alloc(void) void __init setup_IO_APIC(void) { - enable_IO_APIC(); - if (acpi_ioapic) io_apic_irqs = ~0; /* all IRQs go through IOAPIC */ else diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index cf9bb220f90d..f9e27a23d383 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -1221,6 +1221,10 @@ void __init smp_prepare_cpus(void) goto init_uniprocessor; } + if ( !skip_ioapic_setup && nr_ioapics ) + /* Sanitize the IO-APIC pins before enabling the local APIC. */ + sanitize_IO_APIC(); + verify_local_APIC(); connect_bsp_APIC(); -- 2.41.0
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |