aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/sys-x86_64
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2008-02-05 01:30:56 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-05 12:44:28 -0500
commitee3d9bd4de1ed93d2a7ee41c331ed30a1c7b8acd (patch)
treef49369c9f941066bdb8bbb2b4fd9d40bf2fda292 /arch/um/sys-x86_64
parentca77b555c0aafa3070fbb67592abaaa1b8d31913 (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-x86_64')
-rw-r--r--arch/um/sys-x86_64/stub_segv.c39
1 files changed, 5 insertions, 34 deletions
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c
index 3afb590f0072..ced051afc705 100644
--- a/arch/um/sys-x86_64/stub_segv.c
+++ b/arch/um/sys-x86_64/stub_segv.c
@@ -1,51 +1,22 @@
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 <stddef.h>
7#include <signal.h> 6#include <signal.h>
8#include <asm/unistd.h>
9#include "as-layout.h" 7#include "as-layout.h"
10#include "uml-config.h"
11#include "sysdep/sigcontext.h"
12#include "sysdep/faultinfo.h"
13#include "sysdep/stub.h" 8#include "sysdep/stub.h"
14 9#include "sysdep/faultinfo.h"
15/* Copied from sys-x86_64/signal.c - Can't find an equivalent definition 10#include "sysdep/sigcontext.h"
16 * in the libc headers anywhere.
17 */
18struct rt_sigframe
19{
20 char *pretcode;
21 struct ucontext uc;
22 struct siginfo info;
23};
24
25/* Copied here from <linux/kernel.h> - we're userspace. */
26#define container_of(ptr, type, member) ({ \
27 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
28 (type *)( (char *)__mptr - offsetof(type,member) );})
29 11
30void __attribute__ ((__section__ (".__syscall_stub"))) 12void __attribute__ ((__section__ (".__syscall_stub")))
31stub_segv_handler(int sig) 13stub_segv_handler(int sig)
32{ 14{
33 struct ucontext *uc; 15 struct ucontext *uc;
34 int pid;
35 16
36 __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :); 17 __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :);
37 GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), 18 GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA),
38 &uc->uc_mcontext); 19 &uc->uc_mcontext);
39 20 trap_myself();
40 pid = stub_syscall0(__NR_getpid);
41 stub_syscall2(__NR_kill, pid, SIGUSR1);
42
43 /* sys_sigreturn expects that the stack pointer will be 8 bytes into
44 * the signal frame. So, we use the ucontext pointer, which we know
45 * already, to get the signal frame pointer, and add 8 to that.
46 */
47 __asm__ __volatile__("movq %0, %%rsp; movq %1, %%rax ; syscall": :
48 "g" ((unsigned long)
49 container_of(uc, struct rt_sigframe, uc) + 8),
50 "g" (__NR_rt_sigreturn));
51} 21}
22