[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 |