]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
KVM: x86: Emulate MSR_IA32_ARCH_CAPABILITIES on AMD hosts
authorSean Christopherson <sean.j.christopherson@intel.com>
Thu, 7 Mar 2019 23:43:02 +0000 (15:43 -0800)
committerBen Hutchings <ben@decadent.org.uk>
Tue, 13 Aug 2019 11:38:57 +0000 (12:38 +0100)
commit 0cf9135b773bf32fba9dd8e6699c1b331ee4b749 upstream.

The CPUID flag ARCH_CAPABILITIES is unconditioinally exposed to host
userspace for all x86 hosts, i.e. KVM advertises ARCH_CAPABILITIES
regardless of hardware support under the pretense that KVM fully
emulates MSR_IA32_ARCH_CAPABILITIES.  Unfortunately, only VMX hosts
handle accesses to MSR_IA32_ARCH_CAPABILITIES (despite KVM_GET_MSRS
also reporting MSR_IA32_ARCH_CAPABILITIES for all hosts).

Move the MSR_IA32_ARCH_CAPABILITIES handling to common x86 code so
that it's emulated on AMD hosts.

Fixes: 1eaafe91a0df4 ("kvm: x86: IA32_ARCH_CAPABILITIES is always supported")
Reported-by: Xiaoyao Li <xiaoyao.li@linux.intel.com>
Cc: Jim Mattson <jmattson@google.com>
Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[bwh: Backported to 3.16:
 - Keep using guest_cpuid_has_arch_capabilities() to check the CPUID
 - Keep using rdmsrl() to get the initial value of IA32_ARCH_CAPABILITIES
 - Adjust filenames, context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c

index e9eae4fbdde26eb5a3f832bd0707fafcb99f0ee4..de6c067a2cb44acc0abcc4dd1335dbc3bc96b3fc 100644 (file)
@@ -363,6 +363,7 @@ struct kvm_vcpu_arch {
        int mp_state;
        u64 ia32_misc_enable_msr;
        bool tpr_access_reporting;
+       u64 arch_capabilities;
 
        /*
         * Paging state of the vcpu
index bd6b883f3075a1a0d6227a481f8d4faa6a2d673a..00dd9ea13c220d4c58f0d1edd14dfee15caa3189 100644 (file)
@@ -433,7 +433,6 @@ struct vcpu_vmx {
        u64                   msr_guest_kernel_gs_base;
 #endif
 
-       u64                   arch_capabilities;
        u64                   spec_ctrl;
 
        u32 vm_entry_controls_shadow;
@@ -2481,12 +2480,6 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 
                msr_info->data = to_vmx(vcpu)->spec_ctrl;
                break;
-       case MSR_IA32_ARCH_CAPABILITIES:
-               if (!msr_info->host_initiated &&
-                   !guest_cpuid_has_arch_capabilities(vcpu))
-                       return 1;
-               msr_info->data = to_vmx(vcpu)->arch_capabilities;
-               break;
        case MSR_IA32_SYSENTER_CS:
                msr_info->data = vmcs_read32(GUEST_SYSENTER_CS);
                break;
@@ -2636,11 +2629,6 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                vmx_disable_intercept_for_msr(vmx->vmcs01.msr_bitmap, MSR_IA32_PRED_CMD,
                                              MSR_TYPE_W);
                break;
-       case MSR_IA32_ARCH_CAPABILITIES:
-               if (!msr_info->host_initiated)
-                       return 1;
-               vmx->arch_capabilities = data;
-               break;
        case MSR_IA32_CR_PAT:
                if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) {
                        if (!kvm_mtrr_valid(vcpu, MSR_IA32_CR_PAT, data))
@@ -4583,9 +4571,6 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
                ++vmx->nmsrs;
        }
 
-       if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES))
-               rdmsrl(MSR_IA32_ARCH_CAPABILITIES, vmx->arch_capabilities);
-
        vm_exit_controls_init(vmx, vmcs_config.vmexit_ctrl);
 
        /* 22.2.1, 20.8.1 */
index cab3ca9d3f03226e950e54fc0eec673508d6e3d6..7773e286d923c9b81d2c5be3970729d33b5c8aea 100644 (file)
@@ -2089,6 +2089,11 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        case MSR_F15H_EX_CFG:
                break;
 
+       case MSR_IA32_ARCH_CAPABILITIES:
+               if (!msr_info->host_initiated)
+                       return 1;
+               vcpu->arch.arch_capabilities = data;
+               break;
        case MSR_EFER:
                return set_efer(vcpu, data);
        case MSR_K7_HWCR:
@@ -2479,6 +2484,12 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        case MSR_IA32_UCODE_REV:
                msr_info->data = 0x100000000ULL;
                break;
+       case MSR_IA32_ARCH_CAPABILITIES:
+               if (!msr_info->host_initiated &&
+                   !guest_cpuid_has_arch_capabilities(vcpu))
+                       return 1;
+               msr_info->data = vcpu->arch.arch_capabilities;
+               break;
        case MSR_MTRRcap:
                msr_info->data = 0x500 | KVM_NR_VAR_MTRR;
                break;
@@ -6957,6 +6968,9 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
 {
        int r;
 
+       if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES))
+               rdmsrl(MSR_IA32_ARCH_CAPABILITIES,
+                      vcpu->arch.arch_capabilities);
        vcpu->arch.mtrr_state.have_fixed = 1;
        r = vcpu_load(vcpu);
        if (r)