From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Xen-devel <xen-devel@lists.xenproject.org>
Cc: "Andrew Cooper" <andrew.cooper3@citrix.com>,
"Wei Liu" <wl@xen.org>, "Jan Beulich" <JBeulich@suse.com>,
"Roger Pau Monné" <roger.pau@citrix.com>
Subject: [Xen-devel] [PATCH v2] x86/cpuid: Extend the cpuid= option to support all named features
Date: Thu, 5 Sep 2019 20:49:09 +0100 [thread overview]
Message-ID: <20190905194909.6811-1-andrew.cooper3@citrix.com> (raw)
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(), use cmdline_strcmp() and perform a binary search over
INIT_FEATURE_NAMES. A tweak to cmdline_strcmp() is needed to break at equals
signs as well.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Wei Liu <wl@xen.org>
CC: Roger Pau Monné <roger.pau@citrix.com>
v2:
* Rebase over cmdline_strcmp()
---
xen/arch/x86/cpuid.c | 75 +++++++++++++++++++++++++++++++-------------------
xen/common/kernel.c | 6 ++--
xen/include/xen/lib.h | 4 +--
xen/tools/gen-cpuid.py | 22 +++++++++++++--
4 files changed, 71 insertions(+), 36 deletions(-)
diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index ab1a48ff90..040c087689 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -21,45 +21,62 @@ static const uint32_t deep_features[] = INIT_DEEP_FEATURES;
static int __init parse_xen_cpuid(const char *s)
{
+ static const struct feature {
+ const char *name;
+ unsigned int bit;
+ } features[] __initconst = INIT_FEATURE_NAMES, *lhs, *mid, *rhs;
const char *ss;
int val, rc = 0;
do {
+ const char *feat;
+
ss = strchr(s, ',');
if ( !ss )
ss = strchr(s, '\0');
- if ( (val = parse_boolean("md-clear", s, ss)) >= 0 )
- {
- if ( !val )
- setup_clear_cpu_cap(X86_FEATURE_MD_CLEAR);
- }
- else 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 = cmdline_strcmp(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 and boolean were successfully
+ * identified. Everything else is an error.
+ */
+ if ( mid )
rc = -EINVAL;
s = ss + 1;
diff --git a/xen/common/kernel.c b/xen/common/kernel.c
index f7628d73ce..760917dab5 100644
--- a/xen/common/kernel.c
+++ b/xen/common/kernel.c
@@ -309,10 +309,10 @@ int cmdline_strcmp(const char *frag, const char *name)
if ( res || n == '\0' )
{
/*
- * NUL in 'name' matching a comma, colon or semicolon in 'frag'
- * implies success.
+ * NUL in 'name' matching a comma, colon, semicolon or equals in
+ * 'frag' implies success.
*/
- if ( n == '\0' && (f == ',' || f == ':' || f == ';') )
+ if ( n == '\0' && (f == ',' || f == ':' || f == ';' || f == '=') )
res = 0;
return res;
diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h
index ce231c5f4f..8fbe84032d 100644
--- a/xen/include/xen/lib.h
+++ b/xen/include/xen/lib.h
@@ -85,8 +85,8 @@ int parse_boolean(const char *name, const char *s, const char *e);
/**
* Very similar to strcmp(), but will declare a match if the NUL in 'name'
- * lines up with comma, colon or semicolon in 'frag'. Designed for picking
- * exact string matches out of a delimited command line list.
+ * lines up with comma, colon, semicolon or equals in 'frag'. Designed for
+ * picking exact string matches out of a delimited command line list.
*/
int cmdline_strcmp(const char *frag, const char *name);
diff --git a/xen/tools/gen-cpuid.py b/xen/tools/gen-cpuid.py
index 836b010751..f76e80d690 100755
--- a/xen/tools/gen-cpuid.py
+++ b/xen/tools/gen-cpuid.py
@@ -19,7 +19,8 @@ def __init__(self, input, output):
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:
@@ -403,6 +405,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.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next reply other threads:[~2019-09-05 19:49 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-05 19:49 Andrew Cooper [this message]
2019-09-06 15:18 ` [Xen-devel] [PATCH v2] x86/cpuid: Extend the cpuid= option to support all named features Jan Beulich
2019-09-06 15:27 ` Andrew Cooper
2019-09-06 15:54 ` Jan Beulich
2019-09-25 12:30 ` Jan Beulich
2019-09-25 12:32 ` Andrew Cooper
2019-09-25 12:39 ` 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=20190905194909.6811-1-andrew.cooper3@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=JBeulich@suse.com \
--cc=roger.pau@citrix.com \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.