Later changes will cause the cpuid generation logic to seed their information from a featureset. This patch adds the infrastructure to specify a featureset, and will obtain the appropriate default from Xen if omitted.
Signed-off-by: Andrew Cooper <andrew.coop...@citrix.com> Acked-by: Wei Liu <wei.l...@citrix.com> --- CC: Ian Jackson <ian.jack...@eu.citrix.com> v2: * Modify existing call rather than introducing a new one. * Fix up in-tree callsites. --- tools/libxc/include/xenctrl.h | 4 ++- tools/libxc/xc_cpuid_x86.c | 69 ++++++++++++++++++++++++++++++++----- tools/libxl/libxl_cpuid.c | 2 +- tools/ocaml/libs/xc/xenctrl_stubs.c | 2 +- tools/python/xen/lowlevel/xc/xc.c | 2 +- 5 files changed, 66 insertions(+), 13 deletions(-) diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index 66acbd1..872fd08 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -1896,7 +1896,9 @@ int xc_cpuid_set(xc_interface *xch, const char **config, char **config_transformed); int xc_cpuid_apply_policy(xc_interface *xch, - domid_t domid); + domid_t domid, + uint32_t *featureset, + unsigned int nr_features); void xc_cpuid_to_str(const unsigned int *regs, char **strs); /* some strs[] may be NULL if ENOMEM */ int xc_mca_op(xc_interface *xch, struct xen_mc *mc); diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c index 0cffb36..a92f5e4 100644 --- a/tools/libxc/xc_cpuid_x86.c +++ b/tools/libxc/xc_cpuid_x86.c @@ -166,6 +166,9 @@ struct cpuid_domain_info bool pvh; uint64_t xfeature_mask; + uint32_t *featureset; + unsigned int nr_features; + /* PV-only information. */ bool pv64; @@ -197,11 +200,14 @@ static void cpuid(const unsigned int *input, unsigned int *regs) } static int get_cpuid_domain_info(xc_interface *xch, domid_t domid, - struct cpuid_domain_info *info) + struct cpuid_domain_info *info, + uint32_t *featureset, + unsigned int nr_features) { struct xen_domctl domctl = {}; xc_dominfo_t di; unsigned int in[2] = { 0, ~0U }, regs[4]; + unsigned int i, host_nr_features = xc_get_cpu_featureset_size(); int rc; cpuid(in, regs); @@ -223,6 +229,23 @@ static int get_cpuid_domain_info(xc_interface *xch, domid_t domid, info->hvm = di.hvm; info->pvh = di.pvh; + info->featureset = calloc(host_nr_features, sizeof(*info->featureset)); + if ( !info->featureset ) + return -ENOMEM; + + info->nr_features = host_nr_features; + + if ( featureset ) + { + memcpy(info->featureset, featureset, + min(host_nr_features, nr_features) * sizeof(*info->featureset)); + + /* Check for truncated set bits. */ + for ( i = nr_features; i < host_nr_features; ++i ) + if ( featureset[i] != 0 ) + return -EOPNOTSUPP; + } + /* Get xstate information. */ domctl.cmd = XEN_DOMCTL_getvcpuextstate; domctl.domain = domid; @@ -247,6 +270,14 @@ static int get_cpuid_domain_info(xc_interface *xch, domid_t domid, return rc; info->nestedhvm = !!val; + + if ( !featureset ) + { + rc = xc_get_cpu_featureset(xch, XEN_SYSCTL_cpu_featureset_hvm, + &host_nr_features, info->featureset); + if ( rc ) + return rc; + } } else { @@ -257,11 +288,24 @@ static int get_cpuid_domain_info(xc_interface *xch, domid_t domid, return rc; info->pv64 = (width == 8); + + if ( !featureset ) + { + rc = xc_get_cpu_featureset(xch, XEN_SYSCTL_cpu_featureset_pv, + &host_nr_features, info->featureset); + if ( rc ) + return rc; + } } return 0; } +static void free_cpuid_domain_info(struct cpuid_domain_info *info) +{ + free(info->featureset); +} + static void amd_xc_cpuid_policy(xc_interface *xch, const struct cpuid_domain_info *info, const unsigned int *input, unsigned int *regs) @@ -789,16 +833,18 @@ void xc_cpuid_to_str(const unsigned int *regs, char **strs) } } -int xc_cpuid_apply_policy(xc_interface *xch, domid_t domid) +int xc_cpuid_apply_policy(xc_interface *xch, domid_t domid, + uint32_t *featureset, + unsigned int nr_features) { struct cpuid_domain_info info = {}; unsigned int input[2] = { 0, 0 }, regs[4]; unsigned int base_max, ext_max; int rc; - rc = get_cpuid_domain_info(xch, domid, &info); + rc = get_cpuid_domain_info(xch, domid, &info, featureset, nr_features); if ( rc ) - return rc; + goto out; cpuid(input, regs); base_max = (regs[0] <= DEF_MAX_BASE) ? regs[0] : DEF_MAX_BASE; @@ -821,7 +867,7 @@ int xc_cpuid_apply_policy(xc_interface *xch, domid_t domid) { rc = xc_cpuid_do_domctl(xch, domid, input, regs); if ( rc ) - return rc; + goto out; } /* Intel cache descriptor leaves. */ @@ -849,7 +895,9 @@ int xc_cpuid_apply_policy(xc_interface *xch, domid_t domid) break; } - return 0; + out: + free_cpuid_domain_info(&info); + return rc; } /* @@ -938,9 +986,9 @@ int xc_cpuid_set( memset(config_transformed, 0, 4 * sizeof(*config_transformed)); - rc = get_cpuid_domain_info(xch, domid, &info); + rc = get_cpuid_domain_info(xch, domid, &info, NULL, 0); if ( rc ) - return rc; + goto out; cpuid(input, regs); @@ -991,7 +1039,7 @@ int xc_cpuid_set( rc = xc_cpuid_do_domctl(xch, domid, input, regs); if ( rc == 0 ) - return 0; + goto out; fail: for ( i = 0; i < 4; i++ ) @@ -999,5 +1047,8 @@ int xc_cpuid_set( free(config_transformed[i]); config_transformed[i] = NULL; } + + out: + free_cpuid_domain_info(&info); return rc; } diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c index c66e912..fc20157 100644 --- a/tools/libxl/libxl_cpuid.c +++ b/tools/libxl/libxl_cpuid.c @@ -334,7 +334,7 @@ int libxl_cpuid_parse_config_xend(libxl_cpuid_policy_list *cpuid, void libxl_cpuid_apply_policy(libxl_ctx *ctx, uint32_t domid) { - xc_cpuid_apply_policy(ctx->xch, domid); + xc_cpuid_apply_policy(ctx->xch, domid, NULL, 0); } void libxl_cpuid_set(libxl_ctx *ctx, uint32_t domid, diff --git a/tools/ocaml/libs/xc/xenctrl_stubs.c b/tools/ocaml/libs/xc/xenctrl_stubs.c index e7adf37..5477df3 100644 --- a/tools/ocaml/libs/xc/xenctrl_stubs.c +++ b/tools/ocaml/libs/xc/xenctrl_stubs.c @@ -796,7 +796,7 @@ CAMLprim value stub_xc_domain_cpuid_apply_policy(value xch, value domid) #if defined(__i386__) || defined(__x86_64__) int r; - r = xc_cpuid_apply_policy(_H(xch), _D(domid)); + r = xc_cpuid_apply_policy(_H(xch), _D(domid), NULL, 0); if (r < 0) failwith_xc(_H(xch)); #else diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index c40a4e9..22a1c9f 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -731,7 +731,7 @@ static PyObject *pyxc_dom_set_policy_cpuid(XcObject *self, if ( !PyArg_ParseTuple(args, "i", &domid) ) return NULL; - if ( xc_cpuid_apply_policy(self->xc_handle, domid) ) + if ( xc_cpuid_apply_policy(self->xc_handle, domid, NULL, 0) ) return pyxc_error_to_exception(self->xc_handle); Py_INCREF(zero); -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel