From d3c1cfcdb43e023ab1b1c7a555cd9e929026500a Mon Sep 17 00:00:00 2001 From: Martin Pärtel Date: Thu, 2 Aug 2012 00:49:17 +0200 Subject: um: pass siginfo to guest process MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UML guest processes now get correct siginfo_t for SIGTRAP, SIGFPE, SIGILL and SIGBUS. Specifically, si_addr and si_code are now correct where previously they were si_addr = NULL and si_code = 128. Signed-off-by: Martin Pärtel Signed-off-by: Richard Weinberger --- arch/um/os-Linux/skas/process.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'arch/um/os-Linux/skas') diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 2687f1f3a709..d93bb40499f7 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -346,6 +346,7 @@ void userspace(struct uml_pt_regs *regs) int err, status, op, pid = userspace_pid[0]; /* To prevent races if using_sysemu changes under us.*/ int local_using_sysemu; + siginfo_t si; /* Handle any immediate reschedules or signals */ interrupt_end(); @@ -407,13 +408,17 @@ void userspace(struct uml_pt_regs *regs) if (WIFSTOPPED(status)) { int sig = WSTOPSIG(status); + + ptrace(PTRACE_GETSIGINFO, pid, 0, &si); + switch (sig) { case SIGSEGV: if (PTRACE_FULL_FAULTINFO || !ptrace_faultinfo) { get_skas_faultinfo(pid, ®s->faultinfo); - (*sig_info[SIGSEGV])(SIGSEGV, regs); + (*sig_info[SIGSEGV])(SIGSEGV, &si, + regs); } else handle_segv(pid, regs); break; @@ -421,14 +426,14 @@ void userspace(struct uml_pt_regs *regs) handle_trap(pid, regs, local_using_sysemu); break; case SIGTRAP: - relay_signal(SIGTRAP, regs); + relay_signal(SIGTRAP, &si, regs); break; case SIGVTALRM: now = os_nsecs(); if (now < nsecs) break; block_signals(); - (*sig_info[sig])(sig, regs); + (*sig_info[sig])(sig, &si, regs); unblock_signals(); nsecs = timer.it_value.tv_sec * UM_NSEC_PER_SEC + @@ -442,7 +447,7 @@ void userspace(struct uml_pt_regs *regs) case SIGFPE: case SIGWINCH: block_signals(); - (*sig_info[sig])(sig, regs); + (*sig_info[sig])(sig, &si, regs); unblock_signals(); break; default: -- cgit v1.2.3