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>
19 #include <asm/fpswa.h>
21 #include <asm/intrinsics.h>
22 #include <asm/processor.h>
23 #include <asm/uaccess.h>
24 #include <asm/kdebug.h>
26 extern spinlock_t timerlist_lock;
28 fpswa_interface_t *fpswa_interface;
29 EXPORT_SYMBOL(fpswa_interface);
31 struct notifier_block *ia64die_chain;
32 static DEFINE_SPINLOCK(die_notifier_lock);
34 int register_die_notifier(struct notifier_block *nb)
38 spin_lock_irqsave(&die_notifier_lock, flags);
39 err = notifier_chain_register(&ia64die_chain, nb);
40 spin_unlock_irqrestore(&die_notifier_lock, flags);
47 if (ia64_boot_param->fpswa)
48 /* FPSWA fixup: make the interface pointer a kernel virtual address: */
49 fpswa_interface = __va(ia64_boot_param->fpswa);
53 * Unlock any spinlocks which will prevent us from getting the message out (timerlist_lock
54 * is acquired through the console unblank code)
57 bust_spinlocks (int yes)
59 int loglevel_save = console_loglevel;
71 * OK, the message is on the console. Now we call printk() without
72 * oops_in_progress set so that printk will give klogd a poke. Hold onto
75 console_loglevel = 15; /* NMI oopser may have shut the console up */
77 console_loglevel = loglevel_save;
81 die (const char *str, struct pt_regs *regs, long err)
88 .lock = SPIN_LOCK_UNLOCKED,
92 static int die_counter;
95 if (die.lock_owner != cpu) {
97 spin_lock_irq(&die.lock);
99 die.lock_owner_depth = 0;
104 if (++die.lock_owner_depth < 3) {
105 printk("%s[%d]: %s %ld [%d]\n",
106 current->comm, current->pid, str, err, ++die_counter);
109 printk(KERN_ERR "Recursive die() failure, output suppressed\n");
113 spin_unlock_irq(&die.lock);
118 die_if_kernel (char *str, struct pt_regs *regs, long err)
120 if (!user_mode(regs))
125 ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
130 /* break.b always sets cr.iim to 0, which causes problems for
131 * debuggers. Get the real break number from the original instruction,
132 * but only for kernel code. User space break.b is left alone, to
133 * preserve the existing behaviour. All break codings have the same
134 * format, so there is no need to check the slot type.
136 if (break_num == 0 && !user_mode(regs)) {
137 struct ia64_psr *ipsr = ia64_psr(regs);
138 unsigned long *bundle = (unsigned long *)regs->cr_iip;
141 case 0: slot = (bundle[0] >> 5); break;
142 case 1: slot = (bundle[0] >> 46) | (bundle[1] << 18); break;
143 default: slot = (bundle[1] >> 23); break;
145 break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff);
148 /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
149 siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
150 siginfo.si_imm = break_num;
151 siginfo.si_flags = 0; /* clear __ISR_VALID */
155 case 0: /* unknown error (used by GCC for __builtin_abort()) */
156 if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
160 die_if_kernel("bugcheck!", regs, break_num);
161 sig = SIGILL; code = ILL_ILLOPC;
164 case 1: /* integer divide by zero */
165 sig = SIGFPE; code = FPE_INTDIV;
168 case 2: /* integer overflow */
169 sig = SIGFPE; code = FPE_INTOVF;
172 case 3: /* range check/bounds check */
173 sig = SIGFPE; code = FPE_FLTSUB;
176 case 4: /* null pointer dereference */
177 sig = SIGSEGV; code = SEGV_MAPERR;
180 case 5: /* misaligned data */
181 sig = SIGSEGV; code = BUS_ADRALN;
184 case 6: /* decimal overflow */
185 sig = SIGFPE; code = __FPE_DECOVF;
188 case 7: /* decimal divide by zero */
189 sig = SIGFPE; code = __FPE_DECDIV;
192 case 8: /* packed decimal error */
193 sig = SIGFPE; code = __FPE_DECERR;
196 case 9: /* invalid ASCII digit */
197 sig = SIGFPE; code = __FPE_INVASC;
200 case 10: /* invalid decimal digit */
201 sig = SIGFPE; code = __FPE_INVDEC;
204 case 11: /* paragraph stack overflow */
205 sig = SIGSEGV; code = __SEGV_PSTKOVF;
208 case 0x3f000 ... 0x3ffff: /* bundle-update in progress */
209 sig = SIGILL; code = __ILL_BNDMOD;
214 if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP)
218 sig = SIGTRAP; code = TRAP_BRKPT;
222 if (break_num < 0x40000 || break_num > 0x100000)
223 die_if_kernel("Bad break", regs, break_num);
225 if (break_num < 0x80000) {
226 sig = SIGILL; code = __ILL_BREAK;
228 sig = SIGTRAP; code = TRAP_BRKPT;
231 siginfo.si_signo = sig;
232 siginfo.si_errno = 0;
233 siginfo.si_code = code;
234 force_sig_info(sig, &siginfo, current);
238 * disabled_fph_fault() is called when a user-level process attempts to access f32..f127
239 * and it doesn't own the fp-high register partition. When this happens, we save the
240 * current fph partition in the task_struct of the fpu-owner (if necessary) and then load
241 * the fp-high partition of the current task (if necessary). Note that the kernel has
242 * access to fph by the time we get here, as the IVT's "Disabled FP-Register" handler takes
243 * care of clearing psr.dfh.
246 disabled_fph_fault (struct pt_regs *regs)
248 struct ia64_psr *psr = ia64_psr(regs);
250 /* first, grant user-level access to fph partition: */
254 * Make sure that no other task gets in on this processor
255 * while we're claiming the FPU
260 struct task_struct *fpu_owner
261 = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER);
263 if (ia64_is_local_fpu_owner(current)) {
264 preempt_enable_no_resched();
269 ia64_flush_fph(fpu_owner);
271 #endif /* !CONFIG_SMP */
272 ia64_set_local_fpu_owner(current);
273 if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) {
274 __ia64_load_fpu(current->thread.fph);
279 * Set mfh because the state in thread.fph does not match the state in
284 preempt_enable_no_resched();
288 fp_emulate (int fp_fault, void *bundle, long *ipsr, long *fpsr, long *isr, long *pr, long *ifs,
289 struct pt_regs *regs)
294 if (!fpswa_interface)
297 memset(&fp_state, 0, sizeof(fp_state_t));
300 * compute fp_state. only FP registers f6 - f11 are used by the
301 * kernel, so set those bits in the mask and set the low volatile
302 * pointer to point to these registers.
304 fp_state.bitmask_low64 = 0xfc0; /* bit6..bit11 */
306 fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) ®s->f6;
308 * unsigned long (*EFI_FPSWA) (
309 * unsigned long trap_type,
311 * unsigned long *pipsr,
312 * unsigned long *pfsr,
313 * unsigned long *pisr,
314 * unsigned long *ppreds,
315 * unsigned long *pifs,
318 ret = (*fpswa_interface->fpswa)((unsigned long) fp_fault, bundle,
319 (unsigned long *) ipsr, (unsigned long *) fpsr,
320 (unsigned long *) isr, (unsigned long *) pr,
321 (unsigned long *) ifs, &fp_state);
327 * Handle floating-point assist faults and traps.
330 handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
332 long exception, bundle[2];
333 unsigned long fault_ip;
334 struct siginfo siginfo;
335 static int fpu_swa_count = 0;
336 static unsigned long last_time;
338 fault_ip = regs->cr_iip;
339 if (!fp_fault && (ia64_psr(regs)->ri == 0))
341 if (copy_from_user(bundle, (void __user *) fault_ip, sizeof(bundle)))
344 if (jiffies - last_time > 5*HZ)
346 if ((fpu_swa_count < 4) && !(current->thread.flags & IA64_THREAD_FPEMU_NOPRINT)) {
350 "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
351 current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr);
354 exception = fp_emulate(fp_fault, bundle, ®s->cr_ipsr, ®s->ar_fpsr, &isr, ®s->pr,
355 ®s->cr_ifs, regs);
357 if (exception == 0) {
358 /* emulation was successful */
359 ia64_increment_ip(regs);
360 } else if (exception == -1) {
361 printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
364 /* is next instruction a trap? */
366 ia64_increment_ip(regs);
368 siginfo.si_signo = SIGFPE;
369 siginfo.si_errno = 0;
370 siginfo.si_code = __SI_FAULT; /* default code */
371 siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
373 siginfo.si_code = FPE_FLTINV;
374 } else if (isr & 0x22) {
375 /* denormal operand gets the same si_code as underflow
376 * see arch/i386/kernel/traps.c:math_error() */
377 siginfo.si_code = FPE_FLTUND;
378 } else if (isr & 0x44) {
379 siginfo.si_code = FPE_FLTDIV;
381 siginfo.si_isr = isr;
382 siginfo.si_flags = __ISR_VALID;
384 force_sig_info(SIGFPE, &siginfo, current);
387 if (exception == -1) {
388 printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
390 } else if (exception != 0) {
391 /* raise exception */
392 siginfo.si_signo = SIGFPE;
393 siginfo.si_errno = 0;
394 siginfo.si_code = __SI_FAULT; /* default code */
395 siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
397 siginfo.si_code = FPE_FLTOVF;
398 } else if (isr & 0x1100) {
399 siginfo.si_code = FPE_FLTUND;
400 } else if (isr & 0x2200) {
401 siginfo.si_code = FPE_FLTRES;
403 siginfo.si_isr = isr;
404 siginfo.si_flags = __ISR_VALID;
406 force_sig_info(SIGFPE, &siginfo, current);
412 struct illegal_op_return {
413 unsigned long fkt, arg1, arg2, arg3;
416 struct illegal_op_return
417 ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3,
418 long arg4, long arg5, long arg6, long arg7,
421 struct illegal_op_return rv;
425 #ifdef CONFIG_IA64_BRL_EMU
427 extern struct illegal_op_return ia64_emulate_brl (struct pt_regs *, unsigned long);
429 rv = ia64_emulate_brl(®s, ec);
430 if (rv.fkt != (unsigned long) -1)
435 sprintf(buf, "IA-64 Illegal operation fault");
436 die_if_kernel(buf, ®s, 0);
438 memset(&si, 0, sizeof(si));
439 si.si_signo = SIGILL;
440 si.si_code = ILL_ILLOPC;
441 si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(®s)->ri);
442 force_sig_info(SIGILL, &si, current);
448 ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
449 unsigned long iim, unsigned long itir, long arg5, long arg6,
450 long arg7, struct pt_regs regs)
452 unsigned long code, error = isr, iip;
453 struct siginfo siginfo;
456 static const char *reason[] = {
457 "IA-64 Illegal Operation fault",
458 "IA-64 Privileged Operation fault",
459 "IA-64 Privileged Register fault",
460 "IA-64 Reserved Register/Field fault",
461 "Disabled Instruction Set Transition fault",
462 "Unknown fault 5", "Unknown fault 6", "Unknown fault 7", "Illegal Hazard fault",
463 "Unknown fault 9", "Unknown fault 10", "Unknown fault 11", "Unknown fault 12",
464 "Unknown fault 13", "Unknown fault 14", "Unknown fault 15"
467 if ((isr & IA64_ISR_NA) && ((isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH)) {
469 * This fault was due to lfetch.fault, set "ed" bit in the psr to cancel
472 ia64_psr(®s)->ed = 1;
476 iip = regs.cr_iip + ia64_psr(®s)->ri;
479 case 24: /* General Exception */
480 code = (isr >> 4) & 0xf;
481 sprintf(buf, "General Exception: %s%s", reason[code],
482 (code == 3) ? ((isr & (1UL << 37))
483 ? " (RSE access)" : " (data access)") : "");
485 # ifdef CONFIG_IA64_PRINT_HAZARDS
486 printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n",
487 current->comm, current->pid,
488 regs.cr_iip + ia64_psr(®s)->ri, regs.pr);
494 case 25: /* Disabled FP-Register */
496 disabled_fph_fault(®s);
499 sprintf(buf, "Disabled FPL fault---not supposed to happen!");
502 case 26: /* NaT Consumption */
503 if (user_mode(®s)) {
506 if (((isr >> 4) & 0xf) == 2) {
507 /* NaT page consumption */
510 addr = (void __user *) ifa;
512 /* register NaT consumption */
515 addr = (void __user *) (regs.cr_iip
516 + ia64_psr(®s)->ri);
518 siginfo.si_signo = sig;
519 siginfo.si_code = code;
520 siginfo.si_errno = 0;
521 siginfo.si_addr = addr;
522 siginfo.si_imm = vector;
523 siginfo.si_flags = __ISR_VALID;
524 siginfo.si_isr = isr;
525 force_sig_info(sig, &siginfo, current);
527 } else if (ia64_done_with_exception(®s))
529 sprintf(buf, "NaT consumption");
532 case 31: /* Unsupported Data Reference */
533 if (user_mode(®s)) {
534 siginfo.si_signo = SIGILL;
535 siginfo.si_code = ILL_ILLOPN;
536 siginfo.si_errno = 0;
537 siginfo.si_addr = (void __user *) iip;
538 siginfo.si_imm = vector;
539 siginfo.si_flags = __ISR_VALID;
540 siginfo.si_isr = isr;
541 force_sig_info(SIGILL, &siginfo, current);
544 sprintf(buf, "Unsupported data reference");
548 case 35: /* Taken Branch Trap */
549 case 36: /* Single Step Trap */
550 if (fsys_mode(current, ®s)) {
551 extern char __kernel_syscall_via_break[];
553 * Got a trap in fsys-mode: Taken Branch Trap and Single Step trap
554 * need special handling; Debug trap is not supposed to happen.
556 if (unlikely(vector == 29)) {
557 die("Got debug trap in fsys-mode---not supposed to happen!",
561 /* re-do the system call via break 0x100000: */
562 regs.cr_iip = (unsigned long) __kernel_syscall_via_break;
563 ia64_psr(®s)->ri = 0;
564 ia64_psr(®s)->cpl = 3;
569 siginfo.si_code = TRAP_HWBKPT;
570 #ifdef CONFIG_ITANIUM
572 * Erratum 10 (IFA may contain incorrect address) now has
573 * "NoFix" status. There are no plans for fixing this.
575 if (ia64_psr(®s)->is == 0)
579 case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
581 if (notify_die(DIE_SS, "ss", ®s, vector,
582 vector, SIGTRAP) == NOTIFY_STOP)
584 siginfo.si_code = TRAP_TRACE; ifa = 0; break;
586 siginfo.si_signo = SIGTRAP;
587 siginfo.si_errno = 0;
588 siginfo.si_addr = (void __user *) ifa;
590 siginfo.si_flags = __ISR_VALID;
591 siginfo.si_isr = isr;
592 force_sig_info(SIGTRAP, &siginfo, current);
595 case 32: /* fp fault */
596 case 33: /* fp trap */
597 result = handle_fpu_swa((vector == 32) ? 1 : 0, ®s, isr);
598 if ((result < 0) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) {
599 siginfo.si_signo = SIGFPE;
600 siginfo.si_errno = 0;
601 siginfo.si_code = FPE_FLTINV;
602 siginfo.si_addr = (void __user *) iip;
603 siginfo.si_flags = __ISR_VALID;
604 siginfo.si_isr = isr;
606 force_sig_info(SIGFPE, &siginfo, current);
612 /* Lower-Privilege Transfer Trap */
614 * Just clear PSR.lp and then return immediately: all the
615 * interesting work (e.g., signal delivery is done in the kernel
618 ia64_psr(®s)->lp = 0;
621 /* Unimplemented Instr. Address Trap */
622 if (user_mode(®s)) {
623 siginfo.si_signo = SIGILL;
624 siginfo.si_code = ILL_BADIADDR;
625 siginfo.si_errno = 0;
626 siginfo.si_flags = 0;
629 siginfo.si_addr = (void __user *) iip;
630 force_sig_info(SIGILL, &siginfo, current);
633 sprintf(buf, "Unimplemented Instruction Address fault");
638 #ifdef CONFIG_IA32_SUPPORT
639 if (ia32_exception(®s, isr) == 0)
642 printk(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n");
643 printk(KERN_ERR " iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n",
645 force_sig(SIGSEGV, current);
649 #ifdef CONFIG_IA32_SUPPORT
650 if (ia32_intercept(®s, isr) == 0)
653 printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n");
654 printk(KERN_ERR " iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",
656 force_sig(SIGSEGV, current);
660 sprintf(buf, "IA-32 Interruption Fault (int 0x%lx)", isr >> 16);
664 sprintf(buf, "Fault %lu", vector);
667 die_if_kernel(buf, ®s, error);
668 force_sig(SIGILL, current);