trap.c revision 268200
1/*- 2 * Copyright (c) 2005 Marcel Moolenaar 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 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 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: stable/10/sys/ia64/ia64/trap.c 268200 2014-07-02 23:47:43Z marcel $"); 29 30#include "opt_ddb.h" 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/kdb.h> 35#include <sys/ktr.h> 36#include <sys/sysproto.h> 37#include <sys/kernel.h> 38#include <sys/proc.h> 39#include <sys/exec.h> 40#include <sys/lock.h> 41#include <sys/mutex.h> 42#include <sys/sched.h> 43#include <sys/smp.h> 44#include <sys/vmmeter.h> 45#include <sys/sysent.h> 46#include <sys/signalvar.h> 47#include <sys/syscall.h> 48#include <sys/pioctl.h> 49#include <sys/ptrace.h> 50#include <sys/sysctl.h> 51#include <vm/vm.h> 52#include <vm/vm_kern.h> 53#include <vm/vm_page.h> 54#include <vm/vm_map.h> 55#include <vm/vm_extern.h> 56#include <vm/vm_param.h> 57#include <sys/ptrace.h> 58#include <machine/cpu.h> 59#include <machine/md_var.h> 60#include <machine/reg.h> 61#include <machine/pal.h> 62#include <machine/fpu.h> 63#include <machine/efi.h> 64#include <machine/pcb.h> 65#ifdef SMP 66#include <machine/smp.h> 67#endif 68 69#include <security/audit/audit.h> 70 71#include <ia64/disasm/disasm.h> 72 73static int print_usertrap = 0; 74SYSCTL_INT(_machdep, OID_AUTO, print_usertrap, 75 CTLFLAG_RW, &print_usertrap, 0, ""); 76 77static void break_syscall(struct trapframe *tf); 78 79/* 80 * EFI-Provided FPSWA interface (Floating Point SoftWare Assist) 81 */ 82extern struct fpswa_iface *fpswa_iface; 83 84static const char *ia64_vector_names[] = { 85 "VHPT Translation", /* 0 */ 86 "Instruction TLB", /* 1 */ 87 "Data TLB", /* 2 */ 88 "Alternate Instruction TLB", /* 3 */ 89 "Alternate Data TLB", /* 4 */ 90 "Data Nested TLB", /* 5 */ 91 "Instruction Key Miss", /* 6 */ 92 "Data Key Miss", /* 7 */ 93 "Dirty-Bit", /* 8 */ 94 "Instruction Access-Bit", /* 9 */ 95 "Data Access-Bit", /* 10 */ 96 "Break Instruction", /* 11 */ 97 "External Interrupt", /* 12 */ 98 "Reserved 13", /* 13 */ 99 "Reserved 14", /* 14 */ 100 "Reserved 15", /* 15 */ 101 "Reserved 16", /* 16 */ 102 "Reserved 17", /* 17 */ 103 "Reserved 18", /* 18 */ 104 "Reserved 19", /* 19 */ 105 "Page Not Present", /* 20 */ 106 "Key Permission", /* 21 */ 107 "Instruction Access Rights", /* 22 */ 108 "Data Access Rights", /* 23 */ 109 "General Exception", /* 24 */ 110 "Disabled FP-Register", /* 25 */ 111 "NaT Consumption", /* 26 */ 112 "Speculation", /* 27 */ 113 "Reserved 28", /* 28 */ 114 "Debug", /* 29 */ 115 "Unaligned Reference", /* 30 */ 116 "Unsupported Data Reference", /* 31 */ 117 "Floating-point Fault", /* 32 */ 118 "Floating-point Trap", /* 33 */ 119 "Lower-Privilege Transfer Trap", /* 34 */ 120 "Taken Branch Trap", /* 35 */ 121 "Single Step Trap", /* 36 */ 122 "Reserved 37", /* 37 */ 123 "Reserved 38", /* 38 */ 124 "Reserved 39", /* 39 */ 125 "Reserved 40", /* 40 */ 126 "Reserved 41", /* 41 */ 127 "Reserved 42", /* 42 */ 128 "Reserved 43", /* 43 */ 129 "Reserved 44", /* 44 */ 130 "IA-32 Exception", /* 45 */ 131 "IA-32 Intercept", /* 46 */ 132 "IA-32 Interrupt", /* 47 */ 133 "Reserved 48", /* 48 */ 134 "Reserved 49", /* 49 */ 135 "Reserved 50", /* 50 */ 136 "Reserved 51", /* 51 */ 137 "Reserved 52", /* 52 */ 138 "Reserved 53", /* 53 */ 139 "Reserved 54", /* 54 */ 140 "Reserved 55", /* 55 */ 141 "Reserved 56", /* 56 */ 142 "Reserved 57", /* 57 */ 143 "Reserved 58", /* 58 */ 144 "Reserved 59", /* 59 */ 145 "Reserved 60", /* 60 */ 146 "Reserved 61", /* 61 */ 147 "Reserved 62", /* 62 */ 148 "Reserved 63", /* 63 */ 149 "Reserved 64", /* 64 */ 150 "Reserved 65", /* 65 */ 151 "Reserved 66", /* 66 */ 152 "Reserved 67", /* 67 */ 153}; 154 155struct bitname { 156 uint64_t mask; 157 const char* name; 158}; 159 160static void 161printbits(uint64_t mask, struct bitname *bn, int count) 162{ 163 int i, first = 1; 164 uint64_t bit; 165 166 for (i = 0; i < count; i++) { 167 /* 168 * Handle fields wider than one bit. 169 */ 170 bit = bn[i].mask & ~(bn[i].mask - 1); 171 if (bn[i].mask > bit) { 172 if (first) 173 first = 0; 174 else 175 printf(","); 176 printf("%s=%ld", bn[i].name, 177 (mask & bn[i].mask) / bit); 178 } else if (mask & bit) { 179 if (first) 180 first = 0; 181 else 182 printf(","); 183 printf("%s", bn[i].name); 184 } 185 } 186} 187 188struct bitname psr_bits[] = { 189 {IA64_PSR_BE, "be"}, 190 {IA64_PSR_UP, "up"}, 191 {IA64_PSR_AC, "ac"}, 192 {IA64_PSR_MFL, "mfl"}, 193 {IA64_PSR_MFH, "mfh"}, 194 {IA64_PSR_IC, "ic"}, 195 {IA64_PSR_I, "i"}, 196 {IA64_PSR_PK, "pk"}, 197 {IA64_PSR_DT, "dt"}, 198 {IA64_PSR_DFL, "dfl"}, 199 {IA64_PSR_DFH, "dfh"}, 200 {IA64_PSR_SP, "sp"}, 201 {IA64_PSR_PP, "pp"}, 202 {IA64_PSR_DI, "di"}, 203 {IA64_PSR_SI, "si"}, 204 {IA64_PSR_DB, "db"}, 205 {IA64_PSR_LP, "lp"}, 206 {IA64_PSR_TB, "tb"}, 207 {IA64_PSR_RT, "rt"}, 208 {IA64_PSR_CPL, "cpl"}, 209 {IA64_PSR_IS, "is"}, 210 {IA64_PSR_MC, "mc"}, 211 {IA64_PSR_IT, "it"}, 212 {IA64_PSR_ID, "id"}, 213 {IA64_PSR_DA, "da"}, 214 {IA64_PSR_DD, "dd"}, 215 {IA64_PSR_SS, "ss"}, 216 {IA64_PSR_RI, "ri"}, 217 {IA64_PSR_ED, "ed"}, 218 {IA64_PSR_BN, "bn"}, 219 {IA64_PSR_IA, "ia"}, 220}; 221 222static void 223printpsr(uint64_t psr) 224{ 225 printbits(psr, psr_bits, sizeof(psr_bits)/sizeof(psr_bits[0])); 226} 227 228struct bitname isr_bits[] = { 229 {IA64_ISR_CODE, "code"}, 230 {IA64_ISR_VECTOR, "vector"}, 231 {IA64_ISR_X, "x"}, 232 {IA64_ISR_W, "w"}, 233 {IA64_ISR_R, "r"}, 234 {IA64_ISR_NA, "na"}, 235 {IA64_ISR_SP, "sp"}, 236 {IA64_ISR_RS, "rs"}, 237 {IA64_ISR_IR, "ir"}, 238 {IA64_ISR_NI, "ni"}, 239 {IA64_ISR_SO, "so"}, 240 {IA64_ISR_EI, "ei"}, 241 {IA64_ISR_ED, "ed"}, 242}; 243 244static void printisr(uint64_t isr) 245{ 246 printbits(isr, isr_bits, sizeof(isr_bits)/sizeof(isr_bits[0])); 247} 248 249static void 250printtrap(int vector, struct trapframe *tf, int isfatal, int user) 251{ 252 printf("\n"); 253 printf("%s %s trap (cpu %d):\n", isfatal? "fatal" : "handled", 254 user ? "user" : "kernel", PCPU_GET(cpuid)); 255 printf("\n"); 256 printf(" trap vector = 0x%x (%s)\n", 257 vector, ia64_vector_names[vector]); 258 printf(" cr.iip = 0x%lx\n", tf->tf_special.iip); 259 printf(" cr.ipsr = 0x%lx (", tf->tf_special.psr); 260 printpsr(tf->tf_special.psr); 261 printf(")\n"); 262 printf(" cr.isr = 0x%lx (", tf->tf_special.isr); 263 printisr(tf->tf_special.isr); 264 printf(")\n"); 265 printf(" cr.ifa = 0x%lx\n", tf->tf_special.ifa); 266 if (tf->tf_special.psr & IA64_PSR_IS) { 267 printf(" ar.cflg = 0x%lx\n", ia64_get_cflg()); 268 printf(" ar.csd = 0x%lx\n", ia64_get_csd()); 269 printf(" ar.ssd = 0x%lx\n", ia64_get_ssd()); 270 } 271 printf(" curthread = %p\n", curthread); 272 if (curthread != NULL) 273 printf(" pid = %d, comm = %s\n", 274 curthread->td_proc->p_pid, curthread->td_name); 275 printf("\n"); 276} 277 278/* 279 * We got a trap caused by a break instruction and the immediate was 0. 280 * This indicates that we may have a break.b with some non-zero immediate. 281 * The break.b doesn't cause the immediate to be put in cr.iim. Hence, 282 * we need to disassemble the bundle and return the immediate found there. 283 * This may be a 0 value anyway. Return 0 for any error condition. This 284 * will result in a SIGILL, which is pretty much the best thing to do. 285 */ 286static uint64_t 287trap_decode_break(struct trapframe *tf) 288{ 289 struct asm_bundle bundle; 290 struct asm_inst *inst; 291 int slot; 292 293 if (!asm_decode(tf->tf_special.iip, &bundle)) 294 return (0); 295 296 slot = ((tf->tf_special.psr & IA64_PSR_RI) == IA64_PSR_RI_0) ? 0 : 297 ((tf->tf_special.psr & IA64_PSR_RI) == IA64_PSR_RI_1) ? 1 : 2; 298 inst = bundle.b_inst + slot; 299 300 /* 301 * Sanity checking: It must be a break instruction and the operand 302 * that has the break value must be an immediate. 303 */ 304 if (inst->i_op != ASM_OP_BREAK || 305 inst->i_oper[1].o_type != ASM_OPER_IMM) 306 return (0); 307 308 return (inst->i_oper[1].o_value); 309} 310 311void 312trap_panic(int vector, struct trapframe *tf) 313{ 314 315 printtrap(vector, tf, 1, TRAPF_USERMODE(tf)); 316#ifdef KDB 317 kdb_trap(vector, 0, tf); 318#endif 319 panic("trap"); 320} 321 322/* 323 * 324 */ 325int 326do_ast(struct trapframe *tf) 327{ 328 329 ia64_disable_intr(); 330 while (curthread->td_flags & (TDF_ASTPENDING|TDF_NEEDRESCHED)) { 331 ia64_enable_intr(); 332 ast(tf); 333 ia64_disable_intr(); 334 } 335 /* 336 * Keep interrupts disabled. We return r10 as a favor to the EPC 337 * syscall code so that it can quicky determine if the syscall 338 * needs to be restarted or not. 339 */ 340 return (tf->tf_scratch.gr10); 341} 342 343/* 344 * Trap is called from exception.s to handle most types of processor traps. 345 */ 346/*ARGSUSED*/ 347void 348trap(int vector, struct trapframe *tf) 349{ 350 struct proc *p; 351 struct thread *td; 352 uint64_t ucode; 353 int error, sig, user; 354 ksiginfo_t ksi; 355 356 user = TRAPF_USERMODE(tf) ? 1 : 0; 357 if (user) 358 ia64_set_fpsr(IA64_FPSR_DEFAULT); 359 360#ifdef XTRACE 361 ia64_xtrace_save(); 362#endif 363 364 PCPU_INC(cnt.v_trap); 365 366 td = curthread; 367 p = td->td_proc; 368 ucode = 0; 369 370 if (user) { 371 td->td_pticks = 0; 372 td->td_frame = tf; 373 if (td->td_ucred != p->p_ucred) 374 cred_update_thread(td); 375 } else { 376 KASSERT(cold || td->td_ucred != NULL, 377 ("kernel trap doesn't have ucred")); 378#ifdef KDB 379 if (kdb_active) 380 kdb_reenter(); 381#endif 382 } 383 384 sig = 0; 385 switch (vector) { 386 case IA64_VEC_VHPT: 387 /* 388 * This one is tricky. We should hardwire the VHPT, but 389 * don't at this time. I think we're mostly lucky that 390 * the VHPT is mapped. 391 */ 392 trap_panic(vector, tf); 393 break; 394 395 case IA64_VEC_ITLB: 396 case IA64_VEC_DTLB: 397 case IA64_VEC_EXT_INTR: 398 /* We never call trap() with these vectors. */ 399 trap_panic(vector, tf); 400 break; 401 402 case IA64_VEC_ALT_ITLB: 403 case IA64_VEC_ALT_DTLB: 404 /* 405 * These should never happen, because regions 0-4 use the 406 * VHPT. If we get one of these it means we didn't program 407 * the region registers correctly. 408 */ 409 trap_panic(vector, tf); 410 break; 411 412 case IA64_VEC_NESTED_DTLB: 413 /* 414 * When the nested TLB handler encounters an unexpected 415 * condition, it'll switch to the backup stack and transfer 416 * here. All we need to do is panic. 417 */ 418 trap_panic(vector, tf); 419 break; 420 421 case IA64_VEC_IKEY_MISS: 422 case IA64_VEC_DKEY_MISS: 423 case IA64_VEC_KEY_PERMISSION: 424 /* 425 * We don't use protection keys, so we should never get 426 * these faults. 427 */ 428 trap_panic(vector, tf); 429 break; 430 431 case IA64_VEC_DIRTY_BIT: 432 case IA64_VEC_INST_ACCESS: 433 case IA64_VEC_DATA_ACCESS: 434 /* 435 * We get here if we read or write to a page of which the 436 * PTE does not have the access bit or dirty bit set and 437 * we can not find the PTE in our datastructures. This 438 * either means we have a stale PTE in the TLB, or we lost 439 * the PTE in our datastructures. 440 */ 441 trap_panic(vector, tf); 442 break; 443 444 case IA64_VEC_BREAK: 445 if (user) { 446 ucode = (int)tf->tf_special.ifa & 0x1FFFFF; 447 if (ucode == 0) { 448 /* 449 * A break.b doesn't cause the immediate to be 450 * stored in cr.iim (and saved in the TF in 451 * tf_special.ifa). We need to decode the 452 * instruction to find out what the immediate 453 * was. Note that if the break instruction 454 * didn't happen to be a break.b, but any 455 * other break with an immediate of 0, we 456 * will do unnecessary work to get the value 457 * we already had. Not an issue, because a 458 * break 0 is invalid. 459 */ 460 ucode = trap_decode_break(tf); 461 } 462 if (ucode < 0x80000) { 463 /* Software interrupts. */ 464 switch (ucode) { 465 case 0: /* Unknown error. */ 466 sig = SIGILL; 467 break; 468 case 1: /* Integer divide by zero. */ 469 sig = SIGFPE; 470 ucode = FPE_INTDIV; 471 break; 472 case 2: /* Integer overflow. */ 473 sig = SIGFPE; 474 ucode = FPE_INTOVF; 475 break; 476 case 3: /* Range check/bounds check. */ 477 sig = SIGFPE; 478 ucode = FPE_FLTSUB; 479 break; 480 case 6: /* Decimal overflow. */ 481 case 7: /* Decimal divide by zero. */ 482 case 8: /* Packed decimal error. */ 483 case 9: /* Invalid ASCII digit. */ 484 case 10: /* Invalid decimal digit. */ 485 sig = SIGFPE; 486 ucode = FPE_FLTINV; 487 break; 488 case 4: /* Null pointer dereference. */ 489 case 5: /* Misaligned data. */ 490 case 11: /* Paragraph stack overflow. */ 491 sig = SIGSEGV; 492 break; 493 default: 494 sig = SIGILL; 495 break; 496 } 497 } else if (ucode < 0x100000) { 498 /* Debugger breakpoint. */ 499 tf->tf_special.psr &= ~IA64_PSR_SS; 500 sig = SIGTRAP; 501 } else if (ucode == 0x100000) { 502 break_syscall(tf); 503 return; /* do_ast() already called. */ 504 } else if (ucode == 0x180000) { 505 mcontext_t mc; 506 507 error = copyin((void*)tf->tf_scratch.gr8, 508 &mc, sizeof(mc)); 509 if (!error) { 510 set_mcontext(td, &mc); 511 return; /* Don't call do_ast()!!! */ 512 } 513 sig = SIGSEGV; 514 ucode = tf->tf_scratch.gr8; 515 } else 516 sig = SIGILL; 517 } else { 518#ifdef KDB 519 if (kdb_trap(vector, 0, tf)) 520 return; 521 panic("trap"); 522#else 523 trap_panic(vector, tf); 524#endif 525 } 526 break; 527 528 case IA64_VEC_PAGE_NOT_PRESENT: 529 case IA64_VEC_INST_ACCESS_RIGHTS: 530 case IA64_VEC_DATA_ACCESS_RIGHTS: { 531 vm_offset_t va; 532 struct vmspace *vm; 533 vm_map_t map; 534 vm_prot_t ftype; 535 int rv; 536 537 rv = 0; 538 va = trunc_page(tf->tf_special.ifa); 539 540 if (va >= VM_MAXUSER_ADDRESS) { 541 /* 542 * Don't allow user-mode faults for kernel virtual 543 * addresses, including the gateway page. 544 */ 545 if (user) 546 goto no_fault_in; 547 map = kernel_map; 548 } else { 549 vm = (p != NULL) ? p->p_vmspace : NULL; 550 if (vm == NULL) 551 goto no_fault_in; 552 map = &vm->vm_map; 553 } 554 555 if (tf->tf_special.isr & IA64_ISR_X) 556 ftype = VM_PROT_EXECUTE; 557 else if (tf->tf_special.isr & IA64_ISR_W) 558 ftype = VM_PROT_WRITE; 559 else 560 ftype = VM_PROT_READ; 561 562 if (map != kernel_map) { 563 /* 564 * Keep swapout from messing with us during this 565 * critical time. 566 */ 567 PROC_LOCK(p); 568 ++p->p_lock; 569 PROC_UNLOCK(p); 570 571 /* Fault in the user page: */ 572 rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL); 573 574 PROC_LOCK(p); 575 --p->p_lock; 576 PROC_UNLOCK(p); 577 } else { 578 /* 579 * Don't have to worry about process locking or 580 * stacks in the kernel. 581 */ 582 rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL); 583 } 584 585 if (rv == KERN_SUCCESS) 586 goto out; 587 588 no_fault_in: 589 if (!user) { 590 /* Check for copyin/copyout fault. */ 591 if (td != NULL && td->td_pcb->pcb_onfault != 0) { 592 tf->tf_special.iip = 593 td->td_pcb->pcb_onfault; 594 tf->tf_special.psr &= ~IA64_PSR_RI; 595 td->td_pcb->pcb_onfault = 0; 596 goto out; 597 } 598 trap_panic(vector, tf); 599 } 600 ucode = va; 601 sig = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV; 602 break; 603 } 604 605 case IA64_VEC_GENERAL_EXCEPTION: { 606 int code; 607 608 if (!user) 609 trap_panic(vector, tf); 610 611 code = tf->tf_special.isr & (IA64_ISR_CODE & 0xf0ull); 612 switch (code) { 613 case 0x0: /* Illegal Operation Fault. */ 614 sig = ia64_emulate(tf, td); 615 break; 616 default: 617 sig = SIGILL; 618 break; 619 } 620 if (sig == 0) 621 goto out; 622 ucode = vector; 623 break; 624 } 625 626 case IA64_VEC_SPECULATION: 627 /* 628 * The branching behaviour of the chk instruction is not 629 * implemented by the processor. All we need to do is 630 * compute the target address of the branch and make sure 631 * that control is transfered to that address. 632 * We should do this in the IVT table and not by entring 633 * the kernel... 634 */ 635 tf->tf_special.iip += tf->tf_special.ifa << 4; 636 tf->tf_special.psr &= ~IA64_PSR_RI; 637 goto out; 638 639 case IA64_VEC_NAT_CONSUMPTION: 640 case IA64_VEC_UNSUPP_DATA_REFERENCE: 641 if (user) { 642 ucode = vector; 643 sig = SIGILL; 644 } else 645 trap_panic(vector, tf); 646 break; 647 648 case IA64_VEC_DISABLED_FP: { 649 if (user) 650 ia64_highfp_enable(td, tf); 651 else 652 trap_panic(vector, tf); 653 goto out; 654 } 655 656 case IA64_VEC_DEBUG: 657 case IA64_VEC_SINGLE_STEP_TRAP: 658 tf->tf_special.psr &= ~IA64_PSR_SS; 659 if (!user) { 660#ifdef KDB 661 if (kdb_trap(vector, 0, tf)) 662 return; 663 panic("trap"); 664#else 665 trap_panic(vector, tf); 666#endif 667 } 668 sig = SIGTRAP; 669 break; 670 671 case IA64_VEC_UNALIGNED_REFERENCE: 672 /* 673 * If user-land, do whatever fixups, printing, and 674 * signalling is appropriate (based on system-wide 675 * and per-process unaligned-access-handling flags). 676 */ 677 if (user) { 678 sig = unaligned_fixup(tf, td); 679 if (sig == 0) 680 goto out; 681 ucode = tf->tf_special.ifa; /* VA */ 682 } else { 683 /* Check for copyin/copyout fault. */ 684 if (td != NULL && td->td_pcb->pcb_onfault != 0) { 685 tf->tf_special.iip = 686 td->td_pcb->pcb_onfault; 687 tf->tf_special.psr &= ~IA64_PSR_RI; 688 td->td_pcb->pcb_onfault = 0; 689 goto out; 690 } 691 trap_panic(vector, tf); 692 } 693 break; 694 695 case IA64_VEC_FLOATING_POINT_FAULT: 696 case IA64_VEC_FLOATING_POINT_TRAP: { 697 struct fpswa_bundle bundle; 698 struct fpswa_fpctx fpctx; 699 struct fpswa_ret ret; 700 char *ip; 701 u_long fault; 702 703 /* Always fatal in kernel. Should never happen. */ 704 if (!user) 705 trap_panic(vector, tf); 706 707 if (fpswa_iface == NULL) { 708 sig = SIGFPE; 709 ucode = 0; 710 break; 711 } 712 713 ip = (char *)tf->tf_special.iip; 714 if (vector == IA64_VEC_FLOATING_POINT_TRAP && 715 (tf->tf_special.psr & IA64_PSR_RI) == 0) 716 ip -= 16; 717 error = copyin(ip, &bundle, sizeof(bundle)); 718 if (error) { 719 sig = SIGBUS; /* EFAULT, basically */ 720 ucode = 0; /* exception summary */ 721 break; 722 } 723 724 /* f6-f15 are saved in exception_save */ 725 fpctx.mask_low = 0xffc0; /* bits 6 - 15 */ 726 fpctx.mask_high = 0; 727 fpctx.fp_low_preserved = NULL; 728 fpctx.fp_low_volatile = &tf->tf_scratch_fp.fr6; 729 fpctx.fp_high_preserved = NULL; 730 fpctx.fp_high_volatile = NULL; 731 732 fault = (vector == IA64_VEC_FLOATING_POINT_FAULT) ? 1 : 0; 733 734 /* 735 * We have the high FP registers disabled while in the 736 * kernel. Enable them for the FPSWA handler only. 737 */ 738 ia64_enable_highfp(); 739 740 /* The docs are unclear. Is Fpswa reentrant? */ 741 ret = fpswa_iface->if_fpswa(fault, &bundle, 742 &tf->tf_special.psr, &tf->tf_special.fpsr, 743 &tf->tf_special.isr, &tf->tf_special.pr, 744 &tf->tf_special.cfm, &fpctx); 745 746 ia64_disable_highfp(); 747 748 /* 749 * Update ipsr and iip to next instruction. We only 750 * have to do that for faults. 751 */ 752 if (fault && (ret.status == 0 || (ret.status & 2))) { 753 int ei; 754 755 ei = (tf->tf_special.isr >> 41) & 0x03; 756 if (ei == 0) { /* no template for this case */ 757 tf->tf_special.psr &= ~IA64_ISR_EI; 758 tf->tf_special.psr |= IA64_ISR_EI_1; 759 } else if (ei == 1) { /* MFI or MFB */ 760 tf->tf_special.psr &= ~IA64_ISR_EI; 761 tf->tf_special.psr |= IA64_ISR_EI_2; 762 } else if (ei == 2) { /* MMF */ 763 tf->tf_special.psr &= ~IA64_ISR_EI; 764 tf->tf_special.iip += 0x10; 765 } 766 } 767 768 if (ret.status == 0) { 769 goto out; 770 } else if (ret.status == -1) { 771 printf("FATAL: FPSWA err1 %lx, err2 %lx, err3 %lx\n", 772 ret.err1, ret.err2, ret.err3); 773 panic("fpswa fatal error on fp fault"); 774 } else { 775 sig = SIGFPE; 776 ucode = 0; /* XXX exception summary */ 777 break; 778 } 779 } 780 781 case IA64_VEC_LOWER_PRIVILEGE_TRANSFER: 782 /* 783 * The lower-privilege transfer trap is used by the EPC 784 * syscall code to trigger re-entry into the kernel when the 785 * process should be single stepped. The problem is that 786 * there's no way to set single stepping directly without 787 * using the rfi instruction. So instead we enable the 788 * lower-privilege transfer trap and when we get here we 789 * know that the process is about to enter userland (and 790 * has already lowered its privilege). 791 * However, there's another gotcha. When the process has 792 * lowered it's privilege it's still running in the gateway 793 * page. If we enable single stepping, we'll be stepping 794 * the code in the gateway page. In and by itself this is 795 * not a problem, but it's an address debuggers won't know 796 * anything about. Hence, it can only cause confusion. 797 * We know that we need to branch to get out of the gateway 798 * page, so what we do here is enable the taken branch 799 * trap and just let the process continue. When we branch 800 * out of the gateway page we'll get back into the kernel 801 * and then we enable single stepping. 802 * Since this a rather round-about way of enabling single 803 * stepping, don't make things even more complicated by 804 * calling userret() and do_ast(). We do that later... 805 */ 806 tf->tf_special.psr &= ~IA64_PSR_LP; 807 tf->tf_special.psr |= IA64_PSR_TB; 808 return; 809 810 case IA64_VEC_TAKEN_BRANCH_TRAP: 811 /* 812 * Don't assume there aren't any branches other than the 813 * branch that takes us out of the gateway page. Check the 814 * iip and enable single stepping only when it's an user 815 * address. 816 */ 817 if (tf->tf_special.iip >= VM_MAXUSER_ADDRESS) 818 return; 819 tf->tf_special.psr &= ~IA64_PSR_TB; 820 tf->tf_special.psr |= IA64_PSR_SS; 821 return; 822 823 case IA64_VEC_IA32_EXCEPTION: 824 case IA64_VEC_IA32_INTERCEPT: 825 case IA64_VEC_IA32_INTERRUPT: 826 sig = SIGEMT; 827 ucode = tf->tf_special.iip; 828 break; 829 830 default: 831 /* Reserved vectors get here. Should never happen of course. */ 832 trap_panic(vector, tf); 833 break; 834 } 835 836 KASSERT(sig != 0, ("foo")); 837 838 if (print_usertrap) 839 printtrap(vector, tf, 1, user); 840 841 ksiginfo_init(&ksi); 842 ksi.ksi_signo = sig; 843 ksi.ksi_code = ucode; 844 trapsignal(td, &ksi); 845 846out: 847 if (user) { 848 userret(td, tf); 849 do_ast(tf); 850 } 851 return; 852} 853 854/* 855 * Handle break instruction based system calls. 856 */ 857void 858break_syscall(struct trapframe *tf) 859{ 860 uint64_t *bsp, *tfp; 861 uint64_t iip, psr; 862 int error, nargs; 863 864 /* Save address of break instruction. */ 865 iip = tf->tf_special.iip; 866 psr = tf->tf_special.psr; 867 868 /* Advance to the next instruction. */ 869 tf->tf_special.psr += IA64_PSR_RI_1; 870 if ((tf->tf_special.psr & IA64_PSR_RI) > IA64_PSR_RI_2) { 871 tf->tf_special.iip += 16; 872 tf->tf_special.psr &= ~IA64_PSR_RI; 873 } 874 875 /* 876 * Copy the arguments on the register stack into the trapframe 877 * to avoid having interleaved NaT collections. 878 */ 879 tfp = &tf->tf_scratch.gr16; 880 nargs = tf->tf_special.cfm & 0x7f; 881 bsp = (uint64_t*)(curthread->td_kstack + tf->tf_special.ndirty + 882 (tf->tf_special.bspstore & 0x1ffUL)); 883 bsp -= (((uintptr_t)bsp & 0x1ff) < (nargs << 3)) ? (nargs + 1): nargs; 884 while (nargs--) { 885 *tfp++ = *bsp++; 886 if (((uintptr_t)bsp & 0x1ff) == 0x1f8) 887 bsp++; 888 } 889 error = syscall(tf); 890 if (error == ERESTART) { 891 tf->tf_special.iip = iip; 892 tf->tf_special.psr = psr; 893 } 894 895 do_ast(tf); 896} 897 898int 899cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa) 900{ 901 struct proc *p; 902 struct trapframe *tf; 903 904 p = td->td_proc; 905 tf = td->td_frame; 906 907 sa->code = tf->tf_scratch.gr15; 908 sa->args = &tf->tf_scratch.gr16; 909 910 /* 911 * syscall() and __syscall() are handled the same on 912 * the ia64, as everything is 64-bit aligned, anyway. 913 */ 914 if (sa->code == SYS_syscall || sa->code == SYS___syscall) { 915 /* 916 * Code is first argument, followed by actual args. 917 */ 918 sa->code = sa->args[0]; 919 sa->args++; 920 } 921 922 if (p->p_sysent->sv_mask) 923 sa->code &= p->p_sysent->sv_mask; 924 if (sa->code >= p->p_sysent->sv_size) 925 sa->callp = &p->p_sysent->sv_table[0]; 926 else 927 sa->callp = &p->p_sysent->sv_table[sa->code]; 928 sa->narg = sa->callp->sy_narg; 929 930 td->td_retval[0] = 0; 931 td->td_retval[1] = 0; 932 933 return (0); 934} 935 936#include "../../kern/subr_syscall.c" 937 938/* 939 * Process a system call. 940 * 941 * See syscall.s for details as to how we get here. In order to support 942 * the ERESTART case, we return the error to our caller. They deal with 943 * the hairy details. 944 */ 945int 946syscall(struct trapframe *tf) 947{ 948 struct syscall_args sa; 949 struct thread *td; 950 int error; 951 952 td = curthread; 953 td->td_frame = tf; 954 955 ia64_set_fpsr(IA64_FPSR_DEFAULT); 956 tf->tf_scratch.gr10 = EJUSTRETURN; 957 958 error = syscallenter(td, &sa); 959 syscallret(td, error, &sa); 960 961 return (error); 962} 963