diff options
Diffstat (limited to 'arch/um/os-Linux/skas/process.c')
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index cd65727854eb..d93bb40499f7 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -346,6 +346,10 @@ void userspace(struct uml_pt_regs *regs) | |||
346 | int err, status, op, pid = userspace_pid[0]; | 346 | int err, status, op, pid = userspace_pid[0]; |
347 | /* To prevent races if using_sysemu changes under us.*/ | 347 | /* To prevent races if using_sysemu changes under us.*/ |
348 | int local_using_sysemu; | 348 | int local_using_sysemu; |
349 | siginfo_t si; | ||
350 | |||
351 | /* Handle any immediate reschedules or signals */ | ||
352 | interrupt_end(); | ||
349 | 353 | ||
350 | if (getitimer(ITIMER_VIRTUAL, &timer)) | 354 | if (getitimer(ITIMER_VIRTUAL, &timer)) |
351 | printk(UM_KERN_ERR "Failed to get itimer, errno = %d\n", errno); | 355 | printk(UM_KERN_ERR "Failed to get itimer, errno = %d\n", errno); |
@@ -404,13 +408,17 @@ void userspace(struct uml_pt_regs *regs) | |||
404 | 408 | ||
405 | if (WIFSTOPPED(status)) { | 409 | if (WIFSTOPPED(status)) { |
406 | int sig = WSTOPSIG(status); | 410 | int sig = WSTOPSIG(status); |
411 | |||
412 | ptrace(PTRACE_GETSIGINFO, pid, 0, &si); | ||
413 | |||
407 | switch (sig) { | 414 | switch (sig) { |
408 | case SIGSEGV: | 415 | case SIGSEGV: |
409 | if (PTRACE_FULL_FAULTINFO || | 416 | if (PTRACE_FULL_FAULTINFO || |
410 | !ptrace_faultinfo) { | 417 | !ptrace_faultinfo) { |
411 | get_skas_faultinfo(pid, | 418 | get_skas_faultinfo(pid, |
412 | ®s->faultinfo); | 419 | ®s->faultinfo); |
413 | (*sig_info[SIGSEGV])(SIGSEGV, regs); | 420 | (*sig_info[SIGSEGV])(SIGSEGV, &si, |
421 | regs); | ||
414 | } | 422 | } |
415 | else handle_segv(pid, regs); | 423 | else handle_segv(pid, regs); |
416 | break; | 424 | break; |
@@ -418,14 +426,14 @@ void userspace(struct uml_pt_regs *regs) | |||
418 | handle_trap(pid, regs, local_using_sysemu); | 426 | handle_trap(pid, regs, local_using_sysemu); |
419 | break; | 427 | break; |
420 | case SIGTRAP: | 428 | case SIGTRAP: |
421 | relay_signal(SIGTRAP, regs); | 429 | relay_signal(SIGTRAP, &si, regs); |
422 | break; | 430 | break; |
423 | case SIGVTALRM: | 431 | case SIGVTALRM: |
424 | now = os_nsecs(); | 432 | now = os_nsecs(); |
425 | if (now < nsecs) | 433 | if (now < nsecs) |
426 | break; | 434 | break; |
427 | block_signals(); | 435 | block_signals(); |
428 | (*sig_info[sig])(sig, regs); | 436 | (*sig_info[sig])(sig, &si, regs); |
429 | unblock_signals(); | 437 | unblock_signals(); |
430 | nsecs = timer.it_value.tv_sec * | 438 | nsecs = timer.it_value.tv_sec * |
431 | UM_NSEC_PER_SEC + | 439 | UM_NSEC_PER_SEC + |
@@ -439,7 +447,7 @@ void userspace(struct uml_pt_regs *regs) | |||
439 | case SIGFPE: | 447 | case SIGFPE: |
440 | case SIGWINCH: | 448 | case SIGWINCH: |
441 | block_signals(); | 449 | block_signals(); |
442 | (*sig_info[sig])(sig, regs); | 450 | (*sig_info[sig])(sig, &si, regs); |
443 | unblock_signals(); | 451 | unblock_signals(); |
444 | break; | 452 | break; |
445 | default: | 453 | default: |