[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 18/21] libs/guest: rework xc_cpuid_xend_policy
Rename xc_cpuid_xend_policy to xc_cpu_policy_apply_cpuid and make it public. Modify the function internally to use the new xc_cpu_policy_* set of functions. Also don't apply the passed policy to a domain directly, and instead modify the provided xc_cpu_policy_t. The caller will be responsible of applying the modified cpu policy to the domain. Note that further patches will end up removing this function, since the parsing of a cpu policy in xend format is a layering violation, now the callers should have the necessary helpers to modify an xc_cpu_policy_t themselves. No functional change intended. Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- tools/include/xenctrl.h | 4 + tools/libs/guest/xg_cpuid_x86.c | 200 +++++++++++++------------------- 2 files changed, 83 insertions(+), 121 deletions(-) diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h index 9f94e61523e..07b8bfc08aa 100644 --- a/tools/include/xenctrl.h +++ b/tools/include/xenctrl.h @@ -2635,6 +2635,10 @@ int xc_cpu_policy_make_compatible(xc_interface *xch, xc_cpu_policy_t policy, int xc_cpu_policy_topology(xc_interface *xch, xc_cpu_policy_t policy, bool hvm); +/* Apply an xc_xend_cpuid object to the policy. */ +int xc_cpu_policy_apply_cpuid(xc_interface *xch, xc_cpu_policy_t policy, + const struct xc_xend_cpuid *cpuid, bool hvm); + int xc_get_cpu_levelling_caps(xc_interface *xch, uint32_t *caps); int xc_get_cpu_featureset(xc_interface *xch, uint32_t index, uint32_t *nr_features, uint32_t *featureset); diff --git a/tools/libs/guest/xg_cpuid_x86.c b/tools/libs/guest/xg_cpuid_x86.c index d50822c0abb..ce4a4a1a436 100644 --- a/tools/libs/guest/xg_cpuid_x86.c +++ b/tools/libs/guest/xg_cpuid_x86.c @@ -258,144 +258,107 @@ static int set_domain_cpu_policy(xc_interface *xch, uint32_t domid, return ret; } -static int compare_leaves(const void *l, const void *r) -{ - const xen_cpuid_leaf_t *lhs = l; - const xen_cpuid_leaf_t *rhs = r; - - if ( lhs->leaf != rhs->leaf ) - return lhs->leaf < rhs->leaf ? -1 : 1; - - if ( lhs->subleaf != rhs->subleaf ) - return lhs->subleaf < rhs->subleaf ? -1 : 1; - - return 0; -} - -static xen_cpuid_leaf_t *find_leaf( - xen_cpuid_leaf_t *leaves, unsigned int nr_leaves, - const struct xc_xend_cpuid *xend) -{ - const xen_cpuid_leaf_t key = { xend->leaf, xend->subleaf }; - - return bsearch(&key, leaves, nr_leaves, sizeof(*leaves), compare_leaves); -} - -static int xc_cpuid_xend_policy( - xc_interface *xch, uint32_t domid, const struct xc_xend_cpuid *xend) +int xc_cpu_policy_apply_cpuid(xc_interface *xch, xc_cpu_policy_t policy, + const struct xc_xend_cpuid *cpuid, bool hvm) { int rc; - xc_dominfo_t di; - unsigned int nr_leaves, nr_msrs; - uint32_t err_leaf = -1, err_subleaf = -1, err_msr = -1; - /* - * Three full policies. The host, domain max, and domain current for the - * domain type. - */ - xen_cpuid_leaf_t *host = NULL, *max = NULL, *cur = NULL; - unsigned int nr_host, nr_max, nr_cur; + xc_cpu_policy_t host = NULL, max = NULL; - if ( xc_domain_getinfo(xch, domid, 1, &di) != 1 || - di.domid != domid ) - { - ERROR("Failed to obtain d%d info", domid); - rc = -ESRCH; - goto fail; - } - - rc = xc_cpu_policy_get_size(xch, &nr_leaves, &nr_msrs); - if ( rc ) - { - PERROR("Failed to obtain policy info size"); - rc = -errno; - goto fail; - } - - rc = -ENOMEM; - if ( (host = calloc(nr_leaves, sizeof(*host))) == NULL || - (max = calloc(nr_leaves, sizeof(*max))) == NULL || - (cur = calloc(nr_leaves, sizeof(*cur))) == NULL ) - { - ERROR("Unable to allocate memory for %u CPUID leaves", nr_leaves); - goto fail; - } - - /* Get the domain's current policy. */ - nr_msrs = 0; - nr_cur = nr_leaves; - rc = get_domain_cpu_policy(xch, domid, &nr_cur, cur, &nr_msrs, NULL); - if ( rc ) + host = xc_cpu_policy_init(); + max = xc_cpu_policy_init(); + if ( !host || !max ) { - PERROR("Failed to obtain d%d current policy", domid); - rc = -errno; - goto fail; + PERROR("Failed to init policies"); + rc = -ENOMEM; + goto out; } /* Get the domain's max policy. */ - nr_msrs = 0; - nr_max = nr_leaves; - rc = get_system_cpu_policy(xch, di.hvm ? XEN_SYSCTL_cpu_policy_hvm_max + rc = xc_cpu_policy_get_system(xch, hvm ? XEN_SYSCTL_cpu_policy_hvm_max : XEN_SYSCTL_cpu_policy_pv_max, - &nr_max, max, &nr_msrs, NULL); + max); if ( rc ) { - PERROR("Failed to obtain %s max policy", di.hvm ? "hvm" : "pv"); - rc = -errno; - goto fail; + PERROR("Failed to obtain %s max policy", hvm ? "hvm" : "pv"); + goto out; } /* Get the host policy. */ - nr_msrs = 0; - nr_host = nr_leaves; - rc = get_system_cpu_policy(xch, XEN_SYSCTL_cpu_policy_host, - &nr_host, host, &nr_msrs, NULL); + rc = xc_cpu_policy_get_system(xch, XEN_SYSCTL_cpu_policy_host, host); if ( rc ) { PERROR("Failed to obtain host policy"); - rc = -errno; - goto fail; + goto out; } rc = -EINVAL; - for ( ; xend->leaf != XEN_CPUID_INPUT_UNUSED; ++xend ) + for ( ; cpuid->leaf != XEN_CPUID_INPUT_UNUSED; ++cpuid ) { - xen_cpuid_leaf_t *cur_leaf = find_leaf(cur, nr_cur, xend); - const xen_cpuid_leaf_t *max_leaf = find_leaf(max, nr_max, xend); - const xen_cpuid_leaf_t *host_leaf = find_leaf(host, nr_host, xend); + xen_cpuid_leaf_t cur_leaf; + xen_cpuid_leaf_t max_leaf; + xen_cpuid_leaf_t host_leaf; - if ( cur_leaf == NULL || max_leaf == NULL || host_leaf == NULL ) + rc = xc_cpu_policy_get_cpuid(xch, policy, cpuid->leaf, cpuid->subleaf, + &cur_leaf); + if ( rc ) + { + ERROR("Failed to get current policy leaf %#x subleaf %#x", + cpuid->leaf, cpuid->subleaf); + goto out; + } + rc = xc_cpu_policy_get_cpuid(xch, max, cpuid->leaf, cpuid->subleaf, + &max_leaf); + if ( rc ) { - ERROR("Missing leaf %#x, subleaf %#x", xend->leaf, xend->subleaf); - goto fail; + ERROR("Failed to get max policy leaf %#x subleaf %#x", + cpuid->leaf, cpuid->subleaf); + goto out; + } + rc = xc_cpu_policy_get_cpuid(xch, host, cpuid->leaf, cpuid->subleaf, + &host_leaf); + if ( rc ) + { + ERROR("Failed to get host policy leaf %#x subleaf %#x", + cpuid->leaf, cpuid->subleaf); + goto out; } - for ( unsigned int i = 0; i < ARRAY_SIZE(xend->policy); i++ ) + for ( unsigned int i = 0; i < ARRAY_SIZE(cpuid->policy); i++ ) { - uint32_t *cur_reg = &cur_leaf->a + i; - const uint32_t *max_reg = &max_leaf->a + i; - const uint32_t *host_reg = &host_leaf->a + i; + uint32_t *cur_reg = &cur_leaf.a + i; + const uint32_t *max_reg = &max_leaf.a + i; + const uint32_t *host_reg = &host_leaf.a + i; - if ( xend->policy[i] == NULL ) + if ( cpuid->policy[i] == NULL ) continue; for ( unsigned int j = 0; j < 32; j++ ) { bool val; - if ( xend->policy[i][j] == '1' ) + switch ( cpuid->policy[i][j] ) + { + case '1': val = true; - else if ( xend->policy[i][j] == '0' ) + break; + + case '0': val = false; - else if ( xend->policy[i][j] == 'x' ) + break; + + case 'x': val = test_bit(31 - j, max_reg); - else if ( xend->policy[i][j] == 'k' || - xend->policy[i][j] == 's' ) + break; + + case 'k': + case 's': val = test_bit(31 - j, host_reg); - else - { + break; + + default: ERROR("Bad character '%c' in policy[%d] string '%s'", - xend->policy[i][j], i, xend->policy[i]); - goto fail; + cpuid->policy[i][j], i, cpuid->policy[i]); + goto out; } clear_bit(31 - j, cur_reg); @@ -403,25 +366,19 @@ static int xc_cpuid_xend_policy( set_bit(31 - j, cur_reg); } } - } - /* Feed the transformed currrent policy back up to Xen. */ - rc = set_domain_cpu_policy(xch, domid, nr_cur, cur, 0, NULL, - &err_leaf, &err_subleaf, &err_msr); - if ( rc ) - { - PERROR("Failed to set d%d's policy (err leaf %#x, subleaf %#x, msr %#x)", - domid, err_leaf, err_subleaf, err_msr); - rc = -errno; - goto fail; + rc = xc_cpu_policy_update_cpuid(xch, policy, &cur_leaf, 1); + if ( rc ) + { + PERROR("Failed to set policy leaf %#x subleaf %#x", + cpuid->leaf, cpuid->subleaf); + goto out; + } } - /* Success! */ - - fail: - free(cur); - free(max); - free(host); + out: + xc_cpu_policy_destroy(max); + xc_cpu_policy_destroy(host); return rc; } @@ -429,7 +386,7 @@ static int xc_cpuid_xend_policy( 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 *xend) + const struct xc_xend_cpuid *cpuid) { int rc; xc_dominfo_t di; @@ -551,6 +508,10 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore, if ( rc ) goto out; + rc = xc_cpu_policy_apply_cpuid(xch, &policy, cpuid, di.hvm); + if ( rc ) + goto out; + rc = x86_cpuid_copy_to_buffer(p, leaves, &nr_leaves); if ( rc ) { @@ -568,9 +529,6 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore, goto out; } - if ( xend && (rc = xc_cpuid_xend_policy(xch, domid, xend)) ) - goto out; - rc = 0; out: -- 2.30.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |