[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/3] x86/cpuid: Disentangle logic for new feature leaves


  • To: Xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
  • Date: Thu, 27 Jan 2022 16:09:38 +0000
  • Authentication-results: esa3.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Jan Beulich <JBeulich@xxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>
  • Delivery-date: Thu, 27 Jan 2022 16:10:01 +0000
  • Ironport-data: A9a23:FEXvoqkfCCFXMZiQ9ie4v5no5gxVIURdPkR7XQ2eYbSJt1+Wr1Gzt xIdXDvQa/zYMGSheYgiPYqw9B4H75Tdy9NjTAQ/qC81EyMWpZLJC+rCIxarNUt+DCFioGGLT Sk6QoOdRCzhZiaE/n9BClVlxJVF/fngqoDUUYYoAQgsA180IMsdoUg7wbRh29Q32YLR7z6l4 rseneWOYDdJ5BYsWo4kw/rrRMRH5amaVJsw5zTSVNgT1LPsvyB94KE3fMldG0DQUIhMdtNWc s6YpF2PEsE1yD92Yj+tuu6TnkTn2dc+NyDW4pZdc/DKbhSvOkXee0v0XRYRQR4/ttmHozx+4 OxhnoSWbTsvApfJub4kWjxlMmZ/HrITrdcrIVDn2SCS50jPcn+qyPRyFkAme4Yf/46bA0kXq 6ZecmpUKEne2aTmm9pXScE17ignBODtMJkSpTdLyjbBAOx9aZvCX7/L9ZlT2zJYasVmQ6yPP 5RHOGAHgBLoM1piJGlHMM8Fper0nHKvdzBT826KnP9ii4TU5FMoi+W8WDbPQfSVQe1Fk0Deo XjJl0zbKBwHMN2UyRKe72mhwOTImEvTSI8UUbG16PNuqFmS3XAITg0bU0Ohpvu0gVL4XMhQQ 3H44QJ38/J0rhbyCICgAVvo+xZooyLwRfJpP8YiziWxzJbu5ifDP2Ehcx8Gaf854ZpeqSMR6 neFmNbgBDpKubKTSG6A+rr8kQ5eKRT5PkdZO3ZaEFJtD83L5dhq00mRFooL/Lud04WtcQwc1 Qxmu8TXa187qccQn5u28lnc695HjsiYF1Vljuk7s4/M0++YWGJHT9HwgbQ4xawZRGp8crVnl CJZ8yR5xLtWZaxhbATXHI0w8EiBvp5pygH0j191BIUG/D+w4XOldo04yGggeBwzaZ5fJ2KxP R67VeZtCHl7ZiXCgUhfONrZNijX5fK4SYSNug78MLKinaSdhCfYpXozNCZ8LkjmkVQ2kLFXB HtoWZ3EMJruMow+lGDeb75EidcDn3lirUuOG8yT50n5gNK2OS7EIZ9YYQDmRr1os8u5TPD9r ow32z2ikUsPCYUTo0D/rOYuELz9BSFrXM+t850OKLfrz8gPMDhJNsI9CIgJI+RN95m5XM+Rl p1kckMHmlf5m1PdLgCGNiJqZL/1BM4tpnMnJy08e12v3iF7M4qo6a4ecboxfKUmq7M/naIlE aFddpXSGOlLRxTG5y8ZMcv3ort9eUn5ngmJJSekPmQyJsYyWwzT99b4VQLz7y1SXDGvvM4zr uT4hAPWSJYOXSp4C8PSZK79xl+9pyFFyulzQ1HJMp9Yf0C1qNpmLCn4j/kWJcAQKEqcmmvGh ljOWRpB/LvDuY449tXNlJuolYbxHrssBFdeEkna8a2yaXvQ8F28zNISS+2PZz3cCj/5of3we eVPwvjgG/Qbh1IW4ZFkGrNmwK9itdvio7hWklZtEHnRNgn5D7phJj+N3NVVt70Lzbhc4FPkV kWK89hcGLOIJMK6TwJBeFt7NryOhaMOhz3fzfUpO0GrtiZ48Y2OXVhWIxTR2jdWK6F4Md99z Oos0CLMB9dTVvb+3g66sx1p
  • Ironport-hdrordr: A9a23:Jf/qKKlADTwTNAPb36Gq304BkXjpDfIS3DAbv31ZSRFFG/Fw8P re+8jztCWE7Ar5N0tQ++xoVJPhfZq+z/9ICOsqTNGftWDd0QPDQe1fBOPZskTd8kbFh4tgPM lbAstD4fTLfCBHZZmQ2mKF+qwbruVvWprY/ts2tE0DcT1X
  • Ironport-sdr: IFj/TZilgoV/a5sUEyNk8b5YQVsqKHEcaT7+kCO5ldO5aEMbOXSAo/P+jfVHduehIgM8iyXhMI QWM78daELv5M1mWtT8SY6Sk7/FIuahDQGusy8Va03V9hmJLulUKRQvobphE3Rl0v1MAA+bNegn GqFU2DWWOYi7khmc3MmG62G0IxfVjAdBgHjrH7OLb+AhAHKMBUrW4rXkqWjRVuu91so5MEwoLd oYtyTh+kRp0ugsZ6ftWbG8jwHEgsMotUKmhRItH/WYi/d2tI6y1Xgsn81N5YPJNBXZ+UbQ18pL qfL1r6cdhodIJvVS0GysNFLn
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Adding a new feature leaf is a reasonable amount of boilerplate and for the
patch to build, at least one feature from the new leaf needs defining.  This
typically causes two non-trivial changes to be merged together.

