linux/arch/x86/kernel/reboot.c

// SPDX-License-Identifier: GPL-2.0
#define pr_fmt(fmt)

#include <linux/export.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/efi.h>
#include <linux/dmi.h>
#include <linux/sched.h>
#include <linux/tboot.h>
#include <linux/delay.h>
#include <linux/objtool.h>
#include <linux/pgtable.h>
#include <linux/kexec.h>
#include <acpi/reboot.h>
#include <asm/io.h>
#include <asm/apic.h>
#include <asm/io_apic.h>
#include <asm/desc.h>
#include <asm/hpet.h>
#include <asm/proto.h>
#include <asm/reboot_fixups.h>
#include <asm/reboot.h>
#include <asm/pci_x86.h>
#include <asm/cpu.h>
#include <asm/nmi.h>
#include <asm/smp.h>

#include <linux/ctype.h>
#include <linux/mc146818rtc.h>
#include <asm/realmode.h>
#include <asm/x86_init.h>
#include <asm/efi.h>

/*
 * Power off function, if any
 */
void (*pm_power_off)(void);
EXPORT_SYMBOL();

/*
 * This is set if we need to go through the 'emergency' path.
 * When machine_emergency_restart() is called, we may be on
 * an inconsistent state and won't be able to do a clean cleanup
 */
static int reboot_emergency;

/* This is set by the PCI code if either type 1 or type 2 PCI is detected */
bool port_cf9_safe =;

/*
 * Reboot options and system auto-detection code provided by
 * Dell Inc. so their systems "just work". :-)
 */

/*
 * Some machines require the "reboot=a" commandline options
 */
static int __init set_acpi_reboot(const struct dmi_system_id *d)
{}

/*
 * Some machines require the "reboot=b" or "reboot=k"  commandline options,
 * this quirk makes that automatic.
 */
static int __init set_bios_reboot(const struct dmi_system_id *d)
{}

/*
 * Some machines don't handle the default ACPI reboot method and
 * require the EFI reboot method:
 */
static int __init set_efi_reboot(const struct dmi_system_id *d)
{}

void __noreturn machine_real_restart(unsigned int type)
{}
#ifdef CONFIG_APM_MODULE
EXPORT_SYMBOL(machine_real_restart);
#endif
STACK_FRAME_NON_STANDARD();

/*
 * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot
 */
static int __init set_pci_reboot(const struct dmi_system_id *d)
{}

static int __init set_kbd_reboot(const struct dmi_system_id *d)
{}

/*
 * This is a single dmi_table handling all reboot quirks.
 */
static const struct dmi_system_id reboot_dmi_table[] __initconst =;

static int __init reboot_init(void)
{}
core_initcall(reboot_init);

static inline void kb_wait(void)
{}

static inline void nmi_shootdown_cpus_on_restart(void);

#if IS_ENABLED(CONFIG_KVM_X86)
/* RCU-protected callback to disable virtualization prior to reboot. */
static cpu_emergency_virt_cb __rcu *cpu_emergency_virt_callback;

void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback)
{}
EXPORT_SYMBOL_GPL();

void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback)
{}
EXPORT_SYMBOL_GPL();

/*
 * Disable virtualization, i.e. VMX or SVM, to ensure INIT is recognized during
 * reboot.  VMX blocks INIT if the CPU is post-VMXON, and SVM blocks INIT if
 * GIF=0, i.e. if the crash occurred between CLGI and STGI.
 */
void cpu_emergency_disable_virtualization(void)
{}

static void emergency_reboot_disable_virtualization(void)
{}
#else
static void emergency_reboot_disable_virtualization(void) { }
#endif /* CONFIG_KVM_X86 */

void __attribute__((weak)) mach_reboot_fixups(void)
{}

/*
 * To the best of our knowledge Windows compatible x86 hardware expects
 * the following on reboot:
 *
 * 1) If the FADT has the ACPI reboot register flag set, try it
 * 2) If still alive, write to the keyboard controller
 * 3) If still alive, write to the ACPI reboot register again
 * 4) If still alive, write to the keyboard controller again
 * 5) If still alive, call the EFI runtime service to reboot
 * 6) If no EFI runtime service, call the BIOS to do a reboot
 *
 * We default to following the same pattern. We also have
 * two other reboot methods: 'triple fault' and 'PCI', which
 * can be triggered via the reboot= kernel boot option or
 * via quirks.
 *
 * This means that this function can never return, it can misbehave
 * by not rebooting properly and hanging.
 */
static void native_machine_emergency_restart(void)
{}

void native_machine_shutdown(void)
{}

static void __machine_emergency_restart(int emergency)
{}

static void native_machine_restart(char *__unused)
{}

static void native_machine_halt(void)
{}

static void native_machine_power_off(void)
{}

struct machine_ops machine_ops __ro_after_init =;

void machine_power_off(void)
{}

void machine_shutdown(void)
{}

void machine_emergency_restart(void)
{}

void machine_restart(char *cmd)
{}

void machine_halt(void)
{}

#ifdef CONFIG_CRASH_DUMP
void machine_crash_shutdown(struct pt_regs *regs)
{}
#endif

/* This is the CPU performing the emergency shutdown work. */
int crashing_cpu =;

#if defined(CONFIG_SMP)

static nmi_shootdown_cb shootdown_callback;

static atomic_t waiting_for_crash_ipi;
static int crash_ipi_issued;

static int crash_nmi_callback(unsigned int val, struct pt_regs *regs)
{}

/**
 * nmi_shootdown_cpus - Stop other CPUs via NMI
 * @callback:	Optional callback to be invoked from the NMI handler
 *
 * The NMI handler on the remote CPUs invokes @callback, if not
 * NULL, first and then disables virtualization to ensure that
 * INIT is recognized during reboot.
 *
 * nmi_shootdown_cpus() can only be invoked once. After the first
 * invocation all other CPUs are stuck in crash_nmi_callback() and
 * cannot respond to a second NMI.
 */
void nmi_shootdown_cpus(nmi_shootdown_cb callback)
{}

static inline void nmi_shootdown_cpus_on_restart(void)
{}

/*
 * Check if the crash dumping IPI got issued and if so, call its callback
 * directly. This function is used when we have already been in NMI handler.
 * It doesn't return.
 */
void run_crash_ipi_callback(struct pt_regs *regs)
{}

/* Override the weak function in kernel/panic.c */
void __noreturn nmi_panic_self_stop(struct pt_regs *regs)
{}

#else /* !CONFIG_SMP */
void nmi_shootdown_cpus(nmi_shootdown_cb callback)
{
	/* No other CPUs to shoot down */
}

static inline void nmi_shootdown_cpus_on_restart(void) { }

void run_crash_ipi_callback(struct pt_regs *regs)
{
}
#endif