2019-06-13 21:54:14 +03:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Sean Christopherson <sean.j.christopherson@intel.com>
|
|
|
|
Date: Thu, 7 Mar 2019 15:43:02 -0800
|
|
|
|
Subject: [PATCH] KVM: x86: Emulate MSR_IA32_ARCH_CAPABILITIES on AMD hosts
|
|
|
|
|
|
|
|
BugLink: https://bugs.launchpad.net/bugs/1823060
|
|
|
|
|
|
|
|
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>
|
|
|
|
|
|
|
|
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
|
|
|
|
|
|
|
|
(back ported from commit 0cf9135b773bf32fba9dd8e6699c1b331ee4b749)
|
|
|
|
Backported-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|
|
|
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|
|
|
---
|
|
|
|
arch/x86/include/asm/kvm_host.h | 1 +
|
|
|
|
arch/x86/kvm/vmx.c | 14 --------------
|
|
|
|
arch/x86/kvm/x86.c | 12 ++++++++++++
|
|
|
|
3 files changed, 13 insertions(+), 14 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
|
|
|
|
index e76012ca0ddc..fa57f78dff2d 100644
|
|
|
|
--- a/arch/x86/include/asm/kvm_host.h
|
|
|
|
+++ b/arch/x86/include/asm/kvm_host.h
|
|
|
|
@@ -508,6 +508,7 @@ struct kvm_vcpu_arch {
|
|
|
|
bool tpr_access_reporting;
|
|
|
|
u64 ia32_xss;
|
|
|
|
u64 microcode_version;
|
|
|
|
+ u64 arch_capabilities;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Paging state of the vcpu
|
|
|
|
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
|
|
|
|
index 38e50b40db5a..1911ec5e26c1 100644
|
|
|
|
--- a/arch/x86/kvm/vmx.c
|
|
|
|
+++ b/arch/x86/kvm/vmx.c
|
|
|
|
@@ -750,7 +750,6 @@ struct vcpu_vmx {
|
|
|
|
u64 msr_guest_kernel_gs_base;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
- u64 arch_capabilities;
|
|
|
|
u64 spec_ctrl;
|
|
|
|
|
|
|
|
u32 vm_entry_controls_shadow;
|
|
|
|
@@ -3477,12 +3476,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;
|
|
|
|
@@ -3644,11 +3637,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))
|
|
|
|
@@ -5906,8 +5894,6 @@ static void 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 */
|
|
|
|
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
|
2019-06-18 08:35:35 +03:00
|
|
|
index 3d3d6d6548c3..92a8b20b7103 100644
|
2019-06-13 21:54:14 +03:00
|
|
|
--- a/arch/x86/kvm/x86.c
|
|
|
|
+++ b/arch/x86/kvm/x86.c
|
2019-06-18 08:35:35 +03:00
|
|
|
@@ -2247,6 +2247,11 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
2019-06-13 21:54:14 +03:00
|
|
|
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:
|
2019-06-18 08:35:35 +03:00
|
|
|
@@ -2543,6 +2548,12 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
2019-06-13 21:54:14 +03:00
|
|
|
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_IA32_TSC:
|
|
|
|
msr_info->data = kvm_scale_tsc(vcpu, rdtsc()) + vcpu->arch.tsc_offset;
|
|
|
|
break;
|
2019-06-18 08:35:35 +03:00
|
|
|
@@ -7951,6 +7962,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
|
2019-06-13 21:54:14 +03:00
|
|
|
|
|
|
|
int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
+ vcpu->arch.arch_capabilities = kvm_get_arch_capabilities();
|
|
|
|
vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
|
|
|
|
kvm_vcpu_mtrr_init(vcpu);
|
|
|
|
vcpu_load(vcpu);
|