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

[PATCH v7 06/11] libs/guest: introduce helper set cpu topology in cpu policy


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Roger Pau Monne <roger.pau@xxxxxxxxxx>
  • Date: Tue, 25 Jan 2022 15:49:30 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=CKBxmdpTfoOmyTPejv/3lOo/EtPuysXYY91sehS4dfs=; b=PgC8f4UxY/rcMjBlP0pqgErPtoJAavHrM0/vEBjdY4pl77VhzCBJQVv2u12wJQDTG38lxE+1+7RRRqaK7zhsyuj2vztkvxti9UQD014Q6+4MAE+vt16ZDSvtNX/KT24fE7EyysjdsCJHN1dblilQAylgqMHfbliAV4+xG2Ju9gWoxE3aoHYWnWK4coSX9dtXtT/vis9RI6MjoXdhvZ2aTa3mi/zY91bq2sQcSKPiw/kr0Pltr11xBzkWl0liufY4d3nEK3cWTBpbAtArURU6330zZ2kaWKvAeOeENA0O+uCPJ1RFEYAmcDembEe7zuKlVjhZqPoAymiJ7YUSOZdbOw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=dtgMNc/9nKTu6xrSplo0tkkhVA6bxISQ8yJb8WRZvF56l7e0LijgZKI+XeukS8yHWpflwV7evEhF7R17LZiXZCO9Yj9yUbEUOO5oQTUUYLq+ViVlit1MsyNzg3zPEs8swTn08SyFqIH33YBpxvTeyUSkU/LmwfrAq56gx+757OrPw9D2ern5RYL3bkkLvdj/ueEfDYFy7NtBjK2AciLVkBs2gFFGnMfOjU8dWY+JpVjH8wYrRr9a8pNy9Cmiu+0cRgdt7bz0zGmJoruUW2ibpTYr/HLy7VXWbbhkYZ0YLTJ74KJNrNpK19gF6Cf8Vhw3GS4YrF+edEfoPOYdIt6JQQ==
  • Authentication-results: esa6.hc3370-68.iphmx.com; dkim=pass (signature verified) header.i=@citrix.onmicrosoft.com
  • Cc: Roger Pau Monne <roger.pau@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, "Anthony PERARD" <anthony.perard@xxxxxxxxxx>, Juergen Gross <jgross@xxxxxxxx>
  • Delivery-date: Tue, 25 Jan 2022 14:50:25 +0000
  • Ironport-data: A9a23:HdTC5aLOV0tr2qUUFE+RNZIlxSXFcZb7ZxGr2PjKsXjdYENShTQFn GsXWz2CPa7cMzD2Kd52YImxph4HvpKHmoAyHgRlqX01Q3x08seUXt7xwmUcns+xwm8vaGo9s q3yv/GZdJhcokcxIn5BC5C5xZVG/fjgqoHUVaiUakideSc+EH170Us5xrZj6mJVqYPR7z2l6 IuaT/L3YDdJ6xYsWo7Dw/vewP/HlK2aVAIw5jTSV9gS1LPtvyB94KYkDbOwNxPFrrx8RYZWc QphIIaRpQs19z91Yj+sfy2SnkciGtY+NiDW4pZatjTLbrGvaUXe345iXMfwZ3u7hB2Qrtdhk fpJp6bsagEnN/D9ku4AbQthRnQW0a1uoNcrIFC6uM2XiUbHb2Ht07NlC0Re0Y8wo7gtRzsUr LpBdW5LPkvra+GemdpXTsF2gcsuNo/zNZ43sXB81zDJS/0hRPgvRo2Uv4EDgWlq2aiiG971e eswdgZIcyidak10G31LIr0lt8qn0yyXnzpw9wvO+PtfD3Lo5A5+yr/2K/LOZ8eHA85Smy6wu Wbu72n/RBYAO7S32TeDt36hmOLLtSf6Q54JUq218OZwh1+ezXBVDwcZPWZXutHg1BT4AYgGb RVJpGx+9sDe6XBHUPHkbhqo+VGArCRAeNxeGrAL4guQ9LjttlPx6nc/chZNb9kvtckTTDMs1 0OUk96BOQGDoIF5WlrGqO7K8Gra1Tw9aDZbOHRaFVdtD8zL/dlr5i8jWOqPB0JcYjfdPTjri w6HoyEl71n4pZ5ajv7rlbwrbt/Fm3QocuLXzliPNo5GxlkgDGJAW2BOwQKHhRqnBN3BJmRtR FBex6CjABkmVPlhbhClTuQXB62O7P2YKjDailMHN8B/q2/1py/8It4BsWkWyKJV3iAsI2OBj Kj74ls52XOuFCHyMf8fj3yZVazGMpQM5fy6D6uJP7Kik7B6dROd/TEGWKJj9zuFraTYqolmY c3zWZ/1VR4yUP07pBLrGbt1+eJ1l0gWmDOCLbimnk/P+efPOxaopUItbQHmghYRtv3U+W04M r93aqO39vmoeLSuO3aMqd9KcwliwLpSLcmelvG7v9Wre2JOMGogF+XQ0fUmfYlklL5SjeDG4 je2XUow9bY1rSevxdyiZi8xZbXxc4x4qH5nbyUgMUzxgyooYJq17bdZfJwyJOF1+OtmxP9yb v8EZ8TfXagfFmWZo2wQPcvnsYhvVBW3ngbSbSCrVycyIsx7TAvT9966Iga2rHsSDjC6vNcVq qG70l+JWoIKQglvVZ6EaP+mw16rk2IaneZ+AxnBLtVJIR2++4l2MS3hyPQwJphUexnEwzKb0 SeQAAsZ+raR89NkroGRiPnd/YmzEuZ4Ek5LJEXh7O67ZXvA426u4Y5cS+LULzrTY3z5pfe5b uJPwvCibPBexARWs5BxGqpAxL4l44e9vKdTywlpESmZb1mvDb88cHCK0dMW6/9Iz75d/wC3R liO6p9RPrDQYJHpF1sYJQwEaOWf1K5LxmmOvKpteEiqtjVq+LenUFlJO0jegSNQG7J5LYc5z Lpzo8UR8QG+1kInP9vuYvq4LIhQwqjsi5kai6w=
  • Ironport-hdrordr: A9a23:dim6ta3JqpR/3NtUlqmMlgqjBSpyeYIsimQD101hICG9Lfb2qy n+ppgmPEHP5Qr5OEtApTiBUJPwJU80kqQFnbX5XI3SITUO3VHHEGgM1/qF/9SNIVydygcZ79 YaT0EcMqyAMbEZt7eC3ODQKb9Jq7PmgcOVbKXlvg1QpGlRGt9dBmxCe2Gm+yNNNWx77c1TLu vi2iMLnUvqRV0nKuCAQlUVVenKoNPG0LrgfB49HhYirC2Dlymh5rLWGwWRmk52aUID/Z4StU z+1yDp7KSqtP+2jjfaym/o9pxT3P/s0MFKCsCggtUcbh/slgGrToJ8XKDqhkF+nMifrHIR1P XcqRYpOMp+r1vXY2GOuBPonzLt1T4/gkWSv2OwsD/Gm4jUVTg6A81OicZyaR3C8Xctu9l6ze Ziw3+Zn4A/N2KPoA3No/zzEz16nEu9pnQv1cQJiWZEbIcYYLhN6aQC4UJuFosaFi6S0vFpLA BXNrCd2B9qSyLYU5iA1VMfguBEH05DUitue3Jy+/B8iFNt7TVEJ0hx/r1pop5PzuN4d3B+3Z W2Dk1frsA7ciYnV9MMOA4/e7rENoW0e2O1DIuzGyWvKEhVAQOEl3bIiI9Fkd1CPqZ4i6cPpA ==
  • Ironport-sdr: 5u/vxmqF48XsEYBr7dCsFG0wEywCXnBJ1Xi3TEQSOrpeaK+pPZxw1btriIUcPaznONxxMMPJsS jUhKh019TtuHuUR/E74/tK4QJm/g5TFUujNBGViIFN0TN3RK5vqyNIXIJGnjVL5P/zdrMQPgVA arsTHgyIb+aqH+R9stmkZ2P4XW5W2OCfVENhuJgaRQnYHpYOuo3xyEEPUzmYEhZEV5VlM2XaJY cR3NTo7+zs1njCskKWHDWKPiLc0UHLMcFsw7G3ng/0rOp3kI6qpnakbM7befImYdQSj/y2Pzfg aUnZIqb4neRuxnfVVvU6rtNa
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

