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