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