This logic is pulled out from xc_cpuid_apply_policy and placed into a
separate helper. Note the legacy part of the introduced function, as
long term Xen will require a proper topology setter function capable
of expressing a more diverse set of topologies.

No functional change intended.

Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
Changes since v6:
 - Pass a host policy to xc_cpu_policy_legacy_topology.

Changes since v5:
 - Keep using the host featureset.
 - Fix copied comment typo.

Changes since v4:
 - s/xc_cpu_policy_topology/xc_cpu_policy_legacy_topology/
---
 tools/include/xenguest.h        |   9 ++
 tools/libs/guest/xg_cpuid_x86.c | 165 ++++++++++++++++----------------
 2 files changed, 91 insertions(+), 83 deletions(-)

diff --git a/tools/include/xenguest.h b/tools/include/xenguest.h
index df18c73984..5e60f81192 100644
--- a/tools/include/xenguest.h
+++ b/tools/include/xenguest.h
@@ -821,6 +821,15 @@ bool xc_cpu_policy_is_compatible(xc_interface *xch, 
xc_cpu_policy_t *host,
 void xc_cpu_policy_make_compat_4_12(xc_interface *xch, xc_cpu_policy_t *policy,
                                     const xc_cpu_policy_t *host, bool hvm);
 
+/*
+ * Setup the legacy policy topology.
+ *
+ * The `host` parameter should only be provided when creating a policy for a PV
+ * guest.
+ */
+void xc_cpu_policy_legacy_topology(xc_interface *xch, xc_cpu_policy_t *policy,
+                                   const xc_cpu_policy_t *host);
+
 int xc_get_cpu_levelling_caps(xc_interface *xch, uint32_t *caps);
 int xc_get_cpu_featureset(xc_interface *xch, uint32_t index,
                           uint32_t *nr_features, uint32_t *featureset);
diff --git a/tools/libs/guest/xg_cpuid_x86.c b/tools/libs/guest/xg_cpuid_x86.c
index 20fd786da3..6d8d16eed5 100644
--- a/tools/libs/guest/xg_cpuid_x86.c
+++ b/tools/libs/guest/xg_cpuid_x86.c
@@ -429,14 +429,12 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t 
domid, bool restore,
 {
     int rc;
     xc_dominfo_t di;
-    unsigned int i, nr_leaves, nr_msrs;
+    unsigned int nr_leaves, nr_msrs;
     xen_cpuid_leaf_t *leaves = NULL;
     struct cpuid_policy *p = NULL;
     xc_cpu_policy_t *policy = NULL;
     xc_cpu_policy_t *host = NULL;
     uint32_t err_leaf = -1, err_subleaf = -1, err_msr = -1;
-    uint32_t host_featureset[FEATURESET_NR_ENTRIES] = {};
-    uint32_t len = ARRAY_SIZE(host_featureset);
 
     if ( xc_domain_getinfo(xch, domid, 1, &di) != 1 ||
          di.domid != domid )
@@ -461,24 +459,14 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t 
domid, bool restore,
          (host = xc_cpu_policy_init()) == NULL )
         goto out;
 
-    /* Get the host policy. */
-    rc = xc_get_cpu_featureset(xch, XEN_SYSCTL_cpu_featureset_host,
-                               &len, host_featureset);
+    rc = xc_cpu_policy_get_system(xch, XEN_SYSCTL_cpu_policy_host, host);
     if ( rc )
     {
-        /* Tolerate "buffer too small", as we've got the bits we need. */
-        if ( errno == ENOBUFS )
-            rc = 0;
-        else
-        {
-            PERROR("Failed to obtain host featureset");
-            rc = -errno;
-            goto out;
-        }
+        PERROR("Failed to get host policy");
+        rc = -errno;
+        goto out;
     }
 
-    cpuid_featureset_to_policy(host_featureset, &host->cpuid);
-
     /* Get the domain's default policy. */
     nr_msrs = 0;
     rc = get_system_cpu_policy(xch, di.hvm ? XEN_SYSCTL_cpu_policy_hvm_default
@@ -562,72 +550,9 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t 
domid, bool restore,
         }
     }
 
