1 /* $NetBSD: linux_machdep.c,v 1.42 2010/07/07 01:30:34 chs Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by ITOH Yasufumi. 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.42 2010/07/07 01:30:34 chs Exp $"); 34 35 #define COMPAT_LINUX 1 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/kernel.h> 40 #include <sys/proc.h> 41 #include <sys/exec.h> 42 #include <sys/ioctl.h> 43 #include <sys/mount.h> 44 #include <sys/signal.h> 45 #include <sys/signalvar.h> 46 #include <sys/syscallargs.h> 47 #include <sys/kauth.h> 48 49 #include <sys/cpu.h> 50 #include <machine/reg.h> 51 52 #include <compat/linux/common/linux_types.h> 53 #include <compat/linux/common/linux_signal.h> 54 #include <compat/linux/common/linux_ioctl.h> 55 #include <compat/linux/common/linux_exec.h> 56 #include <compat/linux/common/linux_machdep.h> 57 58 #include <compat/linux/linux_syscall.h> 59 #include <compat/linux/linux_syscallargs.h> 60 61 /* XXX should be in an include file somewhere */ 62 #define CC_PURGE 1 63 #define CC_FLUSH 2 64 #define CC_IPURGE 4 65 #define CC_EXTPURGE 0x80000000 66 /* XXX end should be */ 67 68 extern short exframesize[]; 69 70 #ifdef DEBUG 71 extern int sigdebug; 72 extern int sigpid; 73 #define SDB_FOLLOW 0x01 74 #define SDB_KSTACK 0x02 75 #define SDB_FPSTATE 0x04 76 #endif 77 78 void setup_linux_sigframe(struct frame *frame, int sig, 79 const sigset_t *mask, void *usp); 80 void setup_linux_rt_sigframe(struct frame *frame, int sig, 81 const sigset_t *mask, void *usp, struct lwp *l); 82 83 /* 84 * Deal with some m68k-specific things in the Linux emulation code. 85 */ 86 87 /* 88 * Setup registers on program execution. 89 */ 90 void 91 linux_setregs(struct lwp *l, struct exec_package *epp, vaddr_t stack) 92 { 93 94 setregs(l, epp, stack); 95 } 96 97 /* 98 * Setup signal frame for old signal interface. 99 */ 100 void 101 setup_linux_sigframe(struct frame *frame, int sig, const sigset_t *mask, void *usp) 102 { 103 struct lwp *l = curlwp; 104 struct proc *p = l->l_proc; 105 struct linux_sigframe *fp, kf; 106 short ft; 107 int error; 108 109 ft = frame->f_format; 110 111 /* Allocate space for the signal handler context on the user stack. */ 112 fp = (struct linux_sigframe *) usp; 113 fp--; 114 115 #ifdef DEBUG 116 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 117 printf("setup_linux_sigframe(%d): sig %d ssp %p usp %p scp %p ft %d\n", 118 p->p_pid, sig, &ft, fp, &fp->sf_c.c_sc, ft); 119 #endif 120 121 /* Build stack frame. */ 122 kf.sf_psigtramp = fp->sf_sigtramp; /* return addr for handler */ 123 kf.sf_signum = native_to_linux_signo[sig]; 124 kf.sf_code = frame->f_vector; /* Does anyone use it? */ 125 kf.sf_scp = &fp->sf_c.c_sc; 126 127 /* The sigtramp code is on the stack frame on Linux/m68k. */ 128 kf.sf_sigtramp[0] = LINUX_SF_SIGTRAMP0; 129 kf.sf_sigtramp[1] = LINUX_SF_SIGTRAMP1; 130 131 /* 132 * Save necessary hardware state. Currently this includes: 133 * - scratch registers 134 * - original exception frame (if not a "normal" frame) 135 * - FP coprocessor state 136 */ 137 kf.sf_c.c_sc.sc_d0 = frame->f_regs[D0]; 138 kf.sf_c.c_sc.sc_d1 = frame->f_regs[D1]; 139 kf.sf_c.c_sc.sc_a0 = frame->f_regs[A0]; 140 kf.sf_c.c_sc.sc_a1 = frame->f_regs[A1]; 141 142 /* Clear for security (and initialize ss_format). */ 143 memset(&kf.sf_c.c_sc.sc_ss, 0, sizeof kf.sf_c.c_sc.sc_ss); 144 145 if (ft >= FMT4) { 146 #ifdef DEBUG 147 if (ft > 15 || exframesize[ft] < 0) 148 panic("setup_linux_sigframe: bogus frame type"); 149 #endif 150 kf.sf_c.c_sc.sc_ss.ss_format = ft; 151 kf.sf_c.c_sc.sc_ss.ss_vector = frame->f_vector; 152 memcpy( &kf.sf_c.c_sc.sc_ss.ss_frame, &frame->F_u, 153 (size_t) exframesize[ft]); 154 /* 155 * Leave an indicator that we need to clean up the kernel 156 * stack. We do this by setting the "pad word" above the 157 * hardware stack frame to the amount the stack must be 158 * adjusted by. 159 * 160 * N.B. we increment rather than just set f_stackadj in 161 * case we are called from syscall when processing a 162 * sigreturn. In that case, f_stackadj may be non-zero. 163 */ 164 frame->f_stackadj += exframesize[ft]; 165 frame->f_format = frame->f_vector = 0; 166 #ifdef DEBUG 167 if (sigdebug & SDB_FOLLOW) 168 printf("setup_linux_sigframe(%d): copy out %d of frame %d\n", 169 p->p_pid, exframesize[ft], ft); 170 #endif 171 } 172 173 switch (fputype) { 174 case FPU_NONE: 175 break; 176 #ifdef M68060 177 case FPU_68060: 178 __asm("fsave %0" : "=m" (kf.sf_c.c_sc.sc_ss.ss_fpstate.FPF_u1) 179 : : "memory"); 180 if (((struct fpframe060 *)&kf.sf_c.c_sc.sc_ss.ss_fpstate.FPF_u1) 181 ->fpf6_frmfmt != FPF6_FMT_NULL) { 182 __asm("fmovem %%fp0-%%fp1,%0" : 183 "=m" (kf.sf_c.c_sc.sc_ss.ss_fpstate.fpf_regs[0][0])); 184 /* 185 * On 060, "fmovem fpcr/fpsr/fpi,<ea>" is 186 * emulated by software and slow. 187 */ 188 __asm("fmovem %%fpcr,%0; fmovem %%fpsr,%1; fmovem %%fpi,%2" : 189 "=m" (kf.sf_c.c_sc.sc_ss.ss_fpstate.fpf_fpcr), 190 "=m" (kf.sf_c.c_sc.sc_ss.ss_fpstate.fpf_fpsr), 191 "=m" (kf.sf_c.c_sc.sc_ss.ss_fpstate.fpf_fpiar)); 192 } 193 break; 194 #endif 195 default: 196 __asm("fsave %0" : "=m" (kf.sf_c.c_sc.sc_ss.ss_fpstate.FPF_u1) 197 : : "memory"); 198 if (kf.sf_c.c_sc.sc_ss.ss_fpstate.fpf_version) { 199 __asm("fmovem %%fp0-%%fp1,%0; fmovem %%fpcr/%%fpsr/%%fpi,%1" : 200 "=m" (kf.sf_c.c_sc.sc_ss.ss_fpstate.fpf_regs[0][0]), 201 "=m" (kf.sf_c.c_sc.sc_ss.ss_fpstate.fpf_fpcr) 202 : : "memory"); 203 } 204 break; 205 } 206 #ifdef DEBUG 207 if ((sigdebug & SDB_FPSTATE) && *(char *)&kf.sf_c.c_sc.sc_ss.ss_fpstate) 208 printf("setup_linux_sigframe(%d): copy out FP state (%x) to %p\n", 209 p->p_pid, *(u_int *)&kf.sf_c.c_sc.sc_ss.ss_fpstate, 210 &kf.sf_c.c_sc.sc_ss.ss_fpstate); 211 #endif 212 213 /* Build the signal context to be used by sigreturn. */ 214 #if LINUX__NSIG_WORDS > 1 215 native_to_linux_old_extra_sigset(&kf.sf_c.c_sc.sc_mask, 216 kf.sf_c.c_extrasigmask, mask); 217 #else 218 native_to_linux_old_sigset(&kf.sf_c.c_sc.sc_mask, mask); 219 #endif 220 kf.sf_c.c_sc.sc_sp = frame->f_regs[SP]; 221 kf.sf_c.c_sc.sc_pc = frame->f_pc; 222 kf.sf_c.c_sc.sc_ps = frame->f_sr; 223 sendsig_reset(l, sig); 224 225 mutex_exit(p->p_lock); 226 error = copyout(&kf, fp, sizeof(struct linux_sigframe)); 227 mutex_enter(p->p_lock); 228 229 if (error) { 230 #ifdef DEBUG 231 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 232 printf("setup_linux_sigframe(%d): copyout failed on sig %d\n", 233 p->p_pid, sig); 234 #endif 235 /* 236 * Process has trashed its stack; give it a segmentation 237 * violation to halt it in its tracks. 238 */ 239 sigexit(l, SIGSEGV); 240 /* NOTREACHED */ 241 } 242 243 /* 244 * The signal trampoline is on the signal frame. 245 * Clear the instruction cache in case of cached. 246 */ 247 cachectl1(CC_EXTPURGE | CC_IPURGE, 248 (vaddr_t) fp->sf_sigtramp, sizeof fp->sf_sigtramp, p); 249 250 /* Set up the user stack pointer. */ 251 frame->f_regs[SP] = (int)fp; 252 253 #ifdef DEBUG 254 if (sigdebug & SDB_FOLLOW) 255 printf("setup_linux_sigframe(%d): sig %d scp %p fp %p sc_sp %x\n", 256 p->p_pid, sig, kf.sf_scp, fp, kf.sf_c.c_sc.sc_sp); 257 #endif 258 } 259 260 /* 261 * Setup signal frame for new RT signal interface. 262 */ 263 void 264 setup_linux_rt_sigframe(struct frame *frame, int sig, const sigset_t *mask, void *usp, struct lwp *l) 265 { 266 struct proc *p = l->l_proc; 267 struct linux_rt_sigframe *fp, kf; 268 int error; 269 short ft; 270 271 ft = frame->f_format; 272 273 /* Allocate space for the signal handler context on the user stack. */ 274 fp = (struct linux_rt_sigframe *) usp; 275 fp--; 276 277 #ifdef DEBUG 278 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 279 printf("setup_linux_rt_sigframe(%d): sig %d ssp %p usp %p ucp %p ft %d\n", 280 p->p_pid, sig, &ft, fp, &fp->sf_uc, ft); 281 #endif 282 283 /* Build stack frame. */ 284 kf.sf_psigtramp = fp->sf_sigtramp; /* return addr for handler */ 285 kf.sf_signum = native_to_linux_signo[sig]; 286 kf.sf_pinfo = &fp->sf_info; 287 kf.sf_puc = &fp->sf_uc; 288 289 /* The sigtramp code is on the stack frame on Linux/m68k. */ 290 kf.sf_sigtramp[0] = LINUX_RT_SF_SIGTRAMP0; 291 kf.sf_sigtramp[1] = LINUX_RT_SF_SIGTRAMP1; 292 293 /* clear for security (and initialize uc_flags, ss_format, etc.). */ 294 memset(&kf.sf_uc, 0, sizeof(struct linux_ucontext)); 295 296 /* 297 * Save necessary hardware state. Currently this includes: 298 * - general registers 299 * - original exception frame (if not a "normal" frame) 300 * - FP coprocessor state 301 */ 302 /* version of mcontext */ 303 kf.sf_uc.uc_mc.mc_version = LINUX_MCONTEXT_VERSION; 304 305 /* general registers and pc/sr */ 306 memcpy( kf.sf_uc.uc_mc.mc_gregs.gr_regs, frame->f_regs, sizeof(u_int)*16); 307 kf.sf_uc.uc_mc.mc_gregs.gr_pc = frame->f_pc; 308 kf.sf_uc.uc_mc.mc_gregs.gr_sr = frame->f_sr; 309 310 if (ft >= FMT4) { 311 #ifdef DEBUG 312 if (ft > 15 || exframesize[ft] < 0) 313 panic("setup_linux_rt_sigframe: bogus frame type"); 314 #endif 315 kf.sf_uc.uc_ss.ss_format = ft; 316 kf.sf_uc.uc_ss.ss_vector = frame->f_vector; 317 memcpy( &kf.sf_uc.uc_ss.ss_frame, &frame->F_u, 318 (size_t) exframesize[ft]); 319 /* 320 * Leave an indicator that we need to clean up the kernel 321 * stack. We do this by setting the "pad word" above the 322 * hardware stack frame to the amount the stack must be 323 * adjusted by. 324 * 325 * N.B. we increment rather than just set f_stackadj in 326 * case we are called from syscall when processing a 327 * sigreturn. In that case, f_stackadj may be non-zero. 328 */ 329 frame->f_stackadj += exframesize[ft]; 330 frame->f_format = frame->f_vector = 0; 331 #ifdef DEBUG 332 if (sigdebug & SDB_FOLLOW) 333 printf("setup_linux_rt_sigframe(%d): copy out %d of frame %d\n", 334 p->p_pid, exframesize[ft], ft); 335 #endif 336 } 337 338 switch (fputype) { 339 case FPU_NONE: 340 break; 341 #ifdef M68060 342 case FPU_68060: 343 __asm("fsave %0" : "=m" (kf.sf_uc.uc_ss.ss_fpstate)); 344 /* See note below. */ 345 if (((struct fpframe060 *) &kf.sf_uc.uc_ss.ss_fpstate.FPF_u1) 346 ->fpf6_frmfmt != FPF6_FMT_NULL) { 347 __asm("fmovem %%fp0-%%fp7,%0" : 348 "=m" (kf.sf_uc.uc_mc.mc_fpregs.fpr_regs[0][0])); 349 /* 350 * On 060, "fmovem fpcr/fpsr/fpi,<ea>" is 351 * emulated by software and slow. 352 */ 353 __asm("fmovem %%fpcr,%0; fmovem %%fpsr,%1; fmovem %%fpi,%2" : 354 "=m" (kf.sf_uc.uc_mc.mc_fpregs.fpr_fpcr), 355 "=m" (kf.sf_uc.uc_mc.mc_fpregs.fpr_fpsr), 356 "=m" (kf.sf_uc.uc_mc.mc_fpregs.fpr_fpiar)); 357 } 358 break; 359 #endif 360 default: 361 /* 362 * NOTE: We give whole of the "struct linux_rt_fpframe" 363 * to the __asm("fsave") argument; not the FPF_u1 element only. 364 * Unlike the non-RT version of this structure, 365 * this contains only the FPU state used by "fsave" 366 * (and whole of the information is in the structure). 367 * This gives the correct dependency information to the __asm(), 368 * and no "memory" is required to the ``clobberd'' list. 369 */ 370 __asm("fsave %0" : "=m" (kf.sf_uc.uc_ss.ss_fpstate)); 371 if (kf.sf_uc.uc_ss.ss_fpstate.fpf_version) { 372 __asm("fmovem %%fp0-%%fp7,%0; fmovem %%fpcr/%%fpsr/%%fpi,%1" : 373 "=m" (kf.sf_uc.uc_mc.mc_fpregs.fpr_regs[0][0]), 374 "=m" (kf.sf_uc.uc_mc.mc_fpregs.fpr_fpcr) 375 : : "memory"); 376 } 377 break; 378 } 379 #ifdef DEBUG 380 if ((sigdebug & SDB_FPSTATE) && *(char *)&kf.sf_uc.uc_ss.ss_fpstate) 381 printf("setup_linux_rt_sigframe(%d): copy out FP state (%x) to %p\n", 382 p->p_pid, *(u_int *)&kf.sf_uc.uc_ss.ss_fpstate, 383 &kf.sf_uc.uc_ss.ss_fpstate); 384 #endif 385 386 /* 387 * XXX XAX Create bogus siginfo data. This can't really 388 * XXX be fixed until NetBSD has realtime signals. 389 * XXX Or we do the emuldata thing. 390 * XXX -erh 391 */ 392 memset(&kf.sf_info, 0, sizeof(struct linux_siginfo)); 393 kf.sf_info.lsi_signo = sig; 394 kf.sf_info.lsi_code = LINUX_SI_USER; 395 kf.sf_info.lsi_pid = p->p_pid; 396 kf.sf_info.lsi_uid = kauth_cred_geteuid(l->l_cred); /* Use real uid here? */ 397 398 /* Build the signal context to be used by sigreturn. */ 399 native_to_linux_sigset(&kf.sf_uc.uc_sigmask, mask); 400 kf.sf_uc.uc_stack.ss_sp = l->l_sigstk.ss_sp; 401 kf.sf_uc.uc_stack.ss_flags = 402 (l->l_sigstk.ss_flags & SS_ONSTACK ? LINUX_SS_ONSTACK : 0) | 403 (l->l_sigstk.ss_flags & SS_DISABLE ? LINUX_SS_DISABLE : 0); 404 kf.sf_uc.uc_stack.ss_size = l->l_sigstk.ss_size; 405 sendsig_reset(l, sig); 406 407 mutex_exit(p->p_lock); 408 error = copyout(&kf, fp, sizeof(struct linux_rt_sigframe)); 409 mutex_enter(p->p_lock); 410 411 if (error) { 412 #ifdef DEBUG 413 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 414 printf("setup_linux_rt_sigframe(%d): copyout failed on sig %d\n", 415 p->p_pid, sig); 416 #endif 417 /* 418 * Process has trashed its stack; give it a segmentation 419 * violation to halt it in its tracks. 420 */ 421 sigexit(l, SIGSEGV); 422 /* NOTREACHED */ 423 } 424 425 /* 426 * The signal trampoline is on the signal frame. 427 * Clear the instruction cache in case of cached. 428 */ 429 cachectl1(CC_EXTPURGE | CC_IPURGE, 430 (vaddr_t) fp->sf_sigtramp, sizeof fp->sf_sigtramp, p); 431 432 /* Set up the user stack pointer. */ 433 frame->f_regs[SP] = (int)fp; 434 435 #ifdef DEBUG 436 if (sigdebug & SDB_FOLLOW) 437 printf("setup_linux_rt_sigframe(%d): sig %d puc %p fp %p sc_sp %x\n", 438 p->p_pid, sig, kf.sf_puc, fp, 439 kf.sf_uc.uc_mc.mc_gregs.gr_regs[SP]); 440 #endif 441 } 442 443 /* 444 * Send an interrupt to Linux process. 445 */ 446 void 447 linux_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) 448 { 449 /* u_long code = ksi->ksi_trap; */ 450 int sig = ksi->ksi_signo; 451 struct lwp *l = curlwp; 452 struct proc *p = l->l_proc; 453 struct frame *frame = (struct frame *)l->l_md.md_regs; 454 int onstack; 455 /* user stack for signal context */ 456 void *usp = getframe(l, sig, &onstack); 457 sig_t catcher = SIGACTION(p, sig).sa_handler; 458 459 /* Setup the signal frame (and part of the trapframe). */ 460 if (SIGACTION(p, sig).sa_flags & SA_SIGINFO) 461 setup_linux_rt_sigframe(frame, sig, mask, usp, l); 462 else 463 setup_linux_sigframe(frame, sig, mask, usp); 464 465 /* Call the signal handler. */ 466 frame->f_pc = (u_int) catcher; 467 468 /* Remember that we're now on the signal stack. */ 469 if (onstack) 470 l->l_sigstk.ss_flags |= SS_ONSTACK; 471 472 #ifdef DEBUG 473 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 474 printf("linux_sendsig(%d): sig %d returns\n", 475 p->p_pid, sig); 476 #endif 477 } 478 479 /* 480 * The linux_sys_sigreturn and linux_sys_rt_sigreturn 481 * system calls cleanup state after a signal 482 * has been taken. Reset signal mask and stack 483 * state from context left by linux_sendsig (above). 484 * Return to previous pc and psl as specified by 485 * context left by linux_sendsig. Check carefully to 486 * make sure that the user has not modified the 487 * psl to gain improper privileges or to cause 488 * a machine fault. 489 * 490 * Note that the sigreturn system calls of Linux/m68k 491 * do not return on errors, but issue segmentation 492 * violation and terminate the process. 493 */ 494 /* ARGSUSED */ 495 int 496 linux_sys_sigreturn(struct lwp *l, const void *v, register_t *retval) 497 { 498 struct proc *p = l->l_proc; 499 struct frame *frame; 500 struct linux_sigc2 tsigc2; /* extra mask and sigcontext */ 501 struct linux_sigcontext *scp; /* pointer to sigcontext */ 502 sigset_t mask; 503 int sz = 0; /* extra frame size */ 504 int usp; 505 506 /* 507 * sigreturn of Linux/m68k takes no arguments. 508 * The user stack points at struct linux_sigc2. 509 */ 510 frame = (struct frame *) l->l_md.md_regs; 511 usp = frame->f_regs[SP]; 512 if (usp & 1) 513 goto bad; 514 515 #ifdef DEBUG 516 if (sigdebug & SDB_FOLLOW) 517 printf("linux_sys_sigreturn: pid %d, usp %p\n", 518 p->p_pid, (void *) usp); 519 #endif 520 521 /* Grab whole of the sigcontext. */ 522 if (copyin((void *) usp, &tsigc2, sizeof tsigc2)) { 523 bad: 524 mutex_enter(p->p_lock); 525 sigexit(l, SIGSEGV); 526 } 527 528 scp = &tsigc2.c_sc; 529 530 /* 531 * Check kernel stack and re-enter to syscall() if needed. 532 */ 533 if ((sz = scp->sc_ss.ss_format) != 0) { 534 if ((sz = exframesize[sz]) < 0) 535 goto bad; 536 if (sz && frame->f_stackadj == 0) { 537 /* 538 * Extra stack space is required but not allocated. 539 * Allocate and re-enter syscall(). 540 */ 541 reenter_syscall(frame, sz); 542 /* NOTREACHED */ 543 } 544 } 545 #ifdef DEBUG 546 /* reenter_syscall() doesn't adjust stack. */ 547 if (sz != frame->f_stackadj) 548 panic("linux_sys_sigreturn: adj: %d != %d", 549 sz, frame->f_stackadj); 550 #endif 551 552 mutex_enter(p->p_lock); 553 554 /* Restore signal stack. */ 555 l->l_sigstk.ss_flags &= ~SS_ONSTACK; 556 557 /* Restore signal mask. */ 558 #if LINUX__NSIG_WORDS > 1 559 linux_old_extra_to_native_sigset(&mask, &scp->sc_mask, 560 tsigc2.c_extrasigmask); 561 #else 562 linux_old_to_native_sigset(&scp->sc_mask, &mask); 563 #endif 564 (void) sigprocmask1(l, SIG_SETMASK, &mask, 0); 565 566 mutex_exit(p->p_lock); 567 568 /* 569 * Restore the user supplied information. 570 */ 571 frame->f_regs[SP] = scp->sc_sp; 572 frame->f_regs[D0] = scp->sc_d0; 573 frame->f_regs[D1] = scp->sc_d1; 574 frame->f_regs[A0] = scp->sc_a0; 575 frame->f_regs[A1] = scp->sc_a1; 576 frame->f_pc = scp->sc_pc; 577 /* Privileged bits of sr are silently ignored on Linux/m68k. */ 578 frame->f_sr = scp->sc_ps & ~(PSL_MBZ|PSL_IPL|PSL_S); 579 /* 580 * Other registers are assumed to be unchanged, 581 * and not restored. 582 */ 583 584 /* 585 * Restore long stack frames. Note that we do not copy 586 * back the saved SR or PC, they were picked up above from 587 * the sigcontext structure. 588 */ 589 if (scp->sc_ss.ss_format) { 590 frame->f_format = scp->sc_ss.ss_format; 591 frame->f_vector = scp->sc_ss.ss_vector; 592 if (frame->f_stackadj < sz) /* just in case... */ 593 goto bad; 594 frame->f_stackadj -= sz; 595 memcpy( &frame->F_u, &scp->sc_ss.ss_frame, sz); 596 #ifdef DEBUG 597 if (sigdebug & SDB_FOLLOW) 598 printf("linux_sys_sigreturn(%d): copy in %d of frame type %d\n", 599 p->p_pid, sz, scp->sc_ss.ss_format); 600 #endif 601 } 602 603 /* 604 * Finally we restore the original FP context. 605 */ 606 switch (fputype) { 607 case FPU_NONE: 608 break; 609 #ifdef M68060 610 case FPU_68060: 611 if (((struct fpframe060*)&scp->sc_ss.ss_fpstate.FPF_u1) 612 ->fpf6_frmfmt != FPF6_FMT_NULL) { 613 /* 614 * On 060, "fmovem <ea>,fpcr/fpsr/fpi" is 615 * emulated by software and slow. 616 */ 617 __asm("fmovem %0,%%fpcr; fmovem %1,%%fpsr; fmovem %2,%%fpi":: 618 "m" (scp->sc_ss.ss_fpstate.fpf_fpcr), 619 "m" (scp->sc_ss.ss_fpstate.fpf_fpsr), 620 "m" (scp->sc_ss.ss_fpstate.fpf_fpiar)); 621 __asm("fmovem %0,%%fp0-%%fp1" : : 622 "m" (scp->sc_ss.ss_fpstate.fpf_regs[0][0])); 623 } 624 __asm("frestore %0" : : "m" (scp->sc_ss.ss_fpstate.FPF_u1)); 625 break; 626 #endif 627 default: 628 if (scp->sc_ss.ss_fpstate.fpf_version) { 629 __asm("fmovem %0,%%fpcr/%%fpsr/%%fpi; fmovem %1,%%fp0-%%fp1":: 630 "m" (scp->sc_ss.ss_fpstate.fpf_fpcr), 631 "m" (scp->sc_ss.ss_fpstate.fpf_regs[0][0])); 632 } 633 __asm("frestore %0" : : "m" (scp->sc_ss.ss_fpstate.FPF_u1)); 634 break; 635 } 636 637 #ifdef DEBUG 638 if ((sigdebug & SDB_FPSTATE) && *(char *)&scp->sc_ss.ss_fpstate) 639 printf("linux_sys_sigreturn(%d): copied in FP state (%x) at %p\n", 640 p->p_pid, *(u_int *)&scp->sc_ss.ss_fpstate, 641 &scp->sc_ss.ss_fpstate); 642 if ((sigdebug & SDB_FOLLOW) || 643 ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)) 644 printf("linux_sys_sigreturn(%d): returns\n", p->p_pid); 645 #endif 646 647 return EJUSTRETURN; 648 } 649 650 /* ARGSUSED */ 651 int 652 linux_sys_rt_sigreturn(struct lwp *l, const void *v, register_t *retval) 653 { 654 struct proc *p = l->l_proc; 655 struct frame *frame; 656 struct linux_ucontext *ucp; /* ucontext in user space */ 657 struct linux_ucontext tuc; /* copy of *ucp */ 658 sigset_t mask; 659 int sz = 0, error; /* extra frame size */ 660 661 /* 662 * rt_sigreturn of Linux/m68k takes no arguments. 663 * usp + 4 is a pointer to siginfo structure, 664 * usp + 8 is a pointer to ucontext structure. 665 */ 666 frame = (struct frame *) l->l_md.md_regs; 667 error = copyin((char *)frame->f_regs[SP] + 8, (void *)&ucp, 668 sizeof(void *)); 669 if (error || (int) ucp & 1) 670 goto bad; /* error or odd address */ 671 672 #ifdef DEBUG 673 if (sigdebug & SDB_FOLLOW) 674 printf("linux_rt_sigreturn: pid %d, ucp %p\n", p->p_pid, ucp); 675 #endif 676 677 /* Grab whole of the ucontext. */ 678 if (copyin(ucp, &tuc, sizeof tuc)) { 679 bad: 680 mutex_enter(p->p_lock); 681 sigexit(l, SIGSEGV); 682 } 683 684 /* 685 * Check kernel stack and re-enter to syscall() if needed. 686 */ 687 if ((sz = tuc.uc_ss.ss_format) != 0) { 688 if ((sz = exframesize[sz]) < 0) 689 goto bad; 690 if (sz && frame->f_stackadj == 0) { 691 /* 692 * Extra stack space is required but not allocated. 693 * Allocate and re-enter syscall(). 694 */ 695 reenter_syscall(frame, sz); 696 /* NOTREACHED */ 697 } 698 } 699 #ifdef DEBUG 700 /* reenter_syscall() doesn't adjust stack. */ 701 if (sz != frame->f_stackadj) 702 panic("linux_sys_rt_sigreturn: adj: %d != %d", 703 sz, frame->f_stackadj); 704 #endif 705 706 if (tuc.uc_mc.mc_version != LINUX_MCONTEXT_VERSION) 707 goto bad; 708 709 mutex_enter(p->p_lock); 710 711 /* Restore signal stack. */ 712 l->l_sigstk.ss_flags = 713 (l->l_sigstk.ss_flags & ~SS_ONSTACK) | 714 (tuc.uc_stack.ss_flags & LINUX_SS_ONSTACK ? SS_ONSTACK : 0); 715 716 /* Restore signal mask. */ 717 linux_to_native_sigset(&mask, &tuc.uc_sigmask); 718 (void) sigprocmask1(l, SIG_SETMASK, &mask, 0); 719 720 mutex_exit(p->p_lock); 721 722 /* 723 * Restore the user supplied information. 724 */ 725 memcpy( frame->f_regs, tuc.uc_mc.mc_gregs.gr_regs, sizeof(u_int)*16); 726 frame->f_pc = tuc.uc_mc.mc_gregs.gr_pc; 727 /* Privileged bits of sr are silently ignored on Linux/m68k. */ 728 frame->f_sr = tuc.uc_mc.mc_gregs.gr_sr & ~(PSL_MBZ|PSL_IPL|PSL_S); 729 730 /* 731 * Restore long stack frames. Note that we do not copy 732 * back the saved SR or PC, they were picked up above from 733 * the ucontext structure. 734 */ 735 if (tuc.uc_ss.ss_format) { 736 frame->f_format = tuc.uc_ss.ss_format; 737 frame->f_vector = tuc.uc_ss.ss_vector; 738 if (frame->f_stackadj < sz) /* just in case... */ 739 goto bad; 740 frame->f_stackadj -= sz; 741 memcpy( &frame->F_u, &tuc.uc_ss.ss_frame, sz); 742 #ifdef DEBUG 743 if (sigdebug & SDB_FOLLOW) 744 printf("linux_sys_rt_sigreturn(%d): copy in %d of frame type %d\n", 745 p->p_pid, sz, tuc.uc_ss.ss_format); 746 #endif 747 } 748 749 /* 750 * Finally we restore the original FP context. 751 */ 752 switch (fputype) { 753 case FPU_NONE: 754 break; 755 #ifdef M68060 756 case FPU_68060: 757 if (((struct fpframe060*)&tuc.uc_ss.ss_fpstate.FPF_u1) 758 ->fpf6_frmfmt != FPF6_FMT_NULL) { 759 /* 760 * On 060, "fmovem <ea>,fpcr/fpsr/fpi" is 761 * emulated by software and slow. 762 */ 763 __asm("fmovem %0,%%fpcr; fmovem %1,%%fpsr; fmovem %2,%%fpi":: 764 "m" (tuc.uc_mc.mc_fpregs.fpr_fpcr), 765 "m" (tuc.uc_mc.mc_fpregs.fpr_fpsr), 766 "m" (tuc.uc_mc.mc_fpregs.fpr_fpiar)); 767 __asm("fmovem %0,%%fp0-%%fp1" : : 768 "m" (tuc.uc_mc.mc_fpregs.fpr_regs[0][0])); 769 } 770 __asm("frestore %0" : : "m" (tuc.uc_ss.ss_fpstate.FPF_u1)); 771 break; 772 #endif 773 default: 774 if (tuc.uc_ss.ss_fpstate.fpf_version) { 775 __asm("fmovem %0,%%fpcr/%%fpsr/%%fpi; fmovem %1,%%fp0-%%fp1":: 776 "m" (tuc.uc_mc.mc_fpregs.fpr_fpcr), 777 "m" (tuc.uc_mc.mc_fpregs.fpr_regs[0][0])); 778 } 779 __asm("frestore %0" : : "m" (tuc.uc_ss.ss_fpstate.FPF_u1)); 780 break; 781 } 782 783 #ifdef DEBUG 784 if ((sigdebug & SDB_FPSTATE) && *(char *)&tuc.uc_ss.ss_fpstate) 785 printf("linux_rt_sigreturn(%d): copied in FP state (%x) at %p\n", 786 p->p_pid, *(u_int *)&tuc.uc_ss.ss_fpstate, 787 &tuc.uc_ss.ss_fpstate); 788 if ((sigdebug & SDB_FOLLOW) || 789 ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)) 790 printf("linux_rt_sigreturn(%d): returns\n", p->p_pid); 791 #endif 792 793 return EJUSTRETURN; 794 } 795 796 /* 797 * MPU cache operation of Linux/m68k, 798 * mainly used for dynamic linking. 799 */ 800 801 /* scope */ 802 #define LINUX_FLUSH_SCOPE_LINE 1 /* a cache line */ 803 #define LINUX_FLUSH_SCOPE_PAGE 2 /* a page */ 804 #define LINUX_FLUSH_SCOPE_ALL 3 /* the whole cache */ 805 /* cache */ 806 #define LINUX_FLUSH_CACHE_DATA 1 /* flush and purge data cache */ 807 #define LINUX_FLUSH_CACHE_INSN 2 /* purge instruction cache */ 808 #define LINUX_FLUSH_CACHE_BOTH 3 /* both */ 809 810 /* ARGSUSED */ 811 int 812 linux_sys_cacheflush(struct lwp *l, const struct linux_sys_cacheflush_args *uap, register_t *retval) 813 { 814 /* { 815 syscallarg(unsigned long) addr; 816 syscallarg(int) scope; 817 syscallarg(int) cache; 818 syscallarg(unsigned long) len; 819 } */ 820 struct proc *p = l->l_proc; 821 int scope, cache; 822 vaddr_t addr; 823 int len; 824 int error; 825 826 scope = SCARG(uap, scope); 827 cache = SCARG(uap, cache); 828 829 if (scope < LINUX_FLUSH_SCOPE_LINE || scope > LINUX_FLUSH_SCOPE_ALL 830 || cache & ~LINUX_FLUSH_CACHE_BOTH) 831 return EINVAL; 832 833 #if defined(M68040) || defined(M68060) 834 addr = (vaddr_t) SCARG(uap, addr); 835 len = (int) SCARG(uap, len); 836 #else 837 /* 838 * We always flush entire cache on 68020/030 839 * and these values are not used afterwards. 840 */ 841 addr = 0; 842 len = 0; 843 #endif 844 845 /* 846 * LINUX_FLUSH_SCOPE_ALL (flush whole cache) is limited to super users. 847 */ 848 if (scope == LINUX_FLUSH_SCOPE_ALL) { 849 if ((error = kauth_authorize_machdep(l->l_cred, 850 KAUTH_MACHDEP_CACHEFLUSH, NULL, NULL, NULL, NULL)) != 0) 851 return error; 852 #if defined(M68040) || defined(M68060) 853 /* entire cache */ 854 len = INT_MAX; 855 #endif 856 } 857 858 error = 0; 859 if (cache & LINUX_FLUSH_CACHE_DATA) 860 if ((error = cachectl1(CC_EXTPURGE|CC_PURGE, addr, len, p)) !=0) 861 return error; 862 if (cache & LINUX_FLUSH_CACHE_INSN) 863 error = cachectl1(CC_EXTPURGE|CC_IPURGE, addr, len, p); 864 865 return error; 866 } 867 868 /* 869 * Convert NetBSD's devices to Linux's. 870 */ 871 dev_t 872 linux_fakedev(dev_t dev, int raw) 873 { 874 875 /* do nothing for now */ 876 return dev; 877 } 878 879 /* 880 * We come here in a last attempt to satisfy a Linux ioctl() call. 881 */ 882 int 883 linux_machdepioctl(struct lwp *l, const struct linux_sys_ioctl_args *uap, register_t *retval) 884 { 885 /* { 886 syscallarg(int) fd; 887 syscallarg(u_long) com; 888 syscallarg(void *) data; 889 } */ 890 struct sys_ioctl_args bia; 891 u_long com; 892 893 SCARG(&bia, fd) = SCARG(uap, fd); 894 SCARG(&bia, data) = SCARG(uap, data); 895 com = SCARG(uap, com); 896 897 switch (com) { 898 899 /* do nothing for now */ 900 901 default: 902 printf("linux_machdepioctl: invalid ioctl %08lx\n", com); 903 return EINVAL; 904 } 905 SCARG(&bia, com) = com; 906 return sys_ioctl(l, &bia, retval); 907 } 908 909 int 910 linux_usertrap(struct lwp *l, vaddr_t trapaddr, void *arg) 911 { 912 return 0; 913 } 914