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