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

[PATCH 1/9] tools/libx[cl]: Introduce struct xc_xend_cpuid for xc_cpuid_set()


  • To: Xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
  • Date: Mon, 15 Jun 2020 15:15:24 +0100
  • Authentication-results: esa3.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none
  • Cc: Wei Liu <wl@xxxxxxx>, Paul Durrant <paul@xxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Jan Beulich <JBeulich@xxxxxxxx>, Ian Jackson <Ian.Jackson@xxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Delivery-date: Mon, 15 Jun 2020 14:16:14 +0000
  • Ironport-sdr: UDaqbc4TbHeYODtc+HkmveLoGbw/Tno3hC+KDZcJ96XhD748wssAHbyq/SyAnFuaZFPhHX+vxB bf1cOvEcp0XrYwqCjk25x88wV+9yrTrLLVnlEusbDIxnZ4PpdUg3a+Z87VhFRZFkHFN6X0fQXZ YOh1W6DRzAxgseB+FrUBfXJJ6zSxXo8A1nqKicOdIjaC0SInshwv1/D2pHwHSRMXxnEMCLs7Kj hkSjdhOwRY/mg9PzaAnrJ9vWkzMzIdWiK9nyKAvWl0IulfEsBIVT4PZwFNMarlVr63uUEv1R2Y SOY=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

In order to combine the functionality of xc_cpuid_set() with
xc_cpuid_apply_policy(), arrange to pass the data in a single contained
struct, rather than two arrays.

libxl__cpuid_policy is the ideal structure to use, but that would introduce a
reverse dependency between libxc and libxl.  Introduce xc_xend_cpuid (with a
transparent union to provide more useful names for the inputs), and use this
structure in libxl.

The public API has libxl_cpuid_policy as an opaque type referencing
libxl__cpuid_policy.  Drop the inappropriate comment about its internals, and
use xc_xend_cpuid as a differently named opaque backing object.  Users of both
libxl and libxc are not permitted to look at the internals.

No change in behaviour.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Ian Jackson <Ian.Jackson@xxxxxxxxxx>
CC: Wei Liu <wl@xxxxxxx>
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Wei Liu <wl@xxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
CC: Paul Durrant <paul@xxxxxxx>
---
 tools/libxc/include/xenctrl.h | 30 ++++++++++++++++++++++++++++--
 tools/libxc/xc_cpuid_x86.c    | 39 +++++++++++----------------------------
 tools/libxl/libxl.h           |  8 ++++----
 tools/libxl/libxl_cpuid.c     |  7 +++----
 tools/libxl/libxl_internal.h  | 10 ----------
 5 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 113ddd935d..178144e8e2 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -1792,10 +1792,36 @@ int xc_domain_debug_control(xc_interface *xch,
                             uint32_t vcpu);
 
 #if defined(__i386__) || defined(__x86_64__)
