summaryrefslogtreecommitdiffstats
path: root/sys/x86
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-08-21 15:13:25 +0000
committerkib <kib@FreeBSD.org>2015-08-21 15:13:25 +0000
commitb4e34c7b42019b3f519645635bb34f2e7cd6f531 (patch)
tree56f0e30a4df94ee841a508444fe5c5a5c1630266 /sys/x86
parent43164ff2ed6441746170b7dcdd5a37ebda9afa05 (diff)
downloadFreeBSD-src-b4e34c7b42019b3f519645635bb34f2e7cd6f531.zip
FreeBSD-src-b4e34c7b42019b3f519645635bb34f2e7cd6f531.tar.gz
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
Diffstat (limited to 'sys/x86')
-rw-r--r--sys/x86/acpica/madt.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/sys/x86/acpica/madt.c b/sys/x86/acpica/madt.c
index e812358..9b99651 100644
--- a/sys/x86/acpica/madt.c
+++ b/sys/x86/acpica/madt.c
@@ -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);
OpenPOWER on IntegriCloud