File Index
Files and directories
Sign in
FILE

process.c

File preview with syntax highlighting.

linux-6.19.14/arch/um/os-Linux/process.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
  4 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  5 */
  6
  7#include <stdio.h>
  8#include <stdlib.h>
  9#include <unistd.h>
 10#include <errno.h>
 11#include <signal.h>
 12#include <fcntl.h>
 13#include <limits.h>
 14#include <linux/futex.h>
 15#include <sys/mman.h>
 16#include <sys/ptrace.h>
 17#include <sys/prctl.h>
 18#include <sys/wait.h>
 19#include <asm/unistd.h>
 20#include <init.h>
 21#include <longjmp.h>
 22#include <os.h>
 23#include <skas/skas.h>
 24
 25void os_alarm_process(int pid)
 26{
 27	if (pid <= 0)
 28		return;
 29
 30	kill(pid, SIGALRM);
 31}
 32
 33void os_kill_process(int pid, int reap_child)
 34{
 35	if (pid <= 0)
 36		return;
 37
 38	/* Block signals until child is reaped */
 39	block_signals();
 40
 41	kill(pid, SIGKILL);
 42	if (reap_child)
 43		CATCH_EINTR(waitpid(pid, NULL, __WALL));
 44
 45	unblock_signals();
 46}
 47
 48/* Kill off a ptraced child by all means available.  kill it normally first,
 49 * then PTRACE_KILL it, then PTRACE_CONT it in case it's in a run state from
 50 * which it can't exit directly.
 51 */
 52
 53void os_kill_ptraced_process(int pid, int reap_child)
 54{
 55	if (pid <= 0)
 56		return;
 57
 58	/* Block signals until child is reaped */
 59	block_signals();
 60
 61	kill(pid, SIGKILL);
 62	ptrace(PTRACE_KILL, pid);
 63	ptrace(PTRACE_CONT, pid);
 64	if (reap_child)
 65		CATCH_EINTR(waitpid(pid, NULL, __WALL));
 66
 67	unblock_signals();
 68}
 69
 70pid_t os_reap_child(void)
 71{
 72	int status;
 73
 74	/* Try to reap a child */
 75	return waitpid(-1, &status, WNOHANG);
 76}
 77
 78/* Don't use the glibc version, which caches the result in TLS. It misses some
 79 * syscalls, and also breaks with clone(), which does not unshare the TLS.
 80 */
 81
 82int os_getpid(void)
 83{
 84	return syscall(__NR_getpid);
 85}
 86
 87int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
 88		  int r, int w, int x)
 89{
 90	void *loc;
 91	int prot;
 92
 93	prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
 94		(x ? PROT_EXEC : 0);
 95
 96	loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
 97		     fd, off);
 98	if (loc == MAP_FAILED)
 99		return -errno;
100	return 0;
101}
102
103int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
104{
105	int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
106		    (x ? PROT_EXEC : 0));
107
108	if (mprotect(addr, len, prot) < 0)
109		return -errno;
110
111	return 0;
112}
113
114int os_unmap_memory(void *addr, int len)
115{
116	int err;
117
118	err = munmap(addr, len);
119	if (err < 0)
120		return -errno;
121	return 0;
122}
123
124#ifndef MADV_REMOVE
125#define MADV_REMOVE KERNEL_MADV_REMOVE
126#endif
127
128int os_drop_memory(void *addr, int length)
129{
130	int err;
131
132	err = madvise(addr, length, MADV_REMOVE);
133	if (err < 0)
134		err = -errno;
135	return err;
136}
137
138int __init can_drop_memory(void)
139{
140	void *addr;
141	int fd, ok = 0;
142
143	printk(UM_KERN_INFO "Checking host MADV_REMOVE support...");
144	fd = create_mem_file(UM_KERN_PAGE_SIZE);
145	if (fd < 0) {
146		printk(UM_KERN_ERR "Creating test memory file failed, "
147		       "err = %d\n", -fd);
148		goto out;
149	}
150
151	addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
152		      MAP_SHARED, fd, 0);
153	if (addr == MAP_FAILED) {
154		printk(UM_KERN_ERR "Mapping test memory file failed, "
155		       "err = %d\n", -errno);
156		goto out_close;
157	}
158
159	if (madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0) {
160		printk(UM_KERN_ERR "MADV_REMOVE failed, err = %d\n", -errno);
161		goto out_unmap;
162	}
163
164	printk(UM_KERN_CONT "OK\n");
165	ok = 1;
166
167out_unmap:
168	munmap(addr, UM_KERN_PAGE_SIZE);
169out_close:
170	close(fd);
171out:
172	return ok;
173}
174
175void init_new_thread_signals(void)
176{
177	set_handler(SIGSEGV);
178	set_handler(SIGTRAP);
179	set_handler(SIGFPE);
180	set_handler(SIGILL);
181	set_handler(SIGBUS);
182	signal(SIGHUP, SIG_IGN);
183	set_handler(SIGIO);
184	/* We (currently) only use the child reaper IRQ in seccomp mode */
185	if (using_seccomp)
186		set_handler(SIGCHLD);
187	signal(SIGWINCH, SIG_IGN);
188}
189
190void os_set_pdeathsig(void)
191{
192	prctl(PR_SET_PDEATHSIG, SIGKILL);
193}
194
195int os_futex_wait(void *uaddr, unsigned int val)
196{
197	int r;
198
199	CATCH_EINTR(r = syscall(__NR_futex, uaddr, FUTEX_WAIT, val,
200				NULL, NULL, 0));
201	return r < 0 ? -errno : r;
202}
203
204int os_futex_wake(void *uaddr)
205{
206	int r;
207
208	CATCH_EINTR(r = syscall(__NR_futex, uaddr, FUTEX_WAKE, INT_MAX,
209				NULL, NULL, 0));
210	return r < 0 ? -errno : r;
211}
~/ Read-only file preview.