[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 08/13] libs/guest: introduce support for setting guest MSRs
Like it's done with CPUID, introduce support for passing MSR values to xc_cpuid_apply_policy(). The chosen format for expressing MSR policy data matches the current one used for CPUID. Note that existing callers of xc_cpuid_apply_policy() can pass NULL as the value for the newly introduced 'msr' parameter in order to preserve the same functionality, and in fact that's done in libxl on this patch. Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- tools/include/xenctrl.h | 21 ++++++++- tools/include/xenguest.h | 5 ++- tools/libs/guest/xg_cpuid_x86.c | 76 ++++++++++++++++++++++++++++++++- tools/libs/light/libxl_cpuid.c | 2 +- 4 files changed, 99 insertions(+), 5 deletions(-) diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h index 45f05a2d3d7e..786061282c91 100644 --- a/tools/include/xenctrl.h +++ b/tools/include/xenctrl.h @@ -1822,6 +1822,21 @@ struct xc_xend_cpuid { char *policy[4]; }; +/* + * MSR policy data. + * + * The format of the policy string is the following: + * '1' -> force to 1 + * '0' -> force to 0 + * 'x' -> we don't care (use default) + * 'k' -> pass through host value + */ +struct xc_msr { + uint32_t index; + char policy[65]; +}; +#define XC_MSR_INPUT_UNUSED 0xffffffffu + /* * Make adjustments to the CPUID settings for a domain. * @@ -1833,13 +1848,15 @@ struct xc_xend_cpuid { * Either pass a full new @featureset (and @nr_features), or adjust individual * features (@pae, @itsc, @nested_virt). * - * Then (optionally) apply legacy XEND overrides (@xend) to the result. + * Then (optionally) apply legacy XEND CPUID overrides (@cpuid) or MSR (@msr) + * to the result. */ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore, const uint32_t *featureset, unsigned int nr_features, bool pae, bool itsc, - bool nested_virt, const struct xc_xend_cpuid *cpuid); + bool nested_virt, const struct xc_xend_cpuid *cpuid, + const struct xc_msr *msr); int xc_mca_op(xc_interface *xch, struct xen_mc *mc); int xc_mca_op_inject_v2(xc_interface *xch, unsigned int flags, xc_cpumap_t cpumap, unsigned int nr_cpus); diff --git a/tools/include/xenguest.h b/tools/include/xenguest.h index 705a93a058fb..be61ff0af7fe 100644 --- a/tools/include/xenguest.h +++ b/tools/include/xenguest.h @@ -817,10 +817,13 @@ int xc_cpu_policy_get_msr(xc_interface *xch, const xc_cpu_policy_t *policy, bool xc_cpu_policy_is_compatible(xc_interface *xch, xc_cpu_policy_t *host, xc_cpu_policy_t *guest); -/* Apply an array of xc_xend_cpuid leafs to the policy. */ +/* Apply an array of xc_xend_cpuid leafs or xc_msrs to the policy. */ int xc_cpu_policy_apply_cpuid(xc_interface *xch, xc_cpu_policy_t *policy, const struct xc_xend_cpuid *cpuid, const xc_cpu_policy_t *host); +int xc_cpu_policy_apply_msr(xc_interface *xch, xc_cpu_policy_t *policy, + const struct xc_msr *msr, + const xc_cpu_policy_t *host); int xc_get_cpu_levelling_caps(xc_interface *xch, uint32_t *caps); int xc_get_cpu_featureset(xc_interface *xch, uint32_t index, diff --git a/tools/libs/guest/xg_cpuid_x86.c b/tools/libs/guest/xg_cpuid_x86.c index 0d0970d4bd69..09a012960a43 100644 --- a/tools/libs/guest/xg_cpuid_x86.c +++ b/tools/libs/guest/xg_cpuid_x86.c @@ -331,10 +331,74 @@ int xc_cpu_policy_apply_cpuid(xc_interface *xch, xc_cpu_policy_t *policy, return 0; } +int xc_cpu_policy_apply_msr(xc_interface *xch, xc_cpu_policy_t *policy, + const struct xc_msr *msr, + const xc_cpu_policy_t *host) +{ + for ( ; msr->index != XC_MSR_INPUT_UNUSED; ++msr ) + { + xen_msr_entry_t cur_msr, host_msr; + int rc; + + rc = xc_cpu_policy_get_msr(xch, policy, msr->index, &cur_msr); + if ( rc ) + { + ERROR("Failed to get current MSR %#x", msr->index); + return rc; + } + rc = xc_cpu_policy_get_msr(xch, host, msr->index, &host_msr); + if ( rc ) + { + ERROR("Failed to get host policy MSR %#x", msr->index); + return rc; + } + + for ( unsigned int i = 0; i < ARRAY_SIZE(msr->policy) - 1; i++ ) + { + bool val; + + switch ( msr->policy[i] ) + { + case '1': + val = true; + break; + + case '0': + val = false; + break; + + case 'x': + /* Leave alone: the current policy is the default one. */ + continue; + + case 'k': + val = test_bit(63 - i, &host_msr.val); + break; + + default: + ERROR("Bad character '%c' in policy string '%s'", + msr->policy[i], msr->policy); + return -EINVAL; + } + + clear_bit(63 - i, &cur_msr.val); + if ( val ) + set_bit(63 - i, &cur_msr.val); + } + + rc = xc_cpu_policy_update_msrs(xch, policy, &cur_msr, 1); + if ( rc ) + return rc; + } + + return 0; +} + int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore, const uint32_t *featureset, unsigned int nr_features, bool pae, bool itsc, bool nested_virt, - const struct xc_xend_cpuid *cpuid) + const struct xc_xend_cpuid *cpuid, + const struct xc_msr *msr) { int rc; bool hvm; @@ -535,6 +599,16 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore, } } + if ( msr ) + { + rc = xc_cpu_policy_apply_msr(xch, policy, msr, host); + if ( rc ) + { + rc = -errno; + goto out; + } + } + rc = xc_cpu_policy_set_domain(xch, domid, policy); if ( rc ) { diff --git a/tools/libs/light/libxl_cpuid.c b/tools/libs/light/libxl_cpuid.c index f5ce9f97959c..c96aeb3bce46 100644 --- a/tools/libs/light/libxl_cpuid.c +++ b/tools/libs/light/libxl_cpuid.c @@ -502,7 +502,7 @@ int libxl__cpuid_legacy(libxl_ctx *ctx, uint32_t domid, bool restore, info->tsc_mode == LIBXL_TSC_MODE_ALWAYS_EMULATE); r = xc_cpuid_apply_policy(ctx->xch, domid, restore, NULL, 0, - pae, itsc, nested_virt, info->cpuid); + pae, itsc, nested_virt, info->cpuid, NULL); if (r) LOGEVD(ERROR, -r, domid, "Failed to apply CPUID policy"); -- 2.40.0
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |