Author: kib
Date: Mon Aug 17 18:33:16 2015
New Revision: 286852
URL: https://svnweb.freebsd.org/changeset/base/286852

Log:
  MFC r286228:
  Clear the IA32_MISC_ENABLE MSR bit on APs.

Modified:
  stable/10/sys/amd64/amd64/mp_machdep.c
  stable/10/sys/amd64/include/md_var.h
  stable/10/sys/i386/i386/mp_machdep.c
  stable/10/sys/i386/include/md_var.h
  stable/10/sys/x86/x86/identcpu.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- stable/10/sys/amd64/amd64/mp_machdep.c      Mon Aug 17 18:28:40 2015        
(r286851)
+++ stable/10/sys/amd64/amd64/mp_machdep.c      Mon Aug 17 18:33:16 2015        
(r286852)
@@ -682,6 +682,7 @@ init_secondary(void)
        wrmsr(MSR_FSBASE, 0);           /* User value */
        wrmsr(MSR_GSBASE, (u_int64_t)pc);
        wrmsr(MSR_KGSBASE, (u_int64_t)pc);      /* XXX User value while we're 
in the kernel */
+       intel_fix_cpuid();
 
        lidt(&r_idt);
 

Modified: stable/10/sys/amd64/include/md_var.h
==============================================================================
--- stable/10/sys/amd64/include/md_var.h        Mon Aug 17 18:28:40 2015        
(r286851)
+++ stable/10/sys/amd64/include/md_var.h        Mon Aug 17 18:33:16 2015        
(r286852)
@@ -112,6 +112,7 @@ void        dump_drop_page(vm_paddr_t);
 void   identify_cpu(void);
 void   initializecpu(void);
 void   initializecpucache(void);
+bool   intel_fix_cpuid(void);
 void   fillw(int /*u_short*/ pat, void *base, size_t cnt);
 void   fpstate_drop(struct thread *td);
 int    is_physical_memory(vm_paddr_t addr);

Modified: stable/10/sys/i386/i386/mp_machdep.c
==============================================================================
--- stable/10/sys/i386/i386/mp_machdep.c        Mon Aug 17 18:28:40 2015        
(r286851)
+++ stable/10/sys/i386/i386/mp_machdep.c        Mon Aug 17 18:33:16 2015        
(r286852)
@@ -684,6 +684,8 @@ init_secondary(void)
        pc->pc_prvspace = pc;
        pc->pc_curthread = 0;
 
+       intel_fix_cpuid();
+
        gdt_segs[GPRIV_SEL].ssd_base = (int) pc;
        gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss;
 

Modified: stable/10/sys/i386/include/md_var.h
==============================================================================
--- stable/10/sys/i386/include/md_var.h Mon Aug 17 18:28:40 2015        
(r286851)
+++ stable/10/sys/i386/include/md_var.h Mon Aug 17 18:33:16 2015        
(r286852)
@@ -116,6 +116,7 @@ void        fillw(int /*u_short*/ pat, void *ba
 void   fill_based_sd(struct segment_descriptor *sdp, uint32_t base);
 void   initializecpu(void);
 void   initializecpucache(void);
+bool   intel_fix_cpuid(void);
 void   i686_pagezero(void *addr);
 void   sse2_pagezero(void *addr);
 void   init_AMD_Elan_sc520(void);

Modified: stable/10/sys/x86/x86/identcpu.c
==============================================================================
--- stable/10/sys/x86/x86/identcpu.c    Mon Aug 17 18:28:40 2015        
(r286851)
+++ stable/10/sys/x86/x86/identcpu.c    Mon Aug 17 18:33:16 2015        
(r286852)
@@ -1297,6 +1297,33 @@ identify_hypervisor(void)
 #endif
 
 /*
+ * Clear "Limit CPUID Maxval" bit and return true if the caller should
+ * get the largest standard CPUID function number again if it is set
+ * from BIOS.  It is necessary for probing correct CPU topology later
+ * and for the correct operation of the AVX-aware userspace.
+ */
+bool
+intel_fix_cpuid(void)
+{
+       uint64_t msr;
+
+       if (cpu_vendor_id != CPU_VENDOR_INTEL)
+               return (false);
+       if ((CPUID_TO_FAMILY(cpu_id) == 0xf &&
+           CPUID_TO_MODEL(cpu_id) >= 0x3) ||
+           (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
+           CPUID_TO_MODEL(cpu_id) >= 0xe)) {
+               msr = rdmsr(MSR_IA32_MISC_ENABLE);
+               if ((msr & IA32_MISC_EN_LIMCPUID) != 0) {
+                       msr &= ~IA32_MISC_EN_LIMCPUID;
+                       wrmsr(MSR_IA32_MISC_ENABLE, msr);
+                       return (true);
+               }
+       }
+       return (false);
+}
+
+/*
  * Final stage of CPU identification.
  */
 #ifdef __i386__
@@ -1332,22 +1359,9 @@ identify_cpu(void)
 #endif
        cpu_vendor_id = find_cpu_vendor_id();
 
-       /*
-        * Clear "Limit CPUID Maxval" bit and get the largest standard CPUID
-        * function number again if it is set from BIOS.  It is necessary
-        * for probing correct CPU topology later.
-        * XXX This is only done on the BSP package.
-        */
-       if (cpu_vendor_id == CPU_VENDOR_INTEL && cpu_high > 0 && cpu_high < 4 &&
-           ((CPUID_TO_FAMILY(cpu_id) == 0xf && CPUID_TO_MODEL(cpu_id) >= 0x3) 
||
-           (CPUID_TO_FAMILY(cpu_id) == 0x6 && CPUID_TO_MODEL(cpu_id) >= 0xe))) 
{
-               uint64_t msr;
-               msr = rdmsr(MSR_IA32_MISC_ENABLE);
-               if ((msr & 0x400000ULL) != 0) {
-                       wrmsr(MSR_IA32_MISC_ENABLE, msr & ~0x400000ULL);
-                       do_cpuid(0, regs);
-                       cpu_high = regs[0];
-               }
+       if (intel_fix_cpuid()) {
+               do_cpuid(0, regs);
+               cpu_high = regs[0];
        }
 
        if (cpu_high >= 5 && (cpu_feature2 & CPUID2_MON) != 0) {
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to