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