From owner-svn-src-stable-10@freebsd.org Mon Aug 17 18:33:18 2015 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4F2309BB66C; Mon, 17 Aug 2015 18:33:18 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2C3EE15FB; Mon, 17 Aug 2015 18:33:18 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t7HIXIAU072512; Mon, 17 Aug 2015 18:33:18 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t7HIXGWQ072507; Mon, 17 Aug 2015 18:33:16 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201508171833.t7HIXGWQ072507@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Mon, 17 Aug 2015 18:33:16 +0000 (UTC) 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 X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Aug 2015 18:33:18 -0000 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) {