From a6928b3c93a5119c79b8a7aec953579c87d2a4cc Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 19 Dec 2014 22:33:56 +0800 Subject: [PATCH] x86/apic: Fix xen failure caused by commit b81975eade8c Commit b81975eade8c "x86, irq: Clean up irqdomain transition code" breaks Xen because xen_smp_prepare_cpus() doesn't call setup_IO_APIC() so mp_map_pin_to_irq() fails at the very beginning. Signed-off-by: Jiang Liu --- arch/x86/include/asm/hw_irq.h | 2 +- arch/x86/include/asm/smpboot_hooks.h | 6 +++--- arch/x86/kernel/apic/apic.c | 6 +++--- arch/x86/kernel/apic/io_apic.c | 32 +++++++++++++++----------------- arch/x86/xen/smp.c | 3 +++ 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index 4615906d83df..0c6530dfd817 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h @@ -98,7 +98,7 @@ extern void trace_call_function_single_interrupt(void); #define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs)) extern unsigned long io_apic_irqs; -extern void setup_IO_APIC(void); +extern void setup_IO_APIC(bool xen_smp); extern void disable_IO_APIC(void); struct io_apic_irq_attr { diff --git a/arch/x86/include/asm/smpboot_hooks.h b/arch/x86/include/asm/smpboot_hooks.h index 0da7409f0bec..76e5731b03cb 100644 --- a/arch/x86/include/asm/smpboot_hooks.h +++ b/arch/x86/include/asm/smpboot_hooks.h @@ -52,9 +52,9 @@ static inline void __init smpboot_setup_io_apic(void) * Here we can be sure that there is an IO-APIC in the system. Let's * go and set it up: */ - if (!skip_ioapic_setup && nr_ioapics) - setup_IO_APIC(); - else { + if (!skip_ioapic_setup && nr_ioapics) { + setup_IO_APIC(false); + } else { nr_ioapics = 0; } #endif diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index ba6cc041edb1..33ba1f97abea 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -1912,9 +1912,9 @@ int __init APIC_init_uniprocessor(void) bsp_end_local_APIC_setup(); #ifdef CONFIG_X86_IO_APIC - if (smp_found_config && !skip_ioapic_setup && nr_ioapics) - setup_IO_APIC(); - else { + if (smp_found_config && !skip_ioapic_setup && nr_ioapics) { + setup_IO_APIC(false); + } else { nr_ioapics = 0; } #endif diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index a6745e756729..5879ac58c3b6 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2965,31 +2965,29 @@ static int mp_irqdomain_create(int ioapic) return 0; } -void __init setup_IO_APIC(void) +void __init setup_IO_APIC(bool xen_smp) { int ioapic; - /* - * calling enable_IO_APIC() is moved to setup_local_APIC for BP - */ - io_apic_irqs = nr_legacy_irqs() ? ~PIC_IRQS : ~0UL; + if (!xen_smp) { + apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n"); + io_apic_irqs = nr_legacy_irqs() ? ~PIC_IRQS : ~0UL; + + /* Set up IO-APIC IRQ routing. */ + x86_init.mpparse.setup_ioapic_ids(); + sync_Arb_IDs(); + } - apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n"); for_each_ioapic(ioapic) BUG_ON(mp_irqdomain_create(ioapic)); - - /* - * Set up IO-APIC IRQ routing. - */ - x86_init.mpparse.setup_ioapic_ids(); - - sync_Arb_IDs(); setup_IO_APIC_irqs(); - init_IO_APIC_traps(); - if (nr_legacy_irqs()) - check_timer(); - ioapic_initialized = 1; + + if (!xen_smp) { + init_IO_APIC_traps(); + if (nr_legacy_irqs()) + check_timer(); + } } /* diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 4c071aeb8417..7eb0283901fa 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -326,7 +326,10 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus) xen_raw_printk(m); panic(m); + } else { + setup_IO_APIC(true); } + xen_init_lock_cpu(0); smp_store_boot_cpu_info(); -- 1.7.10.4