-    if ( !di.hvm )
-    {
-        /*
-         * On hardware without CPUID Faulting, PV guests see real topology.
-         * As a consequence, they also need to see the host htt/cmp fields.
-         */
-        p->basic.htt       = test_bit(X86_FEATURE_HTT, host_featureset);
-        p->extd.cmp_legacy = test_bit(X86_FEATURE_CMP_LEGACY, host_featureset);
-    }
-    else
-    {
-        /*
-         * Topology for HVM guests is entirely controlled by Xen.  For now, we
-         * hardcode APIC_ID = vcpu_id * 2 to give the illusion of no SMT.
-         */
-        p->basic.htt = true;
-        p->extd.cmp_legacy = false;
-
-        /*
-         * Leaf 1 EBX[23:16] is Maximum Logical Processors Per Package.
-         * Update to reflect vLAPIC_ID = vCPU_ID * 2, but make sure to avoid
-         * overflow.
-         */
-        if ( !p->basic.lppp )
-            p->basic.lppp = 2;
-        else if ( !(p->basic.lppp & 0x80) )
-            p->basic.lppp *= 2;
-
-        switch ( p->x86_vendor )
-        {
-        case X86_VENDOR_INTEL:
-            for ( i = 0; (p->cache.subleaf[i].type &&
-                          i < ARRAY_SIZE(p->cache.raw)); ++i )
-            {
-                p->cache.subleaf[i].cores_per_package =
-                    (p->cache.subleaf[i].cores_per_package << 1) | 1;
-                p->cache.subleaf[i].threads_per_cache = 0;
-            }
-            break;
-
-        case X86_VENDOR_AMD:
-        case X86_VENDOR_HYGON:
-            /*
-             * Leaf 0x80000008 ECX[15:12] is ApicIdCoreSize.
-             * Leaf 0x80000008 ECX[7:0] is NumberOfCores (minus one).
-             * Update to reflect vLAPIC_ID = vCPU_ID * 2.  But avoid
-             * - overflow,
-             * - going out of sync with leaf 1 EBX[23:16],
-             * - incrementing ApicIdCoreSize when it's zero (which changes the
-             *   meaning of bits 7:0).
-             *
-             * UPDATE: I addition to avoiding overflow, some
-             * proprietary operating systems have trouble with
-             * apic_id_size values greater than 7.  Limit the value to
-             * 7 for now.
-             */
-            if ( p->extd.nc < 0x7f )
-            {
-                if ( p->extd.apic_id_size != 0 && p->extd.apic_id_size < 0x7 )
-                    p->extd.apic_id_size++;
-
-                p->extd.nc = (p->extd.nc << 1) | 1;
-            }
-            break;
-        }
-    }
+    policy->cpuid = *p;
+    xc_cpu_policy_legacy_topology(xch, policy, di.hvm ? NULL : host);
+    *p = policy->cpuid;
 
     rc = x86_cpuid_copy_to_buffer(p, leaves, &nr_leaves);
     if ( rc )
