Date: Mon, 17 Aug 2015 18:33:16 +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-10@freebsd.org Subject: svn commit: r286852 - in stable/10/sys: amd64/amd64 amd64/include i386/i386 i386/include x86/x86 Message-ID: <201508171833.t7HIXGWQ072507@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508171833.t7HIXGWQ072507>