First, have gen-cpuid.py write out some extra placeholder defines:

  #define CPUID_BITFIELD_11 bool :1, :1, lfence_dispatch:1, ...
  #define CPUID_BITFIELD_12 uint32_t :32 /* placeholder */
  #define CPUID_BITFIELD_13 uint32_t :32 /* placeholder */
  #define CPUID_BITFIELD_14 uint32_t :32 /* placeholder */
  #define CPUID_BITFIELD_15 uint32_t :32 /* placeholder */

This allows DECL_BITFIELD() to be added to struct cpuid_policy without
requiring a XEN_CPUFEATURE() declared for the leaf.  The choice of 4 is
arbitrary, and allows us to add more than one leaf at a time if necessary.

Second, rework generic_identify() to not use feature leaf names.

The choice of deriving the index from a feature was to avoid mismatches, but
its correctness depends on bugs like c/s 249e0f1d8f20 ("x86/cpuid: Fix
TSXLDTRK definition") not happening.

Switch to using FEATURESET_* just like the policy/featureset helpers.  This
breaks the cognitive complexity of needing to know which leaf a specifically
named feature should reside in, and is shorter to write.  It is also far
easier to identify as correct at a glance, given the correlation with the
CPUID leaf being read.

In addition, tidy up some other bits of generic_identify()
 * Drop leading zeros from leaf numbers.
 * Don't use a locked update for X86_FEATURE_APERFMPERF.
 * Rework extended_cpuid_level calculation to avoid setting it twice.
 * Use "leaf >= $N" consistently so $N matches with the CPUID input.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
CC: Wei Liu <wl@xxxxxxx>
---
 xen/arch/x86/cpu/common.c | 54 +++++++++++++++++++++++------------------------
 xen/tools/gen-cpuid.py    |  2 ++
 2 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index 4a163afbfc7e..c6773c85fd3e 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -379,7 +379,7 @@ static void generic_identify(struct cpuinfo_x86 *c)
        u32 eax, ebx, ecx, edx, tmp;
 
        /* Get vendor name */
-       cpuid(0x00000000, &c->cpuid_level, &ebx, &ecx, &edx);
+       cpuid(0, &c->cpuid_level, &ebx, &ecx, &edx);
        *(u32 *)&c->x86_vendor_id[0] = ebx;
        *(u32 *)&c->x86_vendor_id[8] = ecx;
        *(u32 *)&c->x86_vendor_id[4] = edx;
@@ -394,7 +394,7 @@ static void generic_identify(struct cpuinfo_x86 *c)
        /* Note that the vendor-specific code below might override */
 
        /* Model and family information. */
-       cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
+       cpuid(1, &eax, &ebx, &ecx, &edx);
        c->x86 = get_cpu_family(eax, &c->x86_model, &c->x86_mask);
        c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0);
        c->phys_proc_id = c->apicid;
@@ -404,53 +404,53 @@ static void generic_identify(struct cpuinfo_x86 *c)
 
        /* c_early_init() may have adjusted cpuid levels/features.  Reread. */
        c->cpuid_level = cpuid_eax(0);
-       cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
-       c->x86_capability[cpufeat_word(X86_FEATURE_FPU)] = edx;
-       c->x86_capability[cpufeat_word(X86_FEATURE_SSE3)] = ecx;
+       cpuid(1, &eax, &ebx,
+             &c->x86_capability[FEATURESET_1c],
+             &c->x86_capability[FEATURESET_1d]);
 
        if ( cpu_has(c, X86_FEATURE_CLFLUSH) )
                c->x86_clflush_size = ((ebx >> 8) & 0xff) * 8;
 
        if ( (c->cpuid_level >= CPUID_PM_LEAF) &&
             (cpuid_ecx(CPUID_PM_LEAF) & CPUID6_ECX_APERFMPERF_CAPABILITY) )
-               set_bit(X86_FEATURE_APERFMPERF, c->x86_capability);
+               __set_bit(X86_FEATURE_APERFMPERF, c->x86_capability);
+
+       eax = cpuid_eax(0x80000000);
+       if ((eax >> 16) == 0x8000)
+               c->extended_cpuid_level = eax;
 
        /* AMD-defined flags: level 0x80000001 */
-       c->extended_cpuid_level = cpuid_eax(0x80000000);
-       if ((c->extended_cpuid_level >> 16) != 0x8000)
-               c->extended_cpuid_level = 0;
-       if (c->extended_cpuid_level > 0x80000000)
+       if (c->extended_cpuid_level >= 0x80000001)
                cpuid(0x80000001, &tmp, &tmp,
-                     &c->x86_capability[cpufeat_word(X86_FEATURE_LAHF_LM)],
-                     &c->x86_capability[cpufeat_word(X86_FEATURE_SYSCALL)]);
+                     &c->x86_capability[FEATURESET_e1c],
+                     &c->x86_capability[FEATURESET_e1d]);
 
        if (c->extended_cpuid_level >= 0x80000004)
                get_model_name(c); /* Default name */
        if (c->extended_cpuid_level >= 0x80000007)
-               c->x86_capability[cpufeat_word(X86_FEATURE_ITSC)]
-                       = cpuid_edx(0x80000007);
+               c->x86_capability[FEATURESET_e7d] = cpuid_edx(0x80000007);
        if (c->extended_cpuid_level >= 0x80000008)
-               c->x86_capability[cpufeat_word(X86_FEATURE_CLZERO)]
-                       = cpuid_ebx(0x80000008);
+               c->x86_capability[FEATURESET_e8b] = cpuid_ebx(0x80000008);
        if (c->extended_cpuid_level >= 0x80000021)
-               c->x86_capability[cpufeat_word(X86_FEATURE_LFENCE_DISPATCH)]
-                       = cpuid_eax(0x80000021);
+               c->x86_capability[FEATURESET_e21a] = cpuid_eax(0x80000021);
 
        /* Intel-defined flags: level 0x00000007 */
-       if ( c->cpuid_level >= 0x00000007 ) {
-               cpuid_count(0x00000007, 0, &eax,
-                           
&c->x86_capability[cpufeat_word(X86_FEATURE_FSGSBASE)],
-                           &c->x86_capability[cpufeat_word(X86_FEATURE_PKU)],
-                           
&c->x86_capability[cpufeat_word(X86_FEATURE_AVX512_4VNNIW)]);
-               if (eax > 0)
-                       cpuid_count(0x00000007, 1,
-                                   
&c->x86_capability[cpufeat_word(X86_FEATURE_AVX512_BF16)],
+       if (c->cpuid_level >= 7) {
+               uint32_t max_subleaf;
+
+               cpuid_count(7, 0, &max_subleaf,
+                           &c->x86_capability[FEATURESET_7b0],
+                           &c->x86_capability[FEATURESET_7c0],
+                           &c->x86_capability[FEATURESET_7d0]);
+               if (max_subleaf >= 1)
+                       cpuid_count(7, 1,
+                                   &c->x86_capability[FEATURESET_7a1],
                                    &tmp, &tmp, &tmp);
        }
 
        if (c->cpuid_level >= 0xd)
                cpuid_count(0xd, 1,
-                           
&c->x86_capability[cpufeat_word(X86_FEATURE_XSAVEOPT)],
+                           &c->x86_capability[FEATURESET_Da1],
                            &tmp, &tmp, &tmp);
 }
 
diff --git a/xen/tools/gen-cpuid.py b/xen/tools/gen-cpuid.py
index b953648b6572..470cd76d1c52 100755
--- a/xen/tools/gen-cpuid.py
+++ b/xen/tools/gen-cpuid.py
@@ -423,6 +423,8 @@ def write_results(state):
 
 """)
 
+    state.bitfields += ["uint32_t :32 /* placeholder */"] * 4
+
     for idx, text in enumerate(state.bitfields):
         state.output.write(
             "#define CPUID_BITFIELD_%d \\\n    %s\n\n"
-- 
2.11.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.