1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Sean Christopherson <sean.j.christopherson@intel.com>
3 Date: Thu, 7 Mar 2019 15:43:02 -0800
4 Subject: [PATCH] KVM: x86: Emulate MSR_IA32_ARCH_CAPABILITIES on AMD hosts
6 BugLink: https://bugs.launchpad.net/bugs/1823060
8 commit 0cf9135b773bf32fba9dd8e6699c1b331ee4b749 upstream.
10 The CPUID flag ARCH_CAPABILITIES is unconditioinally exposed to host
11 userspace for all x86 hosts, i.e. KVM advertises ARCH_CAPABILITIES
12 regardless of hardware support under the pretense that KVM fully
13 emulates MSR_IA32_ARCH_CAPABILITIES. Unfortunately, only VMX hosts
14 handle accesses to MSR_IA32_ARCH_CAPABILITIES (despite KVM_GET_MSRS
15 also reporting MSR_IA32_ARCH_CAPABILITIES for all hosts).
17 Move the MSR_IA32_ARCH_CAPABILITIES handling to common x86 code so
18 that it's emulated on AMD hosts.
20 Fixes: 1eaafe91a0df4 ("kvm: x86: IA32_ARCH_CAPABILITIES is always supported")
21 Cc: stable@vger.kernel.org
22 Reported-by: Xiaoyao Li <xiaoyao.li@linux.intel.com>
23 Cc: Jim Mattson <jmattson@google.com>
24 Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
25 Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
26 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28 Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
30 (back ported from commit 0cf9135b773bf32fba9dd8e6699c1b331ee4b749)
31 Backported-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
32 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
34 arch/x86/include/asm/kvm_host.h | 1 +
35 arch/x86/kvm/vmx.c | 14 --------------
36 arch/x86/kvm/x86.c | 12 ++++++++++++
37 3 files changed, 13 insertions(+), 14 deletions(-)
39 diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
40 index c2bb7da8e5b4..e238785c22d3 100644
41 --- a/arch/x86/include/asm/kvm_host.h
42 +++ b/arch/x86/include/asm/kvm_host.h
43 @@ -509,6 +509,7 @@ struct kvm_vcpu_arch {
44 bool tpr_access_reporting;
46 u64 microcode_version;
47 + u64 arch_capabilities;
50 * Paging state of the vcpu
51 diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
52 index 921968c00dde..cddbdd2d615d 100644
53 --- a/arch/x86/kvm/vmx.c
54 +++ b/arch/x86/kvm/vmx.c
55 @@ -750,7 +750,6 @@ struct vcpu_vmx {
56 u64 msr_guest_kernel_gs_base;
59 - u64 arch_capabilities;
62 u32 vm_entry_controls_shadow;
63 @@ -3485,12 +3484,6 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
65 msr_info->data = to_vmx(vcpu)->spec_ctrl;
67 - case MSR_IA32_ARCH_CAPABILITIES:
68 - if (!msr_info->host_initiated &&
69 - !guest_cpuid_has(vcpu, X86_FEATURE_ARCH_CAPABILITIES))
71 - msr_info->data = to_vmx(vcpu)->arch_capabilities;
73 case MSR_IA32_SYSENTER_CS:
74 msr_info->data = vmcs_read32(GUEST_SYSENTER_CS);
76 @@ -3652,11 +3645,6 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
77 vmx_disable_intercept_for_msr(vmx->vmcs01.msr_bitmap, MSR_IA32_PRED_CMD,
80 - case MSR_IA32_ARCH_CAPABILITIES:
81 - if (!msr_info->host_initiated)
83 - vmx->arch_capabilities = data;
86 if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) {
87 if (!kvm_mtrr_valid(vcpu, MSR_IA32_CR_PAT, data))
88 @@ -5914,8 +5902,6 @@ static void vmx_vcpu_setup(struct vcpu_vmx *vmx)
92 - vmx->arch_capabilities = kvm_get_arch_capabilities();
94 vm_exit_controls_init(vmx, vmcs_config.vmexit_ctrl);
97 diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
98 index be629513de13..88f910046a60 100644
99 --- a/arch/x86/kvm/x86.c
100 +++ b/arch/x86/kvm/x86.c
101 @@ -2248,6 +2248,11 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
102 if (msr_info->host_initiated)
103 vcpu->arch.microcode_version = data;
105 + case MSR_IA32_ARCH_CAPABILITIES:
106 + if (!msr_info->host_initiated)
108 + vcpu->arch.arch_capabilities = data;
111 return set_efer(vcpu, data);
113 @@ -2544,6 +2549,12 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
114 case MSR_IA32_UCODE_REV:
115 msr_info->data = vcpu->arch.microcode_version;
117 + case MSR_IA32_ARCH_CAPABILITIES:
118 + if (!msr_info->host_initiated &&
119 + !guest_cpuid_has(vcpu, X86_FEATURE_ARCH_CAPABILITIES))
121 + msr_info->data = vcpu->arch.arch_capabilities;
124 msr_info->data = kvm_scale_tsc(vcpu, rdtsc()) + vcpu->arch.tsc_offset;
126 @@ -7957,6 +7968,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
128 int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
130 + vcpu->arch.arch_capabilities = kvm_get_arch_capabilities();
131 vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
132 kvm_vcpu_mtrr_init(vcpu);