| From foo@baz Tue Aug 14 16:14:56 CEST 2018 |
| From: Wanpeng Li <wanpengli@tencent.com> |
| Date: Wed, 28 Feb 2018 14:03:31 +0800 |
| Subject: KVM: X86: Allow userspace to define the microcode version |
| |
| From: Wanpeng Li <wanpengli@tencent.com> |
| |
| commit 518e7b94817abed94becfe6a44f1ece0d4745afe upstream |
| |
| Linux (among the others) has checks to make sure that certain features |
| aren't enabled on a certain family/model/stepping if the microcode version |
| isn't greater than or equal to a known good version. |
| |
| By exposing the real microcode version, we're preventing buggy guests that |
| don't check that they are running virtualized (i.e., they should trust the |
| hypervisor) from disabling features that are effectively not buggy. |
| |
| Suggested-by: Filippo Sironi <sironi@amazon.de> |
| Signed-off-by: Wanpeng Li <wanpengli@tencent.com> |
| Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> |
| Cc: Liran Alon <liran.alon@oracle.com> |
| Cc: Nadav Amit <nadav.amit@gmail.com> |
| Cc: Borislav Petkov <bp@alien8.de> |
| Cc: Tom Lendacky <thomas.lendacky@amd.com> |
| Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/include/asm/kvm_host.h | 1 + |
| arch/x86/kvm/svm.c | 4 +--- |
| arch/x86/kvm/vmx.c | 1 + |
| arch/x86/kvm/x86.c | 11 +++++++++-- |
| 4 files changed, 12 insertions(+), 5 deletions(-) |
| |
| --- a/arch/x86/include/asm/kvm_host.h |
| +++ b/arch/x86/include/asm/kvm_host.h |
| @@ -486,6 +486,7 @@ struct kvm_vcpu_arch { |
| u64 smbase; |
| bool tpr_access_reporting; |
| u64 ia32_xss; |
| + u64 microcode_version; |
| |
| /* |
| * Paging state of the vcpu |
| --- a/arch/x86/kvm/svm.c |
| +++ b/arch/x86/kvm/svm.c |
| @@ -1569,6 +1569,7 @@ static void svm_vcpu_reset(struct kvm_vc |
| u32 dummy; |
| u32 eax = 1; |
| |
| + vcpu->arch.microcode_version = 0x01000065; |
| svm->spec_ctrl = 0; |
| svm->virt_spec_ctrl = 0; |
| |
| @@ -3585,9 +3586,6 @@ static int svm_get_msr(struct kvm_vcpu * |
| |
| msr_info->data = svm->virt_spec_ctrl; |
| break; |
| - case MSR_IA32_UCODE_REV: |
| - msr_info->data = 0x01000065; |
| - break; |
| case MSR_F15H_IC_CFG: { |
| |
| int family, model; |
| --- a/arch/x86/kvm/vmx.c |
| +++ b/arch/x86/kvm/vmx.c |
| @@ -5481,6 +5481,7 @@ static void vmx_vcpu_reset(struct kvm_vc |
| u64 cr0; |
| |
| vmx->rmode.vm86_active = 0; |
| + vcpu->arch.microcode_version = 0x100000000ULL; |
| vmx->spec_ctrl = 0; |
| |
| vmx->soft_vnmi_blocked = 0; |
| --- a/arch/x86/kvm/x86.c |
| +++ b/arch/x86/kvm/x86.c |
| @@ -1014,6 +1014,7 @@ static unsigned num_emulated_msrs; |
| */ |
| static u32 msr_based_features[] = { |
| MSR_F10H_DECFG, |
| + MSR_IA32_UCODE_REV, |
| }; |
| |
| static unsigned int num_msr_based_features; |
| @@ -1021,6 +1022,9 @@ static unsigned int num_msr_based_featur |
| static int kvm_get_msr_feature(struct kvm_msr_entry *msr) |
| { |
| switch (msr->index) { |
| + case MSR_IA32_UCODE_REV: |
| + rdmsrl(msr->index, msr->data); |
| + break; |
| default: |
| if (kvm_x86_ops->get_msr_feature(msr)) |
| return 1; |
| @@ -2157,13 +2161,16 @@ int kvm_set_msr_common(struct kvm_vcpu * |
| |
| switch (msr) { |
| case MSR_AMD64_NB_CFG: |
| - case MSR_IA32_UCODE_REV: |
| case MSR_IA32_UCODE_WRITE: |
| case MSR_VM_HSAVE_PA: |
| case MSR_AMD64_PATCH_LOADER: |
| case MSR_AMD64_BU_CFG2: |
| break; |
| |
| + case MSR_IA32_UCODE_REV: |
| + if (msr_info->host_initiated) |
| + vcpu->arch.microcode_version = data; |
| + break; |
| case MSR_EFER: |
| return set_efer(vcpu, data); |
| case MSR_K7_HWCR: |
| @@ -2438,7 +2445,7 @@ int kvm_get_msr_common(struct kvm_vcpu * |
| msr_info->data = 0; |
| break; |
| case MSR_IA32_UCODE_REV: |
| - msr_info->data = 0x100000000ULL; |
| + msr_info->data = vcpu->arch.microcode_version; |
| break; |
| case MSR_MTRRcap: |
| case 0x200 ... 0x2ff: |