diff options
Diffstat (limited to 'xen/arch/x86/cpu/amd.c')
-rw-r--r-- | xen/arch/x86/cpu/amd.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c index 98fb80ee88..0d3143031b 100644 --- a/xen/arch/x86/cpu/amd.c +++ b/xen/arch/x86/cpu/amd.c @@ -277,9 +277,14 @@ static void __init noinline amd_init_levelling(void) * * CPUID faulting is an Intel feature analogous to CpuidUserDis, so * that can only be present when Xen is itself virtualized (because - * it can be emulated) + * it can be emulated). + * + * Note that probing for the Intel feature _first_ isn't a mistake, + * but a means to ensure MSR_INTEL_PLATFORM_INFO is read and added + * to the raw CPU policy if present. */ - if (cpu_has_hypervisor && probe_cpuid_faulting()) { + if ((cpu_has_hypervisor && probe_cpuid_faulting()) || + boot_cpu_has(X86_FEATURE_CPUID_USER_DIS)) { expected_levelling_cap |= LCAP_faulting; levelling_caps |= LCAP_faulting; return; @@ -374,6 +379,20 @@ static void __init noinline amd_init_levelling(void) ctxt_switch_masking = amd_ctxt_switch_masking; } +void amd_set_cpuid_user_dis(bool enable) +{ + const uint64_t bit = K8_HWCR_CPUID_USER_DIS; + uint64_t val; + + rdmsrl(MSR_K8_HWCR, val); + + if (!!(val & bit) == enable) + return; + + val ^= bit; + wrmsrl(MSR_K8_HWCR, val); +} + /* * Check for the presence of an AMD erratum. Arguments are defined in amd.h * for each known erratum. Return 1 if erratum is found. |