diff -Naurp a/arch/i386/Kconfig b/arch/i386/Kconfig --- a/arch/i386/Kconfig 2006-01-04 15:18:21.000000000 -0800 +++ b/arch/i386/Kconfig 2006-01-19 14:33:33.000000000 -0800 @@ -253,6 +253,20 @@ config X86_UP_IOAPIC to use it. If you say Y here even though your machine doesn't have an IO-APIC, then the kernel will still run with no slowdown at all. +config X86_UP_APIC_DEFAULT_OFF + bool "APIC support on uniprocessors defaults to off" + depends on !SMP && X86_UP_APIC + help + Some older systems have flaky APICs. Say Y to keep leave the APICs + disabled by default, while still allowing them to be enabled by the + "lapic" (local APIC) and "apic" (I/O APIC) command line options. + Generally speaking, either you want to enable both types of APICs + or none at all. + + Usually this is only necessary for distro installer kernels that + must work with everything. Everyone else can safely say N here + and configure APIC support in or out as needed. + config X86_LOCAL_APIC bool depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) diff -Naurp a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c --- a/arch/i386/kernel/acpi/boot.c 2006-01-04 15:18:21.000000000 -0800 +++ b/arch/i386/kernel/acpi/boot.c 2006-01-19 14:17:50.000000000 -0800 @@ -37,6 +37,10 @@ #include #include +#ifdef CONFIG_X86_32 +extern int enable_local_apic __initdata; +#endif + #ifdef CONFIG_X86_64 extern void __init clustered_apic_check(void); @@ -807,6 +811,16 @@ static void __init acpi_process_madt(voi #ifdef CONFIG_X86_LOCAL_APIC int count, error; +#ifdef CONFIG_X86_32 + if (enable_local_apic < 0) { + printk(KERN_INFO PREFIX "Local APIC disabled; pass 'lapic' " + "to re-enable.\n"); + return; + } + + printk(KERN_INFO PREFIX "Local APIC enabled.\n"); +#endif + count = acpi_table_parse(ACPI_APIC, acpi_parse_madt); if (count >= 1) { diff -Naurp a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c --- a/arch/i386/kernel/apic.c 2006-01-04 15:18:21.000000000 -0800 +++ b/arch/i386/kernel/apic.c 2006-01-19 14:21:24.000000000 -0800 @@ -42,8 +42,9 @@ /* * Knob to control our willingness to enable the local APIC. + * -2=default-disable, -1=force-disable, 1=force-enable, 0=automatic */ -int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ +int enable_local_apic __initdata = (X86_APIC_DEFAULT_OFF ? -2 : 0); /* * Debug level @@ -757,7 +758,7 @@ static int __init detect_init_APIC (void * APIC only if "lapic" specified. */ if (enable_local_apic <= 0) { - printk("Local APIC disabled by BIOS -- " + printk("Local APIC disabled by BIOS (or by default) -- " "you can enable it with \"lapic\"\n"); return -1; } @@ -839,7 +840,7 @@ void __init init_apic_mappings(void) int i; for (i = 0; i < nr_ioapics; i++) { - if (smp_found_config) { + if (smp_found_config && !skip_ioapic_setup) { ioapic_phys = mp_ioapics[i].mpc_apicaddr; if (!ioapic_phys) { printk(KERN_ERR @@ -1273,6 +1274,16 @@ int __init APIC_init_uniprocessor (void) return -1; /* + * If local apic is off due to config_x86_apic_off option, + * jump out here. + */ + if (enable_local_apic < -1) { + printk(KERN_INFO "Local APIC disabled by default; " + "use 'lapic' to enable it.\n"); + return -1; + } + + /* * Complain if the BIOS pretends there is one. */ if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { diff -Naurp a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c --- a/arch/i386/kernel/io_apic.c 2006-01-04 15:18:21.000000000 -0800 +++ b/arch/i386/kernel/io_apic.c 2006-01-17 14:58:30.000000000 -0800 @@ -681,7 +681,7 @@ void fastcall send_IPI_self(int vector) #define MAX_PIRQS 8 static int pirq_entries [MAX_PIRQS]; static int pirqs_enabled; -int skip_ioapic_setup; +int skip_ioapic_setup = X86_APIC_DEFAULT_OFF; static int __init ioapic_setup(char *str) { diff -Naurp a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c --- a/arch/i386/kernel/setup.c 2006-01-04 15:18:21.000000000 -0800 +++ b/arch/i386/kernel/setup.c 2006-01-19 14:23:38.000000000 -0800 @@ -60,6 +60,10 @@ #include "setup_arch_pre.h" #include +#ifdef CONFIG_X86_LOCAL_APIC +extern int enable_local_apic __initdata; +#endif + /* Forward Declaration. */ void __init find_max_pfn(void); @@ -865,6 +869,10 @@ static void __init parse_cmdline_early ( /* disable IO-APIC */ else if (!memcmp(from, "noapic", 6)) disable_ioapic_setup(); + /* enable IO-APIC */ + else if (!memcmp(from, "apic", 4)) + enable_ioapic_setup(); + #endif /* CONFIG_X86_IO_APIC */ #endif /* CONFIG_ACPI */ @@ -1606,8 +1614,14 @@ void __init setup_arch(char **cmdline_p) #endif #endif #ifdef CONFIG_X86_LOCAL_APIC - if (smp_found_config) - get_smp_config(); + if (smp_found_config) { + if (enable_local_apic >= 0) { + printk(KERN_INFO "LAPIC enabled.\n"); + get_smp_config(); + } else { + printk(KERN_INFO "LAPIC disabled.\n"); + } + } #endif register_memory(); diff -Naurp a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h --- a/include/asm-i386/acpi.h 2006-01-04 15:18:23.000000000 -0800 +++ b/include/asm-i386/acpi.h 2006-01-17 14:58:30.000000000 -0800 @@ -134,6 +134,10 @@ static inline void disable_ioapic_setup( { skip_ioapic_setup = 1; } +static inline void enable_ioapic_setup(void) +{ + skip_ioapic_setup = 0; +} static inline int ioapic_setup_disabled(void) { diff -Naurp a/include/asm-i386/apic.h b/include/asm-i386/apic.h --- a/include/asm-i386/apic.h 2006-01-04 15:18:23.000000000 -0800 +++ b/include/asm-i386/apic.h 2006-01-17 14:58:30.000000000 -0800 @@ -82,6 +82,12 @@ int get_physical_broadcast(void); # define apic_write_around(x,y) apic_write_atomic((x),(y)) #endif +#ifdef CONFIG_X86_UP_APIC_DEFAULT_OFF +# define X86_APIC_DEFAULT_OFF 1 +#else +# define X86_APIC_DEFAULT_OFF 0 +#endif + static inline void ack_APIC_irq(void) { /*