KVM: Nullify async #PF worker's "apf" pointer as soon as it might be freed
authorSean Christopherson <seanjc@google.com>
Wed, 10 Jan 2024 01:15:33 +0000 (17:15 -0800)
committerSean Christopherson <seanjc@google.com>
Tue, 6 Feb 2024 19:04:58 +0000 (11:04 -0800)
Nullify the async #PF worker's local "apf" pointer immediately after the
point where the structure can be freed by the vCPU.  The existing comment
is helpful, but easy to overlook as there is no associated code.

Update the comment to clarify that it can be freed by as soon as the lock
is dropped, as "after this point" isn't strictly accurate, nor does it
help understand what prevents the structure from being freed earlier.

Reviewed-by: Xu Yilun <yilun.xu@intel.com>
Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Link: https://lore.kernel.org/r/20240110011533.503302-5-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
virt/kvm/async_pf.c

index 628f6df7609f7186b82ae169b6f31e92679e8dfd..99a63bad0306c5699c8282b175f203bdc7bfba0a 100644 (file)
@@ -83,13 +83,14 @@ static void async_pf_execute(struct work_struct *work)
        apf->vcpu = NULL;
        spin_unlock(&vcpu->async_pf.lock);
 
-       if (!IS_ENABLED(CONFIG_KVM_ASYNC_PF_SYNC) && first)
-               kvm_arch_async_page_present_queued(vcpu);
-
        /*
-        * apf may be freed by kvm_check_async_pf_completion() after
-        * this point
+        * The apf struct may be freed by kvm_check_async_pf_completion() as
+        * soon as the lock is dropped.  Nullify it to prevent improper usage.
         */
+       apf = NULL;
+
+       if (!IS_ENABLED(CONFIG_KVM_ASYNC_PF_SYNC) && first)
+               kvm_arch_async_page_present_queued(vcpu);
 
        trace_kvm_async_pf_completed(addr, cr2_or_gpa);