Module Name: src Committed By: reinoud Date: Thu May 24 19:39:04 UTC 2018
Modified Files: src/sys/arch/usermode/dev: cpu.c Log Message: First try at TLS support and getcontext/setcontext/swapcontext support. To generate a diff of this commit: cvs rdiff -u -r1.75 -r1.76 src/sys/arch/usermode/dev/cpu.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.75 src/sys/arch/usermode/dev/cpu.c:1.76 --- src/sys/arch/usermode/dev/cpu.c:1.75 Thu May 17 19:00:39 2018 +++ src/sys/arch/usermode/dev/cpu.c Thu May 24 19:39:04 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.75 2018/05/17 19:00:39 reinoud Exp $ */ +/* $NetBSD: cpu.c,v 1.76 2018/05/24 19:39:04 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.75 2018/05/17 19:00:39 reinoud Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.76 2018/05/24 19:39:04 reinoud Exp $"); #include <sys/param.h> #include <sys/conf.h> @@ -66,6 +66,11 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.75 static int cpu_match(device_t, cfdata_t, void *); static void cpu_attach(device_t, device_t, void *); +/* XXX */ +//extern void *_lwp_getprivate(void); +//extern int _lwp_setprivate(void *); + + struct cpu_info cpu_info_primary = { .ci_dev = 0, .ci_self = &cpu_info_primary, @@ -130,7 +135,6 @@ cpu_configure(void) if (config_rootfound("mainbus", NULL) == NULL) panic("configure: mainbus not configured"); - spl0(); } @@ -189,6 +193,8 @@ cpu_need_proftick(struct lwp *l) { } + +/* XXX make sure this is atomic? */ static void cpu_switchto_atomic(lwp_t *oldlwp, lwp_t *newlwp) @@ -208,12 +214,22 @@ cpu_switchto_atomic(lwp_t *oldlwp, lwp_t thunk_seterrno(newpcb->pcb_errno); + /* set both ucontexts up for TLS just in case */ + newpcb->pcb_ucp.uc_mcontext._mc_tlsbase = + (uintptr_t) newlwp->l_private; + newpcb->pcb_ucp.uc_flags |= _UC_TLSBASE; + + newpcb->pcb_userret_ucp.uc_mcontext._mc_tlsbase = + (uintptr_t) newlwp->l_private; + newpcb->pcb_userret_ucp.uc_flags |= _UC_TLSBASE; + curlwp = newlwp; if (thunk_setcontext(&newpcb->pcb_ucp)) panic("setcontext failed"); /* not reached */ } + lwp_t * cpu_switchto(lwp_t *oldlwp, lwp_t *newlwp, bool returning) { @@ -232,17 +248,23 @@ cpu_switchto(lwp_t *oldlwp, lwp_t *newlw newlwp ? newlwp->l_lid : -1); if (oldpcb) { thunk_printf_debug(" oldpcb uc_link=%p, uc_stack.ss_sp=%p, " - "uc_stack.ss_size=%d\n", + "uc_stack.ss_size=%d, l_private %p, uc_mcontext._mc_tlsbase=%p(%s)\n", oldpcb->pcb_ucp.uc_link, oldpcb->pcb_ucp.uc_stack.ss_sp, - (int)oldpcb->pcb_ucp.uc_stack.ss_size); + (int)oldpcb->pcb_ucp.uc_stack.ss_size, + (void *) oldlwp->l_private, + (void *) oldpcb->pcb_ucp.uc_mcontext._mc_tlsbase, + oldpcb->pcb_ucp.uc_flags & _UC_TLSBASE? "ON":"off"); } if (newpcb) { - thunk_printf_debug(" newpcb uc_link=%p, uc_stack.ss_sp=%p, " - "uc_stack.ss_size=%d\n", + thunk_printf_debug(" newpewcb uc_link=%p, uc_stack.ss_sp=%p, " + "uc_stack.ss_size=%d, l_private %p, uc_mcontext._mc_tlsbase=%p(%s)\n", newpcb->pcb_ucp.uc_link, newpcb->pcb_ucp.uc_stack.ss_sp, - (int)newpcb->pcb_ucp.uc_stack.ss_size); + (int)newpcb->pcb_ucp.uc_stack.ss_size, + (void *) newlwp->l_private, + (void *) newpcb->pcb_ucp.uc_mcontext._mc_tlsbase, + newpcb->pcb_ucp.uc_flags & _UC_TLSBASE? "ON":"off"); } #endif /* !CPU_DEBUG */ @@ -250,7 +272,6 @@ cpu_switchto(lwp_t *oldlwp, lwp_t *newlw KASSERT(newlwp); thunk_makecontext(&sc->sc_ucp, (void (*)(void)) cpu_switchto_atomic, 2, oldlwp, newlwp, NULL, NULL); - KASSERT(sc); if (oldpcb) { thunk_swapcontext(&oldpcb->pcb_ucp, &sc->sc_ucp); @@ -284,11 +305,16 @@ cpu_getmcontext(struct lwp *l, mcontext_ { struct pcb *pcb = lwp_getpcb(l); ucontext_t *ucp = &pcb->pcb_userret_ucp; - + #ifdef CPU_DEBUG thunk_printf_debug("cpu_getmcontext\n"); #endif memcpy(mcp, &ucp->uc_mcontext, sizeof(mcontext_t)); + + /* XXX be overzealous and provide all */ + mcp->_mc_tlsbase = (uintptr_t) l->l_private; + *flags = _UC_CPU | _UC_STACK | _UC_SIGMASK | _UC_FPU | _UC_TLSBASE; + return; } @@ -299,6 +325,10 @@ cpu_mcontext_validate(struct lwp *l, con * can we check here? or should that be done in the target * specific places? */ + /* XXX NO CHECKING! XXX */ +#ifdef CPU_DEBUG + thunk_printf("cpu_mcontext_validate\n"); +#endif return 0; } @@ -311,7 +341,12 @@ cpu_setmcontext(struct lwp *l, const mco #ifdef CPU_DEBUG thunk_printf_debug("cpu_setmcontext\n"); #endif + ucp->uc_flags = flags; memcpy(&ucp->uc_mcontext, mcp, sizeof(mcontext_t)); + + /* update our private, it might be altered in userland */ + l->l_private = (void *) ucp->uc_mcontext._mc_tlsbase; + return 0; } @@ -382,10 +417,14 @@ cpu_lwp_fork(struct lwp *l1, struct lwp /* copy the PCB and its switchframes from parent */ memcpy(pcb2, pcb1, sizeof(struct pcb)); - /* refresh context */ + /* refresh context, XXX needed? */ if (thunk_getcontext(&pcb2->pcb_ucp)) panic("getcontext failed"); + /* set up for TLS */ + pcb2->pcb_ucp.uc_mcontext._mc_tlsbase = (intptr_t) l2->l_private; + pcb2->pcb_ucp.uc_flags |= _UC_TLSBASE; + /* recalculate the system stack top */ pcb2->sys_stack_top = pcb2->sys_stack + TRAPSTACKSIZE; @@ -395,7 +434,7 @@ cpu_lwp_fork(struct lwp *l1, struct lwp pcb2->pcb_ucp.uc_link = &pcb2->pcb_userret_ucp; thunk_sigemptyset(&pcb2->pcb_ucp.uc_sigmask); - pcb2->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK; + thunk_makecontext(&pcb2->pcb_ucp, (void (*)(void)) cpu_lwp_trampoline, 3, &pcb2->pcb_ucp, func, arg, NULL);