xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Xen-devel <xen-devel@lists.xen.org>
Cc: "Andrew Cooper" <andrew.cooper3@citrix.com>,
	"Wei Liu" <wei.liu2@citrix.com>,
	"Jan Beulich" <JBeulich@suse.com>,
	"Roger Pau Monné" <roger.pau@citrix.com>
Subject: [PATCH 3/9] x86/cpuid: Extend the cpuid= command line option to support all named features
Date: Mon, 3 Dec 2018 16:18:16 +0000	[thread overview]
Message-ID: <1543853902-6257-4-git-send-email-andrew.cooper3@citrix.com> (raw)
In-Reply-To: <1543853902-6257-1-git-send-email-andrew.cooper3@citrix.com>

For gen-cpuid.py, fix a comment describing self.names, and generate the
reverse mapping in self.values.  Write out INIT_FEATURE_NAMES which maps a
string name to a bit position.

For parse_cpuid(), introduce a slightly fuzzy strcmp() to accept changes in
punctuation, and perform a binary search over INIT_FEATURE_NAMES.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Wei Liu <wei.liu2@citrix.com>
CC: Roger Pau Monné <roger.pau@citrix.com>

Slightly RFC, because I'm not entirely certain if this is a good idea or not.
---
 xen/arch/x86/cpuid.c   | 91 ++++++++++++++++++++++++++++++++++++--------------
 xen/tools/gen-cpuid.py | 22 ++++++++++--
 2 files changed, 86 insertions(+), 27 deletions(-)

diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 0591a7d..eb86a86 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -18,9 +18,34 @@ static const uint32_t hvm_shadow_featuremask[] = INIT_HVM_SHADOW_FEATURES;
 static const uint32_t hvm_hap_featuremask[] = INIT_HVM_HAP_FEATURES;
 static const uint32_t deep_features[] = INIT_DEEP_FEATURES;
 
