2 * Architecture-specific trap handling.
4 * Copyright (C) 1998-2003 Hewlett-Packard Co
5 * David Mosberger-Tang <davidm@hpl.hp.com>
7 * 05/12/00 grao <goutham.rao@intel.com> : added isr in siginfo for SIGFPE
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 #include <linux/kprobes.h>
20 #include <asm/fpswa.h>
22 #include <asm/intrinsics.h>
23 #include <asm/processor.h>
24 #include <asm/uaccess.h>
25 #include <asm/kdebug.h>
27 extern spinlock_t timerlist_lock;
29 fpswa_interface_t *fpswa_interface;
30 EXPORT_SYMBOL(fpswa_interface);
32 struct notifier_block *ia64die_chain;
33 static DEFINE_SPINLOCK(die_notifier_lock);
35 int register_die_notifier(struct notifier_block *nb)
39 spin_lock_irqsave(&die_notifier_lock, flags);
40 err = notifier_chain_register(&ia64die_chain, nb);
41 spin_unlock_irqrestore(&die_notifier_lock, flags);
48 if (ia64_boot_param->fpswa)
49 /* FPSWA fixup: make the interface pointer a kernel virtual address: */
50 fpswa_interface = __va(ia64_boot_param->fpswa);
54 * Unlock any spinlocks which will prevent us from getting the message out (timerlist_lock
55 * is acquired through the console unblank code)
58 bust_spinlocks (int yes)
60 int loglevel_save = console_loglevel;
72 * OK, the message is on the console. Now we call printk() without
73 * oops_in_progress set so that printk will give klogd a poke. Hold onto
76 console_loglevel = 15; /* NMI oopser may have shut the console up */
78 console_loglevel = loglevel_save;
82 die (const char *str, struct pt_regs *regs, long err)
89 .lock = SPIN_LOCK_UNLOCKED,
93 static int die_counter;
96 if (die.lock_owner != cpu) {
98 spin_lock_irq(&die.lock);
100 die.lock_owner_depth = 0;
105 if (++die.lock_owner_depth < 3) {
106 printk("%s[%d]: %s %ld [%d]\n",
107 current->comm, current->pid, str, err, ++die_counter);
110 printk(KERN_ERR "Recursive die() failure, output suppressed\n");
114 spin_unlock_irq(&die.lock);
119 die_if_kernel (char *str, struct pt_regs *regs, long err)
121 if (!user_mode(regs))
126 __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
131 /* break.b always sets cr.iim to 0, which causes problems for
132 * debuggers. Get the real break number from the original instruction,
133 * but only for kernel code. User space break.b is left alone, to
134 * preserve the existing behaviour. All break codings have the same
135 * format, so there is no need to check the slot type.
137 if (break_num == 0 && !user_mode(regs)) {
138 struct ia64_psr *ipsr = ia64_psr(regs);
139 unsigned long *bundle = (unsigned long *)regs->cr_iip;
142 case 0: slot = (bundle[0] >> 5); break;
143 case 1: slot = (bundle[0] >> 46) | (bundle[1] << 18); break;
144 default: slot = (bundle[1] >> 23); break;
146 break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff);
149 /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
150 siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
151 siginfo.si_imm = break_num;
152 siginfo.si_flags = 0; /* clear __ISR_VALID */
156 case 0: /* unknown error (used by GCC for __builtin_abort()) */
157 if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
161 die_if_kernel("bugcheck!", regs, break_num);
162 sig = SIGILL; code = ILL_ILLOPC;
165 case 1: /* integer divide by zero */
166 sig = SIGFPE; code = FPE_INTDIV;
169 case 2: /* integer overflow */
170 sig = SIGFPE; code = FPE_INTOVF;
173 case 3: /* range check/bounds check */
174 sig = SIGFPE; code = FPE_FLTSUB;
177 case 4: /* null pointer dereference */
178 sig = SIGSEGV; code = SEGV_MAPERR;
181 case 5: /* misaligned data */
182 sig = SIGSEGV; code = BUS_ADRALN;
185 case 6: /* decimal overflow */
186 sig = SIGFPE; code = __FPE_DECOVF;
189 case 7: /* decimal divide by zero */
190 sig = SIGFPE; code = __FPE_DECDIV;
193 case 8: /* packed decimal error */
194 sig = SIGFPE; code = __FPE_DECERR;
197 case 9: /* invalid ASCII digit */
198 sig = SIGFPE; code = __FPE_INVASC;
201 case 10: /* invalid decimal digit */
202 sig = SIGFPE; code = __FPE_INVDEC;
205 case 11: /* paragraph stack overflow */
206 sig = SIGSEGV; code = __SEGV_PSTKOVF;
209 case 0x3f000 ... 0x3ffff: /* bundle-update in progress */
210 sig = SIGILL; code = __ILL_BNDMOD;
215 if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP)
219 sig = SIGTRAP; code = TRAP_BRKPT;
223 if (break_num < 0x40000 || break_num > 0x100000)
224 die_if_kernel("Bad break", regs, break_num);
226 if (break_num < 0x80000) {
227 sig = SIGILL; code = __ILL_BREAK;
229 sig = SIGTRAP; code = TRAP_BRKPT;
232 siginfo.si_signo = sig;
233 siginfo.si_errno = 0;
234 siginfo.si_code = code;
235 force_sig_info(sig, &siginfo, current);
239 * disabled_fph_fault() is called when a user-level process attempts to access f32..f127
240 * and it doesn't own the fp-high register partition. When this happens, we save the
241 * current fph partition in the task_struct of the fpu-owner (if necessary) and then load
242 * the fp-high partition of the current task (if necessary). Note that the kernel has
243 * access to fph by the time we get here, as the IVT's "Disabled FP-Register" handler takes
244 * care of clearing psr.dfh.
247 disabled_fph_fault (struct pt_regs *regs)
249 struct ia64_psr *psr = ia64_psr(regs);
251 /* first, grant user-level access to fph partition: */
255 * Make sure that no other task gets in on this processor
256 * while we're claiming the FPU
261 struct task_struct *fpu_owner
262 = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER);
264 if (ia64_is_local_fpu_owner(current)) {
265 preempt_enable_no_resched();
270 ia64_flush_fph(fpu_owner);
272 #endif /* !CONFIG_SMP */
273 ia64_set_local_fpu_owner(current);
274 if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) {
275 __ia64_load_fpu(current->thread.fph);
280 * Set mfh because the state in thread.fph does not match the state in
285 preempt_enable_no_resched();
289 fp_emulate (int fp_fault, void *bundle, long *ipsr, long *fpsr, long *isr, long *pr, long *ifs,
290 struct pt_regs *regs)
295 if (!fpswa_interface)
298 memset(&fp_state, 0, sizeof(fp_state_t));
301 * compute fp_state. only FP registers f6 - f11 are used by the
302 * kernel, so set those bits in the mask and set the low volatile
303 * pointer to point to these registers.
305 fp_state.bitmask_low64 = 0xfc0; /* bit6..bit11 */
307 fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) ®s->f6;
309 * unsigned long (*EFI_FPSWA) (
310 * unsigned long trap_type,
312 * unsigned long *pipsr,
313 * unsigned long *pfsr,
314 * unsigned long *pisr,
315 * unsigned long *ppreds,
316 * unsigned long *pifs,
319 ret = (*fpswa_interface->fpswa)((unsigned long) fp_fault, bundle,
320 (unsigned long *) ipsr, (unsigned long *) fpsr,
321 (unsigned long *) isr, (unsigned long *) pr,
322 (unsigned long *) ifs, &fp_state);
328 * Handle floating-point assist faults and traps.
331 handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
333 long exception, bundle[2];
334 unsigned long fault_ip;
335 struct siginfo siginfo;
336 static int fpu_swa_count = 0;
337 static unsigned long last_time;
339 fault_ip = regs->cr_iip;
340 if (!fp_fault && (ia64_psr(regs)->ri == 0))
342 if (copy_from_user(bundle, (void __user *) fault_ip, sizeof(bundle)))
345 if (jiffies - last_time > 5*HZ)
347 if ((fpu_swa_count < 4) && !(current->thread.flags & IA64_THREAD_FPEMU_NOPRINT)) {
351 "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
352 current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr);
355 exception = fp_emulate(fp_fault, bundle, ®s->cr_ipsr, ®s->ar_fpsr, &isr, ®s->pr,
356 ®s->cr_ifs, regs);
358 if (exception == 0) {
359 /* emulation was successful */
360 ia64_increment_ip(regs);
361 } else if (exception == -1) {
362 printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
365 /* is next instruction a trap? */
367 ia64_increment_ip(regs);
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);
374 siginfo.si_code = FPE_FLTINV;
375 } else if (isr & 0x22) {
376 /* denormal operand gets the same si_code as underflow
377 * see arch/i386/kernel/traps.c:math_error() */
378 siginfo.si_code = FPE_FLTUND;
379 } else if (isr & 0x44) {
380 siginfo.si_code = FPE_FLTDIV;
382 siginfo.si_isr = isr;
383 siginfo.si_flags = __ISR_VALID;
385 force_sig_info(SIGFPE, &siginfo, current);
388 if (exception == -1) {
389 printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
391 } else if (exception != 0) {
392 /* raise exception */
393 siginfo.si_signo = SIGFPE;
394 siginfo.si_errno = 0;
395 siginfo.si_code = __SI_FAULT; /* default code */
396 siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
398 siginfo.si_code = FPE_FLTOVF;
399 } else if (isr & 0x1100) {
400 siginfo.si_code = FPE_FLTUND;
401 } else if (isr & 0x2200) {
402 siginfo.si_code = FPE_FLTRES;
404 siginfo.si_isr = isr;
405 siginfo.si_flags = __ISR_VALID;
407 force_sig_info(SIGFPE, &siginfo, current);
413 struct illegal_op_return {
414 unsigned long fkt, arg1, arg2, arg3;
417 struct illegal_op_return
418 ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3,
419 long arg4, long arg5, long arg6, long arg7,
422 struct illegal_op_return rv;
426 #ifdef CONFIG_IA64_BRL_EMU
428 extern struct illegal_op_return ia64_emulate_brl (struct pt_regs *, unsigned long);
430 rv = ia64_emulate_brl(®s, ec);
431 if (rv.fkt != (unsigned long) -1)
436 sprintf(buf, "IA-64 Illegal operation fault");
437 die_if_kernel(buf, ®s, 0);
439 memset(&si, 0, sizeof(si));
440 si.si_signo = SIGILL;
441 si.si_code = ILL_ILLOPC;
442 si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(®s)->ri);
443 force_sig_info(SIGILL, &si, current);
449 ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
450 unsigned long iim, unsigned long itir, long arg5, long arg6,
451 long arg7, struct pt_regs regs)
453 unsigned long code, error = isr, iip;
454 struct siginfo siginfo;
457 static const char *reason[] = {
458 "IA-64 Illegal Operation fault",
459 "IA-64 Privileged Operation fault",
460 "IA-64 Privileged Register fault",
461 "IA-64 Reserved Register/Field fault",
462 "Disabled Instruction Set Transition fault",
463 "Unknown fault 5", "Unknown fault 6", "Unknown fault 7", "Illegal Hazard fault",
464 "Unknown fault 9", "Unknown fault 10", "Unknown fault 11", "Unknown fault 12",
465 "Unknown fault 13", "Unknown fault 14", "Unknown fault 15"
468 if ((isr & IA64_ISR_NA) && ((isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH)) {
470 * This fault was due to lfetch.fault, set "ed" bit in the psr to cancel
473 ia64_psr(®s)->ed = 1;
477 iip = regs.cr_iip + ia64_psr(®s)->ri;
480 case 24: /* General Exception */
481 code = (isr >> 4) & 0xf;
482 sprintf(buf, "General Exception: %s%s", reason[code],
483 (code == 3) ? ((isr & (1UL << 37))
484 ? " (RSE access)" : " (data access)") : "");
486 # ifdef CONFIG_IA64_PRINT_HAZARDS
487 printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n",
488 current->comm, current->pid,
489 regs.cr_iip + ia64_psr(®s)->ri, regs.pr);
495 case 25: /* Disabled FP-Register */
497 disabled_fph_fault(®s);
500 sprintf(buf, "Disabled FPL fault---not supposed to happen!");
503 case 26: /* NaT Consumption */
504 if (user_mode(®s)) {
507 if (((isr >> 4) & 0xf) == 2) {
508 /* NaT page consumption */
511 addr = (void __user *) ifa;
513 /* register NaT consumption */
516 addr = (void __user *) (regs.cr_iip
517 + ia64_psr(®s)->ri);
519 siginfo.si_signo = sig;
520 siginfo.si_code = code;
521 siginfo.si_errno = 0;
522 siginfo.si_addr = addr;
523 siginfo.si_imm = vector;
524 siginfo.si_flags = __ISR_VALID;
525 siginfo.si_isr = isr;
526 force_sig_info(sig, &siginfo, current);
528 } else if (ia64_done_with_exception(®s))
530 sprintf(buf, "NaT consumption");
533 case 31: /* Unsupported Data Reference */
534 if (user_mode(®s)) {
535 siginfo.si_signo = SIGILL;
536 siginfo.si_code = ILL_ILLOPN;
537 siginfo.si_errno = 0;
538 siginfo.si_addr = (void __user *) iip;
539 siginfo.si_imm = vector;
540 siginfo.si_flags = __ISR_VALID;
541 siginfo.si_isr = isr;
542 force_sig_info(SIGILL, &siginfo, current);
545 sprintf(buf, "Unsupported data reference");
549 case 35: /* Taken Branch Trap */
550 case 36: /* Single Step Trap */
551 if (fsys_mode(current, ®s)) {
552 extern char __kernel_syscall_via_break[];
554 * Got a trap in fsys-mode: Taken Branch Trap and Single Step trap
555 * need special handling; Debug trap is not supposed to happen.
557 if (unlikely(vector == 29)) {
558 die("Got debug trap in fsys-mode---not supposed to happen!",
562 /* re-do the system call via break 0x100000: */
563 regs.cr_iip = (unsigned long) __kernel_syscall_via_break;
564 ia64_psr(®s)->ri = 0;
565 ia64_psr(®s)->cpl = 3;
570 siginfo.si_code = TRAP_HWBKPT;
571 #ifdef CONFIG_ITANIUM
573 * Erratum 10 (IFA may contain incorrect address) now has
574 * "NoFix" status. There are no plans for fixing this.
576 if (ia64_psr(®s)->is == 0)
580 case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
582 if (notify_die(DIE_SS, "ss", ®s, vector,
583 vector, SIGTRAP) == NOTIFY_STOP)
585 siginfo.si_code = TRAP_TRACE; ifa = 0; break;
587 siginfo.si_signo = SIGTRAP;
588 siginfo.si_errno = 0;
589 siginfo.si_addr = (void __user *) ifa;
591 siginfo.si_flags = __ISR_VALID;
592 siginfo.si_isr = isr;
593 force_sig_info(SIGTRAP, &siginfo, current);
596 case 32: /* fp fault */
597 case 33: /* fp trap */
598 result = handle_fpu_swa((vector == 32) ? 1 : 0, ®s, isr);
599 if ((result < 0) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) {
600 siginfo.si_signo = SIGFPE;
601 siginfo.si_errno = 0;
602 siginfo.si_code = FPE_FLTINV;
603 siginfo.si_addr = (void __user *) iip;
604 siginfo.si_flags = __ISR_VALID;
605 siginfo.si_isr = isr;
607 force_sig_info(SIGFPE, &siginfo, current);
613 /* Lower-Privilege Transfer Trap */
615 * Just clear PSR.lp and then return immediately: all the
616 * interesting work (e.g., signal delivery is done in the kernel
619 ia64_psr(®s)->lp = 0;
622 /* Unimplemented Instr. Address Trap */
623 if (user_mode(®s)) {
624 siginfo.si_signo = SIGILL;
625 siginfo.si_code = ILL_BADIADDR;
626 siginfo.si_errno = 0;
627 siginfo.si_flags = 0;
630 siginfo.si_addr = (void __user *) iip;
631 force_sig_info(SIGILL, &siginfo, current);
634 sprintf(buf, "Unimplemented Instruction Address fault");
639 #ifdef CONFIG_IA32_SUPPORT
640 if (ia32_exception(®s, isr) == 0)
643 printk(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n");
644 printk(KERN_ERR " iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n",
646 force_sig(SIGSEGV, current);
650 #ifdef CONFIG_IA32_SUPPORT
651 if (ia32_intercept(®s, isr) == 0)
654 printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n");
655 printk(KERN_ERR " iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",
657 force_sig(SIGSEGV, current);
661 sprintf(buf, "IA-32 Interruption Fault (int 0x%lx)", isr >> 16);
665 sprintf(buf, "Fault %lu", vector);
668 die_if_kernel(buf, ®s, error);
669 force_sig(SIGILL, current);