1 1.34 riastrad /* $NetBSD: linux_machdep.c,v 1.34 2021/09/07 11:43:04 riastradh Exp $ */ 2 1.1 bjh21 3 1.1 bjh21 /*- 4 1.1 bjh21 * Copyright (c) 1995, 2000 The NetBSD Foundation, Inc. 5 1.1 bjh21 * All rights reserved. 6 1.1 bjh21 * 7 1.1 bjh21 * This code is derived from software contributed to The NetBSD Foundation 8 1.1 bjh21 * by Frank van der Linden. 9 1.1 bjh21 * 10 1.1 bjh21 * Redistribution and use in source and binary forms, with or without 11 1.1 bjh21 * modification, are permitted provided that the following conditions 12 1.1 bjh21 * are met: 13 1.1 bjh21 * 1. Redistributions of source code must retain the above copyright 14 1.1 bjh21 * notice, this list of conditions and the following disclaimer. 15 1.1 bjh21 * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 bjh21 * notice, this list of conditions and the following disclaimer in the 17 1.1 bjh21 * documentation and/or other materials provided with the distribution. 18 1.1 bjh21 * 19 1.1 bjh21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 bjh21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 bjh21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 bjh21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 bjh21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 bjh21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 bjh21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 bjh21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 bjh21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 bjh21 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 bjh21 * POSSIBILITY OF SUCH DAMAGE. 30 1.1 bjh21 */ 31 1.1 bjh21 32 1.22 hubertf #include <sys/cdefs.h> 33 1.1 bjh21 34 1.34 riastrad __KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.34 2021/09/07 11:43:04 riastradh Exp $"); 35 1.1 bjh21 36 1.1 bjh21 #include <sys/param.h> 37 1.1 bjh21 #include <sys/systm.h> 38 1.1 bjh21 #include <sys/signalvar.h> 39 1.1 bjh21 #include <sys/kernel.h> 40 1.1 bjh21 #include <sys/proc.h> 41 1.1 bjh21 #include <sys/buf.h> 42 1.1 bjh21 #include <sys/reboot.h> 43 1.1 bjh21 #include <sys/conf.h> 44 1.1 bjh21 #include <sys/exec.h> 45 1.1 bjh21 #include <sys/file.h> 46 1.1 bjh21 #include <sys/callout.h> 47 1.1 bjh21 #include <sys/mbuf.h> 48 1.1 bjh21 #include <sys/msgbuf.h> 49 1.1 bjh21 #include <sys/mount.h> 50 1.1 bjh21 #include <sys/vnode.h> 51 1.1 bjh21 #include <sys/device.h> 52 1.1 bjh21 #include <sys/syscallargs.h> 53 1.1 bjh21 #include <sys/filedesc.h> 54 1.1 bjh21 #include <sys/exec_elf.h> 55 1.1 bjh21 #include <sys/disklabel.h> 56 1.1 bjh21 #include <sys/ioctl.h> 57 1.31 matt 58 1.1 bjh21 #include <miscfs/specfs/specdev.h> 59 1.1 bjh21 60 1.1 bjh21 #include <compat/linux/common/linux_types.h> 61 1.1 bjh21 #include <compat/linux/common/linux_signal.h> 62 1.1 bjh21 #include <compat/linux/common/linux_util.h> 63 1.1 bjh21 #include <compat/linux/common/linux_ioctl.h> 64 1.1 bjh21 #include <compat/linux/common/linux_hdio.h> 65 1.1 bjh21 #include <compat/linux/common/linux_exec.h> 66 1.1 bjh21 #include <compat/linux/common/linux_machdep.h> 67 1.1 bjh21 #include <compat/linux/linux_syscallargs.h> 68 1.1 bjh21 69 1.31 matt #include <arm/locore.h> 70 1.31 matt 71 1.1 bjh21 void 72 1.29 chs linux_setregs(struct lwp *l, struct exec_package *epp, vaddr_t stack) 73 1.1 bjh21 { 74 1.1 bjh21 75 1.11 thorpej setregs(l, epp, stack); 76 1.1 bjh21 } 77 1.1 bjh21 78 1.1 bjh21 void 79 1.13 matt linux_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) 80 1.1 bjh21 { 81 1.30 matt struct lwp * const l = curlwp; 82 1.30 matt struct proc * const p = l->l_proc; 83 1.30 matt struct trapframe * const tf = lwp_trapframe(l); 84 1.2 bjh21 struct linux_sigframe *fp, frame; 85 1.19 ad int onstack, error; 86 1.13 matt const int sig = ksi->ksi_signo; 87 1.9 thorpej sig_t catcher = SIGACTION(p, sig).sa_handler; 88 1.2 bjh21 89 1.2 bjh21 90 1.2 bjh21 /* 91 1.2 bjh21 * The Linux version of this code is in 92 1.2 bjh21 * linux/arch/arm/kernel/signal.c. 93 1.2 bjh21 */ 94 1.2 bjh21 95 1.2 bjh21 /* Do we need to jump onto the signal stack? */ 96 1.2 bjh21 onstack = 97 1.19 ad (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && 98 1.2 bjh21 (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; 99 1.2 bjh21 100 1.2 bjh21 /* Allocate space for the signal handler context. */ 101 1.2 bjh21 if (onstack) 102 1.21 christos fp = (struct linux_sigframe *)((char *)l->l_sigstk.ss_sp + 103 1.19 ad l->l_sigstk.ss_size); 104 1.2 bjh21 else 105 1.2 bjh21 fp = (struct linux_sigframe *)tf->tf_usr_sp; 106 1.2 bjh21 fp--; 107 1.2 bjh21 108 1.2 bjh21 /* Build stack frame for signal trampoline. */ 109 1.2 bjh21 110 1.34 riastrad memset(&frame, 0, sizeof(frame)); 111 1.34 riastrad 112 1.2 bjh21 /* Save register context. */ 113 1.2 bjh21 frame.sf_sc.sc_r0 = tf->tf_r0; 114 1.2 bjh21 frame.sf_sc.sc_r1 = tf->tf_r1; 115 1.2 bjh21 frame.sf_sc.sc_r2 = tf->tf_r2; 116 1.2 bjh21 frame.sf_sc.sc_r3 = tf->tf_r3; 117 1.2 bjh21 frame.sf_sc.sc_r4 = tf->tf_r4; 118 1.2 bjh21 frame.sf_sc.sc_r5 = tf->tf_r5; 119 1.2 bjh21 frame.sf_sc.sc_r6 = tf->tf_r6; 120 1.2 bjh21 frame.sf_sc.sc_r7 = tf->tf_r7; 121 1.2 bjh21 frame.sf_sc.sc_r8 = tf->tf_r8; 122 1.2 bjh21 frame.sf_sc.sc_r9 = tf->tf_r9; 123 1.2 bjh21 frame.sf_sc.sc_r10 = tf->tf_r10; 124 1.2 bjh21 frame.sf_sc.sc_r11 = tf->tf_r11; 125 1.2 bjh21 frame.sf_sc.sc_r12 = tf->tf_r12; 126 1.2 bjh21 frame.sf_sc.sc_sp = tf->tf_usr_sp; 127 1.2 bjh21 frame.sf_sc.sc_lr = tf->tf_usr_lr; 128 1.2 bjh21 frame.sf_sc.sc_pc = tf->tf_pc; 129 1.2 bjh21 frame.sf_sc.sc_cpsr = tf->tf_spsr; 130 1.2 bjh21 131 1.2 bjh21 /* Save signal stack. */ 132 1.2 bjh21 /* Linux doesn't save the onstack flag in sigframe */ 133 1.2 bjh21 134 1.2 bjh21 /* Save signal mask. */ 135 1.6 bjh21 native_to_linux_old_extra_sigset(&frame.sf_sc.sc_mask, 136 1.6 bjh21 frame.sf_extramask, mask); 137 1.2 bjh21 138 1.2 bjh21 /* Other state (mostly faked) */ 139 1.2 bjh21 /* 140 1.2 bjh21 * trapno should indicate the trap that caused the signal: 141 1.2 bjh21 * 6 -> undefined instruction 142 1.2 bjh21 * 11 -> address exception 143 1.2 bjh21 * 14 -> data/prefetch abort 144 1.2 bjh21 */ 145 1.2 bjh21 frame.sf_sc.sc_trapno = 0; 146 1.2 bjh21 frame.sf_sc.sc_error_code = 0; 147 1.13 matt frame.sf_sc.sc_fault_address = (u_int32_t) ksi->ksi_addr; 148 1.19 ad sendsig_reset(l, sig); 149 1.2 bjh21 150 1.26 ad mutex_exit(p->p_lock); 151 1.19 ad error = copyout(&frame, fp, sizeof(frame)); 152 1.26 ad mutex_enter(p->p_lock); 153 1.19 ad 154 1.19 ad if (error != 0) { 155 1.2 bjh21 /* 156 1.2 bjh21 * Process has trashed its stack; give it an illegal 157 1.2 bjh21 * instruction to halt it in its tracks. 158 1.2 bjh21 */ 159 1.11 thorpej sigexit(l, SIGILL); 160 1.2 bjh21 /* NOTREACHED */ 161 1.2 bjh21 } 162 1.2 bjh21 /* 163 1.2 bjh21 * Build context to run handler in. 164 1.2 bjh21 */ 165 1.7 christos tf->tf_r0 = native_to_linux_signo[sig]; 166 1.2 bjh21 tf->tf_r1 = 0; /* XXX Should be a siginfo_t */ 167 1.2 bjh21 tf->tf_r2 = 0; 168 1.2 bjh21 tf->tf_r3 = (register_t)catcher; 169 1.2 bjh21 tf->tf_usr_sp = (register_t)fp; 170 1.2 bjh21 tf->tf_pc = (register_t)p->p_sigctx.ps_sigcode; 171 1.2 bjh21 172 1.2 bjh21 /* Remember that we're now on the signal stack. */ 173 1.2 bjh21 if (onstack) 174 1.19 ad l->l_sigstk.ss_flags |= SS_ONSTACK; 175 1.1 bjh21 176 1.1 bjh21 } 177 1.5 bjh21 178 1.5 bjh21 #if 0 179 1.1 bjh21 /* 180 1.1 bjh21 * System call to cleanup state after a signal 181 1.1 bjh21 * has been taken. Reset signal mask and 182 1.1 bjh21 * stack state from context left by sendsig (above). 183 1.1 bjh21 * Return to previous pc and psl as specified by 184 1.1 bjh21 * context left by sendsig. Check carefully to 185 1.1 bjh21 * make sure that the user has not modified the 186 1.1 bjh21 * psl to gain improper privileges or to cause 187 1.1 bjh21 * a machine fault. 188 1.1 bjh21 */ 189 1.1 bjh21 int 190 1.23 dsl linux_sys_rt_sigreturn(struct proc *p, void *v, register_t *retval) 191 1.1 bjh21 { 192 1.1 bjh21 /* XXX XAX write me */ 193 1.1 bjh21 return(ENOSYS); 194 1.1 bjh21 } 195 1.5 bjh21 #endif 196 1.1 bjh21 197 1.1 bjh21 int 198 1.25 matt linux_sys_sigreturn(struct lwp *l, const struct linux_sys_sigreturn_args *v, 199 1.25 matt register_t *retval) 200 1.1 bjh21 { 201 1.30 matt struct trapframe * const tf = lwp_trapframe(l); 202 1.30 matt struct proc * const p = l->l_proc; 203 1.2 bjh21 struct linux_sigframe *sfp, frame; 204 1.2 bjh21 sigset_t mask; 205 1.2 bjh21 206 1.2 bjh21 /* 207 1.2 bjh21 * The trampoline code hands us the context. 208 1.2 bjh21 * It is unsafe to keep track of it ourselves, in the event that a 209 1.2 bjh21 * program jumps out of a signal handler. 210 1.2 bjh21 */ 211 1.2 bjh21 sfp = (struct linux_sigframe *)tf->tf_usr_sp; 212 1.20 christos if (copyin((void *)sfp, &frame, sizeof(*sfp)) != 0) 213 1.2 bjh21 return (EFAULT); 214 1.2 bjh21 215 1.2 bjh21 /* 216 1.2 bjh21 * Make sure the processor mode has not been tampered with and 217 1.2 bjh21 * interrupts have not been disabled. 218 1.2 bjh21 */ 219 1.33 skrll if (!VALID_PSR(frame.sf_sc.sc_cpsr)) 220 1.2 bjh21 return EINVAL; 221 1.2 bjh21 222 1.2 bjh21 /* Restore register context. */ 223 1.2 bjh21 tf->tf_r0 = frame.sf_sc.sc_r0; 224 1.2 bjh21 tf->tf_r1 = frame.sf_sc.sc_r1; 225 1.2 bjh21 tf->tf_r2 = frame.sf_sc.sc_r2; 226 1.2 bjh21 tf->tf_r3 = frame.sf_sc.sc_r3; 227 1.2 bjh21 tf->tf_r4 = frame.sf_sc.sc_r4; 228 1.2 bjh21 tf->tf_r5 = frame.sf_sc.sc_r5; 229 1.2 bjh21 tf->tf_r6 = frame.sf_sc.sc_r6; 230 1.2 bjh21 tf->tf_r7 = frame.sf_sc.sc_r7; 231 1.2 bjh21 tf->tf_r8 = frame.sf_sc.sc_r8; 232 1.2 bjh21 tf->tf_r9 = frame.sf_sc.sc_r9; 233 1.2 bjh21 tf->tf_r10 = frame.sf_sc.sc_r10; 234 1.2 bjh21 tf->tf_r11 = frame.sf_sc.sc_r11; 235 1.2 bjh21 tf->tf_r12 = frame.sf_sc.sc_r12; 236 1.2 bjh21 tf->tf_usr_sp = frame.sf_sc.sc_sp; 237 1.2 bjh21 tf->tf_usr_lr = frame.sf_sc.sc_lr; 238 1.2 bjh21 tf->tf_pc = frame.sf_sc.sc_pc; 239 1.2 bjh21 tf->tf_spsr = frame.sf_sc.sc_cpsr; 240 1.2 bjh21 241 1.26 ad mutex_enter(p->p_lock); 242 1.19 ad 243 1.2 bjh21 /* Restore signal stack. */ 244 1.19 ad l->l_sigstk.ss_flags &= ~SS_ONSTACK; 245 1.2 bjh21 246 1.2 bjh21 /* Restore signal mask. */ 247 1.6 bjh21 linux_old_extra_to_native_sigset(&mask, &frame.sf_sc.sc_mask, 248 1.6 bjh21 frame.sf_extramask); 249 1.19 ad (void) sigprocmask1(l, SIG_SETMASK, &mask, 0); 250 1.19 ad 251 1.26 ad mutex_exit(p->p_lock); 252 1.1 bjh21 253 1.2 bjh21 return (EJUSTRETURN); 254 1.1 bjh21 } 255 1.1 bjh21 256 1.14 perry /* 257 1.1 bjh21 * major device numbers remapping 258 1.1 bjh21 */ 259 1.1 bjh21 dev_t 260 1.23 dsl linux_fakedev(dev_t dev, int raw) 261 1.1 bjh21 { 262 1.8 jdolecek /* XXX write me */ 263 1.8 jdolecek return dev; 264 1.1 bjh21 } 265 1.1 bjh21 266 1.1 bjh21 /* 267 1.1 bjh21 * We come here in a last attempt to satisfy a Linux ioctl() call 268 1.1 bjh21 */ 269 1.1 bjh21 int 270 1.24 dsl linux_machdepioctl(struct lwp *l, const struct linux_sys_ioctl_args *uap, register_t *retval) 271 1.14 perry { 272 1.24 dsl /* { 273 1.1 bjh21 syscallarg(int) fd; 274 1.1 bjh21 syscallarg(u_long) com; 275 1.20 christos syscallarg(void *) data; 276 1.24 dsl } */ 277 1.1 bjh21 struct sys_ioctl_args bia; 278 1.1 bjh21 u_long com; 279 1.14 perry 280 1.1 bjh21 SCARG(&bia, fd) = SCARG(uap, fd); 281 1.1 bjh21 SCARG(&bia, data) = SCARG(uap, data); 282 1.1 bjh21 com = SCARG(uap, com); 283 1.14 perry 284 1.1 bjh21 switch (com) { 285 1.1 bjh21 default: 286 1.1 bjh21 printf("linux_machdepioctl: invalid ioctl %08lx\n", com); 287 1.1 bjh21 return EINVAL; 288 1.1 bjh21 } 289 1.1 bjh21 SCARG(&bia, com) = com; 290 1.17 christos 291 1.17 christos return sys_ioctl(l, &bia, retval); 292 1.1 bjh21 } 293 1.15 fvdl 294 1.15 fvdl int 295 1.15 fvdl linux_usertrap(struct lwp *l, vaddr_t trapaddr, void *arg) 296 1.15 fvdl { 297 1.15 fvdl return 0; 298 1.15 fvdl } 299