upgrade to fedora-2.6.12-1.1398.FC4 + vserver 2.0.rc7
[linux-2.6.git] / arch / ia64 / kernel / traps.c
1 /*
2  * Architecture-specific trap handling.
3  *
4  * Copyright (C) 1998-2003 Hewlett-Packard Co
5  *      David Mosberger-Tang <davidm@hpl.hp.com>
6  *
7  * 05/12/00 grao <goutham.rao@intel.com> : added isr in siginfo for SIGFPE
8  */
9
10 #include <linux/config.h>
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/sched.h>
14 #include <linux/tty.h>
15 #include <linux/vt_kern.h>              /* For unblank_screen() */
16 #include <linux/module.h>       /* for EXPORT_SYMBOL */
17 #include <linux/hardirq.h>
18
19 #include <asm/fpswa.h>
20 #include <asm/ia32.h>
21 #include <asm/intrinsics.h>
22 #include <asm/processor.h>
23 #include <asm/uaccess.h>
24
25 extern spinlock_t timerlist_lock;
26
27 fpswa_interface_t *fpswa_interface;
28 EXPORT_SYMBOL(fpswa_interface);
29
30 void __init
31 trap_init (void)
32 {
33         if (ia64_boot_param->fpswa)
34                 /* FPSWA fixup: make the interface pointer a kernel virtual address: */
35                 fpswa_interface = __va(ia64_boot_param->fpswa);
36 }
37
38 /*
39  * Unlock any spinlocks which will prevent us from getting the message out (timerlist_lock
40  * is acquired through the console unblank code)
41  */
42 void
43 bust_spinlocks (int yes)
44 {
45         int loglevel_save = console_loglevel;
46
47         if (yes) {
48                 oops_in_progress = 1;
49                 return;
50         }
51
52 #ifdef CONFIG_VT
53         unblank_screen();
54 #endif
55         oops_in_progress = 0;
56         /*
57          * OK, the message is on the console.  Now we call printk() without
58          * oops_in_progress set so that printk will give klogd a poke.  Hold onto
59          * your hats...
60          */
61         console_loglevel = 15;          /* NMI oopser may have shut the console up */
62         printk(" ");
63         console_loglevel = loglevel_save;
64 }
65
66 void
67 die (const char *str, struct pt_regs *regs, long err)
68 {
69         static struct {
70                 spinlock_t lock;
71                 u32 lock_owner;
72                 int lock_owner_depth;
73         } die = {
74                 .lock =                 SPIN_LOCK_UNLOCKED,
75                 .lock_owner =           -1,
76                 .lock_owner_depth =     0
77         };
78         static int die_counter;
79
80         if (die.lock_owner != smp_processor_id()) {
81                 console_verbose();
82                 spin_lock_irq(&die.lock);
83                 die.lock_owner = smp_processor_id();
84                 die.lock_owner_depth = 0;
85                 bust_spinlocks(1);
86         }
87
88         if (++die.lock_owner_depth < 3) {
89                 printk("%s[%d]: %s %ld [%d]\n",
90                         current->comm, current->pid, str, err, ++die_counter);
91                 show_regs(regs);
92         } else
93                 printk(KERN_ERR "Recursive die() failure, output suppressed\n");
94
95         try_crashdump(regs);
96         if (panic_on_oops) {
97                 if (netdump_func)
98                         netdump_func = NULL;
99                 panic("Fatal exception");
100         }
101         bust_spinlocks(0);
102         die.lock_owner = -1;
103         spin_unlock_irq(&die.lock);
104         do_exit(SIGSEGV);
105 }
106
107 void
108 die_if_kernel (char *str, struct pt_regs *regs, long err)
109 {
110         if (!user_mode(regs))
111                 die(str, regs, err);
112 }
113
114 void
115 ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
116 {
117         siginfo_t siginfo;
118         int sig, code;
119
120         /* break.b always sets cr.iim to 0, which causes problems for
121          * debuggers.  Get the real break number from the original instruction,
122          * but only for kernel code.  User space break.b is left alone, to
123          * preserve the existing behaviour.  All break codings have the same
124          * format, so there is no need to check the slot type.
125          */
126         if (break_num == 0 && !user_mode(regs)) {
127                 struct ia64_psr *ipsr = ia64_psr(regs);
128                 unsigned long *bundle = (unsigned long *)regs->cr_iip;
129                 unsigned long slot;
130                 switch (ipsr->ri) {
131                       case 0:  slot = (bundle[0] >>  5); break;
132                       case 1:  slot = (bundle[0] >> 46) | (bundle[1] << 18); break;
133                       default: slot = (bundle[1] >> 23); break;
134                 }
135                 break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff);
136         }
137
138         /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
139         siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
140         siginfo.si_imm = break_num;
141         siginfo.si_flags = 0;           /* clear __ISR_VALID */
142         siginfo.si_isr = 0;
143
144         switch (break_num) {
145               case 0: /* unknown error (used by GCC for __builtin_abort()) */
146                 die_if_kernel("bugcheck!", regs, break_num);
147                 sig = SIGILL; code = ILL_ILLOPC;
148                 break;
149
150               case 1: /* integer divide by zero */
151                 sig = SIGFPE; code = FPE_INTDIV;
152                 break;
153
154               case 2: /* integer overflow */
155                 sig = SIGFPE; code = FPE_INTOVF;
156                 break;
157
158               case 3: /* range check/bounds check */
159                 sig = SIGFPE; code = FPE_FLTSUB;
160                 break;
161
162               case 4: /* null pointer dereference */
163                 sig = SIGSEGV; code = SEGV_MAPERR;
164                 break;
165
166               case 5: /* misaligned data */
167                 sig = SIGSEGV; code = BUS_ADRALN;
168                 break;
169
170               case 6: /* decimal overflow */
171                 sig = SIGFPE; code = __FPE_DECOVF;
172                 break;
173
174               case 7: /* decimal divide by zero */
175                 sig = SIGFPE; code = __FPE_DECDIV;
176                 break;
177
178               case 8: /* packed decimal error */
179                 sig = SIGFPE; code = __FPE_DECERR;
180                 break;
181
182               case 9: /* invalid ASCII digit */
183                 sig = SIGFPE; code = __FPE_INVASC;
184                 break;
185
186               case 10: /* invalid decimal digit */
187                 sig = SIGFPE; code = __FPE_INVDEC;
188                 break;
189
190               case 11: /* paragraph stack overflow */
191                 sig = SIGSEGV; code = __SEGV_PSTKOVF;
192                 break;
193
194               case 0x3f000 ... 0x3ffff: /* bundle-update in progress */
195                 sig = SIGILL; code = __ILL_BNDMOD;
196                 break;
197
198               default:
199                 if (break_num < 0x40000 || break_num > 0x100000)
200                         die_if_kernel("Bad break", regs, break_num);
201
202                 if (break_num < 0x80000) {
203                         sig = SIGILL; code = __ILL_BREAK;
204                 } else {
205                         sig = SIGTRAP; code = TRAP_BRKPT;
206                 }
207         }
208         siginfo.si_signo = sig;
209         siginfo.si_errno = 0;
210         siginfo.si_code = code;
211         force_sig_info(sig, &siginfo, current);
212 }
213
214 /*
215  * disabled_fph_fault() is called when a user-level process attempts to access f32..f127
216  * and it doesn't own the fp-high register partition.  When this happens, we save the
217  * current fph partition in the task_struct of the fpu-owner (if necessary) and then load
218  * the fp-high partition of the current task (if necessary).  Note that the kernel has
219  * access to fph by the time we get here, as the IVT's "Disabled FP-Register" handler takes
220  * care of clearing psr.dfh.
221  */
222 static inline void
223 disabled_fph_fault (struct pt_regs *regs)
224 {
225         struct ia64_psr *psr = ia64_psr(regs);
226
227         /* first, grant user-level access to fph partition: */
228         psr->dfh = 0;
229
230         /*
231          * Make sure that no other task gets in on this processor
232          * while we're claiming the FPU
233          */
234         preempt_disable();
235 #ifndef CONFIG_SMP
236         {
237                 struct task_struct *fpu_owner
238                         = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER);
239
240                 if (ia64_is_local_fpu_owner(current)) {
241                         preempt_enable_no_resched();
242                         return;
243                 }
244
245                 if (fpu_owner)
246                         ia64_flush_fph(fpu_owner);
247         }
248 #endif /* !CONFIG_SMP */
249         ia64_set_local_fpu_owner(current);
250         if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) {
251                 __ia64_load_fpu(current->thread.fph);
252                 psr->mfh = 0;
253         } else {
254                 __ia64_init_fpu();
255                 /*
256                  * Set mfh because the state in thread.fph does not match the state in
257                  * the fph partition.
258                  */
259                 psr->mfh = 1;
260         }
261         preempt_enable_no_resched();
262 }
263
264 static inline int
265 fp_emulate (int fp_fault, void *bundle, long *ipsr, long *fpsr, long *isr, long *pr, long *ifs,
266             struct pt_regs *regs)
267 {
268         fp_state_t fp_state;
269         fpswa_ret_t ret;
270
271         if (!fpswa_interface)
272                 return -1;
273
274         memset(&fp_state, 0, sizeof(fp_state_t));
275
276         /*
277          * compute fp_state.  only FP registers f6 - f11 are used by the
278          * kernel, so set those bits in the mask and set the low volatile
279          * pointer to point to these registers.
280          */
281         fp_state.bitmask_low64 = 0xfc0;  /* bit6..bit11 */
282
283         fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) &regs->f6;
284         /*
285          * unsigned long (*EFI_FPSWA) (
286          *      unsigned long    trap_type,
287          *      void             *Bundle,
288          *      unsigned long    *pipsr,
289          *      unsigned long    *pfsr,
290          *      unsigned long    *pisr,
291          *      unsigned long    *ppreds,
292          *      unsigned long    *pifs,
293          *      void             *fp_state);
294          */
295         ret = (*fpswa_interface->fpswa)((unsigned long) fp_fault, bundle,
296                                         (unsigned long *) ipsr, (unsigned long *) fpsr,
297                                         (unsigned long *) isr, (unsigned long *) pr,
298                                         (unsigned long *) ifs, &fp_state);
299
300         return ret.status;
301 }
302
303 /*
304  * Handle floating-point assist faults and traps.
305  */
306 static int
307 handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
308 {
309         long exception, bundle[2];
310         unsigned long fault_ip;
311         struct siginfo siginfo;
312         static int fpu_swa_count = 0;
313         static unsigned long last_time;
314
315         fault_ip = regs->cr_iip;
316         if (!fp_fault && (ia64_psr(regs)->ri == 0))
317                 fault_ip -= 16;
318         if (copy_from_user(bundle, (void __user *) fault_ip, sizeof(bundle)))
319                 return -1;
320
321         if (jiffies - last_time > 5*HZ)
322                 fpu_swa_count = 0;
323         if ((fpu_swa_count < 4) && !(current->thread.flags & IA64_THREAD_FPEMU_NOPRINT)) {
324                 last_time = jiffies;
325                 ++fpu_swa_count;
326                 printk(KERN_WARNING
327                        "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
328                        current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr);
329         }
330
331         exception = fp_emulate(fp_fault, bundle, &regs->cr_ipsr, &regs->ar_fpsr, &isr, &regs->pr,
332                                &regs->cr_ifs, regs);
333         if (fp_fault) {
334                 if (exception == 0) {
335                         /* emulation was successful */
336                         ia64_increment_ip(regs);
337                 } else if (exception == -1) {
338                         printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
339                         return -1;
340                 } else {
341                         /* is next instruction a trap? */
342                         if (exception & 2) {
343                                 ia64_increment_ip(regs);
344                         }
345                         siginfo.si_signo = SIGFPE;
346                         siginfo.si_errno = 0;
347                         siginfo.si_code = __SI_FAULT;   /* default code */
348                         siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
349                         if (isr & 0x11) {
350                                 siginfo.si_code = FPE_FLTINV;
351                         } else if (isr & 0x22) {
352                                 /* denormal operand gets the same si_code as underflow 
353                                 * see arch/i386/kernel/traps.c:math_error()  */
354                                 siginfo.si_code = FPE_FLTUND;
355                         } else if (isr & 0x44) {
356                                 siginfo.si_code = FPE_FLTDIV;
357                         }
358                         siginfo.si_isr = isr;
359                         siginfo.si_flags = __ISR_VALID;
360                         siginfo.si_imm = 0;
361                         force_sig_info(SIGFPE, &siginfo, current);
362                 }
363         } else {
364                 if (exception == -1) {
365                         printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
366                         return -1;
367                 } else if (exception != 0) {
368                         /* raise exception */
369                         siginfo.si_signo = SIGFPE;
370                         siginfo.si_errno = 0;
371                         siginfo.si_code = __SI_FAULT;   /* default code */
372                         siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
373                         if (isr & 0x880) {
374                                 siginfo.si_code = FPE_FLTOVF;
375                         } else if (isr & 0x1100) {
376                                 siginfo.si_code = FPE_FLTUND;
377                         } else if (isr & 0x2200) {
378                                 siginfo.si_code = FPE_FLTRES;
379                         }
380                         siginfo.si_isr = isr;
381                         siginfo.si_flags = __ISR_VALID;
382                         siginfo.si_imm = 0;
383                         force_sig_info(SIGFPE, &siginfo, current);
384                 }
385         }
386         return 0;
387 }
388
389 struct illegal_op_return {
390         unsigned long fkt, arg1, arg2, arg3;
391 };
392
393 struct illegal_op_return
394 ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3,
395                        long arg4, long arg5, long arg6, long arg7,
396                        struct pt_regs regs)
397 {
398         struct illegal_op_return rv;
399         struct siginfo si;
400         char buf[128];
401
402 #ifdef CONFIG_IA64_BRL_EMU
403         {
404                 extern struct illegal_op_return ia64_emulate_brl (struct pt_regs *, unsigned long);
405
406                 rv = ia64_emulate_brl(&regs, ec);
407                 if (rv.fkt != (unsigned long) -1)
408                         return rv;
409         }
410 #endif
411
412         sprintf(buf, "IA-64 Illegal operation fault");
413         die_if_kernel(buf, &regs, 0);
414
415         memset(&si, 0, sizeof(si));
416         si.si_signo = SIGILL;
417         si.si_code = ILL_ILLOPC;
418         si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(&regs)->ri);
419         force_sig_info(SIGILL, &si, current);
420         rv.fkt = 0;
421         return rv;
422 }
423
424 void
425 ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
426             unsigned long iim, unsigned long itir, long arg5, long arg6,
427             long arg7, struct pt_regs regs)
428 {
429         unsigned long code, error = isr, iip;
430         struct siginfo siginfo;
431         char buf[128];
432         int result, sig;
433         static const char *reason[] = {
434                 "IA-64 Illegal Operation fault",
435                 "IA-64 Privileged Operation fault",
436                 "IA-64 Privileged Register fault",
437                 "IA-64 Reserved Register/Field fault",
438                 "Disabled Instruction Set Transition fault",
439                 "Unknown fault 5", "Unknown fault 6", "Unknown fault 7", "Illegal Hazard fault",
440                 "Unknown fault 9", "Unknown fault 10", "Unknown fault 11", "Unknown fault 12",
441                 "Unknown fault 13", "Unknown fault 14", "Unknown fault 15"
442         };
443
444         if ((isr & IA64_ISR_NA) && ((isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH)) {
445                 /*
446                  * This fault was due to lfetch.fault, set "ed" bit in the psr to cancel
447                  * the lfetch.
448                  */
449                 ia64_psr(&regs)->ed = 1;
450                 return;
451         }
452
453         iip = regs.cr_iip + ia64_psr(&regs)->ri;
454
455         switch (vector) {
456               case 24: /* General Exception */
457                 code = (isr >> 4) & 0xf;
458                 sprintf(buf, "General Exception: %s%s", reason[code],
459                         (code == 3) ? ((isr & (1UL << 37))
460                                        ? " (RSE access)" : " (data access)") : "");
461                 if (code == 8) {
462 # ifdef CONFIG_IA64_PRINT_HAZARDS
463                         printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n",
464                                current->comm, current->pid,
465                                regs.cr_iip + ia64_psr(&regs)->ri, regs.pr);
466 # endif
467                         return;
468                 }
469                 break;
470
471               case 25: /* Disabled FP-Register */
472                 if (isr & 2) {
473                         disabled_fph_fault(&regs);
474                         return;
475                 }
476                 sprintf(buf, "Disabled FPL fault---not supposed to happen!");
477                 break;
478
479               case 26: /* NaT Consumption */
480                 if (user_mode(&regs)) {
481                         void __user *addr;
482
483                         if (((isr >> 4) & 0xf) == 2) {
484                                 /* NaT page consumption */
485                                 sig = SIGSEGV;
486                                 code = SEGV_ACCERR;
487                                 addr = (void __user *) ifa;
488                         } else {
489                                 /* register NaT consumption */
490                                 sig = SIGILL;
491                                 code = ILL_ILLOPN;
492                                 addr = (void __user *) (regs.cr_iip
493                                                         + ia64_psr(&regs)->ri);
494                         }
495                         siginfo.si_signo = sig;
496                         siginfo.si_code = code;
497                         siginfo.si_errno = 0;
498                         siginfo.si_addr = addr;
499                         siginfo.si_imm = vector;
500                         siginfo.si_flags = __ISR_VALID;
501                         siginfo.si_isr = isr;
502                         force_sig_info(sig, &siginfo, current);
503                         return;
504                 } else if (ia64_done_with_exception(&regs))
505                         return;
506                 sprintf(buf, "NaT consumption");
507                 break;
508
509               case 31: /* Unsupported Data Reference */
510                 if (user_mode(&regs)) {
511                         siginfo.si_signo = SIGILL;
512                         siginfo.si_code = ILL_ILLOPN;
513                         siginfo.si_errno = 0;
514                         siginfo.si_addr = (void __user *) iip;
515                         siginfo.si_imm = vector;
516                         siginfo.si_flags = __ISR_VALID;
517                         siginfo.si_isr = isr;
518                         force_sig_info(SIGILL, &siginfo, current);
519                         return;
520                 }
521                 sprintf(buf, "Unsupported data reference");
522                 break;
523
524               case 29: /* Debug */
525               case 35: /* Taken Branch Trap */
526               case 36: /* Single Step Trap */
527                 if (fsys_mode(current, &regs)) {
528                         extern char __kernel_syscall_via_break[];
529                         /*
530                          * Got a trap in fsys-mode: Taken Branch Trap and Single Step trap
531                          * need special handling; Debug trap is not supposed to happen.
532                          */
533                         if (unlikely(vector == 29)) {
534                                 die("Got debug trap in fsys-mode---not supposed to happen!",
535                                     &regs, 0);
536                                 return;
537                         }
538                         /* re-do the system call via break 0x100000: */
539                         regs.cr_iip = (unsigned long) __kernel_syscall_via_break;
540                         ia64_psr(&regs)->ri = 0;
541                         ia64_psr(&regs)->cpl = 3;
542                         return;
543                 }
544                 switch (vector) {
545                       case 29:
546                         siginfo.si_code = TRAP_HWBKPT;
547 #ifdef CONFIG_ITANIUM
548                         /*
549                          * Erratum 10 (IFA may contain incorrect address) now has
550                          * "NoFix" status.  There are no plans for fixing this.
551                          */
552                         if (ia64_psr(&regs)->is == 0)
553                           ifa = regs.cr_iip;
554 #endif
555                         break;
556                       case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
557                       case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
558                 }
559                 siginfo.si_signo = SIGTRAP;
560                 siginfo.si_errno = 0;
561                 siginfo.si_addr  = (void __user *) ifa;
562                 siginfo.si_imm   = 0;
563                 siginfo.si_flags = __ISR_VALID;
564                 siginfo.si_isr   = isr;
565                 force_sig_info(SIGTRAP, &siginfo, current);
566                 return;
567
568               case 32: /* fp fault */
569               case 33: /* fp trap */
570                 result = handle_fpu_swa((vector == 32) ? 1 : 0, &regs, isr);
571                 if ((result < 0) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) {
572                         siginfo.si_signo = SIGFPE;
573                         siginfo.si_errno = 0;
574                         siginfo.si_code = FPE_FLTINV;
575                         siginfo.si_addr = (void __user *) iip;
576                         siginfo.si_flags = __ISR_VALID;
577                         siginfo.si_isr = isr;
578                         siginfo.si_imm = 0;
579                         force_sig_info(SIGFPE, &siginfo, current);
580                 }
581                 return;
582
583               case 34:
584                 if (isr & 0x2) {
585                         /* Lower-Privilege Transfer Trap */
586                         /*
587                          * Just clear PSR.lp and then return immediately: all the
588                          * interesting work (e.g., signal delivery is done in the kernel
589                          * exit path).
590                          */
591                         ia64_psr(&regs)->lp = 0;
592                         return;
593                 } else {
594                         /* Unimplemented Instr. Address Trap */
595                         if (user_mode(&regs)) {
596                                 siginfo.si_signo = SIGILL;
597                                 siginfo.si_code = ILL_BADIADDR;
598                                 siginfo.si_errno = 0;
599                                 siginfo.si_flags = 0;
600                                 siginfo.si_isr = 0;
601                                 siginfo.si_imm = 0;
602                                 siginfo.si_addr = (void __user *) iip;
603                                 force_sig_info(SIGILL, &siginfo, current);
604                                 return;
605                         }
606                         sprintf(buf, "Unimplemented Instruction Address fault");
607                 }
608                 break;
609
610               case 45:
611 #ifdef CONFIG_IA32_SUPPORT
612                 if (ia32_exception(&regs, isr) == 0)
613                         return;
614 #endif
615                 printk(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n");
616                 printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n",
617                        iip, ifa, isr);
618                 force_sig(SIGSEGV, current);
619                 break;
620
621               case 46:
622 #ifdef CONFIG_IA32_SUPPORT
623                 if (ia32_intercept(&regs, isr) == 0)
624                         return;
625 #endif
626                 printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n");
627                 printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",
628                        iip, ifa, isr, iim);
629                 force_sig(SIGSEGV, current);
630                 return;
631
632               case 47:
633                 sprintf(buf, "IA-32 Interruption Fault (int 0x%lx)", isr >> 16);
634                 break;
635
636               default:
637                 sprintf(buf, "Fault %lu", vector);
638                 break;
639         }
640         die_if_kernel(buf, &regs, error);
641         force_sig(SIGILL, current);
642 }