1 1.23 simonb /* $NetBSD: netbsd32_lwp.c,v 1.23 2021/01/14 02:51:52 simonb Exp $ */ 2 1.1 cube 3 1.1 cube /* 4 1.20 ad * Copyright (c) 2005, 2006, 2007, 2020 The NetBSD Foundation. 5 1.1 cube * All rights reserved. 6 1.1 cube * 7 1.1 cube * Redistribution and use in source and binary forms, with or without 8 1.1 cube * modification, are permitted provided that the following conditions 9 1.1 cube * are met: 10 1.1 cube * 1. Redistributions of source code must retain the above copyright 11 1.1 cube * notice, this list of conditions and the following disclaimer. 12 1.1 cube * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cube * notice, this list of conditions and the following disclaimer in the 14 1.1 cube * documentation and/or other materials provided with the distribution. 15 1.1 cube * 16 1.1 cube * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 1.1 cube * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 1.1 cube * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 1.1 cube * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 1.1 cube * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 1.1 cube * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 1.1 cube * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 1.1 cube * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 1.1 cube * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 1.1 cube * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 1.1 cube * POSSIBILITY OF SUCH DAMAGE. 27 1.1 cube */ 28 1.1 cube 29 1.1 cube #include <sys/cdefs.h> 30 1.23 simonb __KERNEL_RCSID(0, "$NetBSD: netbsd32_lwp.c,v 1.23 2021/01/14 02:51:52 simonb Exp $"); 31 1.1 cube 32 1.1 cube #include <sys/types.h> 33 1.1 cube #include <sys/param.h> 34 1.1 cube #include <sys/systm.h> 35 1.1 cube #include <sys/kernel.h> 36 1.1 cube #include <sys/dirent.h> 37 1.1 cube #include <sys/mount.h> 38 1.1 cube #include <sys/proc.h> 39 1.1 cube #include <sys/syscallargs.h> 40 1.8 ad #include <sys/lwpctl.h> 41 1.1 cube 42 1.1 cube #include <compat/netbsd32/netbsd32.h> 43 1.1 cube #include <compat/netbsd32/netbsd32_syscallargs.h> 44 1.1 cube #include <compat/netbsd32/netbsd32_conv.h> 45 1.1 cube 46 1.1 cube /* Sycalls conversion */ 47 1.1 cube 48 1.1 cube int 49 1.9 dsl netbsd32__lwp_create(struct lwp *l, const struct netbsd32__lwp_create_args *uap, register_t *retval) 50 1.1 cube { 51 1.9 dsl /* { 52 1.1 cube syscallarg(const netbsd32_ucontextp) ucp; 53 1.1 cube syscallarg(netbsd32_u_long) flags; 54 1.1 cube syscallarg(netbsd32_lwpidp) new_lwp; 55 1.9 dsl } */ 56 1.13 martin struct proc *p = l->l_proc; 57 1.13 martin ucontext32_t *newuc = NULL; 58 1.20 ad lwp_t *l2; 59 1.13 martin int error; 60 1.1 cube 61 1.13 martin KASSERT(p->p_emul->e_ucsize == sizeof(*newuc)); 62 1.1 cube 63 1.14 christos newuc = kmem_alloc(sizeof(ucontext_t), KM_SLEEP); 64 1.13 martin error = copyin(SCARG_P32(uap, ucp), newuc, p->p_emul->e_ucsize); 65 1.13 martin if (error) 66 1.13 martin goto fail; 67 1.13 martin 68 1.13 martin /* validate the ucontext */ 69 1.13 martin if ((newuc->uc_flags & _UC_CPU) == 0) { 70 1.13 martin error = EINVAL; 71 1.13 martin goto fail; 72 1.13 martin } 73 1.13 martin error = cpu_mcontext32_validate(l, &newuc->uc_mcontext); 74 1.13 martin if (error) 75 1.13 martin goto fail; 76 1.13 martin 77 1.19 christos const sigset_t *sigmask = newuc->uc_flags & _UC_SIGMASK ? 78 1.19 christos &newuc->uc_sigmask : &l->l_sigmask; 79 1.19 christos 80 1.20 ad error = do_lwp_create(l, newuc, SCARG(uap, flags), &l2, sigmask, 81 1.19 christos &SS_INIT); 82 1.20 ad if (error != 0) 83 1.13 martin goto fail; 84 1.13 martin 85 1.20 ad error = copyout(&l2->l_lid, SCARG_P32(uap, new_lwp), 86 1.20 ad sizeof(l2->l_lid)); 87 1.21 ad if (error == 0) { 88 1.20 ad lwp_start(l2, SCARG(uap, flags)); 89 1.21 ad return 0; 90 1.21 ad } 91 1.21 ad lwp_exit(l2); 92 1.20 ad fail: 93 1.14 christos kmem_free(newuc, sizeof(ucontext_t)); 94 1.13 martin return error; 95 1.1 cube } 96 1.1 cube 97 1.1 cube int 98 1.9 dsl netbsd32__lwp_wait(struct lwp *l, const struct netbsd32__lwp_wait_args *uap, register_t *retval) 99 1.1 cube { 100 1.9 dsl /* { 101 1.1 cube syscallarg(lwpid_t) wait_for; 102 1.1 cube syscallarg(netbsd32_lwpidp) departed; 103 1.9 dsl } */ 104 1.1 cube struct sys__lwp_wait_args ua; 105 1.1 cube 106 1.1 cube NETBSD32TO64_UAP(wait_for); 107 1.1 cube NETBSD32TOP_UAP(departed, lwpid_t); 108 1.1 cube return sys__lwp_wait(l, &ua, retval); 109 1.1 cube } 110 1.1 cube 111 1.1 cube int 112 1.9 dsl netbsd32__lwp_suspend(struct lwp *l, const struct netbsd32__lwp_suspend_args *uap, register_t *retval) 113 1.1 cube { 114 1.9 dsl /* { 115 1.1 cube syscallarg(lwpid_t) target; 116 1.9 dsl } */ 117 1.1 cube struct sys__lwp_suspend_args ua; 118 1.1 cube 119 1.1 cube NETBSD32TO64_UAP(target); 120 1.1 cube return sys__lwp_suspend(l, &ua, retval); 121 1.1 cube } 122 1.1 cube 123 1.1 cube int 124 1.9 dsl netbsd32__lwp_continue(struct lwp *l, const struct netbsd32__lwp_continue_args *uap, register_t *retval) 125 1.1 cube { 126 1.9 dsl /* { 127 1.1 cube syscallarg(lwpid_t) target; 128 1.9 dsl } */ 129 1.1 cube struct sys__lwp_continue_args ua; 130 1.1 cube 131 1.1 cube NETBSD32TO64_UAP(target); 132 1.1 cube return sys__lwp_continue(l, &ua, retval); 133 1.1 cube } 134 1.1 cube 135 1.1 cube int 136 1.9 dsl netbsd32__lwp_wakeup(struct lwp *l, const struct netbsd32__lwp_wakeup_args *uap, register_t *retval) 137 1.1 cube { 138 1.9 dsl /* { 139 1.1 cube syscallarg(lwpid_t) target; 140 1.9 dsl } */ 141 1.1 cube struct sys__lwp_wakeup_args ua; 142 1.1 cube 143 1.1 cube NETBSD32TO64_UAP(target); 144 1.1 cube return sys__lwp_wakeup(l, &ua, retval); 145 1.1 cube } 146 1.1 cube 147 1.1 cube int 148 1.9 dsl netbsd32__lwp_setprivate(struct lwp *l, const struct netbsd32__lwp_setprivate_args *uap, register_t *retval) 149 1.1 cube { 150 1.9 dsl /* { 151 1.1 cube syscallarg(netbsd32_voidp) ptr; 152 1.9 dsl } */ 153 1.1 cube struct sys__lwp_setprivate_args ua; 154 1.1 cube 155 1.1 cube NETBSD32TOP_UAP(ptr, void); 156 1.1 cube return sys__lwp_setprivate(l, &ua, retval); 157 1.1 cube } 158 1.1 cube 159 1.1 cube int 160 1.15 christos netbsd32____lwp_park60(struct lwp *l, 161 1.15 christos const struct netbsd32____lwp_park60_args *uap, register_t *retval) 162 1.1 cube { 163 1.9 dsl /* { 164 1.15 christos syscallarg(const netbsd32_clockid_t) clock_id; 165 1.15 christos syscallarg(int) flags; 166 1.11 christos syscallarg(const netbsd32_timespec50p) ts; 167 1.15 christos syscallarg(netbsd32_lwpid_t) unpark; 168 1.1 cube syscallarg(netbsd32_voidp) hint; 169 1.6 ad syscallarg(netbsd32_voidp) unparkhint; 170 1.9 dsl } */ 171 1.6 ad struct timespec ts, *tsp; 172 1.5 dsl struct netbsd32_timespec ts32; 173 1.23 simonb int ret; 174 1.5 dsl int error; 175 1.1 cube 176 1.5 dsl if (SCARG_P32(uap, ts) == NULL) 177 1.6 ad tsp = NULL; 178 1.6 ad else { 179 1.6 ad error = copyin(SCARG_P32(uap, ts), &ts32, sizeof ts32); 180 1.6 ad if (error != 0) 181 1.6 ad return error; 182 1.6 ad netbsd32_to_timespec(&ts32, &ts); 183 1.6 ad tsp = &ts; 184 1.6 ad } 185 1.6 ad 186 1.6 ad if (SCARG(uap, unpark) != 0) { 187 1.22 ad error = lwp_unpark(&SCARG(uap, unpark), 1); 188 1.6 ad if (error != 0) 189 1.6 ad return error; 190 1.6 ad } 191 1.5 dsl 192 1.23 simonb ret = lwp_park(SCARG(uap, clock_id), SCARG(uap, flags), tsp); 193 1.23 simonb if (SCARG_P32(uap, ts) != NULL && (SCARG(uap, flags) & TIMER_ABSTIME) == 0) { 194 1.23 simonb netbsd32_from_timespec(&ts, &ts32); 195 1.23 simonb (void)copyout(&ts32, SCARG_P32(uap, ts), sizeof(ts32)); 196 1.23 simonb } 197 1.23 simonb return ret; 198 1.1 cube } 199 1.1 cube 200 1.1 cube int 201 1.9 dsl netbsd32__lwp_kill(struct lwp *l, const struct netbsd32__lwp_kill_args *uap, register_t *retval) 202 1.1 cube { 203 1.9 dsl /* { 204 1.1 cube syscallarg(lwpid_t) target; 205 1.1 cube syscallarg(int) signo; 206 1.9 dsl } */ 207 1.1 cube struct sys__lwp_kill_args ua; 208 1.1 cube 209 1.1 cube NETBSD32TO64_UAP(target); 210 1.1 cube NETBSD32TO64_UAP(signo); 211 1.1 cube return sys__lwp_kill(l, &ua, retval); 212 1.1 cube } 213 1.1 cube int 214 1.9 dsl netbsd32__lwp_detach(struct lwp *l, const struct netbsd32__lwp_detach_args *uap, register_t *retval) 215 1.1 cube { 216 1.9 dsl /* { 217 1.1 cube syscallarg(lwpid_t) target; 218 1.9 dsl } */ 219 1.1 cube struct sys__lwp_detach_args ua; 220 1.1 cube 221 1.1 cube NETBSD32TO64_UAP(target); 222 1.1 cube return sys__lwp_detach(l, &ua, retval); 223 1.1 cube } 224 1.1 cube 225 1.1 cube int 226 1.9 dsl netbsd32__lwp_unpark(struct lwp *l, const struct netbsd32__lwp_unpark_args *uap, register_t *retval) 227 1.1 cube { 228 1.9 dsl /* { 229 1.1 cube syscallarg(lwpid_t) target; 230 1.1 cube syscallarg(netbsd32_voidp) hint; 231 1.9 dsl } */ 232 1.1 cube struct sys__lwp_unpark_args ua; 233 1.1 cube 234 1.1 cube NETBSD32TO64_UAP(target); 235 1.1 cube NETBSD32TOP_UAP(hint, void); 236 1.1 cube return sys__lwp_unpark(l, &ua, retval); 237 1.1 cube } 238 1.1 cube 239 1.1 cube int 240 1.9 dsl netbsd32__lwp_unpark_all(struct lwp *l, const struct netbsd32__lwp_unpark_all_args *uap, register_t *retval) 241 1.1 cube { 242 1.9 dsl /* { 243 1.1 cube syscallarg(const netbsd32_lwpidp) targets; 244 1.1 cube syscallarg(netbsd32_size_t) ntargets; 245 1.1 cube syscallarg(netbsd32_voidp) hint; 246 1.9 dsl } */ 247 1.1 cube struct sys__lwp_unpark_all_args ua; 248 1.1 cube 249 1.1 cube NETBSD32TOP_UAP(targets, const lwpid_t); 250 1.1 cube NETBSD32TOX_UAP(ntargets, size_t); 251 1.1 cube NETBSD32TOP_UAP(hint, void); 252 1.1 cube return sys__lwp_unpark_all(l, &ua, retval); 253 1.1 cube } 254 1.8 ad 255 1.8 ad int 256 1.9 dsl netbsd32__lwp_setname(struct lwp *l, const struct netbsd32__lwp_setname_args *uap, register_t *retval) 257 1.8 ad { 258 1.9 dsl /* { 259 1.8 ad syscallarg(lwpid_t) target; 260 1.8 ad syscallarg(const netbsd32_charp) name; 261 1.9 dsl } */ 262 1.8 ad struct sys__lwp_setname_args ua; 263 1.8 ad 264 1.8 ad NETBSD32TO64_UAP(target); 265 1.8 ad NETBSD32TOP_UAP(name, char *); 266 1.8 ad return sys__lwp_setname(l, &ua, retval); 267 1.8 ad } 268 1.8 ad 269 1.8 ad int 270 1.9 dsl netbsd32__lwp_getname(struct lwp *l, const struct netbsd32__lwp_getname_args *uap, register_t *retval) 271 1.8 ad { 272 1.9 dsl /* { 273 1.8 ad syscallarg(lwpid_t) target; 274 1.8 ad syscallarg(netbsd32_charp) name; 275 1.8 ad syscallarg(netbsd32_size_t) len; 276 1.9 dsl } */ 277 1.8 ad struct sys__lwp_getname_args ua; 278 1.8 ad 279 1.8 ad NETBSD32TO64_UAP(target); 280 1.8 ad NETBSD32TOP_UAP(name, char *); 281 1.8 ad NETBSD32TOX_UAP(len, size_t); 282 1.8 ad return sys__lwp_getname(l, &ua, retval); 283 1.8 ad } 284 1.8 ad 285 1.8 ad int 286 1.9 dsl netbsd32__lwp_ctl(struct lwp *l, const struct netbsd32__lwp_ctl_args *uap, register_t *retval) 287 1.8 ad { 288 1.9 dsl /* { 289 1.8 ad syscallarg(int) features; 290 1.8 ad syscallarg(netbsd32_pointer_t) address; 291 1.9 dsl } */ 292 1.17 matt netbsd32_pointer_t vaddr32; 293 1.16 matt int error, features; 294 1.16 matt vaddr_t vaddr; 295 1.8 ad 296 1.16 matt features = SCARG(uap, features); 297 1.16 matt features &= ~(LWPCTL_FEATURE_CURCPU | LWPCTL_FEATURE_PCTR); 298 1.16 matt if (features != 0) 299 1.16 matt return ENODEV; 300 1.16 matt if ((error = lwp_ctl_alloc(&vaddr)) != 0) 301 1.16 matt return error; 302 1.17 matt NETBSD32PTR32(vaddr32, (void *)vaddr); 303 1.18 matt return copyout(&vaddr32, SCARG_P32(uap, address), sizeof(vaddr32)); 304 1.8 ad } 305