Blame view

arch/um/os-Linux/process.c 5.63 KB
97870c34b   Alex Dewar   um: Add SPDX head...
1
  // SPDX-License-Identifier: GPL-2.0
ba180fd43   Jeff Dike   uml: style fixes ...
2
  /*
2eb5f31bc   Anton Ivanov   um: Switch clocks...
3
   * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
ba180fd43   Jeff Dike   uml: style fixes ...
4
   * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
  #include <stdio.h>
f75b1b1be   Richard Weinberger   um: Implement pro...
7
  #include <stdlib.h>
ba180fd43   Jeff Dike   uml: style fixes ...
8
  #include <unistd.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
  #include <errno.h>
  #include <signal.h>
512b6fb1c   Jeff Dike   uml: userspace fi...
11
  #include <fcntl.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
  #include <sys/mman.h>
ba180fd43   Jeff Dike   uml: style fixes ...
13
  #include <sys/ptrace.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
  #include <sys/wait.h>
ba180fd43   Jeff Dike   uml: style fixes ...
15
  #include <asm/unistd.h>
37185b332   Al Viro   um: get rid of po...
16
17
18
  #include <init.h>
  #include <longjmp.h>
  #include <os.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
20
21
22
23
24
25
26
27
28
  
  #define ARBITRARY_ADDR -1
  #define FAILURE_PID    -1
  
  #define STAT_PATH_LEN sizeof("/proc/#######/stat\0")
  #define COMM_SCANF "%*[^)])"
  
  unsigned long os_process_pc(int pid)
  {
  	char proc_stat[STAT_PATH_LEN], buf[256];
512b6fb1c   Jeff Dike   uml: userspace fi...
29
  	unsigned long pc = ARBITRARY_ADDR;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
31
32
  	int fd, err;
  
  	sprintf(proc_stat, "/proc/%d/stat", pid);
512b6fb1c   Jeff Dike   uml: userspace fi...
33
  	fd = open(proc_stat, O_RDONLY, 0);
ba180fd43   Jeff Dike   uml: style fixes ...
34
35
  	if (fd < 0) {
  		printk(UM_KERN_ERR "os_process_pc - couldn't open '%s', "
512b6fb1c   Jeff Dike   uml: userspace fi...
36
37
38
  		       "errno = %d
  ", proc_stat, errno);
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
  	}
a61f334fd   Jeff Dike   uml: convert libc...
40
  	CATCH_EINTR(err = read(fd, buf, sizeof(buf)));
ba180fd43   Jeff Dike   uml: style fixes ...
41
42
43
44
  	if (err < 0) {
  		printk(UM_KERN_ERR "os_process_pc - couldn't read '%s', "
  		       "err = %d
  ", proc_stat, errno);
512b6fb1c   Jeff Dike   uml: userspace fi...
45
  		goto out_close;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
47
48
  	}
  	os_close_file(fd);
  	pc = ARBITRARY_ADDR;
ba180fd43   Jeff Dike   uml: style fixes ...
49
  	if (sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d "
512b6fb1c   Jeff Dike   uml: userspace fi...
50
51
  		   "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
  		   "%*d %*d %*d %*d %*d %lu", &pc) != 1)
ba180fd43   Jeff Dike   uml: style fixes ...
52
53
54
  		printk(UM_KERN_ERR "os_process_pc - couldn't find pc in '%s'
  ",
  		       buf);
512b6fb1c   Jeff Dike   uml: userspace fi...
55
56
57
   out_close:
  	close(fd);
   out:
ef0470c05   Jeff Dike   uml: tidy libc code
58
  	return pc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
62
63
64
  }
  
  int os_process_parent(int pid)
  {
  	char stat[STAT_PATH_LEN];
  	char data[256];
512b6fb1c   Jeff Dike   uml: userspace fi...
65
  	int parent = FAILURE_PID, n, fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66

ba180fd43   Jeff Dike   uml: style fixes ...
67
  	if (pid == -1)
512b6fb1c   Jeff Dike   uml: userspace fi...
68
  		return parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
70
  
  	snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
512b6fb1c   Jeff Dike   uml: userspace fi...
71
  	fd = open(stat, O_RDONLY, 0);
ba180fd43   Jeff Dike   uml: style fixes ...
72
  	if (fd < 0) {
512b6fb1c   Jeff Dike   uml: userspace fi...
73
74
75
76
  		printk(UM_KERN_ERR "Couldn't open '%s', errno = %d
  ", stat,
  		       errno);
  		return parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
  	}
a61f334fd   Jeff Dike   uml: convert libc...
78
  	CATCH_EINTR(n = read(fd, data, sizeof(data)));
512b6fb1c   Jeff Dike   uml: userspace fi...
79
  	close(fd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80

ba180fd43   Jeff Dike   uml: style fixes ...
81
  	if (n < 0) {
512b6fb1c   Jeff Dike   uml: userspace fi...
82
83
  		printk(UM_KERN_ERR "Couldn't read '%s', errno = %d
  ", stat,
ba180fd43   Jeff Dike   uml: style fixes ...
84
  		       errno);
512b6fb1c   Jeff Dike   uml: userspace fi...
85
  		return parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
88
89
  	}
  
  	parent = FAILURE_PID;
  	n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent);
ba180fd43   Jeff Dike   uml: style fixes ...
90
91
92
  	if (n != 1)
  		printk(UM_KERN_ERR "Failed to scan '%s'
  ", data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93

ef0470c05   Jeff Dike   uml: tidy libc code
94
  	return parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95
  }
2eb5f31bc   Anton Ivanov   um: Switch clocks...
96
97
98
99
  void os_alarm_process(int pid)
  {
  	kill(pid, SIGALRM);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
101
102
103
104
105
106
107
  void os_stop_process(int pid)
  {
  	kill(pid, SIGSTOP);
  }
  
  void os_kill_process(int pid, int reap_child)
  {
  	kill(pid, SIGKILL);
ba180fd43   Jeff Dike   uml: style fixes ...
108
  	if (reap_child)
4dbed85a3   Stanislaw Gruszka   uml: stop gdb fro...
109
  		CATCH_EINTR(waitpid(pid, NULL, __WALL));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
111
112
113
114
115
116
117
118
119
120
121
  }
  
  /* Kill off a ptraced child by all means available.  kill it normally first,
   * then PTRACE_KILL it, then PTRACE_CONT it in case it's in a run state from
   * which it can't exit directly.
   */
  
  void os_kill_ptraced_process(int pid, int reap_child)
  {
  	kill(pid, SIGKILL);
  	ptrace(PTRACE_KILL, pid);
  	ptrace(PTRACE_CONT, pid);
ba180fd43   Jeff Dike   uml: style fixes ...
122
  	if (reap_child)
4dbed85a3   Stanislaw Gruszka   uml: stop gdb fro...
123
  		CATCH_EINTR(waitpid(pid, NULL, __WALL));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
  }
