void sig_handler_common_skas(int sig, void *sc_ptr) { struct sigcontext *sc = sc_ptr; struct uml_pt_regs *r; void (*handler)(int, struct uml_pt_regs *); int save_user, save_errno = errno; /* * This is done because to allow SIGSEGV to be delivered inside a SEGV * handler. This can happen in copy_user, and if SEGV is disabled, * the process will die. * XXX Figure out why this is better than SA_NODEFER */ if (sig == SIGSEGV) { change_sig(SIGSEGV, 1); /* * For segfaults, we want the data from the * sigcontext. In this case, we don't want to mangle * the process registers, so use a static set of * registers. For other signals, the process * registers are OK. */ r = &ksig_regs[cpu()]; copy_sc(r, sc_ptr); } else r = TASK_REGS(get_current()); save_user = r->is_user; r->is_user = 0; if ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || (sig == SIGILL) || (sig == SIGTRAP)) GET_FAULTINFO_FROM_SC(r->faultinfo, sc); change_sig(SIGUSR1, 1); handler = sig_info[sig]; /* unblock SIGVTALRM, SIGIO if sig isn't IRQ signal */ if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM)) unblock_signals(); handler(sig, r); errno = save_errno; r->is_user = save_user; }
stub_segv_handler(int sig) { struct sigcontext *sc = (struct sigcontext *) (&sig + 1); int pid; GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), sc); pid = stub_syscall0(__NR_getpid); stub_syscall2(__NR_kill, pid, SIGUSR1); /* Load pointer to sigcontext into esp, since we need to leave * the stack in its original form when we do the sigreturn here, by * hand. */ __asm__ __volatile__("mov %0,%%esp ; movl %1, %%eax ; " "int $0x80" : : "a" (sc), "g" (__NR_sigreturn)); }
static void sig_handler_common(int sig, struct sigcontext *sc) { struct uml_pt_regs r; int save_errno = errno; r.is_user = 0; if (sig == SIGSEGV) { /* For segfaults, we want the data from the sigcontext. */ copy_sc(&r, sc); GET_FAULTINFO_FROM_SC(r.faultinfo, sc); } /* enable signals if sig isn't IRQ signal */ if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM)) unblock_signals(); (*sig_info[sig])(sig, &r); errno = save_errno; }