Date: Mon, 3 Oct 2016 09:39:47 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r306628 - in stable/11/sys/x86: acpica include x86 xen Message-ID: <201610030939.u939dlsI041123@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Mon Oct 3 09:39:46 2016 New Revision: 306628 URL: https://svnweb.freebsd.org/changeset/base/306628 Log: MFC r305978: Detect x2APIC mode on boot and obey it. Modified: stable/11/sys/x86/acpica/madt.c stable/11/sys/x86/include/apicvar.h stable/11/sys/x86/x86/local_apic.c stable/11/sys/x86/xen/xen_apic.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/x86/acpica/madt.c ============================================================================== --- stable/11/sys/x86/acpica/madt.c Mon Oct 3 09:37:56 2016 (r306627) +++ stable/11/sys/x86/acpica/madt.c Mon Oct 3 09:39:46 2016 (r306628) @@ -135,10 +135,11 @@ madt_setup_local(void) const char *reason; char *hw_vendor; u_int p[4]; + int user_x2apic; + bool bios_x2apic; madt = pmap_mapbios(madt_physaddr, madt_length); if ((cpu_feature2 & CPUID2_X2APIC) != 0) { - x2apic_mode = 1; reason = NULL; /* @@ -150,21 +151,17 @@ madt_setup_local(void) 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 ((dmartbl->Flags & ACPI_DMAR_X2APIC_OPT_OUT) != 0) reason = "by DMAR table"; - } acpi_unmap_table(dmartbl); } if (vm_guest == VM_GUEST_VMWARE) { vmware_hvcall(VMW_HVCMD_GETVCPU_INFO, p); if ((p[0] & VMW_VCPUINFO_VCPU_RESERVED) != 0 || - (p[0] & VMW_VCPUINFO_LEGACY_X2APIC) == 0) { - x2apic_mode = 0; - reason = "inside VMWare without intr redirection"; - } + (p[0] & VMW_VCPUINFO_LEGACY_X2APIC) == 0) + 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 && CPUID_TO_FAMILY(cpu_id) == 0x6 && @@ -184,16 +181,33 @@ madt_setup_local(void) if (!strcmp(hw_vendor, "LENOVO") || !strcmp(hw_vendor, "ASUSTeK Computer Inc.")) { - x2apic_mode = 0; reason = "for a suspected SandyBridge BIOS bug"; } freeenv(hw_vendor); } } - TUNABLE_INT_FETCH("hw.x2apic_enable", &x2apic_mode); - if (!x2apic_mode && reason != NULL && bootverbose) + bios_x2apic = lapic_is_x2apic(); + if (reason != NULL && bios_x2apic) { + if (bootverbose) + printf("x2APIC should be disabled %s but " + "already enabled by BIOS; enabling.\n", + reason); + reason = NULL; + } + if (reason == NULL) + x2apic_mode = 1; + else if (bootverbose) printf("x2APIC available but disabled %s\n", reason); + user_x2apic = x2apic_mode; + TUNABLE_INT_FETCH("hw.x2apic_enable", &user_x2apic); + if (user_x2apic != x2apic_mode) { + if (bios_x2apic && !user_x2apic) + printf("x2APIC disabled by tunable and " + "enabled by BIOS; ignoring tunable."); + else + x2apic_mode = user_x2apic; + } } lapic_init(madt->Address); Modified: stable/11/sys/x86/include/apicvar.h ============================================================================== --- stable/11/sys/x86/include/apicvar.h Mon Oct 3 09:37:56 2016 (r306627) +++ stable/11/sys/x86/include/apicvar.h Mon Oct 3 09:39:46 2016 (r306628) @@ -206,6 +206,7 @@ struct apic_ops { void (*create)(u_int, int); void (*init)(vm_paddr_t); void (*xapic_mode)(void); + bool (*is_x2apic)(void); void (*setup)(int); void (*dump)(const char *); void (*disable)(void); @@ -268,6 +269,13 @@ lapic_xapic_mode(void) apic_ops.xapic_mode(); } +static inline bool +lapic_is_x2apic(void) +{ + + return (apic_ops.is_x2apic()); +} + static inline void lapic_setup(int boot) { Modified: stable/11/sys/x86/x86/local_apic.c ============================================================================== --- stable/11/sys/x86/x86/local_apic.c Mon Oct 3 09:37:56 2016 (r306627) +++ stable/11/sys/x86/x86/local_apic.c Mon Oct 3 09:39:46 2016 (r306628) @@ -269,6 +269,16 @@ native_lapic_enable_x2apic(void) wrmsr(MSR_APICBASE, apic_base); } +static bool +native_lapic_is_x2apic(void) +{ + uint64_t apic_base; + + apic_base = rdmsr(MSR_APICBASE); + return ((apic_base & (APICBASE_X2APIC | APICBASE_ENABLED)) == + (APICBASE_X2APIC | APICBASE_ENABLED)); +} + static void lapic_enable(void); static void lapic_resume(struct pic *pic, bool suspend_cancelled); static void lapic_timer_oneshot(struct lapic *); @@ -329,6 +339,7 @@ struct apic_ops apic_ops = { .create = native_lapic_create, .init = native_lapic_init, .xapic_mode = native_lapic_xapic_mode, + .is_x2apic = native_lapic_is_x2apic, .setup = native_lapic_setup, .dump = native_lapic_dump, .disable = native_lapic_disable, Modified: stable/11/sys/x86/xen/xen_apic.c ============================================================================== --- stable/11/sys/x86/xen/xen_apic.c Mon Oct 3 09:37:56 2016 (r306627) +++ stable/11/sys/x86/xen/xen_apic.c Mon Oct 3 09:39:46 2016 (r306628) @@ -139,6 +139,13 @@ xen_pv_lapic_disable(void) } +static bool +xen_pv_lapic_is_x2apic(void) +{ + + return (false); +} + static void xen_pv_lapic_eoi(void) { @@ -351,6 +358,7 @@ struct apic_ops xen_apic_ops = { .create = xen_pv_lapic_create, .init = xen_pv_lapic_init, .xapic_mode = xen_pv_lapic_disable, + .is_x2apic = xen_pv_lapic_is_x2apic, .setup = xen_pv_lapic_setup, .dump = xen_pv_lapic_dump, .disable = xen_pv_lapic_disable,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610030939.u939dlsI041123>