Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/usermode Big patch that changes the signal stack us...



details:   https://anonhg.NetBSD.org/src/rev/e5b1ec5575d6
branches:  trunk
changeset: 771668:e5b1ec5575d6
user:      reinoud <reinoud%NetBSD.org@localhost>
date:      Sun Nov 27 21:38:17 2011 +0000

description:
Big patch that changes the signal stack usage of urkel significantly.

Formerly, all signals came on the signal stack and the two important ones were
then forwared to either the system call or the pagefault handler. This worked
fine but the signal stack remains that, a stack. When we go multi-process this
stack gets corrupted and out-of-order with all kind of nastyness since a
userland process switch can occure when a system call is called or when a
process gets a page fault.

The new scheme only uses the signal stack as a jumpboard. It swaps states and
then returns from the signal, clearing the stack but instead of returning to
the code it now jumpt to the handler and that handler then returns to the code
when its finished.

diffstat:

 sys/arch/usermode/dev/cpu.c             |   73 ++++-
 sys/arch/usermode/include/machdep.h     |    8 +-
 sys/arch/usermode/include/param.h       |    6 +-
 sys/arch/usermode/include/pcb.h         |    9 +-
 sys/arch/usermode/usermode/machdep.c    |   73 +++--
 sys/arch/usermode/usermode/syscall.c    |   61 ++--
 sys/arch/usermode/usermode/trap.c       |  376 +++++++++++++++++--------------
 sys/arch/usermode/usermode/urkelvisor.c |    8 +-
 8 files changed, 344 insertions(+), 270 deletions(-)

diffs (truncated from 1009 to 300 lines):

diff -r fedcc74bd61e -r e5b1ec5575d6 sys/arch/usermode/dev/cpu.c
--- a/sys/arch/usermode/dev/cpu.c       Sun Nov 27 21:33:19 2011 +0000
+++ b/sys/arch/usermode/dev/cpu.c       Sun Nov 27 21:38:17 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.46 2011/09/14 18:30:13 reinoud Exp $ */
+/* $NetBSD: cpu.c,v 1.47 2011/11/27 21:38:17 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -30,7 +30,7 @@
 #include "opt_hz.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.46 2011/09/14 18:30:13 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.47 2011/11/27 21:38:17 reinoud Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -163,7 +163,7 @@
        struct cpu_info *ci = curcpu();
 
 #ifdef CPU_DEBUG
-       printf("cpu_switchto [%s,pid=%d,lid=%d] -> [%s,pid=%d,lid=%d]\n",
+       dprintf_debug("cpu_switchto [%s,pid=%d,lid=%d] -> [%s,pid=%d,lid=%d]\n",
            oldlwp ? oldlwp->l_name : "none",
            oldlwp ? oldlwp->l_proc->p_pid : -1,
            oldlwp ? oldlwp->l_lid : -1,
@@ -171,14 +171,14 @@
            newlwp ? newlwp->l_proc->p_pid : -1,
            newlwp ? newlwp->l_lid : -1);
        if (oldpcb) {
-               printf("    oldpcb uc_link=%p, uc_stack.ss_sp=%p, "
+               dprintf_debug("    oldpcb uc_link=%p, uc_stack.ss_sp=%p, "
                    "uc_stack.ss_size=%d\n",
                    oldpcb->pcb_ucp.uc_link,
                    oldpcb->pcb_ucp.uc_stack.ss_sp,
                    (int)oldpcb->pcb_ucp.uc_stack.ss_size);
        }
        if (newpcb) {
-               printf("    newpcb uc_link=%p, uc_stack.ss_sp=%p, "
+               dprintf_debug("    newpcb uc_link=%p, uc_stack.ss_sp=%p, "
                    "uc_stack.ss_size=%d\n",
                    newpcb->pcb_ucp.uc_link,
                    newpcb->pcb_ucp.uc_stack.ss_sp,
@@ -202,7 +202,7 @@
        }
 
 #ifdef CPU_DEBUG
-       printf("cpu_switchto: returning %p (was %p)\n", ci->ci_stash, oldlwp);
+       dprintf_debug("cpu_switchto: returning %p (was %p)\n", ci->ci_stash, oldlwp);
 #endif
        return ci->ci_stash;
 }
@@ -211,7 +211,7 @@
 cpu_dumpconf(void)
 {
 #ifdef CPU_DEBUG
-       printf("cpu_dumpconf\n");
+       dprintf_debug("cpu_dumpconf\n");
 #endif
 }
 
@@ -223,16 +223,18 @@
 void
 cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags)
 {
+       panic("cpu_getmcontext");
 #ifdef CPU_DEBUG
-       printf("cpu_getmcontext\n");
+       dprintf_debug("cpu_getmcontext\n");
 #endif
 }
 
 int
 cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags)
 {
+       panic("cpu_setmcontext");
 #ifdef CPU_DEBUG
-       printf("cpu_setmcontext\n");
+       dprintf_debug("cpu_setmcontext\n");
 #endif
        return 0;
 }
@@ -254,7 +256,7 @@
 cpu_lwp_free(struct lwp *l, int proc)
 {
 #ifdef CPU_DEBUG
-       printf("cpu_lwp_free\n");
+       dprintf_debug("cpu_lwp_free (dummy)\n");
 #endif
 }
 
@@ -264,7 +266,7 @@
        struct pcb *pcb = lwp_getpcb(l);
 
 #ifdef CPU_DEBUG
-       printf("cpu_lwp_free2\n");
+       dprintf_debug("cpu_lwp_free2\n");
 #endif
 
        if (pcb == NULL)
@@ -287,7 +289,7 @@
 cpu_lwp_trampoline(ucontext_t *ucp, void (*func)(void *), void *arg)
 {
 #ifdef CPU_DEBUG
-       printf("cpu_lwp_trampoline called with func %p, arg %p\n", (void *) func, arg);
+       dprintf_debug("cpu_lwp_trampoline called with func %p, arg %p\n", (void *) func, arg);
 #endif
        /* init lwp */
        lwp_startup(curcpu()->ci_stash, curlwp);
