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

[Xen-devel] [PATCH v7 07/17] x86/cmdline: Introduce a command line option to disable IBRS/IBPB, STIBP and IBPB



Instead of gaining yet another top level boolean, introduce a more generic
cpuid= option.  Also introduce a helper function to parse a generic boolean
value.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 docs/misc/xen-command-line.markdown | 12 ++++++++++++
 xen/arch/x86/cpuid.c                | 35 +++++++++++++++++++++++++++++++++++
 xen/common/kernel.c                 | 23 +++++++++++++++++++++++
 xen/include/xen/lib.h               |  7 +++++++
 4 files changed, 77 insertions(+)

diff --git a/docs/misc/xen-command-line.markdown 
b/docs/misc/xen-command-line.markdown
index 96e57c2..b42abc6 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -471,6 +471,18 @@ choice of `dom0-kernel` is deprecated and not supported by 
all Dom0 kernels.
   respectively.
 * `verbose` option can be included as a string or also as `verbose=<integer>`
 
+### cpuid (x86)
+> `= List of comma separated booleans`
+
+This option allows for fine tuning of the facilities Xen will use, after
+accounting for hardware capabilities as enumerated via CPUID.
+
+Currently accepted:
+
+The Speculation Control hardware features `ibrsb`, `stibp`, `ibpb` are used by
+default if avaiable.  They can be ignored, e.g. `no-ibrsb`, at which point Xen
+won't use them itself, and won't offer them to guests.
+
 ### cpuid\_mask\_cpu (AMD only)
 > `= fam_0f_rev_c | fam_0f_rev_d | fam_0f_rev_e | fam_0f_rev_f | fam_0f_rev_g 
 > | fam_10_rev_b | fam_10_rev_c | fam_11_rev_b`
 
diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 5ee82d3..2ef71d2 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -18,6 +18,41 @@ 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;
 
+static int __init parse_xen_cpuid(const char *s)
+{
+    const char *ss;
+    int val, rc = 0;
+
+    do {
+        ss = strchr(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
+            rc = -EINVAL;
+
+        s = ss + 1;
+    } while ( *ss );
+
+    return rc;
+}
+custom_param("cpuid", parse_xen_cpuid);
+
 #define EMPTY_LEAF ((struct cpuid_leaf){})
 static void zero_leaves(struct cpuid_leaf *l,
                         unsigned int first, unsigned int last)
diff --git a/xen/common/kernel.c b/xen/common/kernel.c
index 8d137c5..19f9bad 100644
--- a/xen/common/kernel.c
+++ b/xen/common/kernel.c
@@ -244,6 +244,29 @@ int parse_bool(const char *s, const char *e)
     return -1;
 }
 
+int parse_boolean(const char *name, const char *s, const char *e)
+{
+    size_t slen, nlen;
+    int val = !!strncmp(s, "no-", 3);
+
+    if ( !val )
+        s += 3;
+
+    slen = e ? ({ ASSERT(e >= s); e - s; }) : strlen(s);
+    nlen = strlen(name);
+
+    /* Does s now start with name? */
+    if ( slen < nlen || strncmp(s, name, nlen) )
+        return -1;
+
+    switch ( s[nlen] )
+    {
+    case '\0': return val;
+    case '=':  return parse_bool(&s[nlen + 1], e);
+    default:   return -1;
+    }
+}
+
 unsigned int tainted;
 
 /**
diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h
index ed00ae1..1d97713 100644
--- a/xen/include/xen/lib.h
+++ b/xen/include/xen/lib.h
@@ -74,6 +74,13 @@ void cmdline_parse(const char *cmdline);
 int runtime_parse(const char *line);
 int parse_bool(const char *s, const char *e);
 
+/**
+ * Given a specific name, parses a string of the form:
+ *   [no-]$NAME[=...]
+ * returning 0 or 1 for a recognised boolean, or -1 for an error.
+ */
+int parse_boolean(const char *name, const char *s, const char *e);
+
 /*#define DEBUG_TRACE_DUMP*/
 #ifdef DEBUG_TRACE_DUMP
 extern void debugtrace_dump(void);
-- 
2.1.4


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

 


Rackspace

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