x86: Merge xc_cpu_policy's cpuid and msr objects

Right now, they're the same underlying type, containing disjoint information.

Use a single object instead.  Also take the opportunity to rename 'entries' to
'msrs' which is more descriptive, and more in line with nr_msrs being the
count of MSR entries in the API.

test-tsx uses xg_private.h to access the internals of xc_cpu_policy, so needs
updating at the same time.  Take the opportunity to improve the code clarity
by passing a cpu_policy rather than an xc_cpu_policy into some functions.

No practical change.  This undoes the transient doubling of storage space from
earlier patches.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Andrew Cooper committed 2023-04-05 11:47:08 +01:00
1 parent bd13dae348
commit c9985233ca
3 files changed
+53 -59

No files matched your search

+18 -18
View File
@@ -431,7 +431,7 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore,
xc_dominfo_t di;
unsigned int i, nr_leaves, nr_msrs;
xen_cpuid_leaf_t *leaves = NULL;
struct cpuid_policy *p = NULL;
struct cpu_policy *p = NULL;
uint32_t err_leaf = -1, err_subleaf = -1, err_msr = -1;
uint32_t host_featureset[FEATURESET_NR_ENTRIES] = {};
uint32_t len = ARRAY_SIZE(host_featureset);
@@ -692,7 +692,7 @@ static int deserialize_policy(xc_interface *xch, xc_cpu_policy_t *policy,
uint32_t err_leaf = -1, err_subleaf = -1, err_msr = -1;
int rc;
rc = x86_cpuid_copy_from_buffer(&policy->cpuid, policy->leaves,
rc = x86_cpuid_copy_from_buffer(&policy->policy, policy->leaves,
nr_leaves, &err_leaf, &err_subleaf);
if ( rc )
{
@@ -702,7 +702,7 @@ static int deserialize_policy(xc_interface *xch, xc_cpu_policy_t *policy,
return rc;
}
rc = x86_msr_copy_from_buffer(&policy->msr, policy->entries,
rc = x86_msr_copy_from_buffer(&policy->policy, policy->msrs,
nr_entries, &err_msr);
if ( rc )
{
@@ -719,18 +719,18 @@ int xc_cpu_policy_get_system(xc_interface *xch, unsigned int policy_idx,
xc_cpu_policy_t *policy)
{
unsigned int nr_leaves = ARRAY_SIZE(policy->leaves);
unsigned int nr_entries = ARRAY_SIZE(policy->entries);
unsigned int nr_msrs = ARRAY_SIZE(policy->msrs);
int rc;
rc = get_system_cpu_policy(xch, policy_idx, &nr_leaves, policy->leaves,
&nr_entries, policy->entries);
&nr_msrs, policy->msrs);
if ( rc )
{
PERROR("Failed to obtain %u policy", policy_idx);
return rc;
}
rc = deserialize_policy(xch, policy, nr_leaves, nr_entries);
rc = deserialize_policy(xch, policy, nr_leaves, nr_msrs);
if ( rc )
{
errno = -rc;
@@ -744,18 +744,18 @@ int xc_cpu_policy_get_domain(xc_interface *xch, uint32_t domid,
xc_cpu_policy_t *policy)
{
unsigned int nr_leaves = ARRAY_SIZE(policy->leaves);
unsigned int nr_entries = ARRAY_SIZE(policy->entries);
unsigned int nr_msrs = ARRAY_SIZE(policy->msrs);
int rc;
rc = get_domain_cpu_policy(xch, domid, &nr_leaves, policy->leaves,
&nr_entries, policy->entries);
&nr_msrs, policy->msrs);
if ( rc )
{
PERROR("Failed to obtain domain %u policy", domid);
return rc;
}
rc = deserialize_policy(xch, policy, nr_leaves, nr_entries);
rc = deserialize_policy(xch, policy, nr_leaves, nr_msrs);
if ( rc )
{
errno = -rc;
@@ -770,16 +770,16 @@ int xc_cpu_policy_set_domain(xc_interface *xch, uint32_t domid,
{
uint32_t err_leaf = -1, err_subleaf = -1, err_msr = -1;
unsigned int nr_leaves = ARRAY_SIZE(policy->leaves);
unsigned int nr_entries = ARRAY_SIZE(policy->entries);
unsigned int nr_msrs = ARRAY_SIZE(policy->msrs);
int rc;
rc = xc_cpu_policy_serialise(xch, policy, policy->leaves, &nr_leaves,
policy->entries, &nr_entries);
policy->msrs, &nr_msrs);
if ( rc )
return rc;
rc = xc_set_domain_cpu_policy(xch, domid, nr_leaves, policy->leaves,
nr_entries, policy->entries,
nr_msrs, policy->msrs,
&err_leaf, &err_subleaf, &err_msr);
if ( rc )
{
@@ -802,7 +802,7 @@ int xc_cpu_policy_serialise(xc_interface *xch, const xc_cpu_policy_t *p,
if ( leaves )
{
rc = x86_cpuid_copy_to_buffer(&p->cpuid, leaves, nr_leaves);
rc = x86_cpuid_copy_to_buffer(&p->policy, leaves, nr_leaves);
if ( rc )
{
ERROR("Failed to serialize CPUID policy");
@@ -813,7 +813,7 @@ int xc_cpu_policy_serialise(xc_interface *xch, const xc_cpu_policy_t *p,
if ( msrs )
{
rc = x86_msr_copy_to_buffer(&p->msr, msrs, nr_msrs);
rc = x86_msr_copy_to_buffer(&p->policy, msrs, nr_msrs);
if ( rc )
{
ERROR("Failed to serialize MSR policy");
@@ -831,7 +831,7 @@ int xc_cpu_policy_update_cpuid(xc_interface *xch, xc_cpu_policy_t *policy,
uint32_t nr)
{
unsigned int err_leaf = -1, err_subleaf = -1;
int rc = x86_cpuid_copy_from_buffer(&policy->cpuid, leaves, nr,
int rc = x86_cpuid_copy_from_buffer(&policy->policy, leaves, nr,
&err_leaf, &err_subleaf);
if ( rc )
@@ -850,7 +850,7 @@ 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;
int rc = x86_msr_copy_from_buffer(&policy->msr, msrs, nr, &err_msr);
int rc = x86_msr_copy_from_buffer(&policy->policy, msrs, nr, &err_msr);
if ( rc )
{
@@ -868,8 +868,8 @@ bool xc_cpu_policy_is_compatible(xc_interface *xch, xc_cpu_policy_t *host,
xc_cpu_policy_t *guest)
{
struct cpu_policy_errors err = INIT_CPU_POLICY_ERRORS;
struct old_cpu_policy h = { &host->cpuid, &host->msr };
struct old_cpu_policy g = { &guest->cpuid, &guest->msr };
struct old_cpu_policy h = { &host->policy, &host->policy };
struct old_cpu_policy g = { &guest->policy, &guest->policy };
int rc = x86_cpu_policies_are_compatible(&h, &g, &err);
if ( !rc )
+2 -3
View File
@@ -173,10 +173,9 @@ int pin_table(xc_interface *xch, unsigned int type, unsigned long mfn,
#include <xen/lib/x86/cpu-policy.h>
struct xc_cpu_policy {
struct cpuid_policy cpuid;
struct msr_policy msr;
struct cpu_policy policy;
xen_cpuid_leaf_t leaves[CPUID_MAX_SERIALISED_LEAVES];
xen_msr_entry_t entries[MSR_MAX_SERIALISED_ENTRIES];
xen_msr_entry_t msrs[MSR_MAX_SERIALISED_ENTRIES];
};
#endif /* x86 */
+33 -38
View File
@@ -151,15 +151,15 @@ static void test_tsx_msrs(void)
{
printf("Testing MSR_TSX_FORCE_ABORT consistency\n");
test_tsx_msr_consistency(
MSR_TSX_FORCE_ABORT, host.cpuid.feat.tsx_force_abort);
MSR_TSX_FORCE_ABORT, host.policy.feat.tsx_force_abort);
printf("Testing MSR_TSX_CTRL consistency\n");
test_tsx_msr_consistency(
MSR_TSX_CTRL, host.msr.arch_caps.tsx_ctrl);
MSR_TSX_CTRL, host.policy.arch_caps.tsx_ctrl);
printf("Testing MSR_MCU_OPT_CTRL consistency\n");
test_tsx_msr_consistency(
MSR_MCU_OPT_CTRL, host.cpuid.feat.srbds_ctrl);
MSR_MCU_OPT_CTRL, host.policy.feat.srbds_ctrl);
}
/*
@@ -281,7 +281,7 @@ static void test_rtm_behaviour(void)
else
return fail(" Got unexpected behaviour %d\n", rtm_behaviour);
if ( host.cpuid.feat.rtm )
if ( host.policy.feat.rtm )
{
if ( rtm_behaviour == RTM_UD )
fail(" Host reports RTM, but appears unavailable\n");
@@ -293,57 +293,52 @@ static void test_rtm_behaviour(void)
}
}
static void dump_tsx_details(const struct xc_cpu_policy *p, const char *pref)
static void dump_tsx_details(const struct cpu_policy *p, const char *pref)
{
printf(" %s RTM %u, HLE %u, TSX_FORCE_ABORT %u, RTM_ALWAYS_ABORT %u, TSX_CTRL %u\n",
pref,
p->cpuid.feat.rtm,
p->cpuid.feat.hle,
p->cpuid.feat.tsx_force_abort,
p->cpuid.feat.rtm_always_abort,
p->msr.arch_caps.tsx_ctrl);
p->feat.rtm,
p->feat.hle,
p->feat.tsx_force_abort,
p->feat.rtm_always_abort,
p->arch_caps.tsx_ctrl);
}
/* Sanity test various invariants we expect in the default/max policies. */
static void test_guest_policies(const struct xc_cpu_policy *max,
const struct xc_cpu_policy *def)
static void test_guest_policies(const struct cpu_policy *max,
const struct cpu_policy *def)
{
const struct cpuid_policy *cm = &max->cpuid;
const struct cpuid_policy *cd = &def->cpuid;
const struct msr_policy *mm = &max->msr;
const struct msr_policy *md = &def->msr;
dump_tsx_details(max, "Max:");
dump_tsx_details(def, "Def:");
if ( ((cm->feat.raw[0].d | cd->feat.raw[0].d) &
if ( ((max->feat.raw[0].d | def->feat.raw[0].d) &
(bitmaskof(X86_FEATURE_TSX_FORCE_ABORT) |
bitmaskof(X86_FEATURE_RTM_ALWAYS_ABORT) |
bitmaskof(X86_FEATURE_SRBDS_CTRL))) ||
((mm->arch_caps.raw | md->arch_caps.raw) & ARCH_CAPS_TSX_CTRL) )
((max->arch_caps.raw | def->arch_caps.raw) & ARCH_CAPS_TSX_CTRL) )
fail(" Xen-only TSX controls offered to guest\n");
switch ( rtm_behaviour )
{
case RTM_UD:
if ( (cm->feat.raw[0].b | cd->feat.raw[0].b) &
if ( (max->feat.raw[0].b | def->feat.raw[0].b) &
(bitmaskof(X86_FEATURE_HLE) | bitmaskof(X86_FEATURE_RTM)) )
fail(" HLE/RTM offered to guests despite not being available\n");
break;
case RTM_ABORT:
if ( cd->feat.raw[0].b &
if ( def->feat.raw[0].b &
(bitmaskof(X86_FEATURE_HLE) | bitmaskof(X86_FEATURE_RTM)) )
fail(" HLE/RTM offered to guests by default despite not being usable\n");
break;
case RTM_OK:
if ( !cm->feat.rtm || !cd->feat.rtm )
if ( !max->feat.rtm || !def->feat.rtm )
fail(" RTM not offered to guests despite being available\n");
break;
}
if ( cd->feat.hle )
if ( def->feat.hle )
fail(" Fail: HLE offered in default policy\n");
}
@@ -352,13 +347,13 @@ static void test_def_max_policies(void)
if ( xen_has_pv )
{
printf("Testing PV default/max policies\n");
test_guest_policies(&pv_max, &pv_default);
test_guest_policies(&pv_max.policy, &pv_default.policy);
}
if ( xen_has_hvm )
{
printf("Testing HVM default/max policies\n");
test_guest_policies(&hvm_max, &hvm_default);
test_guest_policies(&hvm_max.policy, &hvm_default.policy);
}
}
@@ -382,23 +377,23 @@ static void test_guest(struct xen_domctl_createdomain *c)
goto out;
}
dump_tsx_details(&guest_policy, "Cur:");
dump_tsx_details(&guest_policy.policy, "Cur:");
/*
* Check defaults given to the guest.
*/
if ( guest_policy.cpuid.feat.rtm != (rtm_behaviour == RTM_OK) )
if ( guest_policy.policy.feat.rtm != (rtm_behaviour == RTM_OK) )
fail(" RTM %u in guest, despite rtm behaviour\n",
guest_policy.cpuid.feat.rtm);
guest_policy.policy.feat.rtm);
if ( guest_policy.cpuid.feat.hle ||
guest_policy.cpuid.feat.tsx_force_abort ||
guest_policy.cpuid.feat.rtm_always_abort ||
guest_policy.cpuid.feat.srbds_ctrl ||
guest_policy.msr.arch_caps.tsx_ctrl )
if ( guest_policy.policy.feat.hle ||
guest_policy.policy.feat.tsx_force_abort ||
guest_policy.policy.feat.rtm_always_abort ||
guest_policy.policy.feat.srbds_ctrl ||
guest_policy.policy.arch_caps.tsx_ctrl )
fail(" Unexpected features advertised\n");
if ( host.cpuid.feat.rtm )
if ( host.policy.feat.rtm )
{
unsigned int _7b0;
@@ -406,7 +401,7 @@ static void test_guest(struct xen_domctl_createdomain *c)
* If host RTM is available, all combinations of guest flags should be
* possible. Flip both HLE/RTM to check non-default settings.
*/
_7b0 = (guest_policy.cpuid.feat.raw[0].b ^=
_7b0 = (guest_policy.policy.feat.raw[0].b ^=
(bitmaskof(X86_FEATURE_HLE) | bitmaskof(X86_FEATURE_RTM)));
/* Set the new policy. */
@@ -427,12 +422,12 @@ static void test_guest(struct xen_domctl_createdomain *c)
goto out;
}
dump_tsx_details(&guest_policy, "Cur:");
dump_tsx_details(&guest_policy.policy, "Cur:");
if ( guest_policy.cpuid.feat.raw[0].b != _7b0 )
if ( guest_policy.policy.feat.raw[0].b != _7b0 )
{
fail(" Expected CPUID.7[1].b 0x%08x differs from actual 0x%08x\n",
_7b0, guest_policy.cpuid.feat.raw[0].b);
_7b0, guest_policy.policy.feat.raw[0].b);
goto out;
}
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.