Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/usermode/dev First try at TLS support and getcontex...



details:   https://anonhg.NetBSD.org/src/rev/0aa0625a0048
branches:  trunk
changeset: 322944:0aa0625a0048
user:      reinoud <reinoud%NetBSD.org@localhost>
date:      Thu May 24 19:39:04 2018 +0000

description:
First try at TLS support and getcontext/setcontext/swapcontext support.

diffstat:

 sys/arch/usermode/dev/cpu.c |  63 ++++++++++++++++++++++++++++++++++++--------
 1 files changed, 51 insertions(+), 12 deletions(-)

diffs (174 lines):

diff -r 005fe519a997 -r 0aa0625a0048 sys/arch/usermode/dev/cpu.c
--- a/sys/arch/usermode/dev/cpu.c       Thu May 24 19:21:01 2018 +0000
+++ b/sys/arch/usermode/dev/cpu.c       Thu May 24 19:39:04 2018 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 @@
 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 @@
        if (config_rootfound("mainbus", NULL) == NULL)
                panic("configure: mainbus not configured");
 
-
        spl0();
 }
 
@@ -189,6 +193,8 @@
 {
 }
 
+
+/* XXX make sure this is atomic? */
 static
 void
 cpu_switchto_atomic(lwp_t *oldlwp, lwp_t *newlwp)
@@ -208,12 +214,22 @@
 
        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 @@
            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 @@
        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 @@
 {
        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 @@
         * 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 @@
 #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 @@
        /* 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 @@
        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);



Home | Main Index | Thread Index | Old Index