@@ -933,3 +858,77 @@ void xc_cpu_policy_make_compat_4_12(xc_interface *xch, 
xc_cpu_policy_t *policy,
     policy->cpuid.feat.max_subleaf = 0;
     policy->cpuid.extd.max_leaf = min(policy->cpuid.extd.max_leaf, 0x8000001c);
 }
+
+void xc_cpu_policy_legacy_topology(xc_interface *xch, xc_cpu_policy_t *policy,
+                                   const xc_cpu_policy_t *host)
+{
+    if ( host )
+    {
+        /*
+         * On hardware without CPUID Faulting, PV guests see real topology.
+         * As a consequence, they also need to see the host htt/cmp fields.
+         */
+        policy->cpuid.basic.htt = host->cpuid.basic.htt;
+        policy->cpuid.extd.cmp_legacy = host->cpuid.extd.cmp_legacy;
+    }
+    else
+    {
+        unsigned int i;
+
+        /*
+         * Topology for HVM guests is entirely controlled by Xen.  For now, we
+         * hardcode APIC_ID = vcpu_id * 2 to give the illusion of no SMT.
+         */
+        policy->cpuid.basic.htt = true;
+        policy->cpuid.extd.cmp_legacy = false;
+
+        /*
+         * Leaf 1 EBX[23:16] is Maximum Logical Processors Per Package.
+         * Update to reflect vLAPIC_ID = vCPU_ID * 2, but make sure to avoid
+         * overflow.
+         */
+        if ( !policy->cpuid.basic.lppp )
+            policy->cpuid.basic.lppp = 2;
+        else if ( !(policy->cpuid.basic.lppp & 0x80) )
+            policy->cpuid.basic.lppp *= 2;
+
+        switch ( policy->cpuid.x86_vendor )
+        {
+        case X86_VENDOR_INTEL:
+            for ( i = 0; (policy->cpuid.cache.subleaf[i].type &&
+                          i < ARRAY_SIZE(policy->cpuid.cache.raw)); ++i )
+            {
+                policy->cpuid.cache.subleaf[i].cores_per_package =
+                  (policy->cpuid.cache.subleaf[i].cores_per_package << 1) | 1;
+                policy->cpuid.cache.subleaf[i].threads_per_cache = 0;
+            }
+            break;
+
+        case X86_VENDOR_AMD:
+        case X86_VENDOR_HYGON:
+            /*
+             * Leaf 0x80000008 ECX[15:12] is ApicIdCoreSize.
+             * Leaf 0x80000008 ECX[7:0] is NumberOfCores (minus one).
+             * Update to reflect vLAPIC_ID = vCPU_ID * 2.  But avoid
+             * - overflow,
+             * - going out of sync with leaf 1 EBX[23:16],
+             * - incrementing ApicIdCoreSize when it's zero (which changes the
+             *   meaning of bits 7:0).
+             *
+             * UPDATE: In addition to avoiding overflow, some
+             * proprietary operating systems have trouble with
+             * apic_id_size values greater than 7.  Limit the value to
+             * 7 for now.
+             */
+            if ( policy->cpuid.extd.nc < 0x7f )
+            {
+                if ( policy->cpuid.extd.apic_id_size != 0 &&
+                     policy->cpuid.extd.apic_id_size < 0x7 )
+                    policy->cpuid.extd.apic_id_size++;
+
+                policy->cpuid.extd.nc = (policy->cpuid.extd.nc << 1) | 1;
+            }
+            break;
+        }
+    }
+}
-- 
2.34.1




 


Rackspace

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