+
+/*
+ * CPUID policy data, expressed in the legacy XEND format.
+ *
+ * Policy is an array of strings, 32 chars long:
+ *   policy[0] = eax
+ *   policy[1] = ebx
+ *   policy[2] = ecx
+ *   policy[3] = edx
+ *
+ * The format of the string is the following:
+ *   '1' -> force to 1
+ *   '0' -> force to 0
+ *   'x' -> we don't care (use default)
+ *   'k' -> pass through host value
+ *   's' -> legacy alias for 'k'
+ */
+struct xc_xend_cpuid {
+    union {
+        struct {
+            uint32_t leaf, subleaf;
+        };
+        uint32_t input[2];
+    };
+    char *policy[4];
+};
+
 int xc_cpuid_set(xc_interface *xch,
                  uint32_t domid,
-                 const unsigned int *input,
-                 const char **config);
+                 const struct xc_xend_cpuid *xend);
 
 /*
  * Make adjustments to the CPUID settings for a domain.
diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index b42edd6457..edc2ad9b47 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -259,27 +259,8 @@ int xc_set_domain_cpu_policy(xc_interface *xch, uint32_t 
domid,
     return ret;
 }
 
-/*
- * Configure a single input with the informatiom from config.
- *
- * Config is an array of strings:
- *   config[0] = eax
- *   config[1] = ebx
- *   config[2] = ecx
- *   config[3] = edx
- *
- * The format of the string is the following:
- *   '1' -> force to 1
- *   '0' -> force to 0
- *   'x' -> we don't care (use default)
- *   'k' -> pass through host value
- *   's' -> legacy alias for 'k'
- *
- * In all cases, the returned string consists of just '0' and '1'.
- */
 int xc_cpuid_set(
-    xc_interface *xch, uint32_t domid, const unsigned int *input,
-    const char **config)
+    xc_interface *xch, uint32_t domid, const struct xc_xend_cpuid *xend)
 {
     int rc;
     unsigned int i, j, regs[4] = {}, polregs[4] = {};
@@ -324,7 +305,8 @@ int xc_cpuid_set(
         goto fail;
     }
     for ( i = 0; i < policy_leaves; ++i )
-        if ( leaves[i].leaf == input[0] && leaves[i].subleaf == input[1] )
+        if ( leaves[i].leaf == xend->leaf &&
+             leaves[i].subleaf == xend->subleaf )
         {
             polregs[0] = leaves[i].a;
             polregs[1] = leaves[i].b;
@@ -345,7 +327,8 @@ int xc_cpuid_set(
         goto fail;
     }
     for ( i = 0; i < policy_leaves; ++i )
-        if ( leaves[i].leaf == input[0] && leaves[i].subleaf == input[1] )
+        if ( leaves[i].leaf == xend->leaf &&
+             leaves[i].subleaf == xend->subleaf )
         {
             regs[0] = leaves[i].a;
             regs[1] = leaves[i].b;
@@ -356,7 +339,7 @@ int xc_cpuid_set(
 
     for ( i = 0; i < 4; i++ )
     {
-        if ( config[i] == NULL )
+        if ( xend->policy[i] == NULL )
         {
             regs[i] = polregs[i];
             continue;
@@ -375,14 +358,14 @@ int xc_cpuid_set(
             unsigned char polval = !!((polregs[i] & (1U << (31 - j))));
 
             rc = -EINVAL;
-            if ( !strchr("10xks", config[i][j]) )
+            if ( !strchr("10xks", xend->policy[i][j]) )
                 goto fail;
 
-            if ( config[i][j] == '1' )
+            if ( xend->policy[i][j] == '1' )
                 val = 1;
-            else if ( config[i][j] == '0' )
+            else if ( xend->policy[i][j] == '0' )
                 val = 0;
-            else if ( config[i][j] == 'x' )
+            else if ( xend->policy[i][j] == 'x' )
                 val = polval;
 
             if ( val )
@@ -393,7 +376,7 @@ int xc_cpuid_set(
     }
 
     /* Feed the transformed leaf back up to Xen. */
-    leaves[0] = (xen_cpuid_leaf_t){ input[0], input[1],
+    leaves[0] = (xen_cpuid_leaf_t){ xend->leaf, xend->subleaf,
                                     regs[0], regs[1], regs[2], regs[3] };
     rc = xc_set_domain_cpu_policy(xch, domid, 1, leaves, 0, NULL,
                                   &err_leaf, &err_subleaf, &err_msr);
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 71709dc585..1cd6c38e83 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1310,11 +1310,11 @@ typedef struct {
 void libxl_bitmap_init(libxl_bitmap *map);
 void libxl_bitmap_dispose(libxl_bitmap *map);
 
-/* libxl_cpuid_policy_list is a dynamic array storing CPUID policies
- * for multiple leafs. It is terminated with an entry holding
- * XEN_CPUID_INPUT_UNUSED in input[0]
+/*
+ * libxl_cpuid_policy is opaque in the libxl ABI.  Users of both libxl and
+ * libxc may not make assumptions about xc_xend_cpuid.
  */
-typedef struct libxl__cpuid_policy libxl_cpuid_policy;
+typedef struct xc_xend_cpuid libxl_cpuid_policy;
 typedef libxl_cpuid_policy * libxl_cpuid_policy_list;
 void libxl_cpuid_dispose(libxl_cpuid_policy_list *cpuid_list);
 int libxl_cpuid_policy_list_length(const libxl_cpuid_policy_list *l);
diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c
index 796ec4f2d9..e001cbcd4f 100644
--- a/tools/libxl/libxl_cpuid.c
+++ b/tools/libxl/libxl_cpuid.c
@@ -288,7 +288,7 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list 
*cpuid, const char* str)
     char *sep, *val, *endptr;
     int i;
     const struct cpuid_flags *flag;
-    struct libxl__cpuid_policy *entry;
+    struct xc_xend_cpuid *entry;
     unsigned long num;
     char flags[33], *resstr;
 
@@ -366,7 +366,7 @@ int libxl_cpuid_parse_config_xend(libxl_cpuid_policy_list 
*cpuid,
     char *endptr;
     unsigned long value;
     uint32_t leaf, subleaf = XEN_CPUID_INPUT_UNUSED;
-    struct libxl__cpuid_policy *entry;
+    struct xc_xend_cpuid *entry;
 
     /* parse the leaf number */
     value = strtoul(str, &endptr, 0);
@@ -442,8 +442,7 @@ void libxl__cpuid_legacy(libxl_ctx *ctx, uint32_t domid,
         return;
 
     for (i = 0; cpuid[i].input[0] != XEN_CPUID_INPUT_UNUSED; i++)
-        xc_cpuid_set(ctx->xch, domid, cpuid[i].input,
-                     (const char**)cpuid[i].policy);
+        xc_cpuid_set(ctx->xch, domid, &cpuid[i]);
 }
 
 static const char *input_names[2] = { "leaf", "subleaf" };
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index c7ece066c4..79c2bf5f5e 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -2056,16 +2056,6 @@ typedef yajl_gen_status 
(*libxl__gen_json_callback)(yajl_gen hand, void *);
 _hidden char *libxl__object_to_json(libxl_ctx *ctx, const char *type,
                                     libxl__gen_json_callback gen, void *p);
 
-  /* holds the CPUID response for a single CPUID leaf
-   * input contains the value of the EAX and ECX register,
-   * and each policy string contains a filter to apply to
-   * the host given values for that particular leaf.
-   */
-struct libxl__cpuid_policy {
-    uint32_t input[2];
-    char *policy[4];
-};
-
 _hidden void libxl__cpuid_legacy(libxl_ctx *ctx, uint32_t domid,
                                  libxl_domain_build_info *info);
 
-- 
2.11.0




 


Rackspace

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