1 /*- 2 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 3 * Copyright (C) 1995, 1996 TooLs GmbH. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by TooLs GmbH. 17 * 4. The name of TooLs GmbH may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 /*- 32 * Copyright (C) 2001 Benno Rice 33 * All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 44 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR 45 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 46 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 47 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 49 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 50 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 52 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 53 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 * $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $ 55 */ 56 57 #include <sys/cdefs.h> 58 __FBSDID("$FreeBSD$"); 59 60 #include "opt_compat.h" 61 62 #include <sys/param.h> 63 #include <sys/proc.h> 64 #include <sys/systm.h> 65 #include <sys/bio.h> 66 #include <sys/buf.h> 67 #include <sys/bus.h> 68 #include <sys/cons.h> 69 #include <sys/cpu.h> 70 #include <sys/exec.h> 71 #include <sys/imgact.h> 72 #include <sys/kernel.h> 73 #include <sys/ktr.h> 74 #include <sys/lock.h> 75 #include <sys/malloc.h> 76 #include <sys/mutex.h> 77 #include <sys/signalvar.h> 78 #include <sys/syscallsubr.h> 79 #include <sys/syscall.h> 80 #include <sys/sysent.h> 81 #include <sys/sysproto.h> 82 #include <sys/ucontext.h> 83 #include <sys/uio.h> 84 85 #include <machine/altivec.h> 86 #include <machine/cpu.h> 87 #include <machine/elf.h> 88 #include <machine/fpu.h> 89 #include <machine/pcb.h> 90 #include <machine/reg.h> 91 #include <machine/sigframe.h> 92 #include <machine/trap.h> 93 #include <machine/vmparam.h> 94 95 #ifdef COMPAT_FREEBSD32 96 #include <compat/freebsd32/freebsd32_signal.h> 97 #include <compat/freebsd32/freebsd32_util.h> 98 #include <compat/freebsd32/freebsd32_proto.h> 99 100 typedef struct __ucontext32 { 101 sigset_t uc_sigmask; 102 mcontext32_t uc_mcontext; 103 uint32_t uc_link; 104 struct sigaltstack32 uc_stack; 105 uint32_t uc_flags; 106 uint32_t __spare__[4]; 107 } ucontext32_t; 108 109 struct sigframe32 { 110 ucontext32_t sf_uc; 111 struct siginfo32 sf_si; 112 }; 113 114 static int grab_mcontext32(struct thread *td, mcontext32_t *, int flags); 115 #endif 116 117 static int grab_mcontext(struct thread *, mcontext_t *, int); 118 119 void 120 sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 121 { 122 struct trapframe *tf; 123 struct sigacts *psp; 124 struct sigframe sf; 125 struct thread *td; 126 struct proc *p; 127 #ifdef COMPAT_FREEBSD32 128 struct siginfo32 siginfo32; 129 struct sigframe32 sf32; 130 #endif 131 size_t sfpsize; 132 caddr_t sfp, usfp; 133 int oonstack, rndfsize; 134 int sig; 135 int code; 136 137 td = curthread; 138 p = td->td_proc; 139 PROC_LOCK_ASSERT(p, MA_OWNED); 140 141 psp = p->p_sigacts; 142 mtx_assert(&psp->ps_mtx, MA_OWNED); 143 tf = td->td_frame; 144 oonstack = sigonstack(tf->fixreg[1]); 145 146 /* 147 * Fill siginfo structure. 148 */ 149 ksi->ksi_info.si_signo = ksi->ksi_signo; 150 #ifdef AIM 151 ksi->ksi_info.si_addr = (void *)((tf->exc == EXC_DSI) ? 152 tf->cpu.aim.dar : tf->srr0); 153 #else 154 ksi->ksi_info.si_addr = (void *)((tf->exc == EXC_DSI) ? 155 tf->cpu.booke.dear : tf->srr0); 156 #endif 157 158 #ifdef COMPAT_FREEBSD32 159 if (SV_PROC_FLAG(p, SV_ILP32)) { 160 siginfo_to_siginfo32(&ksi->ksi_info, &siginfo32); 161 sig = siginfo32.si_signo; 162 code = siginfo32.si_code; 163 sfp = (caddr_t)&sf32; 164 sfpsize = sizeof(sf32); 165 rndfsize = ((sizeof(sf32) + 15) / 16) * 16; 166 167 /* 168 * Save user context 169 */ 170 171 memset(&sf32, 0, sizeof(sf32)); 172 grab_mcontext32(td, &sf32.sf_uc.uc_mcontext, 0); 173 174 sf32.sf_uc.uc_sigmask = *mask; 175 sf32.sf_uc.uc_stack.ss_sp = (uintptr_t)td->td_sigstk.ss_sp; 176 sf32.sf_uc.uc_stack.ss_size = (uint32_t)td->td_sigstk.ss_size; 177 sf32.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 178 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 179 180 sf32.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 181 } else { 182 #endif 183 sig = ksi->ksi_signo; 184 code = ksi->ksi_code; 185 sfp = (caddr_t)&sf; 186 sfpsize = sizeof(sf); 187 #ifdef __powerpc64__ 188 /* 189 * 64-bit PPC defines a 288 byte scratch region 190 * below the stack. 191 */ 192 rndfsize = 288 + ((sizeof(sf) + 47) / 48) * 48; 193 #else 194 rndfsize = ((sizeof(sf) + 15) / 16) * 16; 195 #endif 196 197 /* 198 * Save user context 199 */ 200 201 memset(&sf, 0, sizeof(sf)); 202 grab_mcontext(td, &sf.sf_uc.uc_mcontext, 0); 203 204 sf.sf_uc.uc_sigmask = *mask; 205 sf.sf_uc.uc_stack = td->td_sigstk; 206 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 207 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 208 209 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 210 #ifdef COMPAT_FREEBSD32 211 } 212 #endif 213 214 CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, 215 catcher, sig); 216 217 /* 218 * Allocate and validate space for the signal handler context. 219 */ 220 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 221 SIGISMEMBER(psp->ps_sigonstack, sig)) { 222 usfp = (void *)(td->td_sigstk.ss_sp + 223 td->td_sigstk.ss_size - rndfsize); 224 } else { 225 usfp = (void *)(tf->fixreg[1] - rndfsize); 226 } 227 228 /* 229 * Translate the signal if appropriate (Linux emu ?) 230 */ 231 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 232 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 233 234 /* 235 * Save the floating-point state, if necessary, then copy it. 236 */ 237 /* XXX */ 238 239 /* 240 * Set up the registers to return to sigcode. 241 * 242 * r1/sp - sigframe ptr 243 * lr - sig function, dispatched to by blrl in trampoline 244 * r3 - sig number 245 * r4 - SIGINFO ? &siginfo : exception code 246 * r5 - user context 247 * srr0 - trampoline function addr 248 */ 249 tf->lr = (register_t)catcher; 250 tf->fixreg[1] = (register_t)usfp; 251 tf->fixreg[FIRSTARG] = sig; 252 #ifdef COMPAT_FREEBSD32 253 tf->fixreg[FIRSTARG+2] = (register_t)usfp + 254 ((SV_PROC_FLAG(p, SV_ILP32)) ? 255 offsetof(struct sigframe32, sf_uc) : 256 offsetof(struct sigframe, sf_uc)); 257 #else 258 tf->fixreg[FIRSTARG+2] = (register_t)usfp + 259 offsetof(struct sigframe, sf_uc); 260 #endif 261 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 262 /* 263 * Signal handler installed with SA_SIGINFO. 264 */ 265 #ifdef COMPAT_FREEBSD32 266 if (SV_PROC_FLAG(p, SV_ILP32)) { 267 sf32.sf_si = siginfo32; 268 tf->fixreg[FIRSTARG+1] = (register_t)usfp + 269 offsetof(struct sigframe32, sf_si); 270 sf32.sf_si = siginfo32; 271 } else { 272 #endif 273 tf->fixreg[FIRSTARG+1] = (register_t)usfp + 274 offsetof(struct sigframe, sf_si); 275 sf.sf_si = ksi->ksi_info; 276 #ifdef COMPAT_FREEBSD32 277 } 278 #endif 279 } else { 280 /* Old FreeBSD-style arguments. */ 281 tf->fixreg[FIRSTARG+1] = code; 282 #ifdef AIM 283 tf->fixreg[FIRSTARG+3] = (tf->exc == EXC_DSI) ? 284 tf->cpu.aim.dar : tf->srr0; 285 #else 286 tf->fixreg[FIRSTARG+3] = (tf->exc == EXC_DSI) ? 287 tf->cpu.booke.dear : tf->srr0; 288 #endif 289 } 290 mtx_unlock(&psp->ps_mtx); 291 PROC_UNLOCK(p); 292 293 tf->srr0 = (register_t)p->p_sysent->sv_sigcode_base; 294 295 /* 296 * copy the frame out to userland. 297 */ 298 if (copyout(sfp, usfp, sfpsize) != 0) { 299 /* 300 * Process has trashed its stack. Kill it. 301 */ 302 CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp); 303 PROC_LOCK(p); 304 sigexit(td, SIGILL); 305 } 306 307 CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, 308 tf->srr0, tf->fixreg[1]); 309 310 PROC_LOCK(p); 311 mtx_lock(&psp->ps_mtx); 312 } 313 314 int 315 sys_sigreturn(struct thread *td, struct sigreturn_args *uap) 316 { 317 ucontext_t uc; 318 int error; 319 320 CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp); 321 322 if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) { 323 CTR1(KTR_SIG, "sigreturn: efault td=%p", td); 324 return (EFAULT); 325 } 326 327 error = set_mcontext(td, &uc.uc_mcontext); 328 if (error != 0) 329 return (error); 330 331 kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); 332 333 CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x", 334 td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]); 335 336 return (EJUSTRETURN); 337 } 338 339 #ifdef COMPAT_FREEBSD4 340 int 341 freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap) 342 { 343 344 return sys_sigreturn(td, (struct sigreturn_args *)uap); 345 } 346 #endif 347 348 /* 349 * Construct a PCB from a trapframe. This is called from kdb_trap() where 350 * we want to start a backtrace from the function that caused us to enter 351 * the debugger. We have the context in the trapframe, but base the trace 352 * on the PCB. The PCB doesn't have to be perfect, as long as it contains 353 * enough for a backtrace. 354 */ 355 void 356 makectx(struct trapframe *tf, struct pcb *pcb) 357 { 358 359 pcb->pcb_lr = tf->srr0; 360 pcb->pcb_sp = tf->fixreg[1]; 361 } 362 363 /* 364 * get_mcontext/sendsig helper routine that doesn't touch the 365 * proc lock 366 */ 367 static int 368 grab_mcontext(struct thread *td, mcontext_t *mcp, int flags) 369 { 370 struct pcb *pcb; 371 372 pcb = td->td_pcb; 373 374 memset(mcp, 0, sizeof(mcontext_t)); 375 376 mcp->mc_vers = _MC_VERSION; 377 mcp->mc_flags = 0; 378 memcpy(&mcp->mc_frame, td->td_frame, sizeof(struct trapframe)); 379 if (flags & GET_MC_CLEAR_RET) { 380 mcp->mc_gpr[3] = 0; 381 mcp->mc_gpr[4] = 0; 382 } 383 384 #ifdef AIM 385 /* 386 * This assumes that floating-point context is *not* lazy, 387 * so if the thread has used FP there would have been a 388 * FP-unavailable exception that would have set things up 389 * correctly. 390 */ 391 if (pcb->pcb_flags & PCB_FPU) { 392 KASSERT(td == curthread, 393 ("get_mcontext: fp save not curthread")); 394 critical_enter(); 395 save_fpu(td); 396 critical_exit(); 397 mcp->mc_flags |= _MC_FP_VALID; 398 memcpy(&mcp->mc_fpscr, &pcb->pcb_fpu.fpscr, sizeof(double)); 399 memcpy(mcp->mc_fpreg, pcb->pcb_fpu.fpr, 32*sizeof(double)); 400 } 401 402 /* 403 * Repeat for Altivec context 404 */ 405 406 if (pcb->pcb_flags & PCB_VEC) { 407 KASSERT(td == curthread, 408 ("get_mcontext: fp save not curthread")); 409 critical_enter(); 410 save_vec(td); 411 critical_exit(); 412 mcp->mc_flags |= _MC_AV_VALID; 413 mcp->mc_vscr = pcb->pcb_vec.vscr; 414 mcp->mc_vrsave = pcb->pcb_vec.vrsave; 415 memcpy(mcp->mc_avec, pcb->pcb_vec.vr, sizeof(mcp->mc_avec)); 416 } 417 #endif 418 419 mcp->mc_len = sizeof(*mcp); 420 421 return (0); 422 } 423 424 int 425 get_mcontext(struct thread *td, mcontext_t *mcp, int flags) 426 { 427 int error; 428 429 error = grab_mcontext(td, mcp, flags); 430 if (error == 0) { 431 PROC_LOCK(curthread->td_proc); 432 mcp->mc_onstack = sigonstack(td->td_frame->fixreg[1]); 433 PROC_UNLOCK(curthread->td_proc); 434 } 435 436 return (error); 437 } 438 439 int 440 set_mcontext(struct thread *td, const mcontext_t *mcp) 441 { 442 struct pcb *pcb; 443 struct trapframe *tf; 444 register_t tls; 445 446 pcb = td->td_pcb; 447 tf = td->td_frame; 448 449 if (mcp->mc_vers != _MC_VERSION || mcp->mc_len != sizeof(*mcp)) 450 return (EINVAL); 451 452 #ifdef AIM 453 /* 454 * Don't let the user set privileged MSR bits 455 */ 456 if ((mcp->mc_srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC)) { 457 return (EINVAL); 458 } 459 #endif 460 461 /* Copy trapframe, preserving TLS pointer across context change */ 462 if (SV_PROC_FLAG(td->td_proc, SV_LP64)) 463 tls = tf->fixreg[13]; 464 else 465 tls = tf->fixreg[2]; 466 memcpy(tf, mcp->mc_frame, sizeof(mcp->mc_frame)); 467 if (SV_PROC_FLAG(td->td_proc, SV_LP64)) 468 tf->fixreg[13] = tls; 469 else 470 tf->fixreg[2] = tls; 471 472 #ifdef AIM 473 if (mcp->mc_flags & _MC_FP_VALID) { 474 if ((pcb->pcb_flags & PCB_FPU) != PCB_FPU) { 475 critical_enter(); 476 enable_fpu(td); 477 critical_exit(); 478 } 479 memcpy(&pcb->pcb_fpu.fpscr, &mcp->mc_fpscr, sizeof(double)); 480 memcpy(pcb->pcb_fpu.fpr, mcp->mc_fpreg, 32*sizeof(double)); 481 } 482 483 if (mcp->mc_flags & _MC_AV_VALID) { 484 if ((pcb->pcb_flags & PCB_VEC) != PCB_VEC) { 485 critical_enter(); 486 enable_vec(td); 487 critical_exit(); 488 } 489 pcb->pcb_vec.vscr = mcp->mc_vscr; 490 pcb->pcb_vec.vrsave = mcp->mc_vrsave; 491 memcpy(pcb->pcb_vec.vr, mcp->mc_avec, sizeof(mcp->mc_avec)); 492 } 493 #endif 494 495 return (0); 496 } 497 498 /* 499 * Set set up registers on exec. 500 */ 501 void 502 exec_setregs(struct thread *td, struct image_params *imgp, u_long stack) 503 { 504 struct trapframe *tf; 505 register_t argc; 506 #ifdef __powerpc64__ 507 register_t entry_desc[3]; 508 #endif 509 510 tf = trapframe(td); 511 bzero(tf, sizeof *tf); 512 #ifdef __powerpc64__ 513 tf->fixreg[1] = -roundup(-stack + 48, 16); 514 #else 515 tf->fixreg[1] = -roundup(-stack + 8, 16); 516 #endif 517 518 /* 519 * Set up arguments for _start(): 520 * _start(argc, argv, envp, obj, cleanup, ps_strings); 521 * 522 * Notes: 523 * - obj and cleanup are the auxilliary and termination 524 * vectors. They are fixed up by ld.elf_so. 525 * - ps_strings is a NetBSD extention, and will be 526 * ignored by executables which are strictly 527 * compliant with the SVR4 ABI. 528 * 529 * XXX We have to set both regs and retval here due to different 530 * XXX calling convention in trap.c and init_main.c. 531 */ 532 533 /* Collect argc from the user stack */ 534 argc = fuword((void *)stack); 535 536 /* 537 * XXX PG: these get overwritten in the syscall return code. 538 * execve() should return EJUSTRETURN, like it does on NetBSD. 539 * Emulate by setting the syscall return value cells. The 540 * registers still have to be set for init's fork trampoline. 541 */ 542 td->td_retval[0] = argc; 543 td->td_retval[1] = stack + sizeof(register_t); 544 tf->fixreg[3] = argc; 545 tf->fixreg[4] = stack + sizeof(register_t); 546 tf->fixreg[5] = stack + (2 + argc)*sizeof(register_t); 547 tf->fixreg[6] = 0; /* auxillary vector */ 548 tf->fixreg[7] = 0; /* termination vector */ 549 tf->fixreg[8] = (register_t)imgp->ps_strings; /* NetBSD extension */ 550 551 #ifdef __powerpc64__ 552 /* 553 * For 64-bit, we need to disentangle the function descriptor 554 * 555 * 0. entry point 556 * 1. TOC value (r2) 557 * 2. Environment pointer (r11) 558 */ 559 560 (void)copyin((void *)imgp->entry_addr, entry_desc, sizeof(entry_desc)); 561 tf->srr0 = entry_desc[0] + imgp->reloc_base; 562 tf->fixreg[2] = entry_desc[1] + imgp->reloc_base; 563 tf->fixreg[11] = entry_desc[2] + imgp->reloc_base; 564 tf->srr1 = PSL_SF | PSL_USERSET | PSL_FE_DFLT; 565 if (mfmsr() & PSL_HV) 566 tf->srr1 |= PSL_HV; 567 #else 568 tf->srr0 = imgp->entry_addr; 569 tf->srr1 = PSL_USERSET | PSL_FE_DFLT; 570 #endif 571 td->td_pcb->pcb_flags = 0; 572 } 573 574 #ifdef COMPAT_FREEBSD32 575 void 576 ppc32_setregs(struct thread *td, struct image_params *imgp, u_long stack) 577 { 578 struct trapframe *tf; 579 uint32_t argc; 580 581 tf = trapframe(td); 582 bzero(tf, sizeof *tf); 583 tf->fixreg[1] = -roundup(-stack + 8, 16); 584 585 argc = fuword32((void *)stack); 586 587 td->td_retval[0] = argc; 588 td->td_retval[1] = stack + sizeof(uint32_t); 589 tf->fixreg[3] = argc; 590 tf->fixreg[4] = stack + sizeof(uint32_t); 591 tf->fixreg[5] = stack + (2 + argc)*sizeof(uint32_t); 592 tf->fixreg[6] = 0; /* auxillary vector */ 593 tf->fixreg[7] = 0; /* termination vector */ 594 tf->fixreg[8] = (register_t)imgp->ps_strings; /* NetBSD extension */ 595 596 tf->srr0 = imgp->entry_addr; 597 tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT; 598 tf->srr1 &= ~PSL_SF; 599 if (mfmsr() & PSL_HV) 600 tf->srr1 |= PSL_HV; 601 td->td_pcb->pcb_flags = 0; 602 } 603 #endif 604 605 int 606 fill_regs(struct thread *td, struct reg *regs) 607 { 608 struct trapframe *tf; 609 610 tf = td->td_frame; 611 memcpy(regs, tf, sizeof(struct reg)); 612 613 return (0); 614 } 615 616 int 617 fill_dbregs(struct thread *td, struct dbreg *dbregs) 618 { 619 /* No debug registers on PowerPC */ 620 return (ENOSYS); 621 } 622 623 int 624 fill_fpregs(struct thread *td, struct fpreg *fpregs) 625 { 626 struct pcb *pcb; 627 628 pcb = td->td_pcb; 629 630 if ((pcb->pcb_flags & PCB_FPU) == 0) 631 memset(fpregs, 0, sizeof(struct fpreg)); 632 else 633 memcpy(fpregs, &pcb->pcb_fpu, sizeof(struct fpreg)); 634 635 return (0); 636 } 637 638 int 639 set_regs(struct thread *td, struct reg *regs) 640 { 641 struct trapframe *tf; 642 643 tf = td->td_frame; 644 memcpy(tf, regs, sizeof(struct reg)); 645 646 return (0); 647 } 648 649 int 650 set_dbregs(struct thread *td, struct dbreg *dbregs) 651 { 652 /* No debug registers on PowerPC */ 653 return (ENOSYS); 654 } 655 656 int 657 set_fpregs(struct thread *td, struct fpreg *fpregs) 658 { 659 #ifdef AIM 660 struct pcb *pcb; 661 662 pcb = td->td_pcb; 663 if ((pcb->pcb_flags & PCB_FPU) == 0) 664 enable_fpu(td); 665 memcpy(&pcb->pcb_fpu, fpregs, sizeof(struct fpreg)); 666 #endif 667 668 return (0); 669 } 670 671 #ifdef COMPAT_FREEBSD32 672 int 673 set_regs32(struct thread *td, struct reg32 *regs) 674 { 675 struct trapframe *tf; 676 int i; 677 678 tf = td->td_frame; 679 for (i = 0; i < 32; i++) 680 tf->fixreg[i] = regs->fixreg[i]; 681 tf->lr = regs->lr; 682 tf->cr = regs->cr; 683 tf->xer = regs->xer; 684 tf->ctr = regs->ctr; 685 tf->srr0 = regs->pc; 686 687 return (0); 688 } 689 690 int 691 fill_regs32(struct thread *td, struct reg32 *regs) 692 { 693 struct trapframe *tf; 694 int i; 695 696 tf = td->td_frame; 697 for (i = 0; i < 32; i++) 698 regs->fixreg[i] = tf->fixreg[i]; 699 regs->lr = tf->lr; 700 regs->cr = tf->cr; 701 regs->xer = tf->xer; 702 regs->ctr = tf->ctr; 703 regs->pc = tf->srr0; 704 705 return (0); 706 } 707 708 static int 709 grab_mcontext32(struct thread *td, mcontext32_t *mcp, int flags) 710 { 711 mcontext_t mcp64; 712 int i, error; 713 714 error = grab_mcontext(td, &mcp64, flags); 715 if (error != 0) 716 return (error); 717 718 mcp->mc_vers = mcp64.mc_vers; 719 mcp->mc_flags = mcp64.mc_flags; 720 mcp->mc_onstack = mcp64.mc_onstack; 721 mcp->mc_len = mcp64.mc_len; 722 memcpy(mcp->mc_avec,mcp64.mc_avec,sizeof(mcp64.mc_avec)); 723 memcpy(mcp->mc_av,mcp64.mc_av,sizeof(mcp64.mc_av)); 724 for (i = 0; i < 42; i++) 725 mcp->mc_frame[i] = mcp64.mc_frame[i]; 726 memcpy(mcp->mc_fpreg,mcp64.mc_fpreg,sizeof(mcp64.mc_fpreg)); 727 728 return (0); 729 } 730 731 static int 732 get_mcontext32(struct thread *td, mcontext32_t *mcp, int flags) 733 { 734 int error; 735 736 error = grab_mcontext32(td, mcp, flags); 737 if (error == 0) { 738 PROC_LOCK(curthread->td_proc); 739 mcp->mc_onstack = sigonstack(td->td_frame->fixreg[1]); 740 PROC_UNLOCK(curthread->td_proc); 741 } 742 743 return (error); 744 } 745 746 static int 747 set_mcontext32(struct thread *td, const mcontext32_t *mcp) 748 { 749 mcontext_t mcp64; 750 int i, error; 751 752 mcp64.mc_vers = mcp->mc_vers; 753 mcp64.mc_flags = mcp->mc_flags; 754 mcp64.mc_onstack = mcp->mc_onstack; 755 mcp64.mc_len = mcp->mc_len; 756 memcpy(mcp64.mc_avec,mcp->mc_avec,sizeof(mcp64.mc_avec)); 757 memcpy(mcp64.mc_av,mcp->mc_av,sizeof(mcp64.mc_av)); 758 for (i = 0; i < 42; i++) 759 mcp64.mc_frame[i] = mcp->mc_frame[i]; 760 memcpy(mcp64.mc_fpreg,mcp->mc_fpreg,sizeof(mcp64.mc_fpreg)); 761 762 error = set_mcontext(td, &mcp64); 763 764 return (error); 765 } 766 #endif 767 768 #ifdef COMPAT_FREEBSD32 769 int 770 freebsd32_sigreturn(struct thread *td, struct freebsd32_sigreturn_args *uap) 771 { 772 ucontext32_t uc; 773 int error; 774 775 CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp); 776 777 if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) { 778 CTR1(KTR_SIG, "sigreturn: efault td=%p", td); 779 return (EFAULT); 780 } 781 782 error = set_mcontext32(td, &uc.uc_mcontext); 783 if (error != 0) 784 return (error); 785 786 kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); 787 788 CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x", 789 td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]); 790 791 return (EJUSTRETURN); 792 } 793 794 /* 795 * The first two fields of a ucontext_t are the signal mask and the machine 796 * context. The next field is uc_link; we want to avoid destroying the link 797 * when copying out contexts. 798 */ 799 #define UC32_COPY_SIZE offsetof(ucontext32_t, uc_link) 800 801 int 802 freebsd32_getcontext(struct thread *td, struct freebsd32_getcontext_args *uap) 803 { 804 ucontext32_t uc; 805 int ret; 806 807 if (uap->ucp == NULL) 808 ret = EINVAL; 809 else { 810 get_mcontext32(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); 811 PROC_LOCK(td->td_proc); 812 uc.uc_sigmask = td->td_sigmask; 813 PROC_UNLOCK(td->td_proc); 814 ret = copyout(&uc, uap->ucp, UC32_COPY_SIZE); 815 } 816 return (ret); 817 } 818 819 int 820 freebsd32_setcontext(struct thread *td, struct freebsd32_setcontext_args *uap) 821 { 822 ucontext32_t uc; 823 int ret; 824 825 if (uap->ucp == NULL) 826 ret = EINVAL; 827 else { 828 ret = copyin(uap->ucp, &uc, UC32_COPY_SIZE); 829 if (ret == 0) { 830 ret = set_mcontext32(td, &uc.uc_mcontext); 831 if (ret == 0) { 832 kern_sigprocmask(td, SIG_SETMASK, 833 &uc.uc_sigmask, NULL, 0); 834 } 835 } 836 } 837 return (ret == 0 ? EJUSTRETURN : ret); 838 } 839 840 int 841 freebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap) 842 { 843 ucontext32_t uc; 844 int ret; 845 846 if (uap->oucp == NULL || uap->ucp == NULL) 847 ret = EINVAL; 848 else { 849 get_mcontext32(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); 850 PROC_LOCK(td->td_proc); 851 uc.uc_sigmask = td->td_sigmask; 852 PROC_UNLOCK(td->td_proc); 853 ret = copyout(&uc, uap->oucp, UC32_COPY_SIZE); 854 if (ret == 0) { 855 ret = copyin(uap->ucp, &uc, UC32_COPY_SIZE); 856 if (ret == 0) { 857 ret = set_mcontext32(td, &uc.uc_mcontext); 858 if (ret == 0) { 859 kern_sigprocmask(td, SIG_SETMASK, 860 &uc.uc_sigmask, NULL, 0); 861 } 862 } 863 } 864 } 865 return (ret == 0 ? EJUSTRETURN : ret); 866 } 867 868 #endif 869 870 void 871 cpu_set_syscall_retval(struct thread *td, int error) 872 { 873 struct proc *p; 874 struct trapframe *tf; 875 int fixup; 876 877 if (error == EJUSTRETURN) 878 return; 879 880 p = td->td_proc; 881 tf = td->td_frame; 882 883 if (tf->fixreg[0] == SYS___syscall && 884 (SV_PROC_FLAG(p, SV_ILP32))) { 885 int code = tf->fixreg[FIRSTARG + 1]; 886 if (p->p_sysent->sv_mask) 887 code &= p->p_sysent->sv_mask; 888 fixup = (code != SYS_freebsd6_lseek && code != SYS_lseek) ? 889 1 : 0; 890 } else 891 fixup = 0; 892 893 switch (error) { 894 case 0: 895 if (fixup) { 896 /* 897 * 64-bit return, 32-bit syscall. Fixup byte order 898 */ 899 tf->fixreg[FIRSTARG] = 0; 900 tf->fixreg[FIRSTARG + 1] = td->td_retval[0]; 901 } else { 902 tf->fixreg[FIRSTARG] = td->td_retval[0]; 903 tf->fixreg[FIRSTARG + 1] = td->td_retval[1]; 904 } 905 tf->cr &= ~0x10000000; /* Unset summary overflow */ 906 break; 907 case ERESTART: 908 /* 909 * Set user's pc back to redo the system call. 910 */ 911 tf->srr0 -= 4; 912 break; 913 default: 914 if (p->p_sysent->sv_errsize) { 915 error = (error < p->p_sysent->sv_errsize) ? 916 p->p_sysent->sv_errtbl[error] : -1; 917 } 918 tf->fixreg[FIRSTARG] = error; 919 tf->cr |= 0x10000000; /* Set summary overflow */ 920 break; 921 } 922 } 923 924 /* 925 * Threading functions 926 */ 927 void 928 cpu_thread_exit(struct thread *td) 929 { 930 } 931 932 void 933 cpu_thread_clean(struct thread *td) 934 { 935 } 936 937 void 938 cpu_thread_alloc(struct thread *td) 939 { 940 struct pcb *pcb; 941 942 pcb = (struct pcb *)((td->td_kstack + td->td_kstack_pages * PAGE_SIZE - 943 sizeof(struct pcb)) & ~0x2fUL); 944 td->td_pcb = pcb; 945 td->td_frame = (struct trapframe *)pcb - 1; 946 } 947 948 void 949 cpu_thread_free(struct thread *td) 950 { 951 } 952 953 int 954 cpu_set_user_tls(struct thread *td, void *tls_base) 955 { 956 957 if (SV_PROC_FLAG(td->td_proc, SV_LP64)) 958 td->td_frame->fixreg[13] = (register_t)tls_base + 0x7010; 959 else 960 td->td_frame->fixreg[2] = (register_t)tls_base + 0x7008; 961 return (0); 962 } 963 964 void 965 cpu_set_upcall(struct thread *td, struct thread *td0) 966 { 967 struct pcb *pcb2; 968 struct trapframe *tf; 969 struct callframe *cf; 970 971 pcb2 = td->td_pcb; 972 973 /* Copy the upcall pcb */ 974 bcopy(td0->td_pcb, pcb2, sizeof(*pcb2)); 975 976 /* Create a stack for the new thread */ 977 tf = td->td_frame; 978 bcopy(td0->td_frame, tf, sizeof(struct trapframe)); 979 tf->fixreg[FIRSTARG] = 0; 980 tf->fixreg[FIRSTARG + 1] = 0; 981 tf->cr &= ~0x10000000; 982 983 /* Set registers for trampoline to user mode. */ 984 cf = (struct callframe *)tf - 1; 985 memset(cf, 0, sizeof(struct callframe)); 986 cf->cf_func = (register_t)fork_return; 987 cf->cf_arg0 = (register_t)td; 988 cf->cf_arg1 = (register_t)tf; 989 990 pcb2->pcb_sp = (register_t)cf; 991 #ifdef __powerpc64__ 992 pcb2->pcb_lr = ((register_t *)fork_trampoline)[0]; 993 pcb2->pcb_toc = ((register_t *)fork_trampoline)[1]; 994 #else 995 pcb2->pcb_lr = (register_t)fork_trampoline; 996 #endif 997 pcb2->pcb_cpu.aim.usr_vsid = 0; 998 999 /* Setup to release spin count in fork_exit(). */ 1000 td->td_md.md_spinlock_count = 1; 1001 td->td_md.md_saved_msr = PSL_KERNSET; 1002 } 1003 1004 void 1005 cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg, 1006 stack_t *stack) 1007 { 1008 struct trapframe *tf; 1009 uintptr_t sp; 1010 1011 tf = td->td_frame; 1012 /* align stack and alloc space for frame ptr and saved LR */ 1013 #ifdef __powerpc64__ 1014 sp = ((uintptr_t)stack->ss_sp + stack->ss_size - 48) & 1015 ~0x1f; 1016 #else 1017 sp = ((uintptr_t)stack->ss_sp + stack->ss_size - 8) & 1018 ~0x1f; 1019 #endif 1020 bzero(tf, sizeof(struct trapframe)); 1021 1022 tf->fixreg[1] = (register_t)sp; 1023 tf->fixreg[3] = (register_t)arg; 1024 if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) { 1025 tf->srr0 = (register_t)entry; 1026 #ifdef AIM 1027 tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT; 1028 #ifdef __powerpc64__ 1029 tf->srr1 &= ~PSL_SF; 1030 #endif 1031 #else 1032 tf->srr1 = PSL_USERSET; 1033 #endif 1034 } else { 1035 #ifdef __powerpc64__ 1036 register_t entry_desc[3]; 1037 (void)copyin((void *)entry, entry_desc, sizeof(entry_desc)); 1038 tf->srr0 = entry_desc[0]; 1039 tf->fixreg[2] = entry_desc[1]; 1040 tf->fixreg[11] = entry_desc[2]; 1041 tf->srr1 = PSL_SF | PSL_MBO | PSL_USERSET | PSL_FE_DFLT; 1042 #endif 1043 } 1044 1045 #ifdef __powerpc64__ 1046 if (mfmsr() & PSL_HV) 1047 tf->srr1 |= PSL_HV; 1048 #endif 1049 td->td_pcb->pcb_flags = 0; 1050 1051 td->td_retval[0] = (register_t)entry; 1052 td->td_retval[1] = 0; 1053 } 1054 1055