diff options
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r-- | arch/um/os-Linux/registers.c | 21 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 265 | ||||
-rw-r--r-- | arch/um/os-Linux/start_up.c | 4 |
3 files changed, 188 insertions, 102 deletions
diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c index c78fae3aba81..830fe6a1518a 100644 --- a/arch/um/os-Linux/registers.c +++ b/arch/um/os-Linux/registers.c | |||
@@ -8,42 +8,41 @@ | |||
8 | #include <string.h> | 8 | #include <string.h> |
9 | #include <sys/ptrace.h> | 9 | #include <sys/ptrace.h> |
10 | #include "sysdep/ptrace.h" | 10 | #include "sysdep/ptrace.h" |
11 | #include "user.h" | ||
12 | 11 | ||
13 | void save_registers(int pid, struct uml_pt_regs *regs) | 12 | int save_registers(int pid, struct uml_pt_regs *regs) |
14 | { | 13 | { |
15 | int err; | 14 | int err; |
16 | 15 | ||
17 | err = ptrace(PTRACE_GETREGS, pid, 0, regs->gp); | 16 | err = ptrace(PTRACE_GETREGS, pid, 0, regs->gp); |
18 | if (err < 0) | 17 | if (err < 0) |
19 | panic("save_registers - saving registers failed, errno = %d\n", | 18 | return -errno; |
20 | errno); | 19 | return 0; |
21 | } | 20 | } |
22 | 21 | ||
23 | void restore_registers(int pid, struct uml_pt_regs *regs) | 22 | int restore_registers(int pid, struct uml_pt_regs *regs) |
24 | { | 23 | { |
25 | int err; | 24 | int err; |
26 | 25 | ||
27 | err = ptrace(PTRACE_SETREGS, pid, 0, regs->gp); | 26 | err = ptrace(PTRACE_SETREGS, pid, 0, regs->gp); |
28 | if (err < 0) | 27 | if (err < 0) |
29 | panic("restore_registers - saving registers failed, " | 28 | return -errno; |
30 | "errno = %d\n", errno); | 29 | return 0; |
31 | } | 30 | } |
32 | 31 | ||
33 | /* This is set once at boot time and not changed thereafter */ | 32 | /* This is set once at boot time and not changed thereafter */ |
34 | 33 | ||
35 | static unsigned long exec_regs[MAX_REG_NR]; | 34 | static unsigned long exec_regs[MAX_REG_NR]; |
36 | 35 | ||
37 | void init_registers(int pid) | 36 | int init_registers(int pid) |
38 | { | 37 | { |
39 | int err; | 38 | int err; |
40 | 39 | ||
41 | err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); | 40 | err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); |
42 | if (err) | 41 | if (err < 0) |
43 | panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", | 42 | return -errno; |
44 | errno); | ||
45 | 43 | ||
46 | arch_init_registers(pid); | 44 | arch_init_registers(pid); |
45 | return 0; | ||
47 | } | 46 | } |
48 | 47 | ||
49 | void get_safe_registers(unsigned long *regs) | 48 | void get_safe_registers(unsigned long *regs) |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 7dc24e3cb190..862fea0290ec 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -38,17 +38,17 @@ int is_skas_winch(int pid, int fd, void *data) | |||
38 | 38 | ||
39 | static int ptrace_dump_regs(int pid) | 39 | static int ptrace_dump_regs(int pid) |
40 | { | 40 | { |
41 | unsigned long regs[MAX_REG_NR]; | 41 | unsigned long regs[MAX_REG_NR]; |
42 | int i; | 42 | int i; |
43 | 43 | ||
44 | if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) | 44 | if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) |
45 | return -errno; | 45 | return -errno; |
46 | 46 | ||
47 | printk(UM_KERN_ERR "Stub registers -\n"); | 47 | printk(UM_KERN_ERR "Stub registers -\n"); |
48 | for (i = 0; i < ARRAY_SIZE(regs); i++) | 48 | for (i = 0; i < ARRAY_SIZE(regs); i++) |
49 | printk(UM_KERN_ERR "\t%d - %lx\n", i, regs[i]); | 49 | printk(UM_KERN_ERR "\t%d - %lx\n", i, regs[i]); |
50 | 50 | ||
51 | return 0; | 51 | return 0; |
52 | } | 52 | } |
53 | 53 | ||
54 | /* | 54 | /* |
@@ -73,9 +73,11 @@ void wait_stub_done(int pid) | |||
73 | break; | 73 | break; |
74 | 74 | ||
75 | err = ptrace(PTRACE_CONT, pid, 0, 0); | 75 | err = ptrace(PTRACE_CONT, pid, 0, 0); |
76 | if (err) | 76 | if (err) { |
77 | panic("wait_stub_done : continue failed, errno = %d\n", | 77 | printk(UM_KERN_ERR "wait_stub_done : continue failed, " |
78 | errno); | 78 | "errno = %d\n", errno); |
79 | fatal_sigsegv(); | ||
80 | } | ||
79 | } | 81 | } |
80 | 82 | ||
81 | if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0) | 83 | if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0) |
@@ -86,8 +88,10 @@ bad_wait: | |||
86 | if (err) | 88 | if (err) |
87 | printk(UM_KERN_ERR "Failed to get registers from stub, " | 89 | printk(UM_KERN_ERR "Failed to get registers from stub, " |
88 | "errno = %d\n", -err); | 90 | "errno = %d\n", -err); |
89 | panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, " | 91 | printk(UM_KERN_ERR "wait_stub_done : failed to wait for SIGTRAP, " |
90 | "n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status); | 92 | "pid = %d, n = %d, errno = %d, status = 0x%x\n", pid, n, errno, |
93 | status); | ||
94 | fatal_sigsegv(); | ||
91 | } | 95 | } |
92 | 96 | ||
93 | extern unsigned long current_stub_stack(void); | 97 | extern unsigned long current_stub_stack(void); |
@@ -98,9 +102,11 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi) | |||
98 | 102 | ||
99 | if (ptrace_faultinfo) { | 103 | if (ptrace_faultinfo) { |
100 | err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); | 104 | err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); |
101 | if (err) | 105 | if (err) { |
102 | panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, " | 106 | printk(UM_KERN_ERR "get_skas_faultinfo - " |
103 | "errno = %d\n", errno); | 107 | "PTRACE_FAULTINFO failed, errno = %d\n", errno); |
108 | fatal_sigsegv(); | ||
109 | } | ||
104 | 110 | ||
105 | /* Special handling for i386, which has different structs */ | 111 | /* Special handling for i386, which has different structs */ |
106 | if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo)) | 112 | if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo)) |
@@ -110,9 +116,11 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi) | |||
110 | } | 116 | } |
111 | else { | 117 | else { |
112 | err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV); | 118 | err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV); |
113 | if (err) | 119 | if (err) { |
114 | panic("Failed to continue stub, pid = %d, errno = %d\n", | 120 | printk(UM_KERN_ERR "Failed to continue stub, pid = %d, " |
115 | pid, errno); | 121 | "errno = %d\n", pid, errno); |
122 | fatal_sigsegv(); | ||
123 | } | ||
116 | wait_stub_done(pid); | 124 | wait_stub_done(pid); |
117 | 125 | ||
118 | /* | 126 | /* |
@@ -145,25 +153,31 @@ static void handle_trap(int pid, struct uml_pt_regs *regs, | |||
145 | { | 153 | { |
146 | err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, | 154 | err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, |
147 | __NR_getpid); | 155 | __NR_getpid); |
148 | if (err < 0) | 156 | if (err < 0) { |
149 | panic("handle_trap - nullifying syscall failed, " | 157 | printk(UM_KERN_ERR "handle_trap - nullifying syscall " |
150 | "errno = %d\n", errno); | 158 | "failed, errno = %d\n", errno); |
159 | fatal_sigsegv(); | ||
160 | } | ||
151 | 161 | ||
152 | err = ptrace(PTRACE_SYSCALL, pid, 0, 0); | 162 | err = ptrace(PTRACE_SYSCALL, pid, 0, 0); |
153 | if (err < 0) | 163 | if (err < 0) { |
154 | panic("handle_trap - continuing to end of syscall " | 164 | printk(UM_KERN_ERR "handle_trap - continuing to end of " |
155 | "failed, errno = %d\n", errno); | 165 | "syscall failed, errno = %d\n", errno); |
166 | fatal_sigsegv(); | ||
167 | } | ||
156 | 168 | ||
157 | CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL)); | 169 | CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL)); |
158 | if ((err < 0) || !WIFSTOPPED(status) || | 170 | if ((err < 0) || !WIFSTOPPED(status) || |
159 | (WSTOPSIG(status) != SIGTRAP + 0x80)) { | 171 | (WSTOPSIG(status) != SIGTRAP + 0x80)) { |
160 | err = ptrace_dump_regs(pid); | 172 | err = ptrace_dump_regs(pid); |
161 | if (err) | 173 | if (err) |
162 | printk(UM_KERN_ERR "Failed to get registers " | 174 | printk(UM_KERN_ERR "Failed to get registers " |
163 | "from process, errno = %d\n", -err); | 175 | "from process, errno = %d\n", -err); |
164 | panic("handle_trap - failed to wait at end of syscall, " | 176 | printk(UM_KERN_ERR "handle_trap - failed to wait at " |
165 | "errno = %d, status = %d\n", errno, status); | 177 | "end of syscall, errno = %d, status = %d\n", |
166 | } | 178 | errno, status); |
179 | fatal_sigsegv(); | ||
180 | } | ||
167 | } | 181 | } |
168 | 182 | ||
169 | handle_syscall(regs); | 183 | handle_syscall(regs); |
@@ -181,9 +195,11 @@ static int userspace_tramp(void *stack) | |||
181 | signal(SIGTERM, SIG_DFL); | 195 | signal(SIGTERM, SIG_DFL); |
182 | signal(SIGWINCH, SIG_IGN); | 196 | signal(SIGWINCH, SIG_IGN); |
183 | err = set_interval(); | 197 | err = set_interval(); |
184 | if (err) | 198 | if (err) { |
185 | panic("userspace_tramp - setting timer failed, errno = %d\n", | 199 | printk(UM_KERN_ERR "userspace_tramp - setting timer failed, " |
186 | err); | 200 | "errno = %d\n", err); |
201 | exit(1); | ||
202 | } | ||
187 | 203 | ||
188 | if (!proc_mm) { | 204 | if (!proc_mm) { |
189 | /* | 205 | /* |
@@ -226,9 +242,11 @@ static int userspace_tramp(void *stack) | |||
226 | sa.sa_flags = SA_ONSTACK | SA_NODEFER; | 242 | sa.sa_flags = SA_ONSTACK | SA_NODEFER; |
227 | sa.sa_handler = (void *) v; | 243 | sa.sa_handler = (void *) v; |
228 | sa.sa_restorer = NULL; | 244 | sa.sa_restorer = NULL; |
229 | if (sigaction(SIGSEGV, &sa, NULL) < 0) | 245 | if (sigaction(SIGSEGV, &sa, NULL) < 0) { |
230 | panic("userspace_tramp - setting SIGSEGV handler " | 246 | printk(UM_KERN_ERR "userspace_tramp - setting SIGSEGV " |
231 | "failed - errno = %d\n", errno); | 247 | "handler failed - errno = %d\n", errno); |
248 | exit(1); | ||
249 | } | ||
232 | } | 250 | } |
233 | 251 | ||
234 | kill(os_getpid(), SIGSTOP); | 252 | kill(os_getpid(), SIGSTOP); |
@@ -244,13 +262,18 @@ int start_userspace(unsigned long stub_stack) | |||
244 | { | 262 | { |
245 | void *stack; | 263 | void *stack; |
246 | unsigned long sp; | 264 | unsigned long sp; |
247 | int pid, status, n, flags; | 265 | int pid, status, n, flags, err; |
248 | 266 | ||
249 | stack = mmap(NULL, UM_KERN_PAGE_SIZE, | 267 | stack = mmap(NULL, UM_KERN_PAGE_SIZE, |
250 | PROT_READ | PROT_WRITE | PROT_EXEC, | 268 | PROT_READ | PROT_WRITE | PROT_EXEC, |
251 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | 269 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
252 | if (stack == MAP_FAILED) | 270 | if (stack == MAP_FAILED) { |
253 | panic("start_userspace : mmap failed, errno = %d", errno); | 271 | err = -errno; |
272 | printk(UM_KERN_ERR "start_userspace : mmap failed, " | ||
273 | "errno = %d", errno); | ||
274 | return err; | ||
275 | } | ||
276 | |||
254 | sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); | 277 | sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); |
255 | 278 | ||
256 | flags = CLONE_FILES; | 279 | flags = CLONE_FILES; |
@@ -260,29 +283,50 @@ int start_userspace(unsigned long stub_stack) | |||
260 | flags |= SIGCHLD; | 283 | flags |= SIGCHLD; |
261 | 284 | ||
262 | pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); | 285 | pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); |
263 | if (pid < 0) | 286 | if (pid < 0) { |
264 | panic("start_userspace : clone failed, errno = %d", errno); | 287 | err = -errno; |
288 | printk(UM_KERN_ERR "start_userspace : clone failed, " | ||
289 | "errno = %d", errno); | ||
290 | return err; | ||
291 | } | ||
265 | 292 | ||
266 | do { | 293 | do { |
267 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED | __WALL)); | 294 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED | __WALL)); |
268 | if (n < 0) | 295 | if (n < 0) { |
269 | panic("start_userspace : wait failed, errno = %d", | 296 | err = -errno; |
270 | errno); | 297 | printk(UM_KERN_ERR "start_userspace : wait failed, " |
298 | "errno = %d", errno); | ||
299 | goto out_kill; | ||
300 | } | ||
271 | } while (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM)); | 301 | } while (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM)); |
272 | 302 | ||
273 | if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) | 303 | if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) { |
274 | panic("start_userspace : expected SIGSTOP, got status = %d", | 304 | err = -EINVAL; |
275 | status); | 305 | printk(UM_KERN_ERR "start_userspace : expected SIGSTOP, got " |
306 | "status = %d", status); | ||
307 | goto out_kill; | ||
308 | } | ||
276 | 309 | ||
277 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, | 310 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, |
278 | (void *) PTRACE_O_TRACESYSGOOD) < 0) | 311 | (void *) PTRACE_O_TRACESYSGOOD) < 0) { |
279 | panic("start_userspace : PTRACE_OLDSETOPTIONS failed, " | 312 | err = -errno; |
280 | "errno = %d\n", errno); | 313 | printk(UM_KERN_ERR "start_userspace : PTRACE_OLDSETOPTIONS " |
314 | "failed, errno = %d\n", errno); | ||
315 | goto out_kill; | ||
316 | } | ||
281 | 317 | ||
282 | if (munmap(stack, UM_KERN_PAGE_SIZE) < 0) | 318 | if (munmap(stack, UM_KERN_PAGE_SIZE) < 0) { |
283 | panic("start_userspace : munmap failed, errno = %d\n", errno); | 319 | err = -errno; |
320 | printk(UM_KERN_ERR "start_userspace : munmap failed, " | ||
321 | "errno = %d\n", errno); | ||
322 | goto out_kill; | ||
323 | } | ||
284 | 324 | ||
285 | return pid; | 325 | return pid; |
326 | |||
327 | out_kill: | ||
328 | os_kill_ptraced_process(pid, 1); | ||
329 | return err; | ||
286 | } | 330 | } |
287 | 331 | ||
288 | void userspace(struct uml_pt_regs *regs) | 332 | void userspace(struct uml_pt_regs *regs) |
@@ -300,9 +344,16 @@ void userspace(struct uml_pt_regs *regs) | |||
300 | nsecs += os_nsecs(); | 344 | nsecs += os_nsecs(); |
301 | 345 | ||
302 | while (1) { | 346 | while (1) { |
347 | /* | ||
348 | * This can legitimately fail if the process loads a | ||
349 | * bogus value into a segment register. It will | ||
350 | * segfault and PTRACE_GETREGS will read that value | ||
351 | * out of the process. However, PTRACE_SETREGS will | ||
352 | * fail. In this case, there is nothing to do but | ||
353 | * just kill the process. | ||
354 | */ | ||
303 | if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp)) | 355 | if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp)) |
304 | panic("userspace - PTRACE_SETREGS failed, " | 356 | fatal_sigsegv(); |
305 | "errno = %d\n", errno); | ||
306 | 357 | ||
307 | /* Now we set local_using_sysemu to be used for one loop */ | 358 | /* Now we set local_using_sysemu to be used for one loop */ |
308 | local_using_sysemu = get_using_sysemu(); | 359 | local_using_sysemu = get_using_sysemu(); |
@@ -310,21 +361,25 @@ void userspace(struct uml_pt_regs *regs) | |||
310 | op = SELECT_PTRACE_OPERATION(local_using_sysemu, | 361 | op = SELECT_PTRACE_OPERATION(local_using_sysemu, |
311 | singlestepping(NULL)); | 362 | singlestepping(NULL)); |
312 | 363 | ||
313 | err = ptrace(op, pid, 0, 0); | 364 | if (ptrace(op, pid, 0, 0)) { |
314 | if (err) | 365 | printk(UM_KERN_ERR "userspace - ptrace continue " |
315 | panic("userspace - could not resume userspace process, " | 366 | "failed, op = %d, errno = %d\n", op, errno); |
316 | "pid=%d, ptrace operation = %d, errno = %d\n", | 367 | fatal_sigsegv(); |
317 | pid, op, errno); | 368 | } |
318 | 369 | ||
319 | CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL)); | 370 | CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL)); |
320 | if (err < 0) | 371 | if (err < 0) { |
321 | panic("userspace - waitpid failed, errno = %d\n", | 372 | printk(UM_KERN_ERR "userspace - wait failed, " |
322 | errno); | 373 | "errno = %d\n", errno); |
374 | fatal_sigsegv(); | ||
375 | } | ||
323 | 376 | ||
324 | regs->is_user = 1; | 377 | regs->is_user = 1; |
325 | if (ptrace(PTRACE_GETREGS, pid, 0, regs->gp)) | 378 | if (ptrace(PTRACE_GETREGS, pid, 0, regs->gp)) { |
326 | panic("userspace - saving registers failed, " | 379 | printk(UM_KERN_ERR "userspace - PTRACE_GETREGS failed, " |
327 | "errno = %d\n", errno); | 380 | "errno = %d\n", errno); |
381 | fatal_sigsegv(); | ||
382 | } | ||
328 | 383 | ||
329 | UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ | 384 | UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ |
330 | 385 | ||
@@ -371,6 +426,7 @@ void userspace(struct uml_pt_regs *regs) | |||
371 | default: | 426 | default: |
372 | printk(UM_KERN_ERR "userspace - child stopped " | 427 | printk(UM_KERN_ERR "userspace - child stopped " |
373 | "with signal %d\n", sig); | 428 | "with signal %d\n", sig); |
429 | fatal_sigsegv(); | ||
374 | } | 430 | } |
375 | pid = userspace_pid[0]; | 431 | pid = userspace_pid[0]; |
376 | interrupt_end(); | 432 | interrupt_end(); |
@@ -422,9 +478,12 @@ int copy_context_skas0(unsigned long new_stack, int pid) | |||
422 | .it_interval = tv }) }); | 478 | .it_interval = tv }) }); |
423 | 479 | ||
424 | err = ptrace_setregs(pid, thread_regs); | 480 | err = ptrace_setregs(pid, thread_regs); |
425 | if (err < 0) | 481 | if (err < 0) { |
426 | panic("copy_context_skas0 : PTRACE_SETREGS failed, " | 482 | err = -errno; |
427 | "pid = %d, errno = %d\n", pid, -err); | 483 | printk(UM_KERN_ERR "copy_context_skas0 : PTRACE_SETREGS " |
484 | "failed, pid = %d, errno = %d\n", pid, -err); | ||
485 | return err; | ||
486 | } | ||
428 | 487 | ||
429 | /* set a well known return code for detection of child write failure */ | 488 | /* set a well known return code for detection of child write failure */ |
430 | child_data->err = 12345678; | 489 | child_data->err = 12345678; |
@@ -434,31 +493,47 @@ int copy_context_skas0(unsigned long new_stack, int pid) | |||
434 | * parent's stack, and check, if bad result. | 493 | * parent's stack, and check, if bad result. |
435 | */ | 494 | */ |
436 | err = ptrace(PTRACE_CONT, pid, 0, 0); | 495 | err = ptrace(PTRACE_CONT, pid, 0, 0); |
437 | if (err) | 496 | if (err) { |
438 | panic("Failed to continue new process, pid = %d, " | 497 | err = -errno; |
439 | "errno = %d\n", pid, errno); | 498 | printk(UM_KERN_ERR "Failed to continue new process, pid = %d, " |
499 | "errno = %d\n", pid, errno); | ||
500 | return err; | ||
501 | } | ||
502 | |||
440 | wait_stub_done(pid); | 503 | wait_stub_done(pid); |
441 | 504 | ||
442 | pid = data->err; | 505 | pid = data->err; |
443 | if (pid < 0) | 506 | if (pid < 0) { |
444 | panic("copy_context_skas0 - stub-parent reports error %d\n", | 507 | printk(UM_KERN_ERR "copy_context_skas0 - stub-parent reports " |
445 | -pid); | 508 | "error %d\n", -pid); |
509 | return pid; | ||
510 | } | ||
446 | 511 | ||
447 | /* | 512 | /* |
448 | * Wait, until child has finished too: read child's result from | 513 | * Wait, until child has finished too: read child's result from |
449 | * child's stack and check it. | 514 | * child's stack and check it. |
450 | */ | 515 | */ |
451 | wait_stub_done(pid); | 516 | wait_stub_done(pid); |
452 | if (child_data->err != STUB_DATA) | 517 | if (child_data->err != STUB_DATA) { |
453 | panic("copy_context_skas0 - stub-child reports error %ld\n", | 518 | printk(UM_KERN_ERR "copy_context_skas0 - stub-child reports " |
454 | child_data->err); | 519 | "error %ld\n", child_data->err); |
520 | err = child_data->err; | ||
521 | goto out_kill; | ||
522 | } | ||
455 | 523 | ||
456 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, | 524 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, |
457 | (void *)PTRACE_O_TRACESYSGOOD) < 0) | 525 | (void *)PTRACE_O_TRACESYSGOOD) < 0) { |
458 | panic("copy_context_skas0 : PTRACE_OLDSETOPTIONS failed, " | 526 | err = -errno; |
459 | "errno = %d\n", errno); | 527 | printk(UM_KERN_ERR "copy_context_skas0 : PTRACE_OLDSETOPTIONS " |
528 | "failed, errno = %d\n", errno); | ||
529 | goto out_kill; | ||
530 | } | ||
460 | 531 | ||
461 | return pid; | 532 | return pid; |
533 | |||
534 | out_kill: | ||
535 | os_kill_ptraced_process(pid, 1); | ||
536 | return err; | ||
462 | } | 537 | } |
463 | 538 | ||
464 | /* | 539 | /* |
@@ -466,8 +541,8 @@ int copy_context_skas0(unsigned long new_stack, int pid) | |||
466 | * available. Opening /proc/mm creates a new mm_context, which lacks | 541 | * available. Opening /proc/mm creates a new mm_context, which lacks |
467 | * the stub-pages. Thus, we map them using /proc/mm-fd | 542 | * the stub-pages. Thus, we map them using /proc/mm-fd |
468 | */ | 543 | */ |
469 | void map_stub_pages(int fd, unsigned long code, | 544 | int map_stub_pages(int fd, unsigned long code, unsigned long data, |
470 | unsigned long data, unsigned long stack) | 545 | unsigned long stack) |
471 | { | 546 | { |
472 | struct proc_mm_op mmop; | 547 | struct proc_mm_op mmop; |
473 | int n; | 548 | int n; |
@@ -491,8 +566,9 @@ void map_stub_pages(int fd, unsigned long code, | |||
491 | printk(UM_KERN_ERR "mmap args - addr = 0x%lx, fd = %d, " | 566 | printk(UM_KERN_ERR "mmap args - addr = 0x%lx, fd = %d, " |
492 | "offset = %llx\n", code, code_fd, | 567 | "offset = %llx\n", code, code_fd, |
493 | (unsigned long long) code_offset); | 568 | (unsigned long long) code_offset); |
494 | panic("map_stub_pages : /proc/mm map for code failed, " | 569 | printk(UM_KERN_ERR "map_stub_pages : /proc/mm map for code " |
495 | "err = %d\n", n); | 570 | "failed, err = %d\n", n); |
571 | return -n; | ||
496 | } | 572 | } |
497 | 573 | ||
498 | if (stack) { | 574 | if (stack) { |
@@ -510,10 +586,15 @@ void map_stub_pages(int fd, unsigned long code, | |||
510 | .offset = map_offset | 586 | .offset = map_offset |
511 | } } }); | 587 | } } }); |
512 | CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); | 588 | CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); |
513 | if (n != sizeof(mmop)) | 589 | if (n != sizeof(mmop)) { |
514 | panic("map_stub_pages : /proc/mm map for data failed, " | 590 | n = errno; |
515 | "err = %d\n", errno); | 591 | printk(UM_KERN_ERR "map_stub_pages : /proc/mm map for " |
592 | "data failed, err = %d\n", n); | ||
593 | return -n; | ||
594 | } | ||
516 | } | 595 | } |
596 | |||
597 | return 0; | ||
517 | } | 598 | } |
518 | 599 | ||
519 | void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)) | 600 | void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)) |
@@ -574,7 +655,9 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) | |||
574 | kmalloc_ok = 0; | 655 | kmalloc_ok = 0; |
575 | return 1; | 656 | return 1; |
576 | default: | 657 | default: |
577 | panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); | 658 | printk(UM_KERN_ERR "Bad sigsetjmp return in " |
659 | "start_idle_thread - %d\n", n); | ||
660 | fatal_sigsegv(); | ||
578 | } | 661 | } |
579 | longjmp(*switch_buf, 1); | 662 | longjmp(*switch_buf, 1); |
580 | } | 663 | } |
@@ -617,9 +700,11 @@ void __switch_mm(struct mm_id *mm_idp) | |||
617 | if (proc_mm) { | 700 | if (proc_mm) { |
618 | err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, | 701 | err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, |
619 | mm_idp->u.mm_fd); | 702 | mm_idp->u.mm_fd); |
620 | if (err) | 703 | if (err) { |
621 | panic("__switch_mm - PTRACE_SWITCH_MM failed, " | 704 | printk(UM_KERN_ERR "__switch_mm - PTRACE_SWITCH_MM " |
622 | "errno = %d\n", errno); | 705 | "failed, errno = %d\n", errno); |
706 | fatal_sigsegv(); | ||
707 | } | ||
623 | } | 708 | } |
624 | else userspace_pid[0] = mm_idp->u.pid; | 709 | else userspace_pid[0] = mm_idp->u.pid; |
625 | } | 710 | } |
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index b07887c36bb0..6d56d15884fd 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c | |||
@@ -411,7 +411,9 @@ static inline void check_skas3_ptrace_faultinfo(void) | |||
411 | non_fatal("found\n"); | 411 | non_fatal("found\n"); |
412 | } | 412 | } |
413 | 413 | ||
414 | init_registers(pid); | 414 | if (init_registers(pid)) |
415 | fatal("Failed to initialize default registers"); | ||
416 | |||
415 | stop_ptraced_child(pid, 1, 1); | 417 | stop_ptraced_child(pid, 1, 1); |
416 | } | 418 | } |
417 | 419 | ||