summaryrefslogtreecommitdiff
path: root/xen/lib/x86/policy.c
blob: a9c60000af9d7ffe9a6d227ab80b8aaa255e3270 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "private.h"

#include <xen/lib/x86/cpu-policy.h>

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;
    int ret = -EINVAL;

#define NA XEN_CPUID_NO_SUBLEAF
#define FAIL_CPUID(l, s) \
    do { e.leaf = (l); e.subleaf = (s); goto out; } while ( 0 )
#define FAIL_MSR(m) \
    do { e.msr = (m); goto out; } while ( 0 )

    if ( guest->basic.max_leaf > host->basic.max_leaf )
        FAIL_CPUID(0, NA);

    if ( guest->feat.max_subleaf > host->feat.max_subleaf )
        FAIL_CPUID(7, 0);

    if ( guest->extd.max_leaf > host->extd.max_leaf )
        FAIL_CPUID(0x80000000, NA);

    /* TODO: Audit more CPUID data. */

    if ( ~host->platform_info.raw & guest->platform_info.raw )
        FAIL_MSR(MSR_INTEL_PLATFORM_INFO);

#undef FAIL_MSR
#undef FAIL_CPUID
#undef NA

    /* Success. */
    ret = 0;

 out:
    if ( err )
        *err = e;

    return ret;
}

/*
 * Local variables:
 * mode: C
 * c-file-style: "BSD"
 * c-basic-offset: 4
 * tab-width: 4
 * indent-tabs-mode: nil
 * End:
 */