From 067a890347cf07fa1322ef0fad92d335542ea679 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Tue, 14 Dec 2021 16:53:36 +0000 Subject: [PATCH] x86/cpuid: Introduce dom0-cpuid command line option Specifically, this lets the user opt in to non-default features. Collect all dom0 settings together in dom0_{en,dis}able_feat[], and apply it to dom0's policy when other tweaks are being made. As recalculate_cpuid_policy() is an expensive action, and dom0-cpuid= is likely to only be used by the x86 maintainers for development purposes, forgo the recalculation in the general case. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich (cherry picked from commit 5bd2b82df28cb7390f5ffb00fac635d0b9e36674) --- docs/misc/xen-command-line.pandoc | 16 +++++++++++++ xen/arch/x86/cpuid.c | 37 +++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc index b73c4a6050..2eacef5afd 100644 --- a/docs/misc/xen-command-line.pandoc +++ b/docs/misc/xen-command-line.pandoc @@ -809,6 +809,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 and dependency 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=, strict=, map-inclusive=, map-reserved=, none ] diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c index 428fa5a84f..795bbddef8 100644 --- a/xen/arch/x86/cpuid.c +++ b/xen/arch/x86/cpuid.c @@ -116,6 +116,24 @@ static int __init parse_xen_cpuid(const char *s) } custom_param("cpuid", parse_xen_cpuid); +static bool __initdata dom0_cpuid_cmdline; +static uint32_t __initdata dom0_enable_feat[FSCAPINTS]; +static uint32_t __initdata dom0_disable_feat[FSCAPINTS]; + +static void __init _parse_dom0_cpuid(unsigned int feat, bool val) +{ + __set_bit (feat, val ? dom0_enable_feat : dom0_disable_feat); + __clear_bit(feat, val ? dom0_disable_feat : dom0_enable_feat ); +} + +static int __init parse_dom0_cpuid(const char *s) +{ + dom0_cpuid_cmdline = true; + + return parse_cpuid(s, _parse_dom0_cpuid); +} +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) @@ -777,6 +795,25 @@ void __init init_dom0_cpuid_policy(struct domain *d) */ if ( cpu_has_arch_caps ) p->feat.arch_caps = true; + + /* Apply dom0-cpuid= command line settings, if provided. */ + if ( dom0_cpuid_cmdline ) + { + uint32_t fs[FSCAPINTS]; + unsigned int i; + + 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); + + recalculate_cpuid_policy(d); + } } void guest_cpuid(const struct vcpu *v, uint32_t leaf, -- 2.39.5