Message ID | 20210323095849.37858-12-roger.pau@citrix.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | libs/guest: new CPUID/MSR interface | expand |
On 23.03.2021 10:58, Roger Pau Monne wrote: > --- a/tools/libs/guest/xg_cpuid_x86.c > +++ b/tools/libs/guest/xg_cpuid_x86.c > @@ -966,3 +966,70 @@ int xc_cpu_policy_get_msr(xc_interface *xch, const xc_cpu_policy_t policy, > free(msrs); > return rc; > } > + > +int xc_cpu_policy_update_cpuid(xc_interface *xch, xc_cpu_policy_t policy, > + const xen_cpuid_leaf_t *leaves, > + uint32_t nr) > +{ > + unsigned int err_leaf = -1, err_subleaf = -1; > + unsigned int nr_leaves, nr_msrs, i, j; > + xen_cpuid_leaf_t *current; > + int rc = xc_cpu_policy_get_size(xch, &nr_leaves, &nr_msrs); > + > + if ( rc ) > + { > + PERROR("Failed to obtain policy info size"); > + return -1; > + } > + > + current = calloc(nr_leaves, sizeof(*current)); > + if ( !current ) > + { > + PERROR("Failed to allocate resources"); > + errno = ENOMEM; > + return -1; > + } > + > + rc = xc_cpu_policy_serialise(xch, policy, current, &nr_leaves, NULL, 0); > + if ( rc ) > + goto out; > + > + for ( i = 0; i < nr; i++ ) > + { > + const xen_cpuid_leaf_t *update = &leaves[i]; > + > + for ( j = 0; j < nr_leaves; j++ ) > + if ( current[j].leaf == update->leaf && > + current[j].subleaf == update->subleaf ) > + { > + /* > + * NB: cannot use an assignation because of the const vs > + * non-const difference. > + */ > + memcpy(¤t[j], update, sizeof(*update)); I'm having trouble understanding the comment. In current[j] = *update; the lvalue is xen_cpuid_leaf_t and the rvalue is const xen_cpuid_leaf_t. That the usual (and permitted) arrangement afaics. Jan
On Tue, Mar 30, 2021 at 05:56:35PM +0200, Jan Beulich wrote: > On 23.03.2021 10:58, Roger Pau Monne wrote: > > --- a/tools/libs/guest/xg_cpuid_x86.c > > +++ b/tools/libs/guest/xg_cpuid_x86.c > > @@ -966,3 +966,70 @@ int xc_cpu_policy_get_msr(xc_interface *xch, const xc_cpu_policy_t policy, > > free(msrs); > > return rc; > > } > > + > > +int xc_cpu_policy_update_cpuid(xc_interface *xch, xc_cpu_policy_t policy, > > + const xen_cpuid_leaf_t *leaves, > > + uint32_t nr) > > +{ > > + unsigned int err_leaf = -1, err_subleaf = -1; > > + unsigned int nr_leaves, nr_msrs, i, j; > > + xen_cpuid_leaf_t *current; > > + int rc = xc_cpu_policy_get_size(xch, &nr_leaves, &nr_msrs); > > + > > + if ( rc ) > > + { > > + PERROR("Failed to obtain policy info size"); > > + return -1; > > + } > > + > > + current = calloc(nr_leaves, sizeof(*current)); > > + if ( !current ) > > + { > > + PERROR("Failed to allocate resources"); > > + errno = ENOMEM; > > + return -1; > > + } > > + > > + rc = xc_cpu_policy_serialise(xch, policy, current, &nr_leaves, NULL, 0); > > + if ( rc ) > > + goto out; > > + > > + for ( i = 0; i < nr; i++ ) > > + { > > + const xen_cpuid_leaf_t *update = &leaves[i]; > > + > > + for ( j = 0; j < nr_leaves; j++ ) > > + if ( current[j].leaf == update->leaf && > > + current[j].subleaf == update->subleaf ) > > + { > > + /* > > + * NB: cannot use an assignation because of the const vs > > + * non-const difference. > > + */ > > + memcpy(¤t[j], update, sizeof(*update)); > > I'm having trouble understanding the comment. In > > current[j] = *update; > > the lvalue is xen_cpuid_leaf_t and the rvalue is const xen_cpuid_leaf_t. > That the usual (and permitted) arrangement afaics. I'm sure I was doing something really stupid, and as a bonus I failed to properly parse the error message I got from the compiler. It's now fixed here and below. Thanks, Roger.
On 23/03/2021 09:58, Roger Pau Monne wrote: > diff --git a/tools/libs/guest/xg_cpuid_x86.c b/tools/libs/guest/xg_cpuid_x86.c > index 091aeb70c9c..13c2972ccd3 100644 > --- a/tools/libs/guest/xg_cpuid_x86.c > +++ b/tools/libs/guest/xg_cpuid_x86.c > @@ -966,3 +966,70 @@ int xc_cpu_policy_get_msr(xc_interface *xch, const xc_cpu_policy_t policy, > free(msrs); > return rc; > } > + > +int xc_cpu_policy_update_cpuid(xc_interface *xch, xc_cpu_policy_t policy, > + const xen_cpuid_leaf_t *leaves, > + uint32_t nr) > +{ > + unsigned int err_leaf = -1, err_subleaf = -1; > + unsigned int nr_leaves, nr_msrs, i, j; > + xen_cpuid_leaf_t *current; > + int rc = xc_cpu_policy_get_size(xch, &nr_leaves, &nr_msrs); > + > + if ( rc ) > + { > + PERROR("Failed to obtain policy info size"); > + return -1; > + } > + > + current = calloc(nr_leaves, sizeof(*current)); > + if ( !current ) > + { > + PERROR("Failed to allocate resources"); > + errno = ENOMEM; > + return -1; > + } > + > + rc = xc_cpu_policy_serialise(xch, policy, current, &nr_leaves, NULL, 0); > + if ( rc ) > + goto out; > + > + for ( i = 0; i < nr; i++ ) > + { > + const xen_cpuid_leaf_t *update = &leaves[i]; > + > + for ( j = 0; j < nr_leaves; j++ ) > + if ( current[j].leaf == update->leaf && > + current[j].subleaf == update->subleaf ) > + { > + /* > + * NB: cannot use an assignation because of the const vs > + * non-const difference. > + */ > + memcpy(¤t[j], update, sizeof(*update)); > + break; > + } > + > + if ( j == nr_leaves ) > + { > + /* Failed to find a matching leaf, append to the end. */ > + current = realloc(current, (nr_leaves + 1) * sizeof(*current)); > + memcpy(¤t[nr_leaves], update, sizeof(*update)); > + nr_leaves++; > + } > + } > + > + rc = x86_cpuid_copy_from_buffer(policy->cpuid, current, nr_leaves, > + &err_leaf, &err_subleaf); Why do you need any earlier logic? x86_cpuid_copy_from_buffer() already does exactly this operation. ~Andrew
diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h index ab34df1dc98..2143478fe4b 100644 --- a/tools/include/xenctrl.h +++ b/tools/include/xenctrl.h @@ -2613,6 +2613,9 @@ int xc_cpu_policy_get_cpuid(xc_interface *xch, const xc_cpu_policy_t policy, xen_cpuid_leaf_t *out); int xc_cpu_policy_get_msr(xc_interface *xch, const xc_cpu_policy_t policy, uint32_t msr, xen_msr_entry_t *out); +int xc_cpu_policy_update_cpuid(xc_interface *xch, xc_cpu_policy_t policy, + const xen_cpuid_leaf_t *leaves, + uint32_t nr); 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 091aeb70c9c..13c2972ccd3 100644 --- a/tools/libs/guest/xg_cpuid_x86.c +++ b/tools/libs/guest/xg_cpuid_x86.c @@ -966,3 +966,70 @@ int xc_cpu_policy_get_msr(xc_interface *xch, const xc_cpu_policy_t policy, free(msrs); return rc; } + +int xc_cpu_policy_update_cpuid(xc_interface *xch, xc_cpu_policy_t policy, + const xen_cpuid_leaf_t *leaves, + uint32_t nr) +{ + unsigned int err_leaf = -1, err_subleaf = -1; + unsigned int nr_leaves, nr_msrs, i, j; + xen_cpuid_leaf_t *current; + int rc = xc_cpu_policy_get_size(xch, &nr_leaves, &nr_msrs); + + if ( rc ) + { + PERROR("Failed to obtain policy info size"); + return -1; + } + + current = calloc(nr_leaves, sizeof(*current)); + if ( !current ) + { + PERROR("Failed to allocate resources"); + errno = ENOMEM; + return -1; + } + + rc = xc_cpu_policy_serialise(xch, policy, current, &nr_leaves, NULL, 0); + if ( rc ) + goto out; + + for ( i = 0; i < nr; i++ ) + { + const xen_cpuid_leaf_t *update = &leaves[i]; + + for ( j = 0; j < nr_leaves; j++ ) + if ( current[j].leaf == update->leaf && + current[j].subleaf == update->subleaf ) + { + /* + * NB: cannot use an assignation because of the const vs + * non-const difference. + */ + memcpy(¤t[j], update, sizeof(*update)); + break; + } + + if ( j == nr_leaves ) + { + /* Failed to find a matching leaf, append to the end. */ + current = realloc(current, (nr_leaves + 1) * sizeof(*current)); + memcpy(¤t[nr_leaves], update, sizeof(*update)); + nr_leaves++; + } + } + + rc = x86_cpuid_copy_from_buffer(policy->cpuid, current, nr_leaves, + &err_leaf, &err_subleaf); + if ( rc ) + { + ERROR("Failed to deserialise CPUID (err leaf %#x, subleaf %#x) (%d = %s)", + err_leaf, err_subleaf, -rc, strerror(-rc)); + errno = -rc; + rc = -1; + } + + out: + free(current); + return rc; +}
Introduce a helper to update the CPUID policy using an array of xen_cpuid_leaf_t entries. Note the leaves present in the input xen_cpuid_leaf_t array will replace any existing leaves on the policy. No user of the interface introduced on this patch. Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> --- tools/include/xenctrl.h | 3 ++ tools/libs/guest/xg_cpuid_x86.c | 67 +++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+)