mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86: Drop struct old_cpu_policy
With all the complicated callers of x86_cpu_policies_are_compatible() updated
to use a single cpu_policy object, we can drop the final user of struct
old_cpu_policy.
Update x86_cpu_policies_are_compatible() to take (new) cpu_policy pointers,
reducing the amount of internal pointer chasing, and update all callers to
pass their cpu_policy objects directly.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit 66c5c99656)
This commit is contained in:
1 parent
9fd9906c57
commit
0b8a347d7b
5 files changed
+27
-58
No files matched your search
@@ -869,9 +869,7 @@ 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->policy, &host->policy };
|
||||
struct old_cpu_policy g = { &guest->policy, &guest->policy };
|
||||
int rc = x86_cpu_policies_are_compatible(&h, &g, &err);
|
||||
int rc = x86_cpu_policies_are_compatible(&host->policy, &guest->policy, &err);
|
||||
|
||||
if ( !rc )
|
||||
return true;
|
||||
|
||||
@@ -98,7 +98,7 @@ static bool msrs_are_sorted(const xen_msr_entry_t *entries, unsigned int nr)
|
||||
|
||||
static void test_cpuid_current(void)
|
||||
{
|
||||
struct cpuid_policy p;
|
||||
struct cpu_policy p;
|
||||
xen_cpuid_leaf_t leaves[CPUID_MAX_SERIALISED_LEAVES];
|
||||
unsigned int nr = ARRAY_SIZE(leaves);
|
||||
int rc;
|
||||
@@ -118,7 +118,7 @@ static void test_cpuid_current(void)
|
||||
static void test_cpuid_serialise_success(void)
|
||||
{
|
||||
static const struct test {
|
||||
struct cpuid_policy p;
|
||||
struct cpu_policy p;
|
||||
const char *name;
|
||||
unsigned int nr_leaves;
|
||||
} tests[] = {
|
||||
@@ -242,7 +242,7 @@ static void test_cpuid_serialise_success(void)
|
||||
static void test_msr_serialise_success(void)
|
||||
{
|
||||
static const struct test {
|
||||
struct msr_policy p;
|
||||
struct cpu_policy p;
|
||||
const char *name;
|
||||
unsigned int nr_msrs;
|
||||
} tests[] = {
|
||||
@@ -430,7 +430,7 @@ static void test_cpuid_out_of_range_clearing(void)
|
||||
static const struct test {
|
||||
const char *name;
|
||||
unsigned int nr_markers;
|
||||
struct cpuid_policy p;
|
||||
struct cpu_policy p;
|
||||
} tests[] = {
|
||||
{
|
||||
.name = "basic",
|
||||
@@ -550,7 +550,7 @@ static void test_cpuid_out_of_range_clearing(void)
|
||||
for ( size_t i = 0; i < ARRAY_SIZE(tests); ++i )
|
||||
{
|
||||
const struct test *t = &tests[i];
|
||||
struct cpuid_policy *p = memdup(&t->p);
|
||||
struct cpu_policy *p = memdup(&t->p);
|
||||
void *ptr;
|
||||
unsigned int nr_markers;
|
||||
|
||||
@@ -574,23 +574,20 @@ static void test_is_compatible_success(void)
|
||||
{
|
||||
static struct test {
|
||||
const char *name;
|
||||
struct cpuid_policy host_cpuid;
|
||||
struct cpuid_policy guest_cpuid;
|
||||
struct msr_policy host_msr;
|
||||
struct msr_policy guest_msr;
|
||||
struct cpu_policy host, guest;
|
||||
} tests[] = {
|
||||
{
|
||||
.name = "Host CPUID faulting, Guest not",
|
||||
.host_msr = {
|
||||
.host = {
|
||||
.platform_info.cpuid_faulting = true,
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "Host CPUID faulting, Guest wanted",
|
||||
.host_msr = {
|
||||
.host = {
|
||||
.platform_info.cpuid_faulting = true,
|
||||
},
|
||||
.guest_msr = {
|
||||
.guest = {
|
||||
.platform_info.cpuid_faulting = true,
|
||||
},
|
||||
},
|
||||
@@ -602,15 +599,8 @@ static void test_is_compatible_success(void)
|
||||
for ( size_t i = 0; i < ARRAY_SIZE(tests); ++i )
|
||||
{
|
||||
struct test *t = &tests[i];
|
||||
struct old_cpu_policy sys = {
|
||||
&t->host_cpuid,
|
||||
&t->host_msr,
|
||||
}, new = {
|
||||
&t->guest_cpuid,
|
||||
&t->guest_msr,
|
||||
};
|
||||
struct cpu_policy_errors e;
|
||||
int res = x86_cpu_policies_are_compatible(&sys, &new, &e);
|
||||
int res = x86_cpu_policies_are_compatible(&t->host, &t->guest, &e);
|
||||
|
||||
/* Check the expected error output. */
|
||||
if ( res != 0 || memcmp(&no_errors, &e, sizeof(no_errors)) )
|
||||
@@ -624,25 +614,22 @@ static void test_is_compatible_failure(void)
|
||||
{
|
||||
static struct test {
|
||||
const char *name;
|
||||
struct cpuid_policy host_cpuid;
|
||||
struct cpuid_policy guest_cpuid;
|
||||
struct msr_policy host_msr;
|
||||
struct msr_policy guest_msr;
|
||||
struct cpu_policy host, guest;
|
||||
struct cpu_policy_errors e;
|
||||
} tests[] = {
|
||||
{
|
||||
.name = "Host basic.max_leaf out of range",
|
||||
.guest_cpuid.basic.max_leaf = 1,
|
||||
.guest.basic.max_leaf = 1,
|
||||
.e = { 0, -1, -1 },
|
||||
},
|
||||
{
|
||||
.name = "Host extd.max_leaf out of range",
|
||||
.guest_cpuid.extd.max_leaf = 1,
|
||||
.guest.extd.max_leaf = 1,
|
||||
.e = { 0x80000000, -1, -1 },
|
||||
},
|
||||
{
|
||||
.name = "Host no CPUID faulting, Guest wanted",
|
||||
.guest_msr = {
|
||||
.guest = {
|
||||
.platform_info.cpuid_faulting = true,
|
||||
},
|
||||
.e = { -1, -1, 0xce },
|
||||
@@ -654,15 +641,8 @@ static void test_is_compatible_failure(void)
|
||||
for ( size_t i = 0; i < ARRAY_SIZE(tests); ++i )
|
||||
{
|
||||
struct test *t = &tests[i];
|
||||
struct old_cpu_policy sys = {
|
||||
&t->host_cpuid,
|
||||
&t->host_msr,
|
||||
}, new = {
|
||||
&t->guest_cpuid,
|
||||
&t->guest_msr,
|
||||
};
|
||||
struct cpu_policy_errors e;
|
||||
int res = x86_cpu_policies_are_compatible(&sys, &new, &e);
|
||||
int res = x86_cpu_policies_are_compatible(&t->host, &t->guest, &e);
|
||||
|
||||
/* Check the expected error output. */
|
||||
if ( res == 0 || memcmp(&t->e, &e, sizeof(t->e)) )
|
||||
|
||||
@@ -51,10 +51,9 @@ static int update_domain_cpu_policy(struct domain *d,
|
||||
xen_domctl_cpu_policy_t *xdpc)
|
||||
{
|
||||
struct cpu_policy *new;
|
||||
struct cpu_policy *sys = is_pv_domain(d)
|
||||
const struct cpu_policy *sys = is_pv_domain(d)
|
||||
? (IS_ENABLED(CONFIG_PV) ? &pv_max_cpu_policy : NULL)
|
||||
: (IS_ENABLED(CONFIG_HVM) ? &hvm_max_cpu_policy : NULL);
|
||||
struct old_cpu_policy old_sys = { sys, sys }, old_new;
|
||||
struct cpu_policy_errors err = INIT_CPU_POLICY_ERRORS;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
@@ -68,8 +67,6 @@ static int update_domain_cpu_policy(struct domain *d,
|
||||
if ( !(new = xmemdup(d->arch.cpu_policy)) )
|
||||
goto out;
|
||||
|
||||
old_new = (struct old_cpu_policy){ new, new };
|
||||
|
||||
/* Merge the toolstack provided data. */
|
||||
if ( (ret = x86_cpuid_copy_from_buffer(
|
||||
new, xdpc->leaves, xdpc->nr_leaves,
|
||||
@@ -82,7 +79,7 @@ static int update_domain_cpu_policy(struct domain *d,
|
||||
x86_cpuid_policy_clear_out_of_range_leaves(new);
|
||||
|
||||
/* Audit the combined dataset. */
|
||||
ret = x86_cpu_policies_are_compatible(&old_sys, &old_new, &err);
|
||||
ret = x86_cpu_policies_are_compatible(sys, new, &err);
|
||||
if ( ret )
|
||||
goto out;
|
||||
|
||||
|
||||
@@ -379,12 +379,6 @@ struct cpu_policy
|
||||
#define cpuid_policy cpu_policy
|
||||
#define msr_policy cpu_policy
|
||||
|
||||
struct old_cpu_policy
|
||||
{
|
||||
struct cpuid_policy *cpuid;
|
||||
struct msr_policy *msr;
|
||||
};
|
||||
|
||||
struct cpu_policy_errors
|
||||
{
|
||||
uint32_t leaf, subleaf;
|
||||
@@ -559,7 +553,7 @@ int x86_msr_copy_from_buffer(struct msr_policy *policy,
|
||||
const msr_entry_buffer_t msrs, uint32_t nr_entries,
|
||||
uint32_t *err_msr);
|
||||
|
||||
/*
|
||||
/**
|
||||
* Calculate whether two policies are compatible.
|
||||
*
|
||||
* i.e. Can a VM configured with @guest run on a CPU supporting @host.
|
||||
@@ -573,8 +567,8 @@ int x86_msr_copy_from_buffer(struct msr_policy *policy,
|
||||
* incompatibility is detected, the optional err pointer may identify the
|
||||
* problematic leaf/subleaf and/or MSR.
|
||||
*/
|
||||
int x86_cpu_policies_are_compatible(const struct old_cpu_policy *host,
|
||||
const struct old_cpu_policy *guest,
|
||||
int x86_cpu_policies_are_compatible(const struct cpu_policy *host,
|
||||
const struct cpu_policy *guest,
|
||||
struct cpu_policy_errors *err);
|
||||
|
||||
#endif /* !XEN_LIB_X86_POLICIES_H */
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#include <xen/lib/x86/cpu-policy.h>
|
||||
|
||||
int x86_cpu_policies_are_compatible(const struct old_cpu_policy *host,
|
||||
const struct old_cpu_policy *guest,
|
||||
int x86_cpu_policies_are_compatible(const struct cpu_policy *host,
|
||||
const struct cpu_policy *guest,
|
||||
struct cpu_policy_errors *err)
|
||||
{
|
||||
struct cpu_policy_errors e = INIT_CPU_POLICY_ERRORS;
|
||||
@@ -15,18 +15,18 @@ int x86_cpu_policies_are_compatible(const struct old_cpu_policy *host,
|
||||
#define FAIL_MSR(m) \
|
||||
do { e.msr = (m); goto out; } while ( 0 )
|
||||
|
||||
if ( guest->cpuid->basic.max_leaf > host->cpuid->basic.max_leaf )
|
||||
if ( guest->basic.max_leaf > host->basic.max_leaf )
|
||||
FAIL_CPUID(0, NA);
|
||||
|
||||
if ( guest->cpuid->feat.max_subleaf > host->cpuid->feat.max_subleaf )
|
||||
if ( guest->feat.max_subleaf > host->feat.max_subleaf )
|
||||
FAIL_CPUID(7, 0);
|
||||
|
||||
if ( guest->cpuid->extd.max_leaf > host->cpuid->extd.max_leaf )
|
||||
if ( guest->extd.max_leaf > host->extd.max_leaf )
|
||||
FAIL_CPUID(0x80000000, NA);
|
||||
|
||||
/* TODO: Audit more CPUID data. */
|
||||
|
||||
if ( ~host->msr->platform_info.raw & guest->msr->platform_info.raw )
|
||||
if ( ~host->platform_info.raw & guest->platform_info.raw )
|
||||
FAIL_MSR(MSR_INTEL_PLATFORM_INFO);
|
||||
|
||||
#undef FAIL_MSR
|
||||
|
||||