|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] x86/cpuid: Introduce dom0-cpuid command line option
Specifically, this lets the user opt in to non-default for dom0.
Split features[] out of parse_xen_cpuid(), giving it a lightly more
appropraite name, so it can be shared with parse_xen_cpuid().
Collect all dom0 settings together in dom0_{en,dis}able_feat[], and apply it
to dom0's policy when other tweaks are being made.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
CC: Wei Liu <wl@xxxxxxx>
CC: Daniel Smith <dpsmith@xxxxxxxxxxxxxxxxxxxx>
RFC, because I think we've got a preexisting error with late hwdom here. We
really should not be cobbering a late hwdom's settings (which were provided in
the usual way by the toolstack in dom0).
Furthermore, the distinction gets more murky in a hyperlaunch future where
multiple domains may be constructed by Xen, and there is reason to expect that
a full toolstack-like configuration is made available for them.
One option might be to remove the special case from init_domain_cpuid_policy()
and instead make a call into the cpuid code from create_dom0(). It would have
to be placed between domain_create() and alloc_dom0_vcpu0() for dynamic sizing
of the FPU block to work. Thoughts?
---
docs/misc/xen-command-line.pandoc | 16 ++++++
xen/arch/x86/cpuid.c | 114 +++++++++++++++++++++++++++++++++-----
2 files changed, 115 insertions(+), 15 deletions(-)
diff --git a/docs/misc/xen-command-line.pandoc
b/docs/misc/xen-command-line.pandoc
index f7797ea233f9..1278f9c27597 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -801,6 +801,22 @@ Controls for how dom0 is constructed on x86 systems.
If using this option is necessary to fix an issue, please report a bug.
+### dom0-cpuid
+ = List of comma separated booleans
+
+ Applicability: x86
+
+This option allows for fine tuning of the facilities dom0 will use, after
+accounting for hardware capabilities and Xen settings as enumerated via CPUID.
+
+Options are accepted in positive and negative form, to enable or disable
+specific features. All selections via this mechanism are subject to normal
+CPU Policy safety logic.
+
+This option is intended for developers to opt dom0 into non-default features,
+and is not intended for use in production circumstances. If using this option
+is necessary to fix an issue, please report a bug.
+
### dom0-iommu
= List of [ passthrough=<bool>, strict=<bool>, map-inclusive=<bool>,
map-reserved=<bool>, none ]
diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 151944f65702..896bc1595317 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -26,17 +26,18 @@ static const uint32_t __initconst hvm_hap_def_featuremask[]
=
INIT_HVM_HAP_DEF_FEATURES;
static const uint32_t deep_features[] = INIT_DEEP_FEATURES;
+static const struct feature_name {
+ const char *name;
+ unsigned int bit;
+} feature_names[] __initconstrel = INIT_FEATURE_NAMES;
+
static int __init parse_xen_cpuid(const char *s)
{
const char *ss;
int val, rc = 0;
do {
- static const struct feature {
- const char *name;
- unsigned int bit;
- } features[] __initconstrel = INIT_FEATURE_NAMES;
- const struct feature *lhs, *rhs, *mid = NULL /* GCC... */;
+ const struct feature_name *lhs, *rhs, *mid = NULL /* GCC... */;
const char *feat;
ss = strchr(s, ',');
@@ -49,8 +50,8 @@ static int __init parse_xen_cpuid(const char *s)
feat += 3;
/* (Re)initalise lhs and rhs for binary search. */
- lhs = features;
- rhs = features + ARRAY_SIZE(features);
+ lhs = feature_names;
+ rhs = feature_names + ARRAY_SIZE(feature_names);
while ( lhs < rhs )
{
@@ -97,6 +98,73 @@ static int __init parse_xen_cpuid(const char *s)
}
custom_param("cpuid", parse_xen_cpuid);
+static uint32_t __hwdom_initdata dom0_enable_feat[FSCAPINTS];
+static uint32_t __hwdom_initdata dom0_disable_feat[FSCAPINTS];
+
+static int __init parse_dom0_cpuid(const char *s)
+{
+ const char *ss;
+ int val, rc = 0;
+
+ do {
+ const struct feature_name *lhs, *rhs, *mid = NULL /* GCC... */;
+ const char *feat;
+
+ ss = strchr(s, ',');
+ if ( !ss )
+ ss = strchr(s, '\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 = feature_names;
+ rhs = feature_names + ARRAY_SIZE(feature_names);
+
+ while ( lhs < rhs )
+ {
+ 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 )
+ {
+ __set_bit(mid->bit,
+ val ? dom0_enable_feat : dom0_disable_feat);
+ mid = NULL;
+ }
+
+ break;
+ }
+
+ /*
+ * Mid being NULL means that the name and boolean were successfully
+ * identified. Everything else is an error.
+ */
+ if ( mid )
+ rc = -EINVAL;
+
+ s = ss + 1;
+ } while ( *ss );
+
+ return rc;
+}
+custom_param("dom0-cpuid", parse_dom0_cpuid);
+
#define EMPTY_LEAF ((struct cpuid_leaf){})
static void zero_leaves(struct cpuid_leaf *l,
unsigned int first, unsigned int last)
@@ -727,17 +795,33 @@ int init_domain_cpuid_policy(struct domain *d)
if ( !p )
return -ENOMEM;
- /* The hardware domain can't migrate. Give it ITSC if available. */
if ( is_hardware_domain(d) )
+ {
+ uint32_t fs[FSCAPINTS];
+ unsigned int i;
+
+ /* The hardware domain can't migrate. Give it ITSC if available. */
p->extd.itsc = cpu_has_itsc;
- /*
- * Expose the "hardware speculation behaviour" bits of ARCH_CAPS to dom0,
- * so dom0 can turn off workarounds as appropriate. Temporary, until the
- * domain policy logic gains a better understanding of MSRs.
- */
- if ( is_hardware_domain(d) && cpu_has_arch_caps )
- p->feat.arch_caps = true;
+ /*
+ * Expose the "hardware speculation behaviour" bits of ARCH_CAPS to
+ * dom0, so dom0 can turn off workarounds as appropriate. Temporary,
+ * until the domain policy logic gains a better understanding of MSRs.
+ */
+ if ( cpu_has_arch_caps )
+ p->feat.arch_caps = true;
+
+ /* Apply dom0-cpuid= command line settings. */
+ cpuid_policy_to_featureset(p, fs);
+
+ for ( i = 0; i < ARRAY_SIZE(fs); ++i )
+ {
+ fs[i] |= dom0_enable_feat[i];
+ fs[i] &= ~dom0_disable_feat[i];
+ }
+
+ cpuid_featureset_to_policy(fs, p);
+ }
d->arch.cpuid = p;
--
2.11.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |