[PATCH] hwmon: hwmon vs i2c, second round (05/11)
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / arch / ia64 / kernel / traps.c
blob4440c8343fa4303df0dbc658954d9d3cebc1ab8d
1 /*
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
8 */
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>
20 #include <asm/ia32.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)
36 int err = 0;
37 unsigned long flags;
38 spin_lock_irqsave(&die_notifier_lock, flags);
39 err = notifier_chain_register(&ia64die_chain, nb);
40 spin_unlock_irqrestore(&die_notifier_lock, flags);
41 return err;
44 void __init
45 trap_init (void)
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)
56 void
57 bust_spinlocks (int yes)
59 int loglevel_save = console_loglevel;
61 if (yes) {
62 oops_in_progress = 1;
63 return;
66 #ifdef CONFIG_VT
67 unblank_screen();
68 #endif
69 oops_in_progress = 0;
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
73 * your hats...
75 console_loglevel = 15; /* NMI oopser may have shut the console up */
76 printk(" ");
77 console_loglevel = loglevel_save;
80 void
81 die (const char *str, struct pt_regs *regs, long err)
83 static struct {
84 spinlock_t lock;
85 u32 lock_owner;
86 int lock_owner_depth;
87 } die = {
88 .lock = SPIN_LOCK_UNLOCKED,
89 .lock_owner = -1,
90 .lock_owner_depth = 0
92 static int die_counter;
93 int cpu = get_cpu();
95 if (die.lock_owner != cpu) {
96 console_verbose();
97 spin_lock_irq(&die.lock);
98 die.lock_owner = cpu;
99 die.lock_owner_depth = 0;
100 bust_spinlocks(1);
102 put_cpu();
104 if (++die.lock_owner_depth < 3) {
105 printk("%s[%d]: %s %ld [%d]\n",
106 current->comm, current->pid, str, err, ++die_counter);
107 show_regs(regs);
108 } else
109 printk(KERN_ERR "Recursive die() failure, output suppressed\n");
111 bust_spinlocks(0);
112 die.lock_owner = -1;
113 spin_unlock_irq(&die.lock);
114 do_exit(SIGSEGV);
117 void
118 die_if_kernel (char *str, struct pt_regs *regs, long err)
120 if (!user_mode(regs))
121 die(str, regs, err);
124 void
125 ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
127 siginfo_t siginfo;
128 int sig, code;
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;
139 unsigned long slot;
140 switch (ipsr->ri) {
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 */
152 siginfo.si_isr = 0;
154 switch (break_num) {
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)
157 == NOTIFY_STOP) {
158 return;
160 die_if_kernel("bugcheck!", regs, break_num);
161 sig = SIGILL; code = ILL_ILLOPC;
162 break;
164 case 1: /* integer divide by zero */
165 sig = SIGFPE; code = FPE_INTDIV;
166 break;
168 case 2: /* integer overflow */
169 sig = SIGFPE; code = FPE_INTOVF;
170 break;
172 case 3: /* range check/bounds check */
173 sig = SIGFPE; code = FPE_FLTSUB;
174 break;
176 case 4: /* null pointer dereference */
177 sig = SIGSEGV; code = SEGV_MAPERR;
178 break;
180 case 5: /* misaligned data */
181 sig = SIGSEGV; code = BUS_ADRALN;
182 break;
184 case 6: /* decimal overflow */
185 sig = SIGFPE; code = __FPE_DECOVF;
186 break;
188 case 7: /* decimal divide by zero */
189 sig = SIGFPE; code = __FPE_DECDIV;
190 break;
192 case 8: /* packed decimal error */
193 sig = SIGFPE; code = __FPE_DECERR;
194 break;
196 case 9: /* invalid ASCII digit */
197 sig = SIGFPE; code = __FPE_INVASC;
198 break;
200 case 10: /* invalid decimal digit */
201 sig = SIGFPE; code = __FPE_INVDEC;
202 break;
204 case 11: /* paragraph stack overflow */
205 sig = SIGSEGV; code = __SEGV_PSTKOVF;
206 break;
208 case 0x3f000 ... 0x3ffff: /* bundle-update in progress */
209 sig = SIGILL; code = __ILL_BNDMOD;
210 break;
212 case 0x80200:
213 case 0x80300:
214 if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP)
215 == NOTIFY_STOP) {
216 return;
218 sig = SIGTRAP; code = TRAP_BRKPT;
219 break;
221 default:
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;
227 } else {
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.
245 static inline void
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: */
251 psr->dfh = 0;
254 * Make sure that no other task gets in on this processor
255 * while we're claiming the FPU
257 preempt_disable();
258 #ifndef CONFIG_SMP
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();
265 return;
268 if (fpu_owner)
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);
275 psr->mfh = 0;
276 } else {
277 __ia64_init_fpu();
279 * Set mfh because the state in thread.fph does not match the state in
280 * the fph partition.
282 psr->mfh = 1;
284 preempt_enable_no_resched();
287 static inline int
288 fp_emulate (int fp_fault, void *bundle, long *ipsr, long *fpsr, long *isr, long *pr, long *ifs,
289 struct pt_regs *regs)
291 fp_state_t fp_state;
292 fpswa_ret_t ret;
294 if (!fpswa_interface)
295 return -1;
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 *) &regs->f6;
308 * unsigned long (*EFI_FPSWA) (
309 * unsigned long trap_type,
310 * void *Bundle,
311 * unsigned long *pipsr,
312 * unsigned long *pfsr,
313 * unsigned long *pisr,
314 * unsigned long *ppreds,
315 * unsigned long *pifs,
316 * void *fp_state);
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);
323 return ret.status;
327 * Handle floating-point assist faults and traps.
329 static int
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))
340 fault_ip -= 16;
341 if (copy_from_user(bundle, (void __user *) fault_ip, sizeof(bundle)))
342 return -1;
344 if (jiffies - last_time > 5*HZ)
345 fpu_swa_count = 0;
346 if ((fpu_swa_count < 4) && !(current->thread.flags & IA64_THREAD_FPEMU_NOPRINT)) {
347 last_time = jiffies;
348 ++fpu_swa_count;
349 printk(KERN_WARNING
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, &regs->cr_ipsr, &regs->ar_fpsr, &isr, &regs->pr,
355 &regs->cr_ifs, regs);
356 if (fp_fault) {
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");
362 return -1;
363 } else {
364 /* is next instruction a trap? */
365 if (exception & 2) {
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);
372 if (isr & 0x11) {
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;
383 siginfo.si_imm = 0;
384 force_sig_info(SIGFPE, &siginfo, current);
386 } else {
387 if (exception == -1) {
388 printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
389 return -1;
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);
396 if (isr & 0x880) {
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;
405 siginfo.si_imm = 0;
406 force_sig_info(SIGFPE, &siginfo, current);
409 return 0;
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,
419 struct pt_regs regs)
421 struct illegal_op_return rv;
422 struct siginfo si;
423 char buf[128];
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(&regs, ec);
430 if (rv.fkt != (unsigned long) -1)
431 return rv;
433 #endif
435 sprintf(buf, "IA-64 Illegal operation fault");
436 die_if_kernel(buf, &regs, 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(&regs)->ri);
442 force_sig_info(SIGILL, &si, current);
443 rv.fkt = 0;
444 return rv;
447 void
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;
454 char buf[128];
455 int result, sig;
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
470 * the lfetch.
472 ia64_psr(&regs)->ed = 1;
473 return;
476 iip = regs.cr_iip + ia64_psr(&regs)->ri;
478 switch (vector) {
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)") : "");
484 if (code == 8) {
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(&regs)->ri, regs.pr);
489 # endif
490 return;
492 break;
494 case 25: /* Disabled FP-Register */
495 if (isr & 2) {
496 disabled_fph_fault(&regs);
497 return;
499 sprintf(buf, "Disabled FPL fault---not supposed to happen!");
500 break;
502 case 26: /* NaT Consumption */
503 if (user_mode(&regs)) {
504 void __user *addr;
506 if (((isr >> 4) & 0xf) == 2) {
507 /* NaT page consumption */
508 sig = SIGSEGV;
509 code = SEGV_ACCERR;
510 addr = (void __user *) ifa;
511 } else {
512 /* register NaT consumption */
513 sig = SIGILL;
514 code = ILL_ILLOPN;
515 addr = (void __user *) (regs.cr_iip
516 + ia64_psr(&regs)->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);
526 return;
527 } else if (ia64_done_with_exception(&regs))
528 return;
529 sprintf(buf, "NaT consumption");
530 break;
532 case 31: /* Unsupported Data Reference */
533 if (user_mode(&regs)) {
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);
542 return;
544 sprintf(buf, "Unsupported data reference");
545 break;
547 case 29: /* Debug */
548 case 35: /* Taken Branch Trap */
549 case 36: /* Single Step Trap */
550 if (fsys_mode(current, &regs)) {
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!",
558 &regs, 0);
559 return;
561 /* re-do the system call via break 0x100000: */
562 regs.cr_iip = (unsigned long) __kernel_syscall_via_break;
563 ia64_psr(&regs)->ri = 0;
564 ia64_psr(&regs)->cpl = 3;
565 return;
567 switch (vector) {
568 case 29:
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(&regs)->is == 0)
576 ifa = regs.cr_iip;
577 #endif
578 break;
579 case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
580 case 36:
581 if (notify_die(DIE_SS, "ss", &regs, vector,
582 vector, SIGTRAP) == NOTIFY_STOP)
583 return;
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;
589 siginfo.si_imm = 0;
590 siginfo.si_flags = __ISR_VALID;
591 siginfo.si_isr = isr;
592 force_sig_info(SIGTRAP, &siginfo, current);
593 return;
595 case 32: /* fp fault */
596 case 33: /* fp trap */
597 result = handle_fpu_swa((vector == 32) ? 1 : 0, &regs, 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;
605 siginfo.si_imm = 0;
606 force_sig_info(SIGFPE, &siginfo, current);
608 return;
610 case 34:
611 if (isr & 0x2) {
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
616 * exit path).
618 ia64_psr(&regs)->lp = 0;
619 return;
620 } else {
621 /* Unimplemented Instr. Address Trap */
622 if (user_mode(&regs)) {
623 siginfo.si_signo = SIGILL;
624 siginfo.si_code = ILL_BADIADDR;
625 siginfo.si_errno = 0;
626 siginfo.si_flags = 0;
627 siginfo.si_isr = 0;
628 siginfo.si_imm = 0;
629 siginfo.si_addr = (void __user *) iip;
630 force_sig_info(SIGILL, &siginfo, current);
631 return;
633 sprintf(buf, "Unimplemented Instruction Address fault");
635 break;
637 case 45:
638 #ifdef CONFIG_IA32_SUPPORT
639 if (ia32_exception(&regs, isr) == 0)
640 return;
641 #endif
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",
644 iip, ifa, isr);
645 force_sig(SIGSEGV, current);
646 break;
648 case 46:
649 #ifdef CONFIG_IA32_SUPPORT
650 if (ia32_intercept(&regs, isr) == 0)
651 return;
652 #endif
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",
655 iip, ifa, isr, iim);
656 force_sig(SIGSEGV, current);
657 return;
659 case 47:
660 sprintf(buf, "IA-32 Interruption Fault (int 0x%lx)", isr >> 16);
661 break;
663 default:
664 sprintf(buf, "Fault %lu", vector);
665 break;
667 die_if_kernel(buf, &regs, error);
668 force_sig(SIGILL, current);