aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux/skas/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux/skas/process.c')
-rw-r--r--arch/um/os-Linux/skas/process.c16
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 &regs->faultinfo); 419 &regs->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: