]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/ia64/ia64/trap.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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
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/efi.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/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
73 static int print_usertrap = 0;
74 SYSCTL_INT(_machdep, OID_AUTO, print_usertrap,
75     CTLFLAG_RW, &print_usertrap, 0, "");
76
77 static void break_syscall(struct trapframe *tf);
78
79 /*
80  * EFI-Provided FPSWA interface (Floating Point SoftWare Assist)
81  */
82 extern struct fpswa_iface *fpswa_iface;
83
84 static 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
155 struct bitname {
156         uint64_t mask;
157         const char* name;
158 };
159
160 static void
161 printbits(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
188 struct 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
222 static void
223 printpsr(uint64_t psr)
224 {
225         printbits(psr, psr_bits, sizeof(psr_bits)/sizeof(psr_bits[0]));
226 }
227
228 struct 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
244 static void printisr(uint64_t isr)
245 {
246         printbits(isr, isr_bits, sizeof(isr_bits)/sizeof(isr_bits[0]));
247 }
248
249 static void
250 printtrap(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  */
286 static uint64_t
287 trap_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
311 void
312 trap_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  */
325 int
326 do_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*/
347 void
348 trap(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
846 out:
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  */
857 void
858 break_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
898 int
899 cpu_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  */
945 int
946 syscall(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 }