]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: nVMX: Assert that vcpu->mutex is held when accessing secondary VMCSes
authorSean Christopherson <seanjc@google.com>
Fri, 6 Sep 2024 04:34:13 +0000 (21:34 -0700)
committerSean Christopherson <seanjc@google.com>
Tue, 10 Sep 2024 03:15:03 +0000 (20:15 -0700)
Add lockdep assertions in get_vmcs12() and get_shadow_vmcs12() to verify
the vCPU's mutex is held, as the returned VMCS objects are dynamically
allocated/freed when nested VMX is turned on/off, i.e. accessing vmcs12
structures without holding vcpu->mutex is susceptible to use-after-free.

Waive the assertion if the VM is being destroyed, as KVM currently forces
a nested VM-Exit when freeing the vCPU.  If/when that wart is fixed, the
assertion can/should be converted to an unqualified lockdep assertion.
See also https://lore.kernel.org/all/Zsd0TqCeY3B5Sb5b@google.com.

Link: https://lore.kernel.org/r/20240906043413.1049633-8-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/vmx/nested.h

index cce4e2aa30fbf8b98b114a069ef8445cb2b9aaf4..668b6c83a373c312957109d5f4953b454c42ffff 100644 (file)
@@ -39,11 +39,17 @@ bool nested_vmx_check_io_bitmaps(struct kvm_vcpu *vcpu, unsigned int port,
 
 static inline struct vmcs12 *get_vmcs12(struct kvm_vcpu *vcpu)
 {
+       lockdep_assert_once(lockdep_is_held(&vcpu->mutex) ||
+                           !refcount_read(&vcpu->kvm->users_count));
+
        return to_vmx(vcpu)->nested.cached_vmcs12;
 }
 
 static inline struct vmcs12 *get_shadow_vmcs12(struct kvm_vcpu *vcpu)
 {
+       lockdep_assert_once(lockdep_is_held(&vcpu->mutex) ||
+                           !refcount_read(&vcpu->kvm->users_count));
+
        return to_vmx(vcpu)->nested.cached_shadow_vmcs12;
 }