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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Apr 2019 04:25:20 +0000 (06:25 +0200)
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")
Cc: stable@vger.kernel.org
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c

index d2ae93faafe8439cc3b793695e93a50158d13eb8..f9a4b85d7309b1b91a489dda8fd329921d18b812 100644 (file)
@@ -509,6 +509,7 @@ struct kvm_vcpu_arch {
        bool tpr_access_reporting;
        u64 ia32_xss;
        u64 microcode_version;
+       u64 arch_capabilities;
 
        /*
         * Paging state of the vcpu
index 229d5e39f5c063647c001c07f2c31885d9b5698b..4bd878c9f7d2ec04fe983b76fad6ea5fce751595 100644 (file)
@@ -740,7 +740,6 @@ struct vcpu_vmx {
        u64                   msr_guest_kernel_gs_base;
 #endif
 
-       u64                   arch_capabilities;
        u64                   spec_ctrl;
 
        u32 vm_entry_controls_shadow;
@@ -3493,12 +3492,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(vcpu, X86_FEATURE_ARCH_CAPABILITIES))
-                       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;
@@ -3663,11 +3656,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))
@@ -5929,8 +5917,6 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
                ++vmx->nmsrs;
        }
 
-       vmx->arch_capabilities = kvm_get_arch_capabilities();
-
        vm_exit_controls_init(vmx, vmcs_config.vmexit_ctrl);
 
        /* 22.2.1, 20.8.1 */
index ce5b3dc348ce04d56542871af3d741cb7edca930..5f85f17ffb75a7d7caa55aca321d3ba085f4851c 100644 (file)
@@ -2234,6 +2234,11 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                if (msr_info->host_initiated)
                        vcpu->arch.microcode_version = data;
                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:
@@ -2523,6 +2528,12 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        case MSR_IA32_UCODE_REV:
                msr_info->data = vcpu->arch.microcode_version;
                break;
+       case MSR_IA32_ARCH_CAPABILITIES:
+               if (!msr_info->host_initiated &&
+                   !guest_cpuid_has(vcpu, X86_FEATURE_ARCH_CAPABILITIES))
+                       return 1;
+               msr_info->data = vcpu->arch.arch_capabilities;
+               break;
        case MSR_MTRRcap:
        case 0x200 ... 0x2ff:
                return kvm_mtrr_get_msr(vcpu, msr_info->index, &msr_info->data);
@@ -7918,6 +7929,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
 {
        int r;
 
+       vcpu->arch.arch_capabilities = kvm_get_arch_capabilities();
        kvm_vcpu_mtrr_init(vcpu);
        r = vcpu_load(vcpu);
        if (r)