@@ -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,
@@ -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;
+
+}
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.pau@citrix.com> --- tools/include/xenctrl.h | 2 + tools/libs/guest/xg_cpuid_x86.c | 65 +++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+)