Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2002- 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <sys/mman.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <sys/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <asm/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <as-layout.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <kern_util.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <mem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <os.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <ptrace_user.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <registers.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <skas.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <sysdep/stub.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/threads.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) int is_skas_winch(int pid, int fd, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	return pid == getpgrp();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) static int ptrace_dump_regs(int pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	unsigned long regs[MAX_REG_NR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	printk(UM_KERN_ERR "Stub registers -\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	for (i = 0; i < ARRAY_SIZE(regs); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		printk(UM_KERN_ERR "\t%d - %lx\n", i, regs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * Signals that are OK to receive in the stub - we'll just continue it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * SIGWINCH will happen when UML is inside a detached screen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define STUB_SIG_MASK ((1 << SIGALRM) | (1 << SIGWINCH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) /* Signals that the stub will finish with - anything else is an error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define STUB_DONE_MASK (1 << SIGTRAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) void wait_stub_done(int pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	int n, status, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED | __WALL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		if ((n < 0) || !WIFSTOPPED(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			goto bad_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		if (((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		err = ptrace(PTRACE_CONT, pid, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 			printk(UM_KERN_ERR "wait_stub_done : continue failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 			       "errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 			fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) bad_wait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	err = ptrace_dump_regs(pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		printk(UM_KERN_ERR "Failed to get registers from stub, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		       "errno = %d\n", -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	printk(UM_KERN_ERR "wait_stub_done : failed to wait for SIGTRAP, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	       "pid = %d, n = %d, errno = %d, status = 0x%x\n", pid, n, errno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	       status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) extern unsigned long current_stub_stack(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) static void get_skas_faultinfo(int pid, struct faultinfo *fi, unsigned long *aux_fp_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	err = get_fp_registers(pid, aux_fp_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		printk(UM_KERN_ERR "save_fp_registers returned %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		       err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		printk(UM_KERN_ERR "Failed to continue stub, pid = %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		       "errno = %d\n", pid, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	wait_stub_done(pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	 * faultinfo is prepared by the stub_segv_handler at start of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	 * the stub stack page. We just have to copy it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	err = put_fp_registers(pid, aux_fp_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		printk(UM_KERN_ERR "put_fp_registers returned %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		       err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static void handle_segv(int pid, struct uml_pt_regs *regs, unsigned long *aux_fp_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	get_skas_faultinfo(pid, &regs->faultinfo, aux_fp_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	segv(regs->faultinfo, 0, 1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * To use the same value of using_sysemu as the caller, ask it that value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  * (in local_using_sysemu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static void handle_trap(int pid, struct uml_pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			int local_using_sysemu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	int err, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	if ((UPT_IP(regs) >= STUB_START) && (UPT_IP(regs) < STUB_END))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	if (!local_using_sysemu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			     __NR_getpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 			printk(UM_KERN_ERR "handle_trap - nullifying syscall "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			       "failed, errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			printk(UM_KERN_ERR "handle_trap - continuing to end of "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			       "syscall failed, errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		if ((err < 0) || !WIFSTOPPED(status) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		    (WSTOPSIG(status) != SIGTRAP + 0x80)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			err = ptrace_dump_regs(pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 				printk(UM_KERN_ERR "Failed to get registers "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 				       "from process, errno = %d\n", -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 			printk(UM_KERN_ERR "handle_trap - failed to wait at "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			       "end of syscall, errno = %d, status = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			       errno, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	handle_syscall(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) extern char __syscall_stub_start[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  * userspace_tramp() - userspace trampoline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  * @stack:	pointer to the new userspace stack page, can be NULL, if? FIXME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  * The userspace trampoline is used to setup a new userspace process in start_userspace() after it was clone()'ed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  * This function will run on a temporary stack page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  * It ptrace()'es itself, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  * Two pages are mapped into the userspace address space:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  * - STUB_CODE (with EXEC), which contains the skas stub code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  * - STUB_DATA (with R/W), which contains a data page that is used to transfer certain data between the UML userspace process and the UML kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  * Also for the userspace process a SIGSEGV handler is installed to catch pagefaults in the userspace process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  * And last the process stops itself to give control to the UML kernel for this userspace process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  * Return: Always zero, otherwise the current userspace process is ended with non null exit() call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static int userspace_tramp(void *stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	void *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	unsigned long long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	ptrace(PTRACE_TRACEME, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	signal(SIGTERM, SIG_DFL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	signal(SIGWINCH, SIG_IGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	 * This has a pte, but it can't be mapped in with the usual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	 * tlb_flush mechanism because this is part of that mechanism
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	fd = phys_mapping(to_phys(__syscall_stub_start), &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		      PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	if (addr == MAP_FAILED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		printk(UM_KERN_ERR "mapping mmap stub at 0x%lx failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		       "errno = %d\n", STUB_CODE, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	if (stack != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		fd = phys_mapping(to_phys(stack), &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		addr = mmap((void *) STUB_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 			    UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 			    MAP_FIXED | MAP_SHARED, fd, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		if (addr == MAP_FAILED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 			printk(UM_KERN_ERR "mapping segfault stack "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 			       "at 0x%lx failed, errno = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			       STUB_DATA, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if (stack != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		struct sigaction sa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		unsigned long v = STUB_CODE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 				  (unsigned long) stub_segv_handler -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 				  (unsigned long) __syscall_stub_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		sigemptyset(&sa.sa_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		sa.sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		sa.sa_sigaction = (void *) v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		sa.sa_restorer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		if (sigaction(SIGSEGV, &sa, NULL) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			printk(UM_KERN_ERR "userspace_tramp - setting SIGSEGV "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			       "handler failed - errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 			exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	kill(os_getpid(), SIGSTOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int userspace_pid[NR_CPUS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) int kill_userspace_mm[NR_CPUS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)  * start_userspace() - prepare a new userspace process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  * @stub_stack:	pointer to the stub stack. Can be NULL, if? FIXME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)  * Setups a new temporary stack page that is used while userspace_tramp() runs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)  * Clones the kernel process into a new userspace process, with FDs only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)  * Return: When positive: the process id of the new userspace process,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)  *         when negative: an error number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)  * FIXME: can PIDs become negative?!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int start_userspace(unsigned long stub_stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	void *stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	unsigned long sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	int pid, status, n, flags, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	/* setup a temporary stack page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	stack = mmap(NULL, UM_KERN_PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		     PROT_READ | PROT_WRITE | PROT_EXEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	if (stack == MAP_FAILED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		printk(UM_KERN_ERR "start_userspace : mmap failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		       "errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	/* set stack pointer to the end of the stack page, so it can grow downwards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	flags = CLONE_FILES | SIGCHLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	/* clone into new userspace process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	if (pid < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		printk(UM_KERN_ERR "start_userspace : clone failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		       "errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED | __WALL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		if (n < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 			err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 			printk(UM_KERN_ERR "start_userspace : wait failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			       "errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			goto out_kill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	} while (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGALRM));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		printk(UM_KERN_ERR "start_userspace : expected SIGSTOP, got "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		       "status = %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		goto out_kill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		   (void *) PTRACE_O_TRACESYSGOOD) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		printk(UM_KERN_ERR "start_userspace : PTRACE_OLDSETOPTIONS "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		       "failed, errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		goto out_kill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	if (munmap(stack, UM_KERN_PAGE_SIZE) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		printk(UM_KERN_ERR "start_userspace : munmap failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		       "errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		goto out_kill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	return pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)  out_kill:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	os_kill_ptraced_process(pid, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	int err, status, op, pid = userspace_pid[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	/* To prevent races if using_sysemu changes under us.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	int local_using_sysemu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	siginfo_t si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	/* Handle any immediate reschedules or signals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	interrupt_end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		if (kill_userspace_mm[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		 * This can legitimately fail if the process loads a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		 * bogus value into a segment register.  It will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		 * segfault and PTRACE_GETREGS will read that value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		 * out of the process.  However, PTRACE_SETREGS will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		 * fail.  In this case, there is nothing to do but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		 * just kill the process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 			printk(UM_KERN_ERR "userspace - ptrace set regs "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			       "failed, errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 			fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		if (put_fp_registers(pid, regs->fp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 			printk(UM_KERN_ERR "userspace - ptrace set fp regs "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 			       "failed, errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 			fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		/* Now we set local_using_sysemu to be used for one loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		local_using_sysemu = get_using_sysemu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		op = SELECT_PTRACE_OPERATION(local_using_sysemu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 					     singlestepping(NULL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		if (ptrace(op, pid, 0, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			printk(UM_KERN_ERR "userspace - ptrace continue "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			       "failed, op = %d, errno = %d\n", op, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 			fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 			printk(UM_KERN_ERR "userspace - wait failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 			       "errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 			fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		regs->is_user = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		if (ptrace(PTRACE_GETREGS, pid, 0, regs->gp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 			printk(UM_KERN_ERR "userspace - PTRACE_GETREGS failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 			       "errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 			fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		if (get_fp_registers(pid, regs->fp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 			printk(UM_KERN_ERR "userspace -  get_fp_registers failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 			       "errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 			fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		if (WIFSTOPPED(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			int sig = WSTOPSIG(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 			ptrace(PTRACE_GETSIGINFO, pid, 0, (struct siginfo *)&si);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 			switch (sig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 			case SIGSEGV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 				if (PTRACE_FULL_FAULTINFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 					get_skas_faultinfo(pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 							   &regs->faultinfo, aux_fp_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 					(*sig_info[SIGSEGV])(SIGSEGV, (struct siginfo *)&si,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 							     regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 				else handle_segv(pid, regs, aux_fp_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 			case SIGTRAP + 0x80:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			        handle_trap(pid, regs, local_using_sysemu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 			case SIGTRAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 				relay_signal(SIGTRAP, (struct siginfo *)&si, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 			case SIGALRM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 			case SIGIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 			case SIGILL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 			case SIGBUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 			case SIGFPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 			case SIGWINCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 				block_signals_trace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 				(*sig_info[sig])(sig, (struct siginfo *)&si, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 				unblock_signals_trace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 				printk(UM_KERN_ERR "userspace - child stopped "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 				       "with signal %d\n", sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 				fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 			pid = userspace_pid[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 			interrupt_end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 			/* Avoid -ERESTARTSYS handling in host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 			if (PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 				PT_SYSCALL_NR(regs->gp) = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static unsigned long thread_regs[MAX_REG_NR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) static unsigned long thread_fp_regs[FP_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static int __init init_thread_regs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	get_safe_registers(thread_regs, thread_fp_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	/* Set parent's instruction pointer to start of clone-stub */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	thread_regs[REGS_IP_INDEX] = STUB_CODE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 				(unsigned long) stub_clone_handler -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 				(unsigned long) __syscall_stub_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	thread_regs[REGS_SP_INDEX] = STUB_DATA + UM_KERN_PAGE_SIZE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		sizeof(void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) #ifdef __SIGNAL_FRAMESIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) __initcall(init_thread_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) int copy_context_skas0(unsigned long new_stack, int pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	unsigned long current_stack = current_stub_stack();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	struct stub_data *data = (struct stub_data *) current_stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	struct stub_data *child_data = (struct stub_data *) new_stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	unsigned long long new_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	 * prepare offset and fd of child's stack as argument for parent's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	 * and child's mmap2 calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	*data = ((struct stub_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 			.offset	= MMAP_OFFSET(new_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 			.fd     = new_fd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	});
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	err = ptrace_setregs(pid, thread_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		printk(UM_KERN_ERR "copy_context_skas0 : PTRACE_SETREGS "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		       "failed, pid = %d, errno = %d\n", pid, -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	err = put_fp_registers(pid, thread_fp_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		printk(UM_KERN_ERR "copy_context_skas0 : put_fp_registers "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		       "failed, pid = %d, err = %d\n", pid, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	/* set a well known return code for detection of child write failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	child_data->err = 12345678;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	 * Wait, until parent has finished its work: read child's pid from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	 * parent's stack, and check, if bad result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	err = ptrace(PTRACE_CONT, pid, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		printk(UM_KERN_ERR "Failed to continue new process, pid = %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		       "errno = %d\n", pid, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	wait_stub_done(pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	pid = data->err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	if (pid < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		printk(UM_KERN_ERR "copy_context_skas0 - stub-parent reports "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		       "error %d\n", -pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		return pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	 * Wait, until child has finished too: read child's result from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	 * child's stack and check it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	wait_stub_done(pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	if (child_data->err != STUB_DATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		printk(UM_KERN_ERR "copy_context_skas0 - stub-child reports "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		       "error %ld\n", child_data->err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		err = child_data->err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		goto out_kill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		   (void *)PTRACE_O_TRACESYSGOOD) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		err = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		printk(UM_KERN_ERR "copy_context_skas0 : PTRACE_OLDSETOPTIONS "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		       "failed, errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		goto out_kill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	return pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)  out_kill:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	os_kill_ptraced_process(pid, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) void new_thread(void *stack, jmp_buf *buf, void (*handler)(void))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	(*buf)[0].JB_IP = (unsigned long) handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	(*buf)[0].JB_SP = (unsigned long) stack + UM_THREAD_SIZE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		sizeof(void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) #define INIT_JMP_NEW_THREAD 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) #define INIT_JMP_CALLBACK 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) #define INIT_JMP_HALT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) #define INIT_JMP_REBOOT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) void switch_threads(jmp_buf *me, jmp_buf *you)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	if (UML_SETJMP(me) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		UML_LONGJMP(you, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static jmp_buf initial_jmpbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /* XXX Make these percpu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static void (*cb_proc)(void *arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static void *cb_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static jmp_buf *cb_back;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) int start_idle_thread(void *stack, jmp_buf *switch_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	set_handler(SIGWINCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	 * Can't use UML_SETJMP or UML_LONGJMP here because they save
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	 * and restore signals, with the possible side-effect of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	 * trying to handle any signals which came when they were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	 * blocked, which can't be done on this stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	 * Signals must be blocked when jumping back here and restored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	 * after returning to the jumper.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	n = setjmp(initial_jmpbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	switch (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	case INIT_JMP_NEW_THREAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		(*switch_buf)[0].JB_IP = (unsigned long) uml_finishsetup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		(*switch_buf)[0].JB_SP = (unsigned long) stack +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 			UM_THREAD_SIZE - sizeof(void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	case INIT_JMP_CALLBACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		(*cb_proc)(cb_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		longjmp(*cb_back, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	case INIT_JMP_HALT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		kmalloc_ok = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	case INIT_JMP_REBOOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		kmalloc_ok = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		printk(UM_KERN_ERR "Bad sigsetjmp return in "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		       "start_idle_thread - %d\n", n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	longjmp(*switch_buf, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	/* unreachable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	printk(UM_KERN_ERR "impossible long jump!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	fatal_sigsegv();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) void initial_thread_cb_skas(void (*proc)(void *), void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	jmp_buf here;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	cb_proc = proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	cb_arg = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	cb_back = &here;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	block_signals_trace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	if (UML_SETJMP(&here) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 		UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	unblock_signals_trace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	cb_proc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	cb_arg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	cb_back = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) void halt_skas(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	block_signals_trace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	UML_LONGJMP(&initial_jmpbuf, INIT_JMP_HALT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) void reboot_skas(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	block_signals_trace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) void __switch_mm(struct mm_id *mm_idp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	userspace_pid[0] = mm_idp->u.pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	kill_userspace_mm[0] = mm_idp->kill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }