// SPDX-License-Identifier: GPL-2.0-only /* * linux/kernel/reboot.c * * Copyright (C) 2013 Linus Torvalds */ #define pr_fmt(fmt) … #include <linux/atomic.h> #include <linux/ctype.h> #include <linux/export.h> #include <linux/kexec.h> #include <linux/kmod.h> #include <linux/kmsg_dump.h> #include <linux/reboot.h> #include <linux/suspend.h> #include <linux/syscalls.h> #include <linux/syscore_ops.h> #include <linux/uaccess.h> /* * this indicates whether you can reboot with ctrl-alt-del: the default is yes */ static int C_A_D = …; struct pid *cad_pid; EXPORT_SYMBOL(…); #if defined(CONFIG_ARM) #define DEFAULT_REBOOT_MODE … #else #define DEFAULT_REBOOT_MODE #endif enum reboot_mode reboot_mode DEFAULT_REBOOT_MODE; EXPORT_SYMBOL_GPL(…); enum reboot_mode panic_reboot_mode = …; /* * This variable is used privately to keep track of whether or not * reboot_type is still set to its default value (i.e., reboot= hasn't * been set on the command line). This is needed so that we can * suppress DMI scanning for reboot quirks. Without it, it's * impossible to override a faulty reboot quirk without recompiling. */ int reboot_default = …; int reboot_cpu; enum reboot_type reboot_type = …; int reboot_force; struct sys_off_handler { … }; /* * This variable is used to indicate if a halt was initiated instead of a * reboot when the reboot call was invoked with LINUX_REBOOT_CMD_POWER_OFF, but * the system cannot be powered off. This allowes kernel_halt() to notify users * of that. */ static bool poweroff_fallback_to_halt; /* * Temporary stub that prevents linkage failure while we're in process * of removing all uses of legacy pm_power_off() around the kernel. */ void __weak (*pm_power_off)(void); /** * emergency_restart - reboot the system * * Without shutting down any hardware or taking any locks * reboot the system. This is called when we know we are in * trouble so this is our best effort to reboot. This is * safe to call in interrupt context. */ void emergency_restart(void) { … } EXPORT_SYMBOL_GPL(…); void kernel_restart_prepare(char *cmd) { … } /** * register_reboot_notifier - Register function to be called at reboot time * @nb: Info about notifier function to be called * * Registers a function with the list of functions * to be called at reboot time. * * Currently always returns zero, as blocking_notifier_chain_register() * always returns zero. */ int register_reboot_notifier(struct notifier_block *nb) { … } EXPORT_SYMBOL(…); /** * unregister_reboot_notifier - Unregister previously registered reboot notifier * @nb: Hook to be unregistered * * Unregisters a previously registered reboot * notifier function. * * Returns zero on success, or %-ENOENT on failure. */ int unregister_reboot_notifier(struct notifier_block *nb) { … } EXPORT_SYMBOL(…); static void devm_unregister_reboot_notifier(struct device *dev, void *res) { … } int devm_register_reboot_notifier(struct device *dev, struct notifier_block *nb) { … } EXPORT_SYMBOL(…); /* * Notifier list for kernel code which wants to be called * to restart the system. */ static ATOMIC_NOTIFIER_HEAD(restart_handler_list); /** * register_restart_handler - Register function to be called to reset * the system * @nb: Info about handler function to be called * @nb->priority: Handler priority. Handlers should follow the * following guidelines for setting priorities. * 0: Restart handler of last resort, * with limited restart capabilities * 128: Default restart handler; use if no other * restart handler is expected to be available, * and/or if restart functionality is * sufficient to restart the entire system * 255: Highest priority restart handler, will * preempt all other restart handlers * * Registers a function with code to be called to restart the * system. * * Registered functions will be called from machine_restart as last * step of the restart sequence (if the architecture specific * machine_restart function calls do_kernel_restart - see below * for details). * Registered functions are expected to restart the system immediately. * If more than one function is registered, the restart handler priority * selects which function will be called first. * * Restart handlers are expected to be registered from non-architecture * code, typically from drivers. A typical use case would be a system * where restart functionality is provided through a watchdog. Multiple * restart handlers may exist; for example, one restart handler might * restart the entire system, while another only restarts the CPU. * In such cases, the restart handler which only restarts part of the * hardware is expected to register with low priority to ensure that * it only runs if no other means to restart the system is available. * * Currently always returns zero, as atomic_notifier_chain_register() * always returns zero. */ int register_restart_handler(struct notifier_block *nb) { … } EXPORT_SYMBOL(…); /** * unregister_restart_handler - Unregister previously registered * restart handler * @nb: Hook to be unregistered * * Unregisters a previously registered restart handler function. * * Returns zero on success, or %-ENOENT on failure. */ int unregister_restart_handler(struct notifier_block *nb) { … } EXPORT_SYMBOL(…); /** * do_kernel_restart - Execute kernel restart handler call chain * * Calls functions registered with register_restart_handler. * * Expected to be called from machine_restart as last step of the restart * sequence. * * Restarts the system immediately if a restart handler function has been * registered. Otherwise does nothing. */ void do_kernel_restart(char *cmd) { … } void migrate_to_reboot_cpu(void) { … } /* * Notifier list for kernel code which wants to be called * to prepare system for restart. */ static BLOCKING_NOTIFIER_HEAD(restart_prep_handler_list); static void do_kernel_restart_prepare(void) { … } /** * kernel_restart - reboot the system * @cmd: pointer to buffer containing command to execute for restart * or %NULL * * Shutdown everything and perform a clean reboot. * This is not safe to call in interrupt context. */ void kernel_restart(char *cmd) { … } EXPORT_SYMBOL_GPL(…); static void kernel_shutdown_prepare(enum system_states state) { … } /** * kernel_halt - halt the system * * Shutdown everything and perform a clean system halt. */ void kernel_halt(void) { … } EXPORT_SYMBOL_GPL(…); /* * Notifier list for kernel code which wants to be called * to prepare system for power off. */ static BLOCKING_NOTIFIER_HEAD(power_off_prep_handler_list); /* * Notifier list for kernel code which wants to be called * to power off system. */ static ATOMIC_NOTIFIER_HEAD(power_off_handler_list); static int sys_off_notify(struct notifier_block *nb, unsigned long mode, void *cmd) { … } static struct sys_off_handler platform_sys_off_handler; static struct sys_off_handler *alloc_sys_off_handler(int priority) { … } static void free_sys_off_handler(struct sys_off_handler *handler) { … } /** * register_sys_off_handler - Register sys-off handler * @mode: Sys-off mode * @priority: Handler priority * @callback: Callback function * @cb_data: Callback argument * * Registers system power-off or restart handler that will be invoked * at the step corresponding to the given sys-off mode. Handler's callback * should return NOTIFY_DONE to permit execution of the next handler in * the call chain or NOTIFY_STOP to break the chain (in error case for * example). * * Multiple handlers can be registered at the default priority level. * * Only one handler can be registered at the non-default priority level, * otherwise ERR_PTR(-EBUSY) is returned. * * Returns a new instance of struct sys_off_handler on success, or * an ERR_PTR()-encoded error code otherwise. */ struct sys_off_handler * register_sys_off_handler(enum sys_off_mode mode, int priority, int (*callback)(struct sys_off_data *data), void *cb_data) { … } EXPORT_SYMBOL_GPL(…); /** * unregister_sys_off_handler - Unregister sys-off handler * @handler: Sys-off handler * * Unregisters given sys-off handler. */ void unregister_sys_off_handler(struct sys_off_handler *handler) { … } EXPORT_SYMBOL_GPL(…); static void devm_unregister_sys_off_handler(void *data) { … } /** * devm_register_sys_off_handler - Register sys-off handler * @dev: Device that registers handler * @mode: Sys-off mode * @priority: Handler priority * @callback: Callback function * @cb_data: Callback argument * * Registers resource-managed sys-off handler. * * Returns zero on success, or error code on failure. */ int devm_register_sys_off_handler(struct device *dev, enum sys_off_mode mode, int priority, int (*callback)(struct sys_off_data *data), void *cb_data) { … } EXPORT_SYMBOL_GPL(…); /** * devm_register_power_off_handler - Register power-off handler * @dev: Device that registers callback * @callback: Callback function * @cb_data: Callback's argument * * Registers resource-managed sys-off handler with a default priority * and using power-off mode. * * Returns zero on success, or error code on failure. */ int devm_register_power_off_handler(struct device *dev, int (*callback)(struct sys_off_data *data), void *cb_data) { … } EXPORT_SYMBOL_GPL(…); /** * devm_register_restart_handler - Register restart handler * @dev: Device that registers callback * @callback: Callback function * @cb_data: Callback's argument * * Registers resource-managed sys-off handler with a default priority * and using restart mode. * * Returns zero on success, or error code on failure. */ int devm_register_restart_handler(struct device *dev, int (*callback)(struct sys_off_data *data), void *cb_data) { … } EXPORT_SYMBOL_GPL(…); static struct sys_off_handler *platform_power_off_handler; static int platform_power_off_notify(struct sys_off_data *data) { … } /** * register_platform_power_off - Register platform-level power-off callback * @power_off: Power-off callback * * Registers power-off callback that will be called as last step * of the power-off sequence. This callback is expected to be invoked * for the last resort. Only one platform power-off callback is allowed * to be registered at a time. * * Returns zero on success, or error code on failure. */ int register_platform_power_off(void (*power_off)(void)) { … } EXPORT_SYMBOL_GPL(…); /** * unregister_platform_power_off - Unregister platform-level power-off callback * @power_off: Power-off callback * * Unregisters previously registered platform power-off callback. */ void unregister_platform_power_off(void (*power_off)(void)) { … } EXPORT_SYMBOL_GPL(…); static int legacy_pm_power_off(struct sys_off_data *data) { … } static void do_kernel_power_off_prepare(void) { … } /** * do_kernel_power_off - Execute kernel power-off handler call chain * * Expected to be called as last step of the power-off sequence. * * Powers off the system immediately if a power-off handler function has * been registered. Otherwise does nothing. */ void do_kernel_power_off(void) { … } /** * kernel_can_power_off - check whether system can be powered off * * Returns true if power-off handler is registered and system can be * powered off, false otherwise. */ bool kernel_can_power_off(void) { … } EXPORT_SYMBOL_GPL(…); /** * kernel_power_off - power_off the system * * Shutdown everything and perform a clean system power_off. */ void kernel_power_off(void) { … } EXPORT_SYMBOL_GPL(…); DEFINE_MUTEX(…) …; /* * Reboot system call: for obvious reasons only root may call it, * and even root needs to set up some magic numbers in the registers * so that some mistake won't make this reboot the whole machine. * You can also set the meaning of the ctrl-alt-del-key here. * * reboot doesn't sync: do that yourself before calling this. */ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg) { … } static void deferred_cad(struct work_struct *dummy) { … } /* * This function gets called by ctrl-alt-del - ie the keyboard interrupt. * As it's called within an interrupt, it may NOT sync: the only choice * is whether to reboot at once, or just ignore the ctrl-alt-del. */ void ctrl_alt_del(void) { … } #define POWEROFF_CMD_PATH_LEN … static char poweroff_cmd[POWEROFF_CMD_PATH_LEN] = …; static const char reboot_cmd[] = …; static int run_cmd(const char *cmd) { … } static int __orderly_reboot(void) { … } static int __orderly_poweroff(bool force) { … } static bool poweroff_force; static void poweroff_work_func(struct work_struct *work) { … } static DECLARE_WORK(poweroff_work, poweroff_work_func); /** * orderly_poweroff - Trigger an orderly system poweroff * @force: force poweroff if command execution fails * * This may be called from any context to trigger a system shutdown. * If the orderly shutdown fails, it will force an immediate shutdown. */ void orderly_poweroff(bool force) { … } EXPORT_SYMBOL_GPL(…); static void reboot_work_func(struct work_struct *work) { … } static DECLARE_WORK(reboot_work, reboot_work_func); /** * orderly_reboot - Trigger an orderly system reboot * * This may be called from any context to trigger a system reboot. * If the orderly reboot fails, it will force an immediate reboot. */ void orderly_reboot(void) { … } EXPORT_SYMBOL_GPL(…); /** * hw_failure_emergency_poweroff_func - emergency poweroff work after a known delay * @work: work_struct associated with the emergency poweroff function * * This function is called in very critical situations to force * a kernel poweroff after a configurable timeout value. */ static void hw_failure_emergency_poweroff_func(struct work_struct *work) { … } static DECLARE_DELAYED_WORK(hw_failure_emergency_poweroff_work, hw_failure_emergency_poweroff_func); /** * hw_failure_emergency_poweroff - Trigger an emergency system poweroff * * This may be called from any critical situation to trigger a system shutdown * after a given period of time. If time is negative this is not scheduled. */ static void hw_failure_emergency_poweroff(int poweroff_delay_ms) { … } /** * __hw_protection_shutdown - Trigger an emergency system shutdown or reboot * * @reason: Reason of emergency shutdown or reboot to be printed. * @ms_until_forced: Time to wait for orderly shutdown or reboot before * triggering it. Negative value disables the forced * shutdown or reboot. * @shutdown: If true, indicates that a shutdown will happen * after the critical tempeature is reached. * If false, indicates that a reboot will happen * after the critical tempeature is reached. * * Initiate an emergency system shutdown or reboot in order to protect * hardware from further damage. Usage examples include a thermal protection. * NOTE: The request is ignored if protection shutdown or reboot is already * pending even if the previous request has given a large timeout for forced * shutdown/reboot. */ void __hw_protection_shutdown(const char *reason, int ms_until_forced, bool shutdown) { … } EXPORT_SYMBOL_GPL(…); static int __init reboot_setup(char *str) { … } __setup(…); #ifdef CONFIG_SYSFS #define REBOOT_COLD_STR … #define REBOOT_WARM_STR … #define REBOOT_HARD_STR … #define REBOOT_SOFT_STR … #define REBOOT_GPIO_STR … #define REBOOT_UNDEFINED_STR … #define BOOT_TRIPLE_STR … #define BOOT_KBD_STR … #define BOOT_BIOS_STR … #define BOOT_ACPI_STR … #define BOOT_EFI_STR … #define BOOT_PCI_STR … static ssize_t mode_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { … } static ssize_t mode_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { … } static struct kobj_attribute reboot_mode_attr = …; #ifdef CONFIG_X86 static ssize_t force_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { … } static ssize_t force_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { … } static struct kobj_attribute reboot_force_attr = …; static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { … } static ssize_t type_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { … } static struct kobj_attribute reboot_type_attr = …; #endif #ifdef CONFIG_SMP static ssize_t cpu_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { … } static ssize_t cpu_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { … } static struct kobj_attribute reboot_cpu_attr = …; #endif static struct attribute *reboot_attrs[] = …; #ifdef CONFIG_SYSCTL static struct ctl_table kern_reboot_table[] = …; static void __init kernel_reboot_sysctls_init(void) { … } #else #define kernel_reboot_sysctls_init … #endif /* CONFIG_SYSCTL */ static const struct attribute_group reboot_attr_group = …; static int __init reboot_ksysfs_init(void) { … } late_initcall(reboot_ksysfs_init); #endif