On Wed, Sep 14, 2016 at 05:02:21PM +0300, Andriy Gapon wrote:
> On 14/09/2016 15:49, Slawa Olhovchenkov wrote:
> > MSR_APICBASE = 0x        fee00d00
> > x2APIC is prohibited but turned on by BIOS
> 
> Kostik, ^^^^^

Well, the following might work, but I have no good idea what to do
when BIOS does handoff with x2APIC enabled and directs us to not
enable it.  Switching to xAPIC mode is not an option, I suspect.

diff --git a/sys/x86/acpica/madt.c b/sys/x86/acpica/madt.c
index 241a769..3a93fd6 100644
--- a/sys/x86/acpica/madt.c
+++ b/sys/x86/acpica/madt.c
@@ -138,7 +138,6 @@ madt_setup_local(void)
 
        madt = pmap_mapbios(madt_physaddr, madt_length);
        if ((cpu_feature2 & CPUID2_X2APIC) != 0) {
-               x2apic_mode = 1;
                reason = NULL;
 
                /*
@@ -150,21 +149,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,13 +179,21 @@ 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);
                        }
                }
+               if (reason != NULL && lapic_is_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;
                TUNABLE_INT_FETCH("hw.x2apic_enable", &x2apic_mode);
                if (!x2apic_mode && reason != NULL && bootverbose)
                        printf("x2APIC available but disabled %s\n", reason);
diff --git a/sys/x86/include/apicvar.h b/sys/x86/include/apicvar.h
index 1ddb69e..09c3a63 100644
--- a/sys/x86/include/apicvar.h
+++ b/sys/x86/include/apicvar.h
@@ -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)
 {
diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index cd774df..d9a3453 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -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,
diff --git a/sys/x86/xen/xen_apic.c b/sys/x86/xen/xen_apic.c
index 4d7a39b..45c3c18 100644
--- a/sys/x86/xen/xen_apic.c
+++ b/sys/x86/xen/xen_apic.c
@@ -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,
_______________________________________________
freebsd-stable@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-stable
To unsubscribe, send any mail to "freebsd-stable-unsubscr...@freebsd.org"

Reply via email to