Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ee3d9bd4de1ed93d2a7ee41c331ed30a1c7b8acd
Commit:     ee3d9bd4de1ed93d2a7ee41c331ed30a1c7b8acd
Parent:     ca77b555c0aafa3070fbb67592abaaa1b8d31913
Author:     Jeff Dike <[EMAIL PROTECTED]>
AuthorDate: Mon Feb 4 22:30:56 2008 -0800
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Tue Feb 5 09:44:28 2008 -0800

    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 <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 arch/um/os-Linux/skas/process.c |   11 ++----
 arch/um/sys-i386/stub_segv.c    |   49 +++++++++-----------------
 arch/um/sys-x86_64/stub_segv.c  |   73 ++++++++++++---------------------------
 3 files changed, 43 insertions(+), 90 deletions(-)

diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 765cfa6..2cc2071 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -55,10 +55,10 @@ static int ptrace_dump_regs(int pid)
  * Signals that are OK to receive in the stub - we'll just continue it.
  * SIGWINCH will happen when UML is inside a detached screen.
  */
-#define STUB_SIG_MASK ((1 << SIGVTALRM) | (1 << SIGWINCH))
+#define STUB_SIG_MASK (1 << SIGVTALRM)
 
 /* Signals that the stub will finish with - anything else is an error */
-#define STUB_DONE_MASK ((1 << SIGUSR1) | (1 << SIGTRAP))
+#define STUB_DONE_MASK (1 << SIGTRAP)
 
 void wait_stub_done(int pid)
 {
@@ -179,6 +179,7 @@ static int userspace_tramp(void *stack)
        ptrace(PTRACE_TRACEME, 0, 0, 0);
 
        signal(SIGTERM, SIG_DFL);
+       signal(SIGWINCH, SIG_IGN);
        err = set_interval();
        if (err)
                panic("userspace_tramp - setting timer failed, errno = %d\n",
@@ -222,11 +223,7 @@ static int userspace_tramp(void *stack)
 
                set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE);
                sigemptyset(&sa.sa_mask);
-               sigaddset(&sa.sa_mask, SIGIO);
-               sigaddset(&sa.sa_mask, SIGWINCH);
-               sigaddset(&sa.sa_mask, SIGVTALRM);
-               sigaddset(&sa.sa_mask, SIGUSR1);
-               sa.sa_flags = SA_ONSTACK;
+               sa.sa_flags = SA_ONSTACK | SA_NODEFER;
                sa.sa_handler = (void *) v;
                sa.sa_restorer = NULL;
                if (sigaction(SIGSEGV, &sa, NULL) < 0)
diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c
dissimilarity index 66%
index b3999cb..28ccf73 100644
--- a/arch/um/sys-i386/stub_segv.c
+++ b/arch/um/sys-i386/stub_segv.c
@@ -1,32 +1,17 @@
-/*
- * Copyright (C) 2004 Jeff Dike ([EMAIL PROTECTED])
- * Licensed under the GPL
- */
-
-#include <signal.h>
-#include <sys/select.h> /* The only way I can see to get sigset_t */
-#include <asm/unistd.h>
-#include "as-layout.h"
-#include "uml-config.h"
-#include "sysdep/stub.h"
-#include "sysdep/sigcontext.h"
-#include "sysdep/faultinfo.h"
-
-void __attribute__ ((__section__ (".__syscall_stub")))
-stub_segv_handler(int sig)
-{
-       struct sigcontext *sc = (struct sigcontext *) (&sig + 1);
-       int pid;
-
-       GET_FAULTINFO_FROM_SC(*((struct faultinfo *) 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));
-}
+/*
+ * Copyright (C) 2004 - 2007 Jeff Dike ([EMAIL PROTECTED],linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#include "sysdep/stub.h"
+#include "sysdep/sigcontext.h"
+
+void __attribute__ ((__section__ (".__syscall_stub")))
+stub_segv_handler(int sig)
+{
+       struct sigcontext *sc = (struct sigcontext *) (&sig + 1);
+
+       GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), sc);
+
+       trap_myself();
+}
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c
dissimilarity index 72%
index 3afb590..ced051a 100644
--- a/arch/um/sys-x86_64/stub_segv.c
+++ b/arch/um/sys-x86_64/stub_segv.c
@@ -1,51 +1,22 @@
-/*
- * Copyright (C) 2004 Jeff Dike ([EMAIL PROTECTED])
- * Licensed under the GPL
- */
-
-#include <stddef.h>
-#include <signal.h>
-#include <asm/unistd.h>
-#include "as-layout.h"
-#include "uml-config.h"
-#include "sysdep/sigcontext.h"
-#include "sysdep/faultinfo.h"
-#include "sysdep/stub.h"
-
-/* Copied from sys-x86_64/signal.c - Can't find an equivalent definition
- * in the libc headers anywhere.
- */
-struct rt_sigframe
-{
-       char *pretcode;
-       struct ucontext uc;
-       struct siginfo info;
-};
-
-/* Copied here from <linux/kernel.h> - we're userspace. */
-#define container_of(ptr, type, member) ({                   \
-       const typeof( ((type *)0)->member ) *__mptr = (ptr); \
-       (type *)( (char *)__mptr - offsetof(type,member) );})
-
-void __attribute__ ((__section__ (".__syscall_stub")))
-stub_segv_handler(int sig)
-{
-       struct ucontext *uc;
-        int pid;
-
-       __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :);
-       GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA),
-                             &uc->uc_mcontext);
-
-       pid = stub_syscall0(__NR_getpid);
-       stub_syscall2(__NR_kill, pid, SIGUSR1);
-
-       /* sys_sigreturn expects that the stack pointer will be 8 bytes into
-        * the signal frame.  So, we use the ucontext pointer, which we know
-        * already, to get the signal frame pointer, and add 8 to that.
-        */
-       __asm__ __volatile__("movq %0, %%rsp; movq %1, %%rax ; syscall": :
-                             "g" ((unsigned long)
-                                  container_of(uc, struct rt_sigframe, uc) + 
8),
-                             "g" (__NR_rt_sigreturn));
-}
+/*
+ * Copyright (C) 2004 - 2007 Jeff Dike ([EMAIL PROTECTED],linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#include <signal.h>
+#include "as-layout.h"
+#include "sysdep/stub.h"
+#include "sysdep/faultinfo.h"
+#include "sysdep/sigcontext.h"
+
+void __attribute__ ((__section__ (".__syscall_stub")))
+stub_segv_handler(int sig)
+{
+       struct ucontext *uc;
+
+       __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :);
+       GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA),
+                             &uc->uc_mcontext);
+       trap_myself();
+}
+
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to