1 /* $NetBSD: linux_machdep.c,v 1.35 2007/10/19 12:16:38 ad Exp $ */ 2 3 /*- 4 * Copyright (c) 1995, 2000, 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Frank van der Linden and Emmanuel Dreyfus. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <sys/cdefs.h> 40 __KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.35 2007/10/19 12:16:38 ad Exp $"); 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/signalvar.h> 45 #include <sys/kernel.h> 46 #include <sys/proc.h> 47 #include <sys/user.h> 48 #include <sys/buf.h> 49 #include <sys/reboot.h> 50 #include <sys/conf.h> 51 #include <sys/exec.h> 52 #include <sys/file.h> 53 #include <sys/callout.h> 54 #include <sys/malloc.h> 55 #include <sys/mbuf.h> 56 #include <sys/msgbuf.h> 57 #include <sys/mount.h> 58 #include <sys/vnode.h> 59 #include <sys/device.h> 60 #include <sys/syscallargs.h> 61 #include <sys/filedesc.h> 62 #include <sys/exec_elf.h> 63 #include <sys/disklabel.h> 64 #include <sys/ioctl.h> 65 #include <miscfs/specfs/specdev.h> 66 67 #include <compat/linux/common/linux_types.h> 68 #include <compat/linux/common/linux_signal.h> 69 #include <compat/linux/common/linux_util.h> 70 #include <compat/linux/common/linux_ioctl.h> 71 #include <compat/linux/common/linux_hdio.h> 72 #include <compat/linux/common/linux_exec.h> 73 #include <compat/linux/common/linux_machdep.h> 74 75 #include <compat/linux/linux_syscallargs.h> 76 77 #include <sys/cpu.h> 78 #include <machine/fpu.h> 79 #include <machine/psl.h> 80 #include <machine/reg.h> 81 #include <machine/vmparam.h> 82 83 /* 84 * To see whether wscons is configured (for virtual console ioctl calls). 85 */ 86 #if defined(_KERNEL_OPT) 87 #include "wsdisplay.h" 88 #endif 89 #if (NWSDISPLAY > 0) 90 #include <dev/wscons/wsconsio.h> 91 #include <dev/wscons/wsdisplay_usl_io.h> 92 #endif 93 94 /* 95 * Set set up registers on exec. 96 * XXX not used at the moment since in sys/kern/exec_conf, LINUX_COMPAT 97 * entry uses NetBSD's native setregs instead of linux_setregs 98 */ 99 void 100 linux_setregs(l, pack, stack) 101 struct lwp *l; 102 struct exec_package *pack; 103 u_long stack; 104 { 105 setregs(l, pack, stack); 106 } 107 108 /* 109 * Send an interrupt to process. 110 * 111 * Adapted from arch/powerpc/powerpc/sig_machdep.c:sendsig and 112 * compat/linux/arch/i386/linux_machdep.c:linux_sendsig 113 * 114 * XXX Does not work well yet with RT signals 115 * 116 */ 117 118 void 119 linux_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) 120 { 121 const int sig = ksi->ksi_signo; 122 struct lwp *l = curlwp; 123 struct proc *p = l->l_proc; 124 struct trapframe *tf; 125 sig_t catcher = SIGACTION(p, sig).sa_handler; 126 struct linux_sigregs frame; 127 struct linux_pt_regs linux_regs; 128 struct linux_sigcontext sc; 129 register_t fp; 130 int onstack, error; 131 int i; 132 133 tf = trapframe(l); 134 135 /* 136 * Do we need to jump onto the signal stack? 137 */ 138 onstack = 139 (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && 140 (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; 141 142 /* 143 * Signal stack is broken (see at the end of linux_sigreturn), so we do 144 * not use it yet. XXX fix this. 145 */ 146 onstack=0; 147 148 /* 149 * Allocate space for the signal handler context. 150 */ 151 if (onstack) { 152 fp = (register_t) 153 ((char *)l->l_sigstk.ss_sp + 154 l->l_sigstk.ss_size); 155 } else { 156 fp = tf->fixreg[1]; 157 } 158 #ifdef DEBUG_LINUX 159 printf("fp at start of linux_sendsig = %x\n", fp); 160 #endif 161 fp -= sizeof(struct linux_sigregs); 162 fp &= ~0xf; 163 164 /* 165 * Prepare a sigcontext for later. 166 */ 167 memset(&sc, 0, sizeof sc); 168 sc.lsignal = (int)native_to_linux_signo[sig]; 169 sc.lhandler = (unsigned long)catcher; 170 native_to_linux_old_extra_sigset(&sc.lmask, &sc._unused[3], mask); 171 sc.lregs = (struct linux_pt_regs*)fp; 172 173 /* 174 * Setup the signal stack frame as Linux does it in 175 * arch/ppc/kernel/signal.c:setup_frame() 176 * 177 * Save register context. 178 */ 179 for (i = 0; i < 32; i++) 180 linux_regs.lgpr[i] = tf->fixreg[i]; 181 linux_regs.lnip = tf->srr0; 182 linux_regs.lmsr = tf->srr1 & PSL_USERSRR1; 183 linux_regs.lorig_gpr3 = tf->fixreg[3]; /* XXX Is that right? */ 184 linux_regs.lctr = tf->ctr; 185 linux_regs.llink = tf->lr; 186 linux_regs.lxer = tf->xer; 187 linux_regs.lccr = tf->cr; 188 linux_regs.lmq = 0; /* Unused, 601 only */ 189 linux_regs.ltrap = tf->exc; 190 linux_regs.ldar = tf->dar; 191 linux_regs.ldsisr = tf->dsisr; 192 linux_regs.lresult = 0; 193 194 memset(&frame, 0, sizeof(frame)); 195 memcpy(&frame.lgp_regs, &linux_regs, sizeof(linux_regs)); 196 197 save_fpu_lwp(curlwp, FPU_SAVE); 198 memcpy(&frame.lfp_regs, curpcb->pcb_fpu.fpreg, sizeof(frame.lfp_regs)); 199 200 /* 201 * Copy Linux's signal trampoline on the user stack It should not 202 * be used, but Linux binaries might expect it to be there. 203 */ 204 frame.ltramp[0] = 0x38997777; /* li r0, 0x7777 */ 205 frame.ltramp[1] = 0x44000002; /* sc */ 206 207 /* 208 * Move it to the user stack 209 * There is a little trick here, about the LINUX_ABIGAP: the 210 * linux_sigreg structure has a 56 int gap to support rs6000/xcoff 211 * binaries. But the Linux kernel seems to do without it, and it 212 * just skip it when building the stack frame. Hence the LINUX_ABIGAP. 213 */ 214 sendsig_reset(l, sig); 215 mutex_exit(&p->p_smutex); 216 error = copyout(&frame, (void *)fp, sizeof (frame) - LINUX_ABIGAP); 217 218 if (error != 0) { 219 /* 220 * Process has trashed its stack; give it an illegal 221 * instruction to halt it in its tracks. 222 */ 223 mutex_enter(&p->p_smutex); 224 sigexit(l, SIGILL); 225 /* NOTREACHED */ 226 } 227 228 /* 229 * Add a sigcontext on the stack 230 */ 231 fp -= sizeof(struct linux_sigcontext); 232 error = copyout(&sc, (void *)fp, sizeof (struct linux_sigcontext)); 233 mutex_enter(&p->p_smutex); 234 235 if (error != 0) { 236 /* 237 * Process has trashed its stack; give it an illegal 238 * instruction to halt it in its tracks. 239 */ 240 sigexit(l, SIGILL); 241 /* NOTREACHED */ 242 } 243 244 /* 245 * Set the registers according to how the Linux process expects them. 246 * "Mind the gap" Linux expects a gap here. 247 */ 248 tf->fixreg[1] = fp - LINUX__SIGNAL_FRAMESIZE; 249 tf->lr = (int)catcher; 250 tf->fixreg[3] = (int)native_to_linux_signo[sig]; 251 tf->fixreg[4] = fp; 252 tf->srr0 = (int)p->p_sigctx.ps_sigcode; 253 254 #ifdef DEBUG_LINUX 255 printf("fp at end of linux_sendsig = %x\n", fp); 256 #endif 257 /* 258 * Remember that we're now on the signal stack. 259 */ 260 if (onstack) 261 l->l_sigstk.ss_flags |= SS_ONSTACK; 262 #ifdef DEBUG_LINUX 263 printf("linux_sendsig: exitting. fp=0x%lx\n",(long)fp); 264 #endif 265 } 266 267 /* 268 * System call to cleanup state after a signal 269 * has been taken. Reset signal mask and 270 * stack state from context left by sendsig (above). 271 * Return to previous pc and psl as specified by 272 * context left by sendsig. Check carefully to 273 * make sure that the user has not modified the 274 * psl to gain improper privileges or to cause 275 * a machine fault. 276 * 277 * XXX not tested 278 */ 279 int 280 linux_sys_rt_sigreturn(l, v, retval) 281 struct lwp *l; 282 void *v; 283 register_t *retval; 284 { 285 struct linux_sys_rt_sigreturn_args /* { 286 syscallarg(struct linux_rt_sigframe *) sfp; 287 } */ *uap = v; 288 struct proc *p = l->l_proc; 289 struct linux_rt_sigframe *scp, sigframe; 290 struct linux_sigregs sregs; 291 struct linux_pt_regs *lregs; 292 struct trapframe *tf; 293 sigset_t mask; 294 int i; 295 296 /* 297 * The trampoline code hands us the context. 298 * It is unsafe to keep track of it ourselves, in the event that a 299 * program jumps out of a signal handler. 300 */ 301 scp = SCARG(uap, sfp); 302 303 /* 304 * Get the context from user stack 305 */ 306 if (copyin((void *)scp, &sigframe, sizeof(*scp))) 307 return (EFAULT); 308 309 /* 310 * Restore register context. 311 */ 312 if (copyin((void *)sigframe.luc.luc_context.lregs, 313 &sregs, sizeof(sregs))) 314 return (EFAULT); 315 lregs = (struct linux_pt_regs *)&sregs.lgp_regs; 316 317 tf = trapframe(l); 318 #ifdef DEBUG_LINUX 319 (unsigned long)tf, (unsigned long)scp); 320 #endif 321 322 if (!PSL_USEROK_P(lregs->lmsr)) 323 return (EINVAL); 324 325 for (i = 0; i < 32; i++) 326 tf->fixreg[i] = lregs->lgpr[i]; 327 tf->lr = lregs->llink; 328 tf->cr = lregs->lccr; 329 tf->xer = lregs->lxer; 330 tf->ctr = lregs->lctr; 331 tf->srr0 = lregs->lnip; 332 tf->srr1 = lregs->lmsr; 333 334 /* 335 * Make sure the fpu state is discarded 336 */ 337 save_fpu_lwp(curlwp, FPU_DISCARD); 338 339 memcpy(curpcb->pcb_fpu.fpreg, (void *)&sregs.lfp_regs, 340 sizeof(curpcb->pcb_fpu.fpreg)); 341 342 mutex_enter(&p->p_smutex); 343 344 /* 345 * Restore signal stack. 346 * 347 * XXX cannot find the onstack information in Linux sig context. 348 * Is signal stack really supported on Linux? 349 * 350 * It seems to be supported in libc6... 351 */ 352 /* if (sc.sc_onstack & SS_ONSTACK) 353 l->l_sigstk.ss_flags |= SS_ONSTACK; 354 else */ 355 l->l_sigstk.ss_flags &= ~SS_ONSTACK; 356 357 /* 358 * Grab the signal mask 359 */ 360 linux_to_native_sigset(&mask, &sigframe.luc.luc_sigmask); 361 (void) sigprocmask1(l, SIG_SETMASK, &mask, 0); 362 363 mutex_exit(&p->p_smutex); 364 365 return (EJUSTRETURN); 366 } 367 368 369 /* 370 * The following needs code review for potential security issues 371 */ 372 int 373 linux_sys_sigreturn(l, v, retval) 374 struct lwp *l; 375 void *v; 376 register_t *retval; 377 { 378 struct linux_sys_sigreturn_args /* { 379 syscallarg(struct linux_sigcontext *) scp; 380 } */ *uap = v; 381 struct proc *p = l->l_proc; 382 struct linux_sigcontext *scp, context; 383 struct linux_sigregs sregs; 384 struct linux_pt_regs *lregs; 385 struct trapframe *tf; 386 sigset_t mask; 387 int i; 388 389 /* 390 * The trampoline code hands us the context. 391 * It is unsafe to keep track of it ourselves, in the event that a 392 * program jumps out of a signal handler. 393 */ 394 scp = SCARG(uap, scp); 395 396 /* 397 * Get the context from user stack 398 */ 399 if (copyin(scp, &context, sizeof(*scp))) 400 return (EFAULT); 401 402 /* 403 * Restore register context. 404 */ 405 if (copyin((void *)context.lregs, &sregs, sizeof(sregs))) 406 return (EFAULT); 407 lregs = (struct linux_pt_regs *)&sregs.lgp_regs; 408 409 tf = trapframe(l); 410 #ifdef DEBUG_LINUX 411 printf("linux_sys_sigreturn: trapframe=0x%lx scp=0x%lx\n", 412 (unsigned long)tf, (unsigned long)scp); 413 #endif 414 415 if (!PSL_USEROK_P(lregs->lmsr)) 416 return (EINVAL); 417 418 for (i = 0; i < 32; i++) 419 tf->fixreg[i] = lregs->lgpr[i]; 420 tf->lr = lregs->llink; 421 tf->cr = lregs->lccr; 422 tf->xer = lregs->lxer; 423 tf->ctr = lregs->lctr; 424 tf->srr0 = lregs->lnip; 425 tf->srr1 = lregs->lmsr; 426 427 /* 428 * Make sure the fpu state is discarded 429 */ 430 save_fpu_lwp(curlwp, FPU_DISCARD); 431 432 memcpy(curpcb->pcb_fpu.fpreg, (void *)&sregs.lfp_regs, 433 sizeof(curpcb->pcb_fpu.fpreg)); 434 435 mutex_enter(&p->p_smutex); 436 437 /* 438 * Restore signal stack. 439 * 440 * XXX cannot find the onstack information in Linux sig context. 441 * Is signal stack really supported on Linux? 442 */ 443 #if 0 444 if (sc.sc_onstack & SS_ONSTACK) 445 l->l_sigstk.ss_flags |= SS_ONSTACK; 446 else 447 #endif 448 l->l_sigstk.ss_flags &= ~SS_ONSTACK; 449 450 /* Restore signal mask. */ 451 linux_old_extra_to_native_sigset(&mask, &context.lmask, 452 &context._unused[3]); 453 (void) sigprocmask1(l, SIG_SETMASK, &mask, 0); 454 455 mutex_exit(&p->p_smutex); 456 457 return (EJUSTRETURN); 458 } 459 460 461 #if 0 462 int 463 linux_sys_modify_ldt(p, v, retval) 464 struct proc *p; 465 void *v; 466 register_t *retval; 467 { 468 /* 469 * This syscall is not implemented in Linux/PowerPC: we should not 470 * be here 471 */ 472 #ifdef DEBUG_LINUX 473 printf("linux_sys_modify_ldt: should not be here.\n"); 474 #endif 475 return 0; 476 } 477 #endif 478 479 /* 480 * major device numbers remapping 481 */ 482 dev_t 483 linux_fakedev(dev, raw) 484 dev_t dev; 485 int raw; 486 { 487 /* XXX write me */ 488 return dev; 489 } 490 491 /* 492 * We come here in a last attempt to satisfy a Linux ioctl() call 493 */ 494 int 495 linux_machdepioctl(l, v, retval) 496 struct lwp *l; 497 void *v; 498 register_t *retval; 499 { 500 struct linux_sys_ioctl_args /* { 501 syscallarg(int) fd; 502 syscallarg(u_long) com; 503 syscallarg(void *) data; 504 } */ *uap = v; 505 struct sys_ioctl_args bia; 506 u_long com; 507 508 SCARG(&bia, fd) = SCARG(uap, fd); 509 SCARG(&bia, data) = SCARG(uap, data); 510 com = SCARG(uap, com); 511 512 switch (com) { 513 default: 514 printf("linux_machdepioctl: invalid ioctl %08lx\n", com); 515 return EINVAL; 516 } 517 SCARG(&bia, com) = com; 518 /* XXX NJWLWP */ 519 return sys_ioctl(curlwp, &bia, retval); 520 } 521 #if 0 522 /* 523 * Set I/O permissions for a process. Just set the maximum level 524 * right away (ignoring the argument), otherwise we would have 525 * to rely on I/O permission maps, which are not implemented. 526 */ 527 int 528 linux_sys_iopl(l, v, retval) 529 struct lwp *l; 530 void *v; 531 register_t *retval; 532 { 533 /* 534 * This syscall is not implemented in Linux/PowerPC: we should not be here 535 */ 536 #ifdef DEBUG_LINUX 537 printf("linux_sys_iopl: should not be here.\n"); 538 #endif 539 return 0; 540 } 541 #endif 542 543 /* 544 * See above. If a root process tries to set access to an I/O port, 545 * just let it have the whole range. 546 */ 547 int 548 linux_sys_ioperm(l, v, retval) 549 struct lwp *l; 550 void *v; 551 register_t *retval; 552 { 553 /* 554 * This syscall is not implemented in Linux/PowerPC: we should not be here 555 */ 556 #ifdef DEBUG_LINUX 557 printf("linux_sys_ioperm: should not be here.\n"); 558 #endif 559 return 0; 560 } 561 562 /* 563 * wrapper linux_sys_new_uname() -> linux_sys_uname() 564 */ 565 int 566 linux_sys_new_uname(l, v, retval) 567 struct lwp *l; 568 void *v; 569 register_t *retval; 570 { 571 return linux_sys_uname(l, v, retval); 572 } 573 574 /* 575 * wrapper linux_sys_new_select() -> linux_sys_select() 576 */ 577 int 578 linux_sys_new_select(l, v, retval) 579 struct lwp *l; 580 void *v; 581 register_t *retval; 582 { 583 return linux_sys_select(l, v, retval); 584 } 585 586 int 587 linux_usertrap(struct lwp *l, vaddr_t trapaddr, void *arg) 588 { 589 return 0; 590 } 591