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
This commit is contained in:
Konstantin Belousov 2015-08-21 15:13:25 +00:00
parent bb1816daa4
commit 8c48615974
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=286994

View file

@ -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);