> Date: Tue, 2 Feb 2016 09:43:54 -0800
> From: Philip Guenther <[email protected]>
> 
> On Tue, 2 Feb 2016, Philip Guenther wrote:
> ...
> > Currently we seem to assume that the presence of certain CPU features like 
> > AVX implies that CPUID supports the related leaf; that BIOS option breaks 
> > that assumption, resulting in the bogus fpu_save_len sizing you hit.  
> > From the dmesg you posted I see it also explains the bogus mwait sizing 
> > that has been reported by some others.  Your machine will perform better 
> > with that option off; I guess we should add check to the code to catch 
> > this sort of setup by checking the cpuid_level variable before using the 
> > higher CPUID leafs.
> 
> Revised version that switches a few places to check cpuid_level instead of 
> calling CPUID(0) again and similar for using curcpu()->ci_pnfeatset 
> instead of calling CPUID(0x80000000) once identifycpu() sets that, and add 
> a check of ci->ci_pnfeatset before using CPUID(CPUID_AMD_SVM_CAP) in the 
> vmm bits.
> 
> ok?

ok kettenis@

> Index: i386/i386/cpu.c
> ===================================================================
> RCS file: /data/src/openbsd/src/sys/arch/i386/i386/cpu.c,v
> retrieving revision 1.70
> diff -u -p -r1.70 cpu.c
> --- i386/i386/cpu.c   27 Dec 2015 04:31:34 -0000      1.70
> +++ i386/i386/cpu.c   2 Feb 2016 16:54:09 -0000
> @@ -784,7 +784,7 @@ cpu_init_mwait(struct device *dv)
>  {
>       unsigned int smallest, largest, extensions, c_substates;
>  
> -     if ((cpu_ecxfeature & CPUIDECX_MWAIT) == 0)
> +     if ((cpu_ecxfeature & CPUIDECX_MWAIT) == 0 || cpuid_level < 0x5)
>               return;
>  
>       /* get the monitor granularity */
> Index: amd64/amd64/amd64_mem.c
> ===================================================================
> RCS file: /data/src/openbsd/src/sys/arch/amd64/amd64/amd64_mem.c,v
> retrieving revision 1.11
> diff -u -p -r1.11 amd64_mem.c
> --- amd64/amd64/amd64_mem.c   14 Mar 2015 03:38:46 -0000      1.11
> +++ amd64/amd64/amd64_mem.c   2 Feb 2016 17:37:55 -0000
> @@ -583,8 +583,7 @@ mrinit(struct mem_range_softc *sc)
>        * If CPUID does not support leaf function 0x80000008, use the
>        * default a 36-bit address size.
>        */
> -     CPUID(0x80000000, regs[0], regs[1], regs[2], regs[3]);
> -     if (regs[0] >= 0x80000008) {
> +     if (curcpu()->ci_pnfeatset >= 0x80000008) {
>               CPUID(0x80000008, regs[0], regs[1], regs[2], regs[3]);
>               if (regs[0] & 0xff) {
>                       mtrrmask = (1ULL << (regs[0] & 0xff)) - 1;
> Index: amd64/amd64/cacheinfo.c
> ===================================================================
> RCS file: /data/src/openbsd/src/sys/arch/amd64/amd64/cacheinfo.c,v
> retrieving revision 1.7
> diff -u -p -r1.7 cacheinfo.c
> --- amd64/amd64/cacheinfo.c   13 Nov 2015 07:52:20 -0000      1.7
> +++ amd64/amd64/cacheinfo.c   2 Feb 2016 17:36:11 -0000
> @@ -159,7 +159,6 @@ amd_cpu_cacheinfo(struct cpu_info *ci)
>       struct x86_cache_info *cai;
>       int family, model;
>       u_int descs[4];
> -     u_int lfunc;
>  
>       family = ci->ci_family;
>       model = ci->ci_model;
> @@ -171,15 +170,9 @@ amd_cpu_cacheinfo(struct cpu_info *ci)
>               return;
>  
>       /*
> -      * Determine the largest extended function value.
> -      */
> -     CPUID(0x80000000, descs[0], descs[1], descs[2], descs[3]);
> -     lfunc = descs[0];
> -
> -     /*
>        * Determine L1 cache/TLB info.
>        */
> -     if (lfunc < 0x80000005) {
> +     if (ci->ci_pnfeatset < 0x80000005) {
>               /* No L1 cache info available. */
>               return;
>       }
> @@ -228,7 +221,7 @@ amd_cpu_cacheinfo(struct cpu_info *ci)
>       /*
>        * Determine L2 cache/TLB info.
>        */
> -     if (lfunc < 0x80000006) {
> +     if (ci->ci_pnfeatset < 0x80000006) {
>               /* No L2 cache info available. */
>               return;
>       }
> Index: amd64/amd64/cpu.c
> ===================================================================
> RCS file: /data/src/openbsd/src/sys/arch/amd64/amd64/cpu.c,v
> retrieving revision 1.94
> diff -u -p -r1.94 cpu.c
> --- amd64/amd64/cpu.c 27 Dec 2015 04:31:34 -0000      1.94
> +++ amd64/amd64/cpu.c 2 Feb 2016 17:03:04 -0000
> @@ -282,7 +282,7 @@ cpu_init_mwait(struct cpu_softc *sc)
>  {
>       unsigned int smallest, largest, extensions, c_substates;
>  
> -     if ((cpu_ecxfeature & CPUIDECX_MWAIT) == 0)
> +     if ((cpu_ecxfeature & CPUIDECX_MWAIT) == 0 || cpuid_level < 0x5)
>               return;
>  
>       /* get the monitor granularity */
> @@ -505,7 +505,7 @@ cpu_init(struct cpu_info *ci)
>               cr4 |= CR4_OSXSAVE;
>       lcr4(cr4);
>  
> -     if (cpu_ecxfeature & CPUIDECX_XSAVE) {
> +     if ((cpu_ecxfeature & CPUIDECX_XSAVE) && cpuid_level >= 0xd) {
>               u_int32_t eax, ebx, ecx, edx;
>  
>               xsave_mask = XCR0_X87 | XCR0_SSE;
> Index: amd64/amd64/identcpu.c
> ===================================================================
> RCS file: /data/src/openbsd/src/sys/arch/amd64/amd64/identcpu.c,v
> retrieving revision 1.71
> diff -u -p -r1.71 identcpu.c
> --- amd64/amd64/identcpu.c    27 Dec 2015 04:31:34 -0000      1.71
> +++ amd64/amd64/identcpu.c    2 Feb 2016 17:35:36 -0000
> @@ -700,8 +700,7 @@ cpu_topology(struct cpu_info *ci)
>       u_int32_t smt_mask = 0, core_mask, pkg_mask = 0;
>  
>       /* We need at least apicid at CPUID 1 */
> -     CPUID(0, eax, ebx, ecx, edx);
> -     if (eax < 1)
> +     if (cpuid_level < 1)
>               goto no_topology;
>  
>       /* Initial apicid */
> @@ -710,8 +709,7 @@ cpu_topology(struct cpu_info *ci)
>  
>       if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
>               /* We need at least apicid at CPUID 0x80000008 */
> -             CPUID(0x80000000, eax, ebx, ecx, edx);
> -             if (eax < 0x80000008)
> +             if (ci->ci_pnfeatset < 0x80000008)
>                       goto no_topology;
>  
>               CPUID(0x80000008, eax, ebx, ecx, edx);
> @@ -727,8 +725,7 @@ cpu_topology(struct cpu_info *ci)
>               ci->ci_pkg_id >>= core_bits;
>       } else if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
>               /* We only support leaf 1/4 detection */
> -             CPUID(0, eax, ebx, ecx, edx);
> -             if (eax < 4)
> +             if (cpuid_level < 4)
>                       goto no_topology;
>               /* Get max_apicid */
>               CPUID(1, eax, ebx, ecx, edx);
> @@ -858,7 +855,8 @@ cpu_check_vmm_cap(struct cpu_info *ci)
>       /*
>        * Check for SVM Nested Paging
>        */
> -     if (ci->ci_vmm_flags & CI_VMM_SVM) {
> +     if ((ci->ci_vmm_flags & CI_VMM_SVM) &&
> +         ci->ci_pnfeatset >= CPUID_AMD_SVM_CAP) {
>               CPUID(CPUID_AMD_SVM_CAP, dummy, dummy, dummy, cap);
>               if (cap & AMD_SVM_NESTED_PAGING_CAP)
>                       ci->ci_vmm_flags |= CI_VMM_RVI;
> 
> 

Reply via email to