Skip to content

Commit edc8deb

Browse files
committed
x86/reboot: Hoist "disable virt" helpers above "emergency reboot" path
Move the various "disable virtualization" helpers above the emergency reboot path so that emergency_reboot_disable_virtualization() can be stubbed out in a future patch if neither KVM_INTEL nor KVM_AMD is enabled, i.e. if there is no in-tree user of CPU virtualization. No functional change intended. Reviewed-by: Kai Huang <kai.huang@intel.com> Link: https://lore.kernel.org/r/20230721201859.2307736-7-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent ad93c1a commit edc8deb

File tree

1 file changed

+45
-45
lines changed

1 file changed

+45
-45
lines changed

arch/x86/kernel/reboot.c

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,51 @@ static inline void kb_wait(void)
530530

531531
static inline void nmi_shootdown_cpus_on_restart(void);
532532

533+
/* RCU-protected callback to disable virtualization prior to reboot. */
534+
static cpu_emergency_virt_cb __rcu *cpu_emergency_virt_callback;
535+
536+
void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback)
537+
{
538+
if (WARN_ON_ONCE(rcu_access_pointer(cpu_emergency_virt_callback)))
539+
return;
540+
541+
rcu_assign_pointer(cpu_emergency_virt_callback, callback);
542+
}
543+
EXPORT_SYMBOL_GPL(cpu_emergency_register_virt_callback);
544+
545+
void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback)
546+
{
547+
if (WARN_ON_ONCE(rcu_access_pointer(cpu_emergency_virt_callback) != callback))
548+
return;
549+
550+
rcu_assign_pointer(cpu_emergency_virt_callback, NULL);
551+
synchronize_rcu();
552+
}
553+
EXPORT_SYMBOL_GPL(cpu_emergency_unregister_virt_callback);
554+
555+
/*
556+
* Disable virtualization, i.e. VMX or SVM, to ensure INIT is recognized during
557+
* reboot. VMX blocks INIT if the CPU is post-VMXON, and SVM blocks INIT if
558+
* GIF=0, i.e. if the crash occurred between CLGI and STGI.
559+
*/
560+
void cpu_emergency_disable_virtualization(void)
561+
{
562+
cpu_emergency_virt_cb *callback;
563+
564+
/*
565+
* IRQs must be disabled as KVM enables virtualization in hardware via
566+
* function call IPIs, i.e. IRQs need to be disabled to guarantee
567+
* virtualization stays disabled.
568+
*/
569+
lockdep_assert_irqs_disabled();
570+
571+
rcu_read_lock();
572+
callback = rcu_dereference(cpu_emergency_virt_callback);
573+
if (callback)
574+
callback();
575+
rcu_read_unlock();
576+
}
577+
533578
static void emergency_reboot_disable_virtualization(void)
534579
{
535580
local_irq_disable();
@@ -786,54 +831,9 @@ void machine_crash_shutdown(struct pt_regs *regs)
786831
}
787832
#endif
788833

789-
/* RCU-protected callback to disable virtualization prior to reboot. */
790-
static cpu_emergency_virt_cb __rcu *cpu_emergency_virt_callback;
791-
792-
void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback)
793-
{
794-
if (WARN_ON_ONCE(rcu_access_pointer(cpu_emergency_virt_callback)))
795-
return;
796-
797-
rcu_assign_pointer(cpu_emergency_virt_callback, callback);
798-
}
799-
EXPORT_SYMBOL_GPL(cpu_emergency_register_virt_callback);
800-
801-
void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback)
802-
{
803-
if (WARN_ON_ONCE(rcu_access_pointer(cpu_emergency_virt_callback) != callback))
804-
return;
805-
806-
rcu_assign_pointer(cpu_emergency_virt_callback, NULL);
807-
synchronize_rcu();
808-
}
809-
EXPORT_SYMBOL_GPL(cpu_emergency_unregister_virt_callback);
810-
811834
/* This is the CPU performing the emergency shutdown work. */
812835
int crashing_cpu = -1;
813836

814-
/*
815-
* Disable virtualization, i.e. VMX or SVM, to ensure INIT is recognized during
816-
* reboot. VMX blocks INIT if the CPU is post-VMXON, and SVM blocks INIT if
817-
* GIF=0, i.e. if the crash occurred between CLGI and STGI.
818-
*/
819-
void cpu_emergency_disable_virtualization(void)
820-
{
821-
cpu_emergency_virt_cb *callback;
822-
823-
/*
824-
* IRQs must be disabled as KVM enables virtualization in hardware via
825-
* function call IPIs, i.e. IRQs need to be disabled to guarantee
826-
* virtualization stays disabled.
827-
*/
828-
lockdep_assert_irqs_disabled();
829-
830-
rcu_read_lock();
831-
callback = rcu_dereference(cpu_emergency_virt_callback);
832-
if (callback)
833-
callback();
834-
rcu_read_unlock();
835-
}
836-
837837
#if defined(CONFIG_SMP)
838838

839839
static nmi_shootdown_cb shootdown_callback;

0 commit comments

Comments
 (0)