1/* $NetBSD: trap.c,v 1.126 2011/06/07 00:48:30 matt Exp $ */ 2 3/*- 4 * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center, by Charles M. Hannum, and by Ross Harvey. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33/* 34 * Copyright (c) 1999 Christopher G. Demetriou. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. All advertising materials mentioning features or use of this software 45 * must display the following acknowledgement: 46 * This product includes software developed by Christopher G. Demetriou 47 * for the NetBSD Project. 48 * 4. The name of the author may not be used to endorse or promote products 49 * derived from this software without specific prior written permission 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 52 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 53 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 54 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 55 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 60 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 61 */ 62 63/* 64 * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. 65 * All rights reserved. 66 * 67 * Author: Chris G. Demetriou 68 * 69 * Permission to use, copy, modify and distribute this software and 70 * its documentation is hereby granted, provided that both the copyright 71 * notice and this permission notice appear in all copies of the 72 * software, derivative works or modified versions, and any portions 73 * thereof, and that both notices appear in supporting documentation. 74 * 75 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 76 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 77 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 78 * 79 * Carnegie Mellon requests users of this software to return to 80 * 81 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 82 * School of Computer Science 83 * Carnegie Mellon University 84 * Pittsburgh PA 15213-3890 85 * 86 * any improvements or extensions that they make and grant Carnegie the 87 * rights to redistribute these changes. 88 */ 89 90#include "opt_fix_unaligned_vax_fp.h" 91#include "opt_ddb.h" 92#include "opt_multiprocessor.h" 93 94#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 95 96__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.126 2011/06/07 00:48:30 matt Exp $"); 97 98#include <sys/param.h> 99#include <sys/systm.h> 100#include <sys/proc.h> 101#include <sys/sa.h> 102#include <sys/savar.h> 103#include <sys/syscall.h> 104#include <sys/buf.h> 105#include <sys/kauth.h> 106#include <sys/kmem.h> 107#include <sys/cpu.h> 108#include <sys/atomic.h> 109 110#include <uvm/uvm_extern.h> 111 112#include <machine/reg.h> 113#include <machine/alpha.h> 114#include <machine/fpu.h> 115#include <machine/rpb.h> 116#ifdef DDB 117#include <machine/db_machdep.h> 118#endif 119#include <alpha/alpha/db_instruction.h> 120#include <machine/userret.h> 121 122static int unaligned_fixup(u_long, u_long, u_long, struct lwp *); 123static int handle_opdec(struct lwp *l, u_long *ucodep); 124static int alpha_ucode_to_ksiginfo(u_long ucode); 125 126/* 127 * Initialize the trap vectors for the current processor. 128 */ 129void 130trap_init(void) 131{ 132 133 /* 134 * Point interrupt/exception vectors to our own. 135 */ 136 alpha_pal_wrent(XentInt, ALPHA_KENTRY_INT); 137 alpha_pal_wrent(XentArith, ALPHA_KENTRY_ARITH); 138 alpha_pal_wrent(XentMM, ALPHA_KENTRY_MM); 139 alpha_pal_wrent(XentIF, ALPHA_KENTRY_IF); 140 alpha_pal_wrent(XentUna, ALPHA_KENTRY_UNA); 141 alpha_pal_wrent(XentSys, ALPHA_KENTRY_SYS); 142 143 /* 144 * Clear pending machine checks and error reports, and enable 145 * system- and processor-correctable error reporting. 146 */ 147 alpha_pal_wrmces(alpha_pal_rdmces() & 148 ~(ALPHA_MCES_DSC|ALPHA_MCES_DPC)); 149} 150 151static void 152printtrap(const u_long a0, const u_long a1, const u_long a2, 153 const u_long entry, struct trapframe *framep, int isfatal, int user) 154{ 155 char ubuf[64]; 156 const char *entryname; 157 u_long cpu_id = cpu_number(); 158 159 switch (entry) { 160 case ALPHA_KENTRY_INT: 161 entryname = "interrupt"; 162 break; 163 case ALPHA_KENTRY_ARITH: 164 entryname = "arithmetic trap"; 165 break; 166 case ALPHA_KENTRY_MM: 167 entryname = "memory management fault"; 168 break; 169 case ALPHA_KENTRY_IF: 170 entryname = "instruction fault"; 171 break; 172 case ALPHA_KENTRY_UNA: 173 entryname = "unaligned access fault"; 174 break; 175 case ALPHA_KENTRY_SYS: 176 entryname = "system call"; 177 break; 178 default: 179 sprintf(ubuf, "type %lx", entry); 180 entryname = (const char *) ubuf; 181 break; 182 } 183 184 printf("\n"); 185 printf("CPU %lu: %s %s trap:\n", cpu_id, isfatal ? "fatal" : "handled", 186 user ? "user" : "kernel"); 187 printf("\n"); 188 printf("CPU %lu trap entry = 0x%lx (%s)\n", cpu_id, entry, 189 entryname); 190 printf("CPU %lu a0 = 0x%lx\n", cpu_id, a0); 191 printf("CPU %lu a1 = 0x%lx\n", cpu_id, a1); 192 printf("CPU %lu a2 = 0x%lx\n", cpu_id, a2); 193 printf("CPU %lu pc = 0x%lx\n", cpu_id, 194 framep->tf_regs[FRAME_PC]); 195 printf("CPU %lu ra = 0x%lx\n", cpu_id, 196 framep->tf_regs[FRAME_RA]); 197 printf("CPU %lu pv = 0x%lx\n", cpu_id, 198 framep->tf_regs[FRAME_T12]); 199 printf("CPU %lu curlwp = %p\n", cpu_id, curlwp); 200 printf("CPU %lu pid = %d, comm = %s\n", cpu_id, 201 curproc->p_pid, curproc->p_comm); 202 printf("\n"); 203} 204 205/* 206 * Trap is called from locore to handle most types of processor traps. 207 * System calls are broken out for efficiency and ASTs are broken out 208 * to make the code a bit cleaner and more representative of the 209 * Alpha architecture. 210 */ 211/*ARGSUSED*/ 212void 213trap(const u_long a0, const u_long a1, const u_long a2, const u_long entry, 214 struct trapframe *framep) 215{ 216 struct lwp *l; 217 struct proc *p; 218 struct pcb *pcb; 219 vaddr_t onfault; 220 ksiginfo_t ksi; 221 vm_prot_t ftype; 222 uint64_t ucode; 223 int i, user; 224#if defined(DDB) 225 int call_debugger = 1; 226#endif 227 228 curcpu()->ci_data.cpu_ntrap++; 229 230 l = curlwp; 231 232 user = (framep->tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE) != 0; 233 if (user) { 234 l->l_md.md_tf = framep; 235 p = l->l_proc; 236 (void)memset(&ksi, 0, sizeof(ksi)); 237 LWP_CACHE_CREDS(l, p); 238 } else { 239 p = NULL; 240 } 241 242 switch (entry) { 243 case ALPHA_KENTRY_UNA: 244 /* 245 * If user-land, do whatever fixups, printing, and 246 * signalling is appropriate (based on system-wide 247 * and per-process unaligned-access-handling flags). 248 */ 249 if (user) { 250 i = unaligned_fixup(a0, a1, a2, l); 251 if (i == 0) 252 goto out; 253 254 KSI_INIT_TRAP(&ksi); 255 ksi.ksi_signo = i; 256 ksi.ksi_code = BUS_ADRALN; 257 ksi.ksi_addr = (void *)a0; /* VA */ 258 ksi.ksi_trap = BUS_ADRALN; /* XXX appropriate? */ 259 break; 260 } 261 262 /* 263 * Unaligned access from kernel mode is always an error, 264 * EVEN IF A COPY FAULT HANDLER IS SET! 265 * 266 * It's an error if a copy fault handler is set because 267 * the various routines which do user-initiated copies 268 * do so in a memcpy-like manner. In other words, the 269 * kernel never assumes that pointers provided by the 270 * user are properly aligned, and so if the kernel 271 * does cause an unaligned access it's a kernel bug. 272 */ 273 goto dopanic; 274 275 case ALPHA_KENTRY_ARITH: 276 /* 277 * Resolve trap shadows, interpret FP ops requiring infinities, 278 * NaNs, or denorms, and maintain FPCR corrections. 279 */ 280 if (user) { 281 i = alpha_fp_complete(a0, a1, l, &ucode); 282 if (i == 0) 283 goto out; 284 KSI_INIT_TRAP(&ksi); 285 ksi.ksi_signo = i; 286 if (i == SIGSEGV) 287 ksi.ksi_code = SEGV_MAPERR; /* just pick one */ 288 else { 289 ksi.ksi_code = alpha_ucode_to_ksiginfo(ucode); 290 ksi.ksi_addr = 291 (void *)l->l_md.md_tf->tf_regs[FRAME_PC]; 292 ksi.ksi_trap = (int)ucode; 293 } 294 break; 295 } 296 297 /* Always fatal in kernel. Should never happen. */ 298 goto dopanic; 299 300 case ALPHA_KENTRY_IF: 301 /* 302 * These are always fatal in kernel, and should never 303 * happen. (Debugger entry is handled in XentIF.) 304 */ 305 if (user == 0) { 306#if defined(DDB) 307 /* 308 * ...unless a debugger is configured. It will 309 * inform us if the trap was handled. 310 */ 311 if (alpha_debug(a0, a1, a2, entry, framep)) 312 goto out; 313 314 /* 315 * Debugger did NOT handle the trap, don't 316 * call the debugger again! 317 */ 318 call_debugger = 0; 319#endif 320 goto dopanic; 321 } 322 i = 0; 323 switch (a0) { 324 case ALPHA_IF_CODE_GENTRAP: 325 if (framep->tf_regs[FRAME_A0] == -2) { /* weird! */ 326 KSI_INIT_TRAP(&ksi); 327 ksi.ksi_signo = SIGFPE; 328 ksi.ksi_code = alpha_ucode_to_ksiginfo(ucode); 329 ksi.ksi_addr = 330 (void *)l->l_md.md_tf->tf_regs[FRAME_PC]; 331 ksi.ksi_trap = a0; /* exception summary */ 332 break; 333 } 334 /* FALLTHROUGH */ 335 case ALPHA_IF_CODE_BPT: 336 case ALPHA_IF_CODE_BUGCHK: 337 KSI_INIT_TRAP(&ksi); 338 ksi.ksi_signo = SIGTRAP; 339 ksi.ksi_code = TRAP_BRKPT; 340 ksi.ksi_addr = (void *)l->l_md.md_tf->tf_regs[FRAME_PC]; 341 ksi.ksi_trap = a0; /* trap type */ 342 break; 343 344 case ALPHA_IF_CODE_OPDEC: 345 i = handle_opdec(l, &ucode); 346 KSI_INIT_TRAP(&ksi); 347 if (i == 0) 348 goto out; 349 else if (i == SIGSEGV) 350 ksi.ksi_code = SEGV_MAPERR; 351 else if (i == SIGILL) 352 ksi.ksi_code = ILL_ILLOPC; 353 ksi.ksi_signo = i; 354 ksi.ksi_addr = 355 (void *)l->l_md.md_tf->tf_regs[FRAME_PC]; 356 ksi.ksi_trap = (int)ucode; 357 break; 358 359 case ALPHA_IF_CODE_FEN: 360 fpu_load(); 361 goto out; 362 363 default: 364 printf("trap: unknown IF type 0x%lx\n", a0); 365 goto dopanic; 366 } 367 break; 368 369 case ALPHA_KENTRY_MM: 370 pcb = lwp_getpcb(l); 371 onfault = pcb->pcb_onfault; 372 373 switch (a1) { 374 case ALPHA_MMCSR_FOR: 375 case ALPHA_MMCSR_FOE: 376 case ALPHA_MMCSR_FOW: 377 if (pmap_emulate_reference(l, a0, user, a1)) { 378 ftype = VM_PROT_EXECUTE; 379 goto do_fault; 380 } 381 goto out; 382 383 case ALPHA_MMCSR_INVALTRANS: 384 case ALPHA_MMCSR_ACCESS: 385 { 386 vaddr_t va; 387 struct vmspace *vm = NULL; 388 struct vm_map *map; 389 int rv; 390 391 switch (a2) { 392 case -1: /* instruction fetch fault */ 393 ftype = VM_PROT_EXECUTE; 394 break; 395 case 0: /* load instruction */ 396 ftype = VM_PROT_READ; 397 break; 398 case 1: /* store instruction */ 399 ftype = VM_PROT_WRITE; 400 break; 401 default: 402#ifdef DIAGNOSTIC 403 panic("trap: bad fault type"); 404#else 405 ftype = VM_PROT_NONE; 406 break; 407#endif 408 } 409 410 if (user) { 411 if (l->l_flag & LW_SA) { 412 l->l_savp->savp_faultaddr = (vaddr_t)a0; 413 l->l_pflag |= LP_SA_PAGEFAULT; 414 } 415 } else { 416 struct cpu_info *ci = curcpu(); 417 418 if (l == NULL) { 419 /* 420 * If there is no current process, 421 * it can be nothing but a fatal 422 * error (i.e. memory in this case 423 * must be wired). 424 */ 425 goto dopanic; 426 } 427 428 /* 429 * If it was caused by fuswintr or suswintr, 430 * just punt. Note that we check the faulting 431 * address against the address accessed by 432 * [fs]uswintr, in case another fault happens 433 * when they are running. 434 */ 435 436 if (onfault == (vaddr_t)fswintrberr && 437 pcb->pcb_accessaddr == a0) { 438 framep->tf_regs[FRAME_PC] = onfault; 439 pcb->pcb_onfault = 0; 440 goto out; 441 } 442 443 /* 444 * If we're in interrupt context at this 445 * point, this is an error. 446 */ 447 if (ci->ci_intrdepth != 0) 448 goto dopanic; 449 } 450 451 /* 452 * It is only a kernel address space fault iff: 453 * 1. !user and 454 * 2. pcb_onfault not set or 455 * 3. pcb_onfault set but kernel space data fault 456 * The last can occur during an exec() copyin where the 457 * argument space is lazy-allocated. 458 */ 459do_fault: 460 pcb = lwp_getpcb(l); 461 if (user == 0 && (a0 >= VM_MIN_KERNEL_ADDRESS || 462 onfault == 0)) 463 map = kernel_map; 464 else { 465 vm = l->l_proc->p_vmspace; 466 map = &vm->vm_map; 467 } 468 469 va = trunc_page((vaddr_t)a0); 470 pcb->pcb_onfault = 0; 471 rv = uvm_fault(map, va, ftype); 472 pcb->pcb_onfault = onfault; 473 474 /* 475 * If this was a stack access we keep track of the 476 * maximum accessed stack size. Also, if vm_fault 477 * gets a protection failure it is due to accessing 478 * the stack region outside the current limit and 479 * we need to reflect that as an access error. 480 */ 481 if (map != kernel_map && 482 (void *)va >= vm->vm_maxsaddr && 483 va < USRSTACK) { 484 if (rv == 0) 485 uvm_grow(l->l_proc, va); 486 else if (rv == EACCES && 487 ftype != VM_PROT_EXECUTE) 488 rv = EFAULT; 489 } 490 if (rv == 0) { 491 if (user) 492 l->l_pflag &= ~LP_SA_PAGEFAULT; 493 goto out; 494 } 495 496 if (user == 0) { 497 /* Check for copyin/copyout fault */ 498 if (onfault != 0) { 499 framep->tf_regs[FRAME_PC] = onfault; 500 framep->tf_regs[FRAME_V0] = rv; 501 goto out; 502 } 503 goto dopanic; 504 } 505 KSI_INIT_TRAP(&ksi); 506 ksi.ksi_addr = (void *)a0; 507 ksi.ksi_trap = a1; /* MMCSR VALUE */ 508 if (rv == ENOMEM) { 509 printf("UVM: pid %d (%s), uid %d killed: " 510 "out of swap\n", l->l_proc->p_pid, 511 l->l_proc->p_comm, 512 l->l_cred ? 513 kauth_cred_geteuid(l->l_cred) : -1); 514 ksi.ksi_signo = SIGKILL; 515 } else 516 ksi.ksi_signo = SIGSEGV; 517 if (rv == EACCES) 518 ksi.ksi_code = SEGV_ACCERR; 519 else 520 ksi.ksi_code = SEGV_MAPERR; 521 l->l_pflag &= ~LP_SA_PAGEFAULT; 522 break; 523 } 524 525 default: 526 printf("trap: unknown MMCSR value 0x%lx\n", a1); 527 goto dopanic; 528 } 529 break; 530 531 default: 532 goto dopanic; 533 } 534 535#ifdef DEBUG 536 printtrap(a0, a1, a2, entry, framep, 1, user); 537#endif 538 (*p->p_emul->e_trapsignal)(l, &ksi); 539out: 540 if (user) 541 userret(l); 542 return; 543 544dopanic: 545 printtrap(a0, a1, a2, entry, framep, 1, user); 546 547 /* XXX dump registers */ 548 549#if defined(DDB) 550 if (call_debugger && alpha_debug(a0, a1, a2, entry, framep)) { 551 /* 552 * The debugger has handled the trap; just return. 553 */ 554 goto out; 555 } 556#endif 557 558 panic("trap"); 559} 560 561/* 562 * Process an asynchronous software trap. 563 * This is relatively easy. 564 */ 565void 566ast(struct trapframe *framep) 567{ 568 struct lwp *l; 569 570 /* 571 * We may not have a current process to do AST processing 572 * on. This happens on multiprocessor systems in which 573 * at least one CPU simply has no current process to run, 574 * but roundrobin() (called via hardclock()) kicks us to 575 * attempt to preempt the process running on our CPU. 576 */ 577 l = curlwp; 578 if (l == NULL) 579 return; 580 581 //curcpu()->ci_data.cpu_nast++; 582 l->l_md.md_tf = framep; 583 584 if (l->l_pflag & LP_OWEUPC) { 585 l->l_pflag &= ~LP_OWEUPC; 586 ADDUPROF(l); 587 } 588 589 if (curcpu()->ci_want_resched) { 590 /* 591 * We are being preempted. 592 */ 593 preempt(); 594 } 595 596 userret(l); 597} 598 599/* 600 * Unaligned access handler. It's not clear that this can get much slower... 601 * 602 */ 603static const int reg_to_framereg[32] = { 604 FRAME_V0, FRAME_T0, FRAME_T1, FRAME_T2, 605 FRAME_T3, FRAME_T4, FRAME_T5, FRAME_T6, 606 FRAME_T7, FRAME_S0, FRAME_S1, FRAME_S2, 607 FRAME_S3, FRAME_S4, FRAME_S5, FRAME_S6, 608 FRAME_A0, FRAME_A1, FRAME_A2, FRAME_A3, 609 FRAME_A4, FRAME_A5, FRAME_T8, FRAME_T9, 610 FRAME_T10, FRAME_T11, FRAME_RA, FRAME_T12, 611 FRAME_AT, FRAME_GP, FRAME_SP, -1, 612}; 613 614#define irp(l, reg) \ 615 ((reg_to_framereg[(reg)] == -1) ? NULL : \ 616 &(l)->l_md.md_tf->tf_regs[reg_to_framereg[(reg)]]) 617 618#define frp(l, reg) \ 619 (&pcb->pcb_fp.fpr_regs[(reg)]) 620 621#define unaligned_load(storage, ptrf, mod) \ 622 if (copyin((void *)va, &(storage), sizeof (storage)) != 0) \ 623 break; \ 624 signo = 0; \ 625 if ((regptr = ptrf(l, reg)) != NULL) \ 626 *regptr = mod (storage); 627 628#define unaligned_store(storage, ptrf, mod) \ 629 if ((regptr = ptrf(l, reg)) != NULL) \ 630 (storage) = mod (*regptr); \ 631 else \ 632 (storage) = 0; \ 633 if (copyout(&(storage), (void *)va, sizeof (storage)) != 0) \ 634 break; \ 635 signo = 0; 636 637#define unaligned_load_integer(storage) \ 638 unaligned_load(storage, irp, ) 639 640#define unaligned_store_integer(storage) \ 641 unaligned_store(storage, irp, ) 642 643#define unaligned_load_floating(storage, mod) do { \ 644 struct pcb * const pcb = lwp_getpcb(l); \ 645 fpu_save(); \ 646 unaligned_load(storage, frp, mod) \ 647} while (/*CONSTCOND*/0) 648 649#define unaligned_store_floating(storage, mod) do { \ 650 struct pcb * const pcb = lwp_getpcb(l); \ 651 fpu_save(); \ 652 unaligned_store(storage, frp, mod) \ 653} while (/*CONSTCOND*/0) 654 655static unsigned long 656Sfloat_to_reg(u_int s) 657{ 658 unsigned long sign, expn, frac; 659 unsigned long result; 660 661 sign = (s & 0x80000000) >> 31; 662 expn = (s & 0x7f800000) >> 23; 663 frac = (s & 0x007fffff) >> 0; 664 665 /* map exponent part, as appropriate. */ 666 if (expn == 0xff) 667 expn = 0x7ff; 668 else if ((expn & 0x80) != 0) 669 expn = (0x400 | (expn & ~0x80)); 670 else if ((expn & 0x80) == 0 && expn != 0) 671 expn = (0x380 | (expn & ~0x80)); 672 673 result = (sign << 63) | (expn << 52) | (frac << 29); 674 return (result); 675} 676 677static unsigned int 678reg_to_Sfloat(u_long r) 679{ 680 unsigned long sign, expn, frac; 681 unsigned int result; 682 683 sign = (r & 0x8000000000000000) >> 63; 684 expn = (r & 0x7ff0000000000000) >> 52; 685 frac = (r & 0x000fffffe0000000) >> 29; 686 687 /* map exponent part, as appropriate. */ 688 expn = (expn & 0x7f) | ((expn & 0x400) != 0 ? 0x80 : 0x00); 689 690 result = (sign << 31) | (expn << 23) | (frac << 0); 691 return (result); 692} 693 694/* 695 * Conversion of T floating datums to and from register format 696 * requires no bit reordering whatsoever. 697 */ 698static unsigned long 699Tfloat_reg_cvt(u_long input) 700{ 701 702 return (input); 703} 704 705#ifdef FIX_UNALIGNED_VAX_FP 706static unsigned long 707Ffloat_to_reg(u_int f) 708{ 709 unsigned long sign, expn, frlo, frhi; 710 unsigned long result; 711 712 sign = (f & 0x00008000) >> 15; 713 expn = (f & 0x00007f80) >> 7; 714 frhi = (f & 0x0000007f) >> 0; 715 frlo = (f & 0xffff0000) >> 16; 716 717 /* map exponent part, as appropriate. */ 718 if ((expn & 0x80) != 0) 719 expn = (0x400 | (expn & ~0x80)); 720 else if ((expn & 0x80) == 0 && expn != 0) 721 expn = (0x380 | (expn & ~0x80)); 722 723 result = (sign << 63) | (expn << 52) | (frhi << 45) | (frlo << 29); 724 return (result); 725} 726 727static unsigned int 728reg_to_Ffloat(u_long r) 729{ 730 unsigned long sign, expn, frhi, frlo; 731 unsigned int result; 732 733 sign = (r & 0x8000000000000000) >> 63; 734 expn = (r & 0x7ff0000000000000) >> 52; 735 frhi = (r & 0x000fe00000000000) >> 45; 736 frlo = (r & 0x00001fffe0000000) >> 29; 737 738 /* map exponent part, as appropriate. */ 739 expn = (expn & 0x7f) | ((expn & 0x400) != 0 ? 0x80 : 0x00); 740 741 result = (sign << 15) | (expn << 7) | (frhi << 0) | (frlo << 16); 742 return (result); 743} 744 745/* 746 * Conversion of G floating datums to and from register format is 747 * symmetrical. Just swap shorts in the quad... 748 */ 749static unsigned long 750Gfloat_reg_cvt(u_long input) 751{ 752 unsigned long a, b, c, d; 753 unsigned long result; 754 755 a = (input & 0x000000000000ffff) >> 0; 756 b = (input & 0x00000000ffff0000) >> 16; 757 c = (input & 0x0000ffff00000000) >> 32; 758 d = (input & 0xffff000000000000) >> 48; 759 760 result = (a << 48) | (b << 32) | (c << 16) | (d << 0); 761 return (result); 762} 763#endif /* FIX_UNALIGNED_VAX_FP */ 764 765struct unaligned_fixup_data { 766 const char *type; /* opcode name */ 767 int fixable; /* fixable, 0 if fixup not supported */ 768 int size; /* size, 0 if unknown */ 769}; 770 771#define UNKNOWN() { "0x%lx", 0, 0 } 772#define FIX_LD(n,s) { n, 1, s } 773#define FIX_ST(n,s) { n, 1, s } 774#define NOFIX_LD(n,s) { n, 0, s } 775#define NOFIX_ST(n,s) { n, 0, s } 776 777int 778unaligned_fixup(u_long va, u_long opcode, u_long reg, struct lwp *l) 779{ 780 static const struct unaligned_fixup_data tab_unknown[1] = { 781 UNKNOWN(), 782 }; 783 static const struct unaligned_fixup_data tab_0c[0x02] = { 784 FIX_LD("ldwu", 2), FIX_ST("stw", 2), 785 }; 786 static const struct unaligned_fixup_data tab_20[0x10] = { 787#ifdef FIX_UNALIGNED_VAX_FP 788 FIX_LD("ldf", 4), FIX_LD("ldg", 8), 789#else 790 NOFIX_LD("ldf", 4), NOFIX_LD("ldg", 8), 791#endif 792 FIX_LD("lds", 4), FIX_LD("ldt", 8), 793#ifdef FIX_UNALIGNED_VAX_FP 794 FIX_ST("stf", 4), FIX_ST("stg", 8), 795#else 796 NOFIX_ST("stf", 4), NOFIX_ST("stg", 8), 797#endif 798 FIX_ST("sts", 4), FIX_ST("stt", 8), 799 FIX_LD("ldl", 4), FIX_LD("ldq", 8), 800 NOFIX_LD("ldl_c", 4), NOFIX_LD("ldq_c", 8), 801 FIX_ST("stl", 4), FIX_ST("stq", 8), 802 NOFIX_ST("stl_c", 4), NOFIX_ST("stq_c", 8), 803 }; 804 const struct unaligned_fixup_data *selected_tab; 805 int doprint, dofix, dosigbus, signo; 806 unsigned long *regptr, longdata; 807 int intdata; /* signed to get extension when storing */ 808 uint16_t worddata; /* unsigned to _avoid_ extension */ 809 810 /* 811 * Read USP into frame in case it's the register to be modified. 812 * This keeps us from having to check for it in lots of places 813 * later. 814 */ 815 l->l_md.md_tf->tf_regs[FRAME_SP] = alpha_pal_rdusp(); 816 817 /* 818 * Figure out what actions to take. 819 * 820 * XXX In the future, this should have a per-process component 821 * as well. 822 */ 823 doprint = alpha_unaligned_print; 824 dofix = alpha_unaligned_fix; 825 dosigbus = alpha_unaligned_sigbus; 826 827 /* 828 * Find out which opcode it is. Arrange to have the opcode 829 * printed if it's an unknown opcode. 830 */ 831 if (opcode >= 0x0c && opcode <= 0x0d) 832 selected_tab = &tab_0c[opcode - 0x0c]; 833 else if (opcode >= 0x20 && opcode <= 0x2f) 834 selected_tab = &tab_20[opcode - 0x20]; 835 else 836 selected_tab = tab_unknown; 837 838 /* 839 * If we're supposed to be noisy, squawk now. 840 */ 841 if (doprint) { 842 uprintf( 843 "pid %d (%s): unaligned access: " 844 "va=0x%lx pc=0x%lx ra=0x%lx sp=0x%lx op=", 845 l->l_proc->p_pid, l->l_proc->p_comm, va, 846 l->l_md.md_tf->tf_regs[FRAME_PC] - 4, 847 l->l_md.md_tf->tf_regs[FRAME_RA], 848 l->l_md.md_tf->tf_regs[FRAME_SP]); 849 uprintf(selected_tab->type,opcode); 850 uprintf("\n"); 851 } 852 853 /* 854 * If we should try to fix it and know how, give it a shot. 855 * 856 * We never allow bad data to be unknowingly used by the user process. 857 * That is, if we can't access the address needed to fix up the trap, 858 * we cause a SIGSEGV rather than letting the user process go on 859 * without warning. 860 * 861 * If we're trying to do a fixup, we assume that things 862 * will be botched. If everything works out OK, 863 * unaligned_{load,store}_* clears the signal flag. 864 */ 865 signo = SIGSEGV; 866 if (dofix && selected_tab->fixable) { 867 switch (opcode) { 868 case 0x0c: /* ldwu */ 869 /* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */ 870 unaligned_load_integer(worddata); 871 break; 872 873 case 0x0d: /* stw */ 874 /* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */ 875 unaligned_store_integer(worddata); 876 break; 877 878#ifdef FIX_UNALIGNED_VAX_FP 879 case 0x20: /* ldf */ 880 unaligned_load_floating(intdata, Ffloat_to_reg); 881 break; 882 883 case 0x21: /* ldg */ 884 unaligned_load_floating(longdata, Gfloat_reg_cvt); 885 break; 886#endif 887 888 case 0x22: /* lds */ 889 unaligned_load_floating(intdata, Sfloat_to_reg); 890 break; 891 892 case 0x23: /* ldt */ 893 unaligned_load_floating(longdata, Tfloat_reg_cvt); 894 break; 895 896#ifdef FIX_UNALIGNED_VAX_FP 897 case 0x24: /* stf */ 898 unaligned_store_floating(intdata, reg_to_Ffloat); 899 break; 900 901 case 0x25: /* stg */ 902 unaligned_store_floating(longdata, Gfloat_reg_cvt); 903 break; 904#endif 905 906 case 0x26: /* sts */ 907 unaligned_store_floating(intdata, reg_to_Sfloat); 908 break; 909 910 case 0x27: /* stt */ 911 unaligned_store_floating(longdata, Tfloat_reg_cvt); 912 break; 913 914 case 0x28: /* ldl */ 915 unaligned_load_integer(intdata); 916 break; 917 918 case 0x29: /* ldq */ 919 unaligned_load_integer(longdata); 920 break; 921 922 case 0x2c: /* stl */ 923 unaligned_store_integer(intdata); 924 break; 925 926 case 0x2d: /* stq */ 927 unaligned_store_integer(longdata); 928 break; 929 930#ifdef DIAGNOSTIC 931 default: 932 panic("unaligned_fixup: can't get here"); 933#endif 934 } 935 } 936 937 /* 938 * Force SIGBUS if requested. 939 */ 940 if (dosigbus) 941 signo = SIGBUS; 942 943 /* 944 * Write back USP. 945 */ 946 alpha_pal_wrusp(l->l_md.md_tf->tf_regs[FRAME_SP]); 947 948 return (signo); 949} 950 951/* 952 * Reserved/unimplemented instruction (opDec fault) handler 953 * 954 * Argument is the process that caused it. No useful information 955 * is passed to the trap handler other than the fault type. The 956 * address of the instruction that caused the fault is 4 less than 957 * the PC stored in the trap frame. 958 * 959 * If the instruction is emulated successfully, this function returns 0. 960 * Otherwise, this function returns the signal to deliver to the process, 961 * and fills in *ucodep with the code to be delivered. 962 */ 963int 964handle_opdec(struct lwp *l, u_long *ucodep) 965{ 966 alpha_instruction inst; 967 register_t *regptr, memaddr; 968 uint64_t inst_pc; 969 int sig; 970 971 /* 972 * Read USP into frame in case it's going to be used or modified. 973 * This keeps us from having to check for it in lots of places 974 * later. 975 */ 976 l->l_md.md_tf->tf_regs[FRAME_SP] = alpha_pal_rdusp(); 977 978 inst_pc = memaddr = l->l_md.md_tf->tf_regs[FRAME_PC] - 4; 979 if (copyin((void *)inst_pc, &inst, sizeof (inst)) != 0) { 980 /* 981 * really, this should never happen, but in case it 982 * does we handle it. 983 */ 984 printf("WARNING: handle_opdec() couldn't fetch instruction\n"); 985 goto sigsegv; 986 } 987 988 switch (inst.generic_format.opcode) { 989 case op_ldbu: 990 case op_ldwu: 991 case op_stw: 992 case op_stb: 993 regptr = irp(l, inst.mem_format.rb); 994 if (regptr != NULL) 995 memaddr = *regptr; 996 else 997 memaddr = 0; 998 memaddr += inst.mem_format.displacement; 999 1000 regptr = irp(l, inst.mem_format.ra); 1001 1002 if (inst.mem_format.opcode == op_ldwu || 1003 inst.mem_format.opcode == op_stw) { 1004 if (memaddr & 0x01) { 1005 sig = unaligned_fixup(memaddr, 1006 inst.mem_format.opcode, 1007 inst.mem_format.ra, l); 1008 if (sig) 1009 goto unaligned_fixup_sig; 1010 break; 1011 } 1012 } 1013 1014 if (inst.mem_format.opcode == op_ldbu) { 1015 uint8_t b; 1016 1017 /* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */ 1018 if (copyin((void *)memaddr, &b, sizeof (b)) != 0) 1019 goto sigsegv; 1020 if (regptr != NULL) 1021 *regptr = b; 1022 } else if (inst.mem_format.opcode == op_ldwu) { 1023 uint16_t w; 1024 1025 /* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */ 1026 if (copyin((void *)memaddr, &w, sizeof (w)) != 0) 1027 goto sigsegv; 1028 if (regptr != NULL) 1029 *regptr = w; 1030 } else if (inst.mem_format.opcode == op_stw) { 1031 uint16_t w; 1032 1033 /* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */ 1034 w = (regptr != NULL) ? *regptr : 0; 1035 if (copyout(&w, (void *)memaddr, sizeof (w)) != 0) 1036 goto sigsegv; 1037 } else if (inst.mem_format.opcode == op_stb) { 1038 uint8_t b; 1039 1040 /* XXX ONLY WORKS ON LITTLE-ENDIAN ALPHA */ 1041 b = (regptr != NULL) ? *regptr : 0; 1042 if (copyout(&b, (void *)memaddr, sizeof (b)) != 0) 1043 goto sigsegv; 1044 } 1045 break; 1046 1047 case op_intmisc: 1048 if (inst.operate_generic_format.function == op_sextb && 1049 inst.operate_generic_format.ra == 31) { 1050 int8_t b; 1051 1052 if (inst.operate_generic_format.is_lit) { 1053 b = inst.operate_lit_format.literal; 1054 } else { 1055 if (inst.operate_reg_format.sbz != 0) 1056 goto sigill; 1057 regptr = irp(l, inst.operate_reg_format.rb); 1058 b = (regptr != NULL) ? *regptr : 0; 1059 } 1060 1061 regptr = irp(l, inst.operate_generic_format.rc); 1062 if (regptr != NULL) 1063 *regptr = b; 1064 break; 1065 } 1066 if (inst.operate_generic_format.function == op_sextw && 1067 inst.operate_generic_format.ra == 31) { 1068 int16_t w; 1069 1070 if (inst.operate_generic_format.is_lit) { 1071 w = inst.operate_lit_format.literal; 1072 } else { 1073 if (inst.operate_reg_format.sbz != 0) 1074 goto sigill; 1075 regptr = irp(l, inst.operate_reg_format.rb); 1076 w = (regptr != NULL) ? *regptr : 0; 1077 } 1078 1079 regptr = irp(l, inst.operate_generic_format.rc); 1080 if (regptr != NULL) 1081 *regptr = w; 1082 break; 1083 } 1084 goto sigill; 1085 1086 default: 1087 goto sigill; 1088 } 1089 1090 /* 1091 * Write back USP. Note that in the error cases below, 1092 * nothing will have been successfully modified so we don't 1093 * have to write it out. 1094 */ 1095 alpha_pal_wrusp(l->l_md.md_tf->tf_regs[FRAME_SP]); 1096 1097 return (0); 1098 1099sigill: 1100 *ucodep = ALPHA_IF_CODE_OPDEC; /* trap type */ 1101 return (SIGILL); 1102 1103sigsegv: 1104 sig = SIGSEGV; 1105 l->l_md.md_tf->tf_regs[FRAME_PC] = inst_pc; /* re-run instr. */ 1106unaligned_fixup_sig: 1107 *ucodep = memaddr; /* faulting address */ 1108 return (sig); 1109} 1110 1111/* map alpha fp flags to ksiginfo fp codes */ 1112static int 1113alpha_ucode_to_ksiginfo(u_long ucode) 1114{ 1115 long i; 1116 1117 static const int alpha_ksiginfo_table[] = { FPE_FLTINV, 1118 FPE_FLTDIV, 1119 FPE_FLTOVF, 1120 FPE_FLTUND, 1121 FPE_FLTRES, 1122 FPE_INTOVF }; 1123 1124 for(i=0;i < sizeof(alpha_ksiginfo_table)/sizeof(int); i++) { 1125 if (ucode & (1 << i)) 1126 return (alpha_ksiginfo_table[i]); 1127 } 1128 /* punt if the flags weren't set */ 1129 return (0); 1130} 1131 1132/* 1133 * Start a new LWP 1134 */ 1135void 1136startlwp(void *arg) 1137{ 1138 ucontext_t *uc = arg; 1139 lwp_t *l = curlwp; 1140 int error; 1141 1142 error = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags); 1143 KASSERT(error == 0); 1144 1145 kmem_free(uc, sizeof(ucontext_t)); 1146 userret(l); 1147} 1148 1149/* 1150 * XXX This is a terrible name. 1151 */ 1152void 1153upcallret(struct lwp *l) 1154{ 1155 KERNEL_UNLOCK_LAST(l); 1156 1157 userret(l); 1158} 1159