Module Name: src Committed By: reinoud Date: Sat Jan 14 21:45:29 UTC 2012
Modified Files: src/sys/arch/usermode/dev: cpu.c src/sys/arch/usermode/usermode: syscall.c trap.c Log Message: Reimplement userret() to also include AST for preemption. Note it would be nice if we could do the check "are we going to userland?" in a less intrusive way. To generate a diff of this commit: cvs rdiff -u -r1.64 -r1.65 src/sys/arch/usermode/dev/cpu.c cvs rdiff -u -r1.21 -r1.22 src/sys/arch/usermode/usermode/syscall.c cvs rdiff -u -r1.56 -r1.57 src/sys/arch/usermode/usermode/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/usermode/dev/cpu.c diff -u src/sys/arch/usermode/dev/cpu.c:1.64 src/sys/arch/usermode/dev/cpu.c:1.65 --- src/sys/arch/usermode/dev/cpu.c:1.64 Sat Jan 14 17:42:51 2012 +++ src/sys/arch/usermode/dev/cpu.c Sat Jan 14 21:45:28 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.64 2012/01/14 17:42:51 reinoud Exp $ */ +/* $NetBSD: cpu.c,v 1.65 2012/01/14 21:45:28 reinoud Exp $ */ /*- * Copyright (c) 2007 Jared D. McNeill <jmcne...@invisible.ca> @@ -30,7 +30,7 @@ #include "opt_hz.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.64 2012/01/14 17:42:51 reinoud Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.65 2012/01/14 21:45:28 reinoud Exp $"); #include <sys/param.h> #include <sys/conf.h> @@ -43,6 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.64 #include <sys/mbuf.h> #include <sys/msgbuf.h> #include <sys/kmem.h> +#include <sys/kernel.h> #include <dev/cons.h> @@ -155,6 +156,7 @@ void cpu_need_resched(struct cpu_info *ci, int flags) { ci->ci_want_resched |= flags; + aston(ci); } void Index: src/sys/arch/usermode/usermode/syscall.c diff -u src/sys/arch/usermode/usermode/syscall.c:1.21 src/sys/arch/usermode/usermode/syscall.c:1.22 --- src/sys/arch/usermode/usermode/syscall.c:1.21 Sat Jan 14 17:42:52 2012 +++ src/sys/arch/usermode/usermode/syscall.c Sat Jan 14 21:45:28 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: syscall.c,v 1.21 2012/01/14 17:42:52 reinoud Exp $ */ +/* $NetBSD: syscall.c,v 1.22 2012/01/14 21:45:28 reinoud Exp $ */ /*- * Copyright (c) 2007 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.21 2012/01/14 17:42:52 reinoud Exp $"); +__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.22 2012/01/14 21:45:28 reinoud Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -45,16 +45,6 @@ __KERNEL_RCSID(0, "$NetBSD: syscall.c,v #include <machine/thunk.h> #include <machine/machdep.h> - -void userret(struct lwp *l); - -void -userret(struct lwp *l) -{ - /* invoke MI userret code */ - mi_userret(l); -} - void child_return(void *arg) { @@ -161,7 +151,6 @@ syscall(void) } //thunk_printf_debug("end of syscall : return to userland\n"); //if (code != 4) thunk_printf("userret() code %d\n", code); - userret(l); } Index: src/sys/arch/usermode/usermode/trap.c diff -u src/sys/arch/usermode/usermode/trap.c:1.56 src/sys/arch/usermode/usermode/trap.c:1.57 --- src/sys/arch/usermode/usermode/trap.c:1.56 Sat Jan 14 17:42:52 2012 +++ src/sys/arch/usermode/usermode/trap.c Sat Jan 14 21:45:28 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.56 2012/01/14 17:42:52 reinoud Exp $ */ +/* $NetBSD: trap.c,v 1.57 2012/01/14 21:45:28 reinoud Exp $ */ /*- * Copyright (c) 2011 Reinoud Zandijk <rein...@netbsd.org> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.56 2012/01/14 17:42:52 reinoud Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.57 2012/01/14 21:45:28 reinoud Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -50,6 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.5 /* forwards and externals */ void setup_signal_handlers(void); void stop_all_signal_handlers(void); +void userret(struct lwp *l); static void mem_access_handler(int sig, siginfo_t *info, void *ctx); static void illegal_instruction_handler(int sig, siginfo_t *info, void *ctx); @@ -62,6 +63,7 @@ bool pmap_fault(pmap_t pmap, vaddr_t va, static stack_t sigstk; +int astpending; void startlwp(void *arg) @@ -203,6 +205,49 @@ mem_access_handler(int sig, siginfo_t *i } +/* ast and userret */ +void +userret(struct lwp *l) +{ + struct pcb *pcb; + ucontext_t ucp, *nucp; + vaddr_t pc; + + KASSERT(l); + + /* are we going back to userland? */ + pcb = lwp_getpcb(l); + KASSERT(pcb); + + /* where are we going back to ? */ + thunk_getcontext(&ucp); + nucp = (ucontext_t *) ucp.uc_link; + pc = md_get_pc(nucp); + + if (pc >= kmem_k_start) + return; + + /* ok, going to userland, proceed! */ + if (astpending) { + astpending = 0; + + curcpu()->ci_data.cpu_ntrap++; +#if 0 + /* profiling */ + if (l->l_pflag & LP_OWEUPC) { + l->l_pflag &= ~LP_OWEUPC; + ADDUPROF(l); + } +#endif + /* allow a forced task switch */ + if (l->l_cpu->ci_want_resched) + preempt(); + } + + /* invoke MI userret code */ + mi_userret(l); +} + /* signal handler switching to a illegal instruction context */ static void illegal_instruction_handler(int sig, siginfo_t *info, void *ctx) @@ -317,10 +362,11 @@ pagefault(vaddr_t pc, vaddr_t va) (void *) pc, (void *) va); #endif - /* can pmap handle it? on its own? (r/m) */ + /* can pmap handle it? on its own? (r/m) emulation */ if (pmap_fault(vm_map->pmap, va, &atype)) { // thunk_printf("pagefault leave (pmap)\n"); - goto out; + /* no use doing anything else here */ + goto out_quick; } /* ask UVM */ @@ -386,10 +432,11 @@ pagefault(vaddr_t pc, vaddr_t va) #else trapsignal(l, &ksi); #endif - mi_userret(l); // thunk_printf("pagefault leave\n"); out: + userret(l); +out_quick: thunk_seterrno(lwp_errno); pcb->pcb_errno = lwp_errno; } @@ -410,6 +457,7 @@ illegal_instruction(void) if (md_syscall_check_opcode(ucp)) { syscall(); // thunk_printf("illegal instruction leave\n"); + userret(l); return; } @@ -427,6 +475,6 @@ illegal_instruction(void) #else trapsignal(l, &ksi); #endif - mi_userret(l); + userret(l); }