Juergen Gross 1f6ece
Patch-mainline: v5.15-rc4
Juergen Gross 1f6ece
Git-commit: 7117003fe4e3c8977744f2ad33bb95fd3e10023f
Juergen Gross 1f6ece
References: git-fixes
Juergen Gross 1f6ece
From: Sean Christopherson <seanjc@google.com>
Juergen Gross 1f6ece
Date: Mon, 20 Sep 2021 17:02:54 -0700
Juergen Gross 1f6ece
Subject: [PATCH] KVM: x86: Mark all registers as avail/dirty at vCPU creation
Juergen Gross 1f6ece
Juergen Gross 1f6ece
Mark all registers as available and dirty at vCPU creation, as the vCPU has
Juergen Gross 1f6ece
obviously not been loaded into hardware, let alone been given the chance to
Juergen Gross 1f6ece
be modified in hardware.  On SVM, reading from "uninitialized" hardware is
Juergen Gross 1f6ece
a non-issue as VMCBs are zero allocated (thus not truly uninitialized) and
Juergen Gross 1f6ece
hardware does not allow for arbitrary field encoding schemes.
Juergen Gross 1f6ece
Juergen Gross 1f6ece
On VMX, backing memory for VMCSes is also zero allocated, but true
Juergen Gross 1f6ece
initialization of the VMCS _technically_ requires VMWRITEs, as the VMX
Juergen Gross 1f6ece
architectural specification technically allows CPU implementations to
Juergen Gross 1f6ece
encode fields with arbitrary schemes.  E.g. a CPU could theoretically store
Juergen Gross 1f6ece
the inverted value of every field, which would result in VMREAD to a
Juergen Gross 1f6ece
zero-allocated field returns all ones.
Juergen Gross 1f6ece
Juergen Gross 1f6ece
In practice, only the AR_BYTES fields are known to be manipulated by
Juergen Gross 1f6ece
hardware during VMREAD/VMREAD; no known hardware or VMM (for nested VMX)
Juergen Gross 1f6ece
does fancy encoding of cacheable field values (CR0, CR3, CR4, etc...).  In
Juergen Gross 1f6ece
other words, this is technically a bug fix, but practically speakings it's
Juergen Gross 1f6ece
a glorified nop.
Juergen Gross 1f6ece
Juergen Gross 1f6ece
Failure to mark registers as available has been a lurking bug for quite
Juergen Gross 1f6ece
some time.  The original register caching supported only GPRs (+RIP, which
Juergen Gross 1f6ece
is kinda sorta a GPR), with the masks initialized at ->vcpu_reset().  That
Juergen Gross 1f6ece
worked because the two cacheable registers, RIP and RSP, are generally
Juergen Gross 1f6ece
speaking not read as side effects in other flows.
Juergen Gross 1f6ece
Juergen Gross 1f6ece
Arguably, commit aff48baa34c0 ("KVM: Fetch guest cr3 from hardware on
Juergen Gross 1f6ece
demand") was the first instance of failure to mark regs available.  While
Juergen Gross 1f6ece
_just_ marking CR3 available during vCPU creation wouldn't have fixed the
Juergen Gross 1f6ece
VMREAD from an uninitialized VMCS bug because ept_update_paging_mode_cr0()
Juergen Gross 1f6ece
unconditionally read vmcs.GUEST_CR3, marking CR3 _and_ intentionally not
Juergen Gross 1f6ece
reading GUEST_CR3 when it's available would have avoided VMREAD to a
Juergen Gross 1f6ece
technically-uninitialized VMCS.
Juergen Gross 1f6ece
Juergen Gross 1f6ece
Fixes: aff48baa34c0 ("KVM: Fetch guest cr3 from hardware on demand")
Juergen Gross 1f6ece
Fixes: 6de4f3ada40b ("KVM: Cache pdptrs")
Juergen Gross 1f6ece
Fixes: 6de12732c42c ("KVM: VMX: Optimize vmx_get_rflags()")
Juergen Gross 1f6ece
Fixes: 2fb92db1ec08 ("KVM: VMX: Cache vmcs segment fields")
Juergen Gross 1f6ece
Fixes: bd31fe495d0d ("KVM: VMX: Add proper cache tracking for CR0")
Juergen Gross 1f6ece
Fixes: f98c1e77127d ("KVM: VMX: Add proper cache tracking for CR4")
Juergen Gross 1f6ece
Fixes: 5addc235199f ("KVM: VMX: Cache vmcs.EXIT_QUALIFICATION using arch avail_reg flags")
Juergen Gross 1f6ece
Fixes: 8791585837f6 ("KVM: VMX: Cache vmcs.EXIT_INTR_INFO using arch avail_reg flags")
Juergen Gross 1f6ece
Signed-off-by: Sean Christopherson <seanjc@google.com>
Juergen Gross 1f6ece
Message-Id: <20210921000303.400537-2-seanjc@google.com>
Juergen Gross 1f6ece
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Juergen Gross 1f6ece
Signed-off-by: Juergen Gross <jgross@suse.com>
Juergen Gross 1f6ece
---
Juergen Gross 1f6ece
 arch/x86/kvm/x86.c | 2 ++
Juergen Gross 1f6ece
 1 file changed, 2 insertions(+)
Juergen Gross 1f6ece
Juergen Gross 1f6ece
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
Juergen Gross 1f6ece
index 28ef14155726..06026f3d7ea2 100644
Juergen Gross 1f6ece
--- a/arch/x86/kvm/x86.c
Juergen Gross 1f6ece
+++ b/arch/x86/kvm/x86.c
Juergen Gross 1f6ece
@@ -10652,6 +10652,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
Juergen Gross 1f6ece
 	int r;
Juergen Gross 1f6ece
 
Juergen Gross 1f6ece
 	vcpu->arch.last_vmentry_cpu = -1;
Juergen Gross 1f6ece
+	vcpu->arch.regs_avail = ~0;
Juergen Gross 1f6ece
+	vcpu->arch.regs_dirty = ~0;
Juergen Gross 1f6ece
 
Juergen Gross 1f6ece
 	if (!irqchip_in_kernel(vcpu->kvm) || kvm_vcpu_is_reset_bsp(vcpu))
Juergen Gross 1f6ece
 		vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
Juergen Gross 1f6ece
-- 
Juergen Gross 1f6ece
2.35.3
Juergen Gross 1f6ece