diff options
author | Jeff Dike <jdike@addtoit.com> | 2008-02-05 01:30:56 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-05 12:44:28 -0500 |
commit | ee3d9bd4de1ed93d2a7ee41c331ed30a1c7b8acd (patch) | |
tree | f49369c9f941066bdb8bbb2b4fd9d40bf2fda292 /arch/um/sys-i386/stub_segv.c | |
parent | ca77b555c0aafa3070fbb67592abaaa1b8d31913 (diff) |
uml: simplify SIGSEGV handling
Simplify the page fault stub by not masking signals while it is running. This
allows it to signal that it is done by executing an instruction which will
generate a SIGTRAP (int3 on x86) rather than running sigreturn by hand after
queueing a blocked SIGUSR1.
userspace_tramp now no longer puts anything in the SIGSEGV sa_mask, but it
does add SA_NODEFER to sa_flags so that SIGSEGV is still enabled after the
signal handler fails to run sigreturn.
SIGWINCH is just blocked so that we don't have to deal with it and the signal
masks used by wait_stub_done are updated to reflect the smaller number of
signals that it has to worry about.
Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um/sys-i386/stub_segv.c')
-rw-r--r-- | arch/um/sys-i386/stub_segv.c | 19 |
1 files changed, 2 insertions, 17 deletions
diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c index b3999cb76bfd..28ccf737a79f 100644 --- a/arch/um/sys-i386/stub_segv.c +++ b/arch/um/sys-i386/stub_segv.c | |||
@@ -1,32 +1,17 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) | 2 | * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <signal.h> | ||
7 | #include <sys/select.h> /* The only way I can see to get sigset_t */ | ||
8 | #include <asm/unistd.h> | ||
9 | #include "as-layout.h" | ||
10 | #include "uml-config.h" | ||
11 | #include "sysdep/stub.h" | 6 | #include "sysdep/stub.h" |
12 | #include "sysdep/sigcontext.h" | 7 | #include "sysdep/sigcontext.h" |
13 | #include "sysdep/faultinfo.h" | ||
14 | 8 | ||
15 | void __attribute__ ((__section__ (".__syscall_stub"))) | 9 | void __attribute__ ((__section__ (".__syscall_stub"))) |
16 | stub_segv_handler(int sig) | 10 | stub_segv_handler(int sig) |
17 | { | 11 | { |
18 | struct sigcontext *sc = (struct sigcontext *) (&sig + 1); | 12 | struct sigcontext *sc = (struct sigcontext *) (&sig + 1); |
19 | int pid; | ||
20 | 13 | ||
21 | GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), sc); | 14 | GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), sc); |
22 | 15 | ||
23 | pid = stub_syscall0(__NR_getpid); | 16 | trap_myself(); |
24 | stub_syscall2(__NR_kill, pid, SIGUSR1); | ||
25 | |||
26 | /* Load pointer to sigcontext into esp, since we need to leave | ||
27 | * the stack in its original form when we do the sigreturn here, by | ||
28 | * hand. | ||
29 | */ | ||
30 | __asm__ __volatile__("mov %0,%%esp ; movl %1, %%eax ; " | ||
31 | "int $0x80" : : "a" (sc), "g" (__NR_sigreturn)); | ||
32 | } | 17 | } |