Check the FADT hints for physical/clustered APIC ID when selecting generic arch subarchitecture FADTv2 has fields to select clustered or physical mode. We can't handle clustered mode now, but at least warn. For physical select bigsmp. Cc: Len.Brown@intel.com Signed-off-by: Andi Kleen --- arch/i386/mach-generic/bigsmp.c | 18 ++++++++++++++++++ include/asm-i386/mach-summit/mach_mpparse.h | 22 ++++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) Index: linux/arch/i386/mach-generic/bigsmp.c =================================================================== --- linux.orig/arch/i386/mach-generic/bigsmp.c +++ linux/arch/i386/mach-generic/bigsmp.c @@ -19,6 +19,9 @@ #include #include #include +#ifdef CONFIG_ACPI +#include +#endif static int dmi_bigsmp; /* can be set by dmi scanners */ @@ -52,6 +55,21 @@ static __init int probe_bigsmp(void) dmi_bigsmp = 1; else dmi_check_system(bigsmp_dmi_table); +#ifdef CONFIG_ACPI + if (acpi_fadt.revision > FADT2_REVISION_ID) { + if (acpi_fadt.force_apic_physical_destination_mode) { + printk(KERN_NOTICE + "APIC: FADT forces physical destination. Using bigsmp mode.\n"); + dmi_bigsmp = 1; + } + if (acpi_fadt.force_apic_cluster_model) { + /* Hopefully this won't happen. Summit uses + Clustered mode, but it has been handled earlier. */ + printk(KERN_ERR + "APIC: FADT wants clustered model. Cannot support that. Sorry\n"); + } + } +#endif return dmi_bigsmp; } Index: linux/include/asm-i386/mach-summit/mach_mpparse.h =================================================================== --- linux.orig/include/asm-i386/mach-summit/mach_mpparse.h +++ linux/include/asm-i386/mach-summit/mach_mpparse.h @@ -3,6 +3,10 @@ #include +#ifdef CONFIG_ACPI +#include +#endif + extern int use_cyclone; #ifdef CONFIG_X86_SUMMIT_NUMA @@ -22,10 +26,24 @@ static inline void mpc_oem_pci_bus(struc { } +static inline int summit_need_physical(void) +{ +#ifdef CONFIG_ACPI + /* Only useful on GENERICARCH actually. */ + if (acpi_fadt.revision > FADT2_REVISION_ID && + acpi_fadt.force_apic_physical_destination_mode) { + printk(KERN_NOTICE "APIC: Summit: BIOS prefers physical mode. Leaving it to bigsmp\n"); + return 1; + } +#endif + return 0; +} + static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, char *productid) { - if (!strncmp(oem, "IBM ENSW", 8) && + if (!summit_need_physical() && + !strncmp(oem, "IBM ENSW", 8) && (!strncmp(productid, "VIGIL SMP", 9) || !strncmp(productid, "EXA", 3) || !strncmp(productid, "RUTHLESS SMP", 12))){ @@ -39,7 +57,7 @@ static inline int mps_oem_check(struct m /* Hook from generic ACPI tables.c */ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { - if (!strncmp(oem_id, "IBM", 3) && + if (!summit_need_physical() && !strncmp(oem_id, "IBM", 3) && (!strncmp(oem_table_id, "SERVIGIL", 8) || !strncmp(oem_table_id, "EXA", 3))){ use_cyclone = 1; /*enable cyclone-timer*/