Author: kib
Date: Fri Aug 21 15:13:25 2015
New Revision: 286994
URL: https://svnweb.freebsd.org/changeset/base/286994

Log:
  Automatically disable x2APIC mode on SandyBridge Lenovo machines.  I
  believe that the bug only affects mobile CPUs, at least I did not see
  other reports, but it is impossible to detect it in madt_setup_local().
  
  While there, reduce duplication in the information strings printed
  when x2APIC is auto-disabled, and do not print the line when user
  manually override the setting.
  
  Tested and reviewed by:         royger (previous version)
  Sponsored by: The FreeBSD Foundation

Modified:
  head/sys/x86/acpica/madt.c

Modified: head/sys/x86/acpica/madt.c
==============================================================================
--- head/sys/x86/acpica/madt.c  Fri Aug 21 14:28:14 2015        (r286993)
+++ head/sys/x86/acpica/madt.c  Fri Aug 21 15:13:25 2015        (r286994)
@@ -132,20 +132,27 @@ madt_setup_local(void)
 {
        ACPI_TABLE_DMAR *dmartbl;
        vm_paddr_t dmartbl_physaddr;
+       const char *reason;
+       char *hw_vendor;
        u_int p[4];
 
        madt = pmap_mapbios(madt_physaddr, madt_length);
        if ((cpu_feature2 & CPUID2_X2APIC) != 0) {
                x2apic_mode = 1;
+               reason = NULL;
+
+               /*
+                * Automatically detect several configurations where
+                * x2APIC mode is known to cause troubles.  User can
+                * override the setting with hw.x2apic_enable tunable.
+                */
                dmartbl_physaddr = acpi_find_table(ACPI_SIG_DMAR);
                if (dmartbl_physaddr != 0) {
                        dmartbl = acpi_map_table(dmartbl_physaddr,
                            ACPI_SIG_DMAR);
                        if ((dmartbl->Flags & ACPI_DMAR_X2APIC_OPT_OUT) != 0) {
                                x2apic_mode = 0;
-                               if (bootverbose)
-                                       printf(
-               "x2APIC available but disabled by DMAR table\n");
+                               reason = "by DMAR table";
                        }
                        acpi_unmap_table(dmartbl);
                }
@@ -154,14 +161,34 @@ madt_setup_local(void)
                        if ((p[0] & VMW_VCPUINFO_VCPU_RESERVED) != 0 ||
                            (p[0] & VMW_VCPUINFO_LEGACY_X2APIC) == 0) {
                                x2apic_mode = 0;
-                               if (bootverbose)
-                                       printf(
-       "x2APIC available but disabled inside VMWare without intr 
redirection\n");
+               reason = "inside VMWare without intr redirection";
                        }
                } else if (vm_guest == VM_GUEST_XEN) {
                        x2apic_mode = 0;
+                       reason = "due to running under XEN";
+               } else if (vm_guest == VM_GUEST_NO) {
+                       hw_vendor = kern_getenv("smbios.planar.maker");
+                       /*
+                        * It seems that some Lenovo SandyBridge-based
+                        * notebook BIOSes have a bug which prevents
+                        * booting AP in x2APIC mode.  Since the only
+                        * way to detect mobile CPU is to check
+                        * northbridge pci id, which cannot be done
+                        * that early, disable x2APIC for all Lenovo
+                        * SandyBridge machines.
+                        */
+                       if (hw_vendor != NULL &&
+                           !strcmp(hw_vendor, "LENOVO") &&
+                           CPUID_TO_FAMILY(cpu_id) == 0x6 &&
+                           CPUID_TO_MODEL(cpu_id) == 0x2a) {
+                               x2apic_mode = 0;
+               reason = "for a suspected Lenovo SandyBridge BIOS bug";
+                       }
+                       freeenv(hw_vendor);
                }
                TUNABLE_INT_FETCH("hw.x2apic_enable", &x2apic_mode);
+               if (!x2apic_mode && reason != NULL && bootverbose)
+                       printf("x2APIC available but disabled %s\n", reason);
        }
 
        lapic_init(madt->Address);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to