@@ -303,10 +305,10 @@
 {
        struct pcb *pcb1 = lwp_getpcb(l1);
        struct pcb *pcb2 = lwp_getpcb(l2);
-       void *stack_ucp, *stack_syscall_ucp;
+       void *stack_ucp, *stack_syscall_ucp, *stack_pagefault_ucp;
 
 #ifdef CPU_DEBUG
-       printf("cpu_lwp_fork [%s/%p] -> [%s/%p] stack=%p stacksize=%d\n",
+       dprintf_debug("cpu_lwp_fork [%s/%p] -> [%s/%p] stack=%p stacksize=%d\n",
            l1 ? l1->l_name : "none", l1,
            l2 ? l2->l_name : "none", l2,
            stack, (int)stacksize);
@@ -318,9 +320,10 @@
        /* copy the PCB and its switchframes from parent */
        memcpy(pcb2, pcb1, sizeof(struct pcb));
 
-       stacksize = 4*PAGE_SIZE;
-       stack_ucp          = malloc(stacksize, M_TEMP, M_NOWAIT);
-       stack_syscall_ucp  = malloc(stacksize, M_TEMP, M_NOWAIT);
+       stacksize = 16*PAGE_SIZE;
+       stack_ucp           = malloc(stacksize, M_TEMP, M_NOWAIT);
+       stack_syscall_ucp   = malloc(stacksize, M_TEMP, M_NOWAIT);
+       stack_pagefault_ucp = malloc(stacksize, M_TEMP, M_NOWAIT);
        pcb2->pcb_needfree = true;
 
        if (thunk_getcontext(&pcb2->pcb_ucp))
@@ -329,8 +332,8 @@
        /* set up the ucontext for the userland switch */
        pcb2->pcb_ucp.uc_stack.ss_sp = stack_ucp;
        pcb2->pcb_ucp.uc_stack.ss_size = stacksize;
-       pcb2->pcb_ucp.uc_link = &pcb2->pcb_userland_ucp;
        pcb2->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU;
+       pcb2->pcb_ucp.uc_link = &pcb2->pcb_userret_ucp;
        thunk_makecontext(&pcb2->pcb_ucp,
            (void (*)(void)) cpu_lwp_trampoline,
            3, &pcb2->pcb_ucp, func, arg);
@@ -338,10 +341,18 @@
        /* set up the ucontext for the syscall */
        pcb2->pcb_syscall_ucp.uc_stack.ss_sp = stack_syscall_ucp;
        pcb2->pcb_syscall_ucp.uc_stack.ss_size = stacksize;
-       pcb2->pcb_syscall_ucp.uc_flags = _UC_CPU;
-       pcb2->pcb_syscall_ucp.uc_link = &pcb2->pcb_userland_ucp;
+       pcb2->pcb_syscall_ucp.uc_flags = _UC_STACK | _UC_CPU;
+       pcb2->pcb_syscall_ucp.uc_link = &pcb2->pcb_userret_ucp;
        thunk_makecontext(&pcb2->pcb_syscall_ucp, (void (*)(void)) syscall,
            0, NULL, NULL, NULL);
+
+       /* set up the ucontext for the pagefault */
+       pcb2->pcb_pagefault_ucp.uc_stack.ss_sp = stack_pagefault_ucp;
+       pcb2->pcb_pagefault_ucp.uc_stack.ss_size = stacksize;
+       pcb2->pcb_pagefault_ucp.uc_flags = _UC_STACK | _UC_CPU;
+       pcb2->pcb_pagefault_ucp.uc_link = &pcb2->pcb_trapret_ucp;
+       thunk_makecontext(&pcb2->pcb_pagefault_ucp, (void (*)(void)) pagefault,
+           0, NULL, NULL, NULL);
 }
 
 void
@@ -358,6 +369,9 @@
 void
 cpu_startup(void)
 {
+       size_t stacksize;
+       void *stack_pagefault_ucp;
+
        msgbuf = thunk_malloc(PAGE_SIZE);
        if (msgbuf == NULL)
                panic("couldn't allocate msgbuf");
@@ -370,9 +384,22 @@
                panic("getcontext failed");
        uvm_lwp_setuarea(&lwp0, (vaddr_t)&lwp0pcb);
 
-       /* init trapframe (going nowhere!), maybe a panic func? */
-       memcpy(&lwp0pcb.pcb_userland_ucp, &lwp0pcb.pcb_ucp, sizeof(ucontext_t));
-       memcpy(&lwp0pcb.pcb_syscall_ucp,  &lwp0pcb.pcb_ucp, sizeof(ucontext_t));
+       /* init trapframes (going nowhere!), maybe a panic func? */
+       memcpy(&lwp0pcb.pcb_syscall_ucp,   &lwp0pcb.pcb_ucp, sizeof(ucontext_t));
+       memcpy(&lwp0pcb.pcb_userret_ucp,   &lwp0pcb.pcb_ucp, sizeof(ucontext_t));
+       memcpy(&lwp0pcb.pcb_pagefault_ucp, &lwp0pcb.pcb_ucp, sizeof(ucontext_t));
+       memcpy(&lwp0pcb.pcb_trapret_ucp,   &lwp0pcb.pcb_ucp, sizeof(ucontext_t));
+
+       /* set up the ucontext for the pagefault */
+       stacksize = 16*PAGE_SIZE;
+       stack_pagefault_ucp = malloc(stacksize, M_TEMP, M_NOWAIT);
+
+       lwp0pcb.pcb_pagefault_ucp.uc_stack.ss_sp = stack_pagefault_ucp;
+       lwp0pcb.pcb_pagefault_ucp.uc_stack.ss_size = stacksize;
+       lwp0pcb.pcb_pagefault_ucp.uc_flags = _UC_STACK | _UC_CPU;
+       lwp0pcb.pcb_pagefault_ucp.uc_link = &lwp0pcb.pcb_userret_ucp;
+       thunk_makecontext(&lwp0pcb.pcb_pagefault_ucp, (void (*)(void)) pagefault,
+           0, NULL, NULL, NULL);
 }
 
 void
diff -r fedcc74bd61e -r e5b1ec5575d6 sys/arch/usermode/include/machdep.h
--- a/sys/arch/usermode/include/machdep.h       Sun Nov 27 21:33:19 2011 +0000
+++ b/sys/arch/usermode/include/machdep.h       Sun Nov 27 21:38:17 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.h,v 1.3 2011/09/09 12:44:27 reinoud Exp $ */
+/* $NetBSD: machdep.h,v 1.4 2011/11/27 21:38:17 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2011 Reinoud Zandijk <reinoud%netbsd.org@localhost>
@@ -27,12 +27,16 @@
  */
 
 int    md_syscall_check_opcode(void *ptr);
+void   md_syscall_get_opcode(ucontext_t *ucp, uint32_t *opcode);
 void   md_syscall_get_syscallnumber(ucontext_t *ucp, uint32_t *code);
 int    md_syscall_getargs(lwp_t *l, ucontext_t *ucp, int nargs, int argsize,
                register_t *args);
 void   md_syscall_set_returnargs(lwp_t *l, ucontext_t *ucp,
                int error, register_t *rval);
-void   md_syscall_inc_pc(ucontext_t *ucp);
+void   md_syscall_inc_pc(ucontext_t *ucp, uint32_t opcode);
+void   md_syscall_dec_pc(ucontext_t *ucp, uint32_t opcode);
 
+/* handlers */
 void   syscall(void);
+void   pagefault(void);
 
diff -r fedcc74bd61e -r e5b1ec5575d6 sys/arch/usermode/include/param.h
--- a/sys/arch/usermode/include/param.h Sun Nov 27 21:33:19 2011 +0000
+++ b/sys/arch/usermode/include/param.h Sun Nov 27 21:38:17 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: param.h,v 1.4 2011/09/08 10:49:57 jmcneill Exp $ */
+/* $NetBSD: param.h,v 1.5 2011/11/27 21:38:17 reinoud Exp $ */
 
 /*
  * Automatically generated by genheaders.sh on Thu Sep  8 06:50:18 EDT 2011
@@ -14,7 +14,9 @@
 #else
 #error port me
 #endif
+#undef UPAGES
+#define UPAGES 6
 #undef USPACE
-#define USPACE (PAGE_SIZE*4)
+#define USPACE (PAGE_SIZE*UPAGES)
 
 #endif
diff -r fedcc74bd61e -r e5b1ec5575d6 sys/arch/usermode/include/pcb.h
--- a/sys/arch/usermode/include/pcb.h   Sun Nov 27 21:33:19 2011 +0000
+++ b/sys/arch/usermode/include/pcb.h   Sun Nov 27 21:38:17 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pcb.h,v 1.12 2011/09/08 19:37:01 reinoud Exp $ */
+/* $NetBSD: pcb.h,v 1.13 2011/11/27 21:38:17 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -41,13 +41,16 @@
 
 struct pcb {
        ucontext_t       pcb_ucp;               /* lwp switchframe */
-       ucontext_t       pcb_userland_ucp;      /* userland switchframe */
-       ucontext_t       pcb_syscall_ucp;       /* to switch to for syscall */
+       ucontext_t       pcb_syscall_ucp;       /* syscall context */
+       ucontext_t       pcb_userret_ucp;       /* reutn to userland context */
+       ucontext_t       pcb_pagefault_ucp;     /* pagefault context */
+       ucontext_t       pcb_trapret_ucp;
 
        bool             pcb_needfree;
        void *           pcb_onfault;           /* on fault handler */
 
        int              pcb_errno;             /* save/restore place */
+       vaddr_t          pcb_fault_addr;        /* save place for fault addr */
 };
 
 #endif /* !_ARCH_USERMODE_INCLUDE_PCB_H */
diff -r fedcc74bd61e -r e5b1ec5575d6 sys/arch/usermode/usermode/machdep.c
--- a/sys/arch/usermode/usermode/machdep.c      Sun Nov 27 21:33:19 2011 +0000
+++ b/sys/arch/usermode/usermode/machdep.c      Sun Nov 27 21:38:17 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.32 2011/09/16 16:26:19 reinoud Exp $ */
+/* $NetBSD: machdep.c,v 1.33 2011/11/27 21:38:17 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2011 Reinoud Zandijk <reinoud%netbsd.org@localhost>
@@ -32,7 +32,7 @@
 #include "opt_urkelvisor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.32 2011/09/16 16:26:19 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.33 2011/11/27 21:38:17 reinoud Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -176,7 +176,7 @@
 setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
 {



Home | Main Index | Thread Index | Old Index