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