| From 7c83d096aed055a7763a03384f92115363448b71 Mon Sep 17 00:00:00 2001 |
| From: Sean Christopherson <sean.j.christopherson@intel.com> |
| Date: Thu, 2 Jul 2020 21:04:21 -0700 |
| Subject: KVM: x86: Mark CR4.TSD as being possibly owned by the guest |
| |
| From: Sean Christopherson <sean.j.christopherson@intel.com> |
| |
| commit 7c83d096aed055a7763a03384f92115363448b71 upstream. |
| |
| Mark CR4.TSD as being possibly owned by the guest as that is indeed the |
| case on VMX. Without TSD being tagged as possibly owned by the guest, a |
| targeted read of CR4 to get TSD could observe a stale value. This bug |
| is benign in the current code base as the sole consumer of TSD is the |
| emulator (for RDTSC) and the emulator always "reads" the entirety of CR4 |
| when grabbing bits. |
| |
| Add a build-time assertion in to ensure VMX doesn't hand over more CR4 |
| bits without also updating x86. |
| |
| Fixes: 52ce3c21aec3 ("x86,kvm,vmx: Don't trap writes to CR4.TSD") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> |
| Message-Id: <20200703040422.31536-2-sean.j.christopherson@intel.com> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/x86/kvm/kvm_cache_regs.h | 2 +- |
| arch/x86/kvm/vmx/vmx.c | 2 ++ |
| 2 files changed, 3 insertions(+), 1 deletion(-) |
| |
| --- a/arch/x86/kvm/kvm_cache_regs.h |
| +++ b/arch/x86/kvm/kvm_cache_regs.h |
| @@ -7,7 +7,7 @@ |
| #define KVM_POSSIBLE_CR0_GUEST_BITS X86_CR0_TS |
| #define KVM_POSSIBLE_CR4_GUEST_BITS \ |
| (X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR \ |
| - | X86_CR4_OSXMMEXCPT | X86_CR4_LA57 | X86_CR4_PGE) |
| + | X86_CR4_OSXMMEXCPT | X86_CR4_LA57 | X86_CR4_PGE | X86_CR4_TSD) |
| |
| #define BUILD_KVM_GPR_ACCESSORS(lname, uname) \ |
| static __always_inline unsigned long kvm_##lname##_read(struct kvm_vcpu *vcpu)\ |
| --- a/arch/x86/kvm/vmx/vmx.c |
| +++ b/arch/x86/kvm/vmx/vmx.c |
| @@ -3913,6 +3913,8 @@ void vmx_set_constant_host_state(struct |
| |
| void set_cr4_guest_host_mask(struct vcpu_vmx *vmx) |
| { |
| + BUILD_BUG_ON(KVM_CR4_GUEST_OWNED_BITS & ~KVM_POSSIBLE_CR4_GUEST_BITS); |
| + |
| vmx->vcpu.arch.cr4_guest_owned_bits = KVM_CR4_GUEST_OWNED_BITS; |
| if (enable_ept) |
| vmx->vcpu.arch.cr4_guest_owned_bits |= X86_CR4_PGE; |