xref: /linux/arch/um/kernel/reboot.c (revision c8d430db8eec7d4fd13a6bea27b7086a54eda6da)
10d1fb0a4SAlex Dewar // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
3ba180fd4SJeff Dike  * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
41da177e4SLinus Torvalds  */
51da177e4SLinus Torvalds 
63f07c014SIngo Molnar #include <linux/sched/signal.h>
729930025SIngo Molnar #include <linux/sched/task.h>
8589ee628SIngo Molnar #include <linux/sched/mm.h>
937185b33SAl Viro #include <linux/spinlock.h>
1037185b33SAl Viro #include <linux/slab.h>
1137185b33SAl Viro #include <linux/oom.h>
129ffc6724STiwei Bie #include <linux/reboot.h>
1337185b33SAl Viro #include <kern_util.h>
1437185b33SAl Viro #include <os.h>
1537185b33SAl Viro #include <skas.h>
161da177e4SLinus Torvalds 
175e38291dSEric W. Biederman void (*pm_power_off)(void);
180834f9ccSRichard Weinberger EXPORT_SYMBOL(pm_power_off);
195e38291dSEric W. Biederman 
201da177e4SLinus Torvalds static void kill_off_processes(void)
211da177e4SLinus Torvalds {
2277bf4400SJeff Dike 	struct task_struct *p;
23f1c93e49SRichard Weinberger 	int pid;
2477bf4400SJeff Dike 
259bd0a077SAnton Vorontsov 	read_lock(&tasklist_lock);
2677bf4400SJeff Dike 	for_each_process(p) {
272c922c51SAnton Vorontsov 		struct task_struct *t;
282c922c51SAnton Vorontsov 
292c922c51SAnton Vorontsov 		t = find_lock_task_mm(p);
302c922c51SAnton Vorontsov 		if (!t)
3177bf4400SJeff Dike 			continue;
32*59376fb2STiwei Bie 		pid = t->mm->context.id.pid;
332c922c51SAnton Vorontsov 		task_unlock(t);
3477bf4400SJeff Dike 		os_kill_ptraced_process(pid, 1);
3577bf4400SJeff Dike 	}
369bd0a077SAnton Vorontsov 	read_unlock(&tasklist_lock);
3777bf4400SJeff Dike }
381da177e4SLinus Torvalds 
391da177e4SLinus Torvalds void uml_cleanup(void)
401da177e4SLinus Torvalds {
41026549d2SJeff Dike 	kmalloc_ok = 0;
421da177e4SLinus Torvalds 	do_uml_exitcalls();
43026549d2SJeff Dike 	kill_off_processes();
441da177e4SLinus Torvalds }
451da177e4SLinus Torvalds 
461da177e4SLinus Torvalds void machine_restart(char * __unused)
471da177e4SLinus Torvalds {
48026549d2SJeff Dike 	uml_cleanup();
496aa802ceSJeff Dike 	reboot_skas();
501da177e4SLinus Torvalds }
511da177e4SLinus Torvalds 
521da177e4SLinus Torvalds void machine_power_off(void)
531da177e4SLinus Torvalds {
54026549d2SJeff Dike 	uml_cleanup();
556aa802ceSJeff Dike 	halt_skas();
561da177e4SLinus Torvalds }
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds void machine_halt(void)
591da177e4SLinus Torvalds {
601da177e4SLinus Torvalds 	machine_power_off();
611da177e4SLinus Torvalds }
6286abcd6eSJohannes Berg 
6386abcd6eSJohannes Berg static int sys_power_off_handler(struct sys_off_data *data)
6486abcd6eSJohannes Berg {
6586abcd6eSJohannes Berg 	machine_power_off();
6686abcd6eSJohannes Berg 	return 0;
6786abcd6eSJohannes Berg }
6886abcd6eSJohannes Berg 
6986abcd6eSJohannes Berg static int register_power_off(void)
7086abcd6eSJohannes Berg {
7186abcd6eSJohannes Berg 	register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
7286abcd6eSJohannes Berg 				 SYS_OFF_PRIO_DEFAULT,
7386abcd6eSJohannes Berg 				 sys_power_off_handler, NULL);
7486abcd6eSJohannes Berg 	return 0;
7586abcd6eSJohannes Berg }
7686abcd6eSJohannes Berg __initcall(register_power_off);
77