60d339f6f   Gennady Sharapov   [PATCH] uml: move...
125
126
127
  /* Don't use the glibc version, which caches the result in TLS. It misses some
   * syscalls, and also breaks with clone(), which does not unshare the TLS.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
  int os_getpid(void)
  {
ef0470c05   Jeff Dike   uml: tidy libc code
130
  	return syscall(__NR_getpid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
  }
cd2ee4a30   Jeff Dike   [PATCH] uml: Fix ...
132
133
134
135
  int os_getpgrp(void)
  {
  	return getpgrp();
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
136
137
138
139
140
  int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
  		  int r, int w, int x)
  {
  	void *loc;
  	int prot;
ba180fd43   Jeff Dike   uml: style fixes ...
141
  	prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
143
144
145
  		(x ? PROT_EXEC : 0);
  
  	loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
  		     fd, off);
ba180fd43   Jeff Dike   uml: style fixes ...
146
  	if (loc == MAP_FAILED)
ef0470c05   Jeff Dike   uml: tidy libc code
147
148
  		return -errno;
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
151
152
  }
  
  int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
  {
ba180fd43   Jeff Dike   uml: style fixes ...
153
  	int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
  		    (x ? PROT_EXEC : 0));
ba180fd43   Jeff Dike   uml: style fixes ...
155
  	if (mprotect(addr, len, prot) < 0)
ef0470c05   Jeff Dike   uml: tidy libc code
156
  		return -errno;
ba180fd43   Jeff Dike   uml: style fixes ...
157
158
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
160
161
162
  }
  
  int os_unmap_memory(void *addr, int len)
  {
ba180fd43   Jeff Dike   uml: style fixes ...
163
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164

ba180fd43   Jeff Dike   uml: style fixes ...
165
166
  	err = munmap(addr, len);
  	if (err < 0)
ef0470c05   Jeff Dike   uml: tidy libc code
167
  		return -errno;
ba180fd43   Jeff Dike   uml: style fixes ...
168
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
169
  }
02dea0875   Jeff Dike   [PATCH] UML: Hotp...
170
  #ifndef MADV_REMOVE
b73781c86   Jeff Dike   [PATCH] uml: MADV...
171
  #define MADV_REMOVE KERNEL_MADV_REMOVE
02dea0875   Jeff Dike   [PATCH] UML: Hotp...
172
  #endif
97a1fcbb2   Jeff Dike   uml: more __init ...
173
  int os_drop_memory(void *addr, int length)
02dea0875   Jeff Dike   [PATCH] UML: Hotp...
174
175
176
177
  {
  	int err;
  
  	err = madvise(addr, length, MADV_REMOVE);
ba180fd43   Jeff Dike   uml: style fixes ...
178
  	if (err < 0)
02dea0875   Jeff Dike   [PATCH] UML: Hotp...
179
180
181
  		err = -errno;
  	return err;
  }
36e454630   Jeff Dike   uml: add missing ...
182
  int __init can_drop_memory(void)
02dea0875   Jeff Dike   [PATCH] UML: Hotp...
183
184
  {
  	void *addr;
e3104f50d   Jeff Dike   [PATCH] uml: clea...
185
  	int fd, ok = 0;
02dea0875   Jeff Dike   [PATCH] UML: Hotp...
186

ba180fd43   Jeff Dike   uml: style fixes ...
187
  	printk(UM_KERN_INFO "Checking host MADV_REMOVE support...");
02dea0875   Jeff Dike   [PATCH] UML: Hotp...
188
  	fd = create_mem_file(UM_KERN_PAGE_SIZE);
ba180fd43   Jeff Dike   uml: style fixes ...
189
190
191
192
  	if (fd < 0) {
  		printk(UM_KERN_ERR "Creating test memory file failed, "
  		       "err = %d
  ", -fd);
e3104f50d   Jeff Dike   [PATCH] uml: clea...
193
  		goto out;
02dea0875   Jeff Dike   [PATCH] UML: Hotp...
194
195
196
  	}
  
  	addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
b73781c86   Jeff Dike   [PATCH] uml: MADV...
197
  		      MAP_SHARED, fd, 0);
ba180fd43   Jeff Dike   uml: style fixes ...
198
199
200
201
  	if (addr == MAP_FAILED) {
  		printk(UM_KERN_ERR "Mapping test memory file failed, "
  		       "err = %d
  ", -errno);
e3104f50d   Jeff Dike   [PATCH] uml: clea...
202
  		goto out_close;
02dea0875   Jeff Dike   [PATCH] UML: Hotp...
203
  	}
ba180fd43   Jeff Dike   uml: style fixes ...
204
205
206
  	if (madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0) {
  		printk(UM_KERN_ERR "MADV_REMOVE failed, err = %d
  ", -errno);
e3104f50d   Jeff Dike   [PATCH] uml: clea...
207
  		goto out_unmap;
02dea0875   Jeff Dike   [PATCH] UML: Hotp...
208
  	}
5134d8fea   Jeff Dike   uml: style fixes ...
209
210
  	printk(UM_KERN_CONT "OK
  ");
e3104f50d   Jeff Dike   [PATCH] uml: clea...
211
212
213
214
215
216
217
218
  	ok = 1;
  
  out_unmap:
  	munmap(addr, UM_KERN_PAGE_SIZE);
  out_close:
  	close(fd);
  out:
  	return ok;
02dea0875   Jeff Dike   [PATCH] UML: Hotp...
219
  }
f75b1b1be   Richard Weinberger   um: Implement pro...
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
  static int os_page_mincore(void *addr)
  {
  	char vec[2];
  	int ret;
  
  	ret = mincore(addr, UM_KERN_PAGE_SIZE, vec);
  	if (ret < 0) {
  		if (errno == ENOMEM || errno == EINVAL)
  			return 0;
  		else
  			return -errno;
  	}
  
  	return vec[0] & 1;
  }
  
  int os_mincore(void *addr, unsigned long len)
  {
  	char *vec;
  	int ret, i;
  
  	if (len <= UM_KERN_PAGE_SIZE)
  		return os_page_mincore(addr);
  
  	vec = calloc(1, (len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE);
  	if (!vec)
  		return -ENOMEM;
  
  	ret = mincore(addr, UM_KERN_PAGE_SIZE, vec);
  	if (ret < 0) {
  		if (errno == ENOMEM || errno == EINVAL)
  			ret = 0;
  		else
  			ret = -errno;
  
  		goto out;
  	}
  
  	for (i = 0; i < ((len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE); i++) {
  		if (!(vec[i] & 1)) {
  			ret = 0;
  			goto out;
  		}
  	}
  
  	ret = 1;
  out:
  	free(vec);
  	return ret;
  }
e64bd1340   Jeff Dike   [PATCH] uml: sign...
270
  void init_new_thread_signals(void)
60d339f6f   Gennady Sharapov   [PATCH] uml: move...
271
  {
00361683c   Al Viro   um: fill the hand...
272
273
274
275
276
  	set_handler(SIGSEGV);
  	set_handler(SIGTRAP);
  	set_handler(SIGFPE);
  	set_handler(SIGILL);
  	set_handler(SIGBUS);
60d339f6f   Gennady Sharapov   [PATCH] uml: move...
277
  	signal(SIGHUP, SIG_IGN);
00361683c   Al Viro   um: fill the hand...
278
  	set_handler(SIGIO);
3a24ebf0c   Jeff Dike   uml: remove init_...
279
  	signal(SIGWINCH, SIG_IGN);
60d339f6f   Gennady Sharapov   [PATCH] uml: move...
280
  }