On Fri, Mar 10, 2023 at 01:42:17PM -0800, Sean Christopherson wrote: >+void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback) >+{ >+ if (WARN_ON_ONCE(rcu_access_pointer(cpu_emergency_virt_callback))) >+ return; >+ >+ rcu_assign_pointer(cpu_emergency_virt_callback, callback); Was it intentional to not call synchronize_rcu() (in the original code), different from the un-registration path? >+} >+EXPORT_SYMBOL_GPL(cpu_emergency_register_virt_callback); >+ >+void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback) >+{ >+ if (WARN_ON_ONCE(rcu_access_pointer(cpu_emergency_virt_callback) != callback)) >+ return; >+ >+ rcu_assign_pointer(cpu_emergency_virt_callback, NULL); >+ synchronize_rcu(); >+} >+EXPORT_SYMBOL_GPL(cpu_emergency_unregister_virt_callback); > > static inline void cpu_crash_vmclear_loaded_vmcss(void) > { >- crash_vmclear_fn *do_vmclear_operation = NULL; >+ cpu_emergency_virt_cb *callback; > > rcu_read_lock(); >- do_vmclear_operation = rcu_dereference(crash_vmclear_loaded_vmcss); >- if (do_vmclear_operation) >- do_vmclear_operation(); >+ callback = rcu_dereference(cpu_emergency_virt_callback); >+ if (callback) >+ callback(); > rcu_read_unlock(); > } > #endif >diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c >index 302086255be6..41095fc864f3 100644 >--- a/arch/x86/kvm/vmx/vmx.c >+++ b/arch/x86/kvm/vmx/vmx.c >@@ -8551,8 +8551,7 @@ static void __vmx_exit(void) > { > allow_smaller_maxphyaddr = false; > >- RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL); >- synchronize_rcu(); >+ cpu_emergency_unregister_virt_callback(crash_vmclear_local_loaded_vmcss); > > vmx_cleanup_l1d_flush(); > } >@@ -8602,8 +8601,7 @@ static int __init vmx_init(void) > pi_init_cpu(cpu); > } > >- rcu_assign_pointer(crash_vmclear_loaded_vmcss, >- crash_vmclear_local_loaded_vmcss); >+ cpu_emergency_register_virt_callback(crash_vmclear_local_loaded_vmcss); > > vmx_check_vmcs12_offsets(); > >-- >2.40.0.rc1.284.g88254d51c5-goog >