From: "Maciej W. Rozycki" <macro@linux-mips.org> Fix a kexec problem whcih causes local APIC detection failure. The problem is detect_init_APIC() is called early, before the command line have been processed. Therefore "lapic" (and "nolapic") have not been seen, yet. Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Signed-off-by: Andrew Morton <akpm@osdl.org> --- 25-akpm/arch/i386/kernel/apic.c | 25 +++++-------------------- 25-akpm/arch/i386/kernel/setup.c | 11 +++++++++++ 25-akpm/include/asm-i386/apic.h | 13 +++++++++++++ 3 files changed, 29 insertions(+), 20 deletions(-) diff -puN arch/i386/kernel/apic.c~x86-local-apic-fix arch/i386/kernel/apic.c --- 25/arch/i386/kernel/apic.c~x86-local-apic-fix 2004-12-03 20:56:52.828729000 -0800 +++ 25-akpm/arch/i386/kernel/apic.c 2004-12-03 20:56:52.834728088 -0800 @@ -41,6 +41,11 @@ #include "io_ports.h" /* + * Knob to control our willingness to enable the local APIC. + */ +int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ + +/* * Debug level */ int apic_verbosity; @@ -697,26 +702,6 @@ static void apic_pm_activate(void) { } * Original code written by Keir Fraser. */ -/* - * Knob to control our willingness to enable the local APIC. - */ -int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ - -static int __init lapic_disable(char *str) -{ - enable_local_apic = -1; - clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); - return 0; -} -__setup("nolapic", lapic_disable); - -static int __init lapic_enable(char *str) -{ - enable_local_apic = 1; - return 0; -} -__setup("lapic", lapic_enable); - static int __init apic_set_verbosity(char *str) { if (strcmp("debug", str) == 0) diff -puN arch/i386/kernel/setup.c~x86-local-apic-fix arch/i386/kernel/setup.c --- 25/arch/i386/kernel/setup.c~x86-local-apic-fix 2004-12-03 20:56:52.829728848 -0800 +++ 25-akpm/arch/i386/kernel/setup.c 2004-12-03 20:56:52.836727784 -0800 @@ -40,6 +40,7 @@ #include <linux/init.h> #include <linux/edd.h> #include <video/edid.h> +#include <asm/apic.h> #include <asm/e820.h> #include <asm/mpspec.h> #include <asm/setup.h> @@ -814,6 +815,16 @@ static void __init parse_cmdline_early ( #endif /* CONFIG_X86_LOCAL_APIC */ #endif /* CONFIG_ACPI_BOOT */ +#ifdef CONFIG_X86_LOCAL_APIC + /* enable local APIC */ + else if (!memcmp(from, "lapic", 5)) + lapic_enable(); + + /* disable local APIC */ + else if (!memcmp(from, "nolapic", 6)) + lapic_disable(); +#endif /* CONFIG_X86_LOCAL_APIC */ + /* * highmem=size forces highmem to be exactly 'size' bytes. * This works even on boxes that have no highmem otherwise. diff -puN include/asm-i386/apic.h~x86-local-apic-fix include/asm-i386/apic.h --- 25/include/asm-i386/apic.h~x86-local-apic-fix 2004-12-03 20:56:52.831728544 -0800 +++ 25-akpm/include/asm-i386/apic.h 2004-12-03 20:56:52.836727784 -0800 @@ -5,6 +5,7 @@ #include <linux/pm.h> #include <asm/fixmap.h> #include <asm/apicdef.h> +#include <asm/processor.h> #include <asm/system.h> #define Dprintk(x...) @@ -16,8 +17,20 @@ #define APIC_VERBOSE 1 #define APIC_DEBUG 2 +extern int enable_local_apic; extern int apic_verbosity; +static inline void lapic_disable(void) +{ + enable_local_apic = -1; + clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); +} + +static inline void lapic_enable(void) +{ + enable_local_apic = 1; +} + /* * Define the default level of output to be very little * This can be turned up by using apic=verbose for more _