+/*
+ * Works like strcmp(), but customised specifically for this usecase.  'name'
+ * is a NUL terminated string.  's' is considered to match 'name' if the NUL
+ * terminator of 'name' match punctiation in 's'.
+ */
+static int __init cpuid_name_cmp(const char *s, const char *name)
+{
+    int res;
+
+    /* Basic strcmp(). */
+    for ( ; *name != '\0'; ++name, ++s )
+        if ( (res = (*s - *name)) != 0 )
+            break;
+
+    /* If a failure, but only because '=' or ',', override to success. */
+    if ( res && *name == '\0' && (*s == '=' || *s == ',') )
+        res = 0;
+
+    return res;
+}
+
 static int __init parse_xen_cpuid(const char *s)
 {
-    const char *ss;
+    static const struct feature {
+        const char *name;
+        unsigned int bit;
+    } features[] __initconst = INIT_FEATURE_NAMES, *lhs, *mid, *rhs;
+    const char *ss, *feat;
     int val, rc = 0;
 
     do {
@@ -28,32 +53,48 @@ static int __init parse_xen_cpuid(const char *s)
         if ( !ss )
             ss = strchr(s, '\0');
 
-        if ( (val = parse_boolean("ibpb", s, ss)) >= 0 )
-        {
-            if ( !val )
-                setup_clear_cpu_cap(X86_FEATURE_IBPB);
-        }
-        else if ( (val = parse_boolean("ibrsb", s, ss)) >= 0 )
-        {
-            if ( !val )
-                setup_clear_cpu_cap(X86_FEATURE_IBRSB);
-        }
-        else if ( (val = parse_boolean("stibp", s, ss)) >= 0 )
-        {
-            if ( !val )
-                setup_clear_cpu_cap(X86_FEATURE_STIBP);
-        }
-        else if ( (val = parse_boolean("l1d-flush", s, ss)) >= 0 )
-        {
-            if ( !val )
-                setup_clear_cpu_cap(X86_FEATURE_L1D_FLUSH);
-        }
-        else if ( (val = parse_boolean("ssbd", s, ss)) >= 0 )
+        /* Skip the 'no-' prefix for name comparisons. */
+        feat = s;
+        if ( strncmp(s, "no-", 3) == 0 )
+            feat += 3;
+
+        /* (Re)initalise lhs and rhs for binary search. */
+        lhs = features;
+        rhs = features + ARRAY_SIZE(features);
+
+        while ( lhs < rhs )
         {
-            if ( !val )
-                setup_clear_cpu_cap(X86_FEATURE_SSBD);
+            int res;
+
+            mid = lhs + (rhs - lhs) / 2;
+            res = cpuid_name_cmp(feat, mid->name);
+
+            if ( res < 0 )
+            {
+                rhs = mid;
+                continue;
+            }
+            if ( res > 0 )
+            {
+                lhs = mid + 1;
+                continue;
+            }
+
+            if ( (val = parse_boolean(mid->name, s, ss)) >= 0 )
+            {
+                if ( !val )
+                    setup_clear_cpu_cap(mid->bit);
+                mid = NULL;
+            }
+
+            break;
         }
-        else
+
+        /*
+         * Mid being NULL means that the name search failed, or that
+         * parse_boolean() failed.
+         */
+        if ( mid )
             rc = -EINVAL;
 
         s = ss + 1;
diff --git a/xen/tools/gen-cpuid.py b/xen/tools/gen-cpuid.py
index 27569bd..002de6f 100755
--- a/xen/tools/gen-cpuid.py
+++ b/xen/tools/gen-cpuid.py
@@ -19,7 +19,8 @@ class State(object):
         self.output = open_file_or_fd(output, "w", 2)
 
         # State parsed from input
-        self.names = {} # Name => value mapping
+        self.names = {}  # Value => Name mapping
+        self.values = {} # Name => Value mapping
         self.raw_special = set()
         self.raw_pv = set()
         self.raw_hvm_shadow = set()
@@ -76,8 +77,9 @@ def parse_definitions(state):
             this_name = name
         setattr(this, this_name, val)
 
-        # Construct a reverse mapping of value to name
+        # Construct forward and reverse mappings between name and value
         state.names[val] = name
+        state.values[name.lower().replace("_", "-")] = val
 
         for a in attr:
 
@@ -393,6 +395,22 @@ def write_results(state):
     state.output.write(
 """}
 
+#define INIT_FEATURE_NAMES { \\
+""")
+
+    try:
+        _tmp = state.values.iteritems()
+    except AttributeError:
+        _tmp = state.values.items()
+
+    for name, bit in sorted(_tmp):
+        state.output.write(
+            '    { "%s", %sU },\\\n' % (name, bit)
+            )
+
+    state.output.write(
+"""}
+
 """)
 
     for idx, text in enumerate(state.bitfields):
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2018-12-03 16:18 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-03 16:18 [PATCH 0/9] xen/amd: Support for guest MSR_VIRT_SPEC_CTRL support Andrew Cooper
2018-12-03 16:18 ` [PATCH 1/9] x86/spec-ctrl: Drop the bti= command line option Andrew Cooper
2018-12-04 16:19   ` Jan Beulich
2018-12-03 16:18 ` [PATCH 2/9] x86/cpuid: Drop the synthetic X86_FEATURE_XEN_IBPB Andrew Cooper
2018-12-04 16:21   ` Jan Beulich
2018-12-03 16:18 ` Andrew Cooper [this message]
2018-12-04 16:28   ` [PATCH 3/9] x86/cpuid: Extend the cpuid= command line option to support all named features Jan Beulich
2018-12-06 12:52   ` Wei Liu
2018-12-03 16:18 ` [PATCH 4/9] x86/amd: Introduce CPUID/MSR definitions for per-vcpu SSBD support Andrew Cooper
2018-12-04 16:06   ` Woods, Brian
2018-12-05 16:39   ` Jan Beulich
2018-12-05 17:50     ` Andrew Cooper
2018-12-06  8:49       ` Jan Beulich
2018-12-06 18:35         ` Andrew Cooper
2018-12-03 16:18 ` [PATCH 5/9] x86/amd: Probe for legacy SSBD interfaces on boot Andrew Cooper
2018-12-04 16:15   ` Woods, Brian
2018-12-05 16:50   ` Jan Beulich
2018-12-05 17:09     ` Andrew Cooper
2018-12-06  8:53       ` Jan Beulich
2018-12-06 10:59   ` Jan Beulich
2018-12-28 16:30     ` Andrew Cooper
2019-01-04  8:58       ` Jan Beulich
2018-12-03 16:18 ` [PATCH 6/9] x86/amd: Allocate resources to cope with LS_CFG being per-core on Fam17h Andrew Cooper
2018-12-04 16:38   ` Woods, Brian
2018-12-05 16:57   ` Jan Beulich
2018-12-05 17:05     ` Andrew Cooper
2018-12-06  8:54       ` Jan Beulich
2018-12-06 18:46         ` Andrew Cooper
2018-12-06 19:25           ` Woods, Brian
2018-12-07 10:17           ` Jan Beulich
2018-12-03 16:18 ` [PATCH 7/9] x86/amd: Support context switching legacy SSBD interface Andrew Cooper
2018-12-04 20:27   ` Woods, Brian
2018-12-06 10:51   ` Jan Beulich
2018-12-06 18:55     ` Andrew Cooper
2018-12-07 10:25       ` Jan Beulich
2018-12-03 16:18 ` [PATCH 8/9] x86/amd: Virtualise MSR_VIRT_SPEC_CTRL for guests Andrew Cooper
2018-12-04 21:35   ` Woods, Brian
2018-12-05  8:41     ` Jan Beulich
2018-12-05 19:09       ` Andrew Cooper
2018-12-06  8:59         ` Jan Beulich
2018-12-06 19:41       ` Woods, Brian
2018-12-06 10:55   ` Jan Beulich
2018-12-03 16:18 ` [PATCH 9/9] x86/amd: Offer MSR_VIRT_SPEC_CTRL to guests Andrew Cooper
2018-12-06 10:57   ` Jan Beulich
2018-12-03 16:24 ` [PATCH 0/9] xen/amd: Support for guest MSR_VIRT_SPEC_CTRL support Jan Beulich
2018-12-03 16:31   ` Andrew Cooper
2018-12-04  9:45     ` Jan Beulich
2018-12-04 11:26       ` Andrew Cooper
2018-12-04 12:45         ` Jan Beulich
2018-12-04 13:41           ` Andrew Cooper
2018-12-04 14:07             ` Jan Beulich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1543853902-6257-4-git-send-email-andrew.cooper3@citrix.com \
    --to=andrew.cooper3@citrix.com \
    --cc=JBeulich@suse.com \
    --cc=roger.pau@citrix.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).