Introduce a helper to update the MSR policy using an array of xen_msr_entry_t entries. Note the MSRs present in the input xen_msr_entry_t array will replace any existing entries on the policy.
No user of the interface introduced on this patch. Signed-off-by: Roger Pau MonnĂ© <roger....@citrix.com> --- tools/include/xenctrl.h | 2 + tools/libs/guest/xg_cpuid_x86.c | 65 +++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h index 2143478fe4b..46f5026081c 100644 --- a/tools/include/xenctrl.h +++ b/tools/include/xenctrl.h @@ -2616,6 +2616,8 @@ int xc_cpu_policy_get_msr(xc_interface *xch, const xc_cpu_policy_t policy, 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_cpu_policy_update_msrs(xc_interface *xch, xc_cpu_policy_t policy, + const xen_msr_entry_t *msrs, 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 13c2972ccd3..07756743e76 100644 --- a/tools/libs/guest/xg_cpuid_x86.c +++ b/tools/libs/guest/xg_cpuid_x86.c @@ -1033,3 +1033,68 @@ int xc_cpu_policy_update_cpuid(xc_interface *xch, xc_cpu_policy_t policy, free(current); return rc; } + +int xc_cpu_policy_update_msrs(xc_interface *xch, xc_cpu_policy_t policy, + const xen_msr_entry_t *msrs, uint32_t nr) +{ + unsigned int err_msr = -1; + unsigned int nr_leaves, nr_msrs, i, j; + xen_msr_entry_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_msrs, sizeof(*current)); + if ( !current ) + { + PERROR("Failed to allocate resources"); + errno = ENOMEM; + return -1; + } + + rc = xc_cpu_policy_serialise(xch, policy, NULL, 0, current, &nr_msrs); + if ( rc ) + goto out; + + for ( i = 0; i < nr; i++ ) + { + const xen_msr_entry_t *update = &msrs[i]; + + for ( j = 0; j < nr_msrs; j++ ) + if ( current[j].idx == update->idx ) + { + /* + * NB: cannot use an assignation because of the const vs + * non-const difference. + */ + memcpy(¤t[j], update, sizeof(*update)); + break; + } + + if ( j == nr_msrs ) + { + /* Failed to find a matching MSR, append to the end. */ + current = realloc(current, (nr_msrs + 1) * sizeof(*current)); + memcpy(¤t[nr_msrs], update, sizeof(*update)); + nr_msrs++; + } + } + + rc = x86_msr_copy_from_buffer(policy->msr, current, nr_msrs, &err_msr); + if ( rc ) + { + ERROR("Failed to deserialise MSRS (err index %#x) (%d = %s)", + err_msr, -rc, strerror(-rc)); + errno = -rc; + rc = -1; + } + + out: + free(current); + return rc; + +} -- 2.30.1