Merge branch 'upstream' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/misc-2.6
[sfrench/cifs-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 #include <linux/kprobes.h>
19
20 #include <asm/fpswa.h>
21 #include <asm/ia32.h>
22 #include <asm/intrinsics.h>
23 #include <asm/processor.h>
24 #include <asm/uaccess.h>
25 #include <asm/kdebug.h>
26
27 extern spinlock_t timerlist_lock;
28
29 fpswa_interface_t *fpswa_interface;
30 EXPORT_SYMBOL(fpswa_interface);
31
32 struct notifier_block *ia64die_chain;
33 static DEFINE_SPINLOCK(die_notifier_lock);
34
35 int register_die_notifier(struct notifier_block *nb)
36 {
37         int err = 0;
38         unsigned long flags;
39         spin_lock_irqsave(&die_notifier_lock, flags);
40         err = notifier_chain_register(&ia64die_chain, nb);
41         spin_unlock_irqrestore(&die_notifier_lock, flags);
42         return err;
43 }
44
45 void __init
46 trap_init (void)
47 {
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);
51 }
52
53 /*
54  * Unlock any spinlocks which will prevent us from getting the message out (timerlist_lock
55  * is acquired through the console unblank code)
56  */
57 void
58 bust_spinlocks (int yes)
59 {
60         int loglevel_save = console_loglevel;
61
62         if (yes) {
63                 oops_in_progress = 1;
64                 return;
65         }
66
67 #ifdef CONFIG_VT
68         unblank_screen();
69 #endif
70         oops_in_progress = 0;
71         /*
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
74          * your hats...
75          */
76         console_loglevel = 15;          /* NMI oopser may have shut the console up */
77         printk(" ");
78         console_loglevel = loglevel_save;
79 }
80
81 void
82 die (const char *str, struct pt_regs *regs, long err)
83 {
84         static struct {
85                 spinlock_t lock;
86                 u32 lock_owner;
87                 int lock_owner_depth;
88         } die = {
89                 .lock =                 SPIN_LOCK_UNLOCKED,
90                 .lock_owner =           -1,
91                 .lock_owner_depth =     0
92         };
93         static int die_counter;
94         int cpu = get_cpu();
95
96         if (die.lock_owner != cpu) {
97                 console_verbose();
98                 spin_lock_irq(&die.lock);
99                 die.lock_owner = cpu;
100                 die.lock_owner_depth = 0;
101                 bust_spinlocks(1);
102         }
103         put_cpu();
104
105         if (++die.lock_owner_depth < 3) {
106                 printk("%s[%d]: %s %ld [%d]\n",
107                         current->comm, current->pid, str, err, ++die_counter);
108                 show_regs(regs);
109         } else
110                 printk(KERN_ERR "Recursive die() failure, output suppressed\n");
111
112         bust_spinlocks(0);
113         die.lock_owner = -1;
114         spin_unlock_irq(&die.lock);
115         do_exit(SIGSEGV);
116 }
117
118 void
119 die_if_kernel (char *str, struct pt_regs *regs, long err)
120 {
121         if (!user_mode(regs))
122                 die(str, regs, err);
123 }
124
125 void
126 __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
127 {
128         siginfo_t siginfo;
129         int sig, code;
130
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.
136          */
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;
140                 unsigned long slot;
141                 switch (ipsr->ri) {
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;
145                 }
146                 break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff);
147         }
148
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 */
153         siginfo.si_isr = 0;
154
155         switch (break_num) {
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)
158                                 == NOTIFY_STOP) {
159                         return;
160                 }
161                 die_if_kernel("bugcheck!", regs, break_num);
162                 sig = SIGILL; code = ILL_ILLOPC;
163                 break;
164
165               case 1: /* integer divide by zero */
166                 sig = SIGFPE; code = FPE_INTDIV;
167                 break;
168
169               case 2: /* integer overflow */
170                 sig = SIGFPE; code = FPE_INTOVF;
171                 break;
172
173               case 3: /* range check/bounds check */
174                 sig = SIGFPE; code = FPE_FLTSUB;
175                 break;
176
177               case 4: /* null pointer dereference */
178                 sig = SIGSEGV; code = SEGV_MAPERR;
179                 break;
180
181               case 5: /* misaligned data */
182                 sig = SIGSEGV; code = BUS_ADRALN;
183                 break;
184
185               case 6: /* decimal overflow */
186                 sig = SIGFPE; code = __FPE_DECOVF;
187                 break;
188
189               case 7: /* decimal divide by zero */
190                 sig = SIGFPE; code = __FPE_DECDIV;
191                 break;
192
193               case 8: /* packed decimal error */
194                 sig = SIGFPE; code = __FPE_DECERR;
195                 break;
196
197               case 9: /* invalid ASCII digit */
198                 sig = SIGFPE; code = __FPE_INVASC;
199                 break;
200
201               case 10: /* invalid decimal digit */
202                 sig = SIGFPE; code = __FPE_INVDEC;
203                 break;
204
205               case 11: /* paragraph stack overflow */
206                 sig = SIGSEGV; code = __SEGV_PSTKOVF;
207                 break;
208
209               case 0x3f000 ... 0x3ffff: /* bundle-update in progress */
210                 sig = SIGILL; code = __ILL_BNDMOD;
211                 break;
212
213               case 0x80200:
214               case 0x80300:
215                 if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP)
216                                 == NOTIFY_STOP) {
217                         return;
218                 }
219                 sig = SIGTRAP; code = TRAP_BRKPT;
220                 break;
221
222               default:
223                 if (break_num < 0x40000 || break_num > 0x100000)
224                         die_if_kernel("Bad break", regs, break_num);
225
226                 if (break_num < 0x80000) {
227                         sig = SIGILL; code = __ILL_BREAK;
228                 } else {
229                         sig = SIGTRAP; code = TRAP_BRKPT;
230                 }
231         }
232         siginfo.si_signo = sig;
233         siginfo.si_errno = 0;
234         siginfo.si_code = code;
235         force_sig_info(sig, &siginfo, current);
236 }
237
238 /*
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.
245  */
246 static inline void
247 disabled_fph_fault (struct pt_regs *regs)
248 {
249         struct ia64_psr *psr = ia64_psr(regs);
250
251         /* first, grant user-level access to fph partition: */
252         psr->dfh = 0;
253
254         /*
255          * Make sure that no other task gets in on this processor
256          * while we're claiming the FPU
257          */
258         preempt_disable();
259 #ifndef CONFIG_SMP
260         {
261                 struct task_struct *fpu_owner
262                         = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER);
263
264                 if (ia64_is_local_fpu_owner(current)) {
265                         preempt_enable_no_resched();
266                         return;
267                 }
268
269                 if (fpu_owner)
270                         ia64_flush_fph(fpu_owner);
271         }
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);
276                 psr->mfh = 0;
277         } else {
278                 __ia64_init_fpu();
279                 /*
280                  * Set mfh because the state in thread.fph does not match the state in
281                  * the fph partition.
282                  */
283                 psr->mfh = 1;
284         }
285         preempt_enable_no_resched();
286 }
287
288 static inline int
289 fp_emulate (int fp_fault, void *bundle, long *ipsr, long *fpsr, long *isr, long *pr, long *ifs,
290             struct pt_regs *regs)
291 {
292         fp_state_t fp_state;
293         fpswa_ret_t ret;
294
295         if (!fpswa_interface)
296                 return -1;
297
298         memset(&fp_state, 0, sizeof(fp_state_t));
299
300         /*
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.
304          */
305         fp_state.bitmask_low64 = 0xfc0;  /* bit6..bit11 */
306
307         fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) &regs->f6;
308         /*
309          * unsigned long (*EFI_FPSWA) (
310          *      unsigned long    trap_type,
311          *      void             *Bundle,
312          *      unsigned long    *pipsr,
313          *      unsigned long    *pfsr,
314          *      unsigned long    *pisr,
315          *      unsigned long    *ppreds,
316          *      unsigned long    *pifs,
317          *      void             *fp_state);
318          */
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);
323
324         return ret.status;
325 }
326
327 /*
328  * Handle floating-point assist faults and traps.
329  */
330 static int
331 handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
332 {
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;
338
339         fault_ip = regs->cr_iip;
340         if (!fp_fault && (ia64_psr(regs)->ri == 0))
341                 fault_ip -= 16;
342         if (copy_from_user(bundle, (void __user *) fault_ip, sizeof(bundle)))
343                 return -1;
344
345         if (jiffies - last_time > 5*HZ)
346                 fpu_swa_count = 0;
347         if ((fpu_swa_count < 4) && !(current->thread.flags & IA64_THREAD_FPEMU_NOPRINT)) {
348                 last_time = jiffies;
349                 ++fpu_swa_count;
350                 printk(KERN_WARNING
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);
353         }
354
355         exception = fp_emulate(fp_fault, bundle, &regs->cr_ipsr, &regs->ar_fpsr, &isr, &regs->pr,
356                                &regs->cr_ifs, regs);
357         if (fp_fault) {
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");
363                         return -1;
364                 } else {
365                         /* is next instruction a trap? */
366                         if (exception & 2) {
367                                 ia64_increment_ip(regs);
368                         }
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 & 0x11) {
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;
381                         }
382                         siginfo.si_isr = isr;
383                         siginfo.si_flags = __ISR_VALID;
384                         siginfo.si_imm = 0;
385                         force_sig_info(SIGFPE, &siginfo, current);
386                 }
387         } else {
388                 if (exception == -1) {
389                         printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
390                         return -1;
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);
397                         if (isr & 0x880) {
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;
403                         }
404                         siginfo.si_isr = isr;
405                         siginfo.si_flags = __ISR_VALID;
406                         siginfo.si_imm = 0;
407                         force_sig_info(SIGFPE, &siginfo, current);
408                 }
409         }
410         return 0;
411 }
412
413 struct illegal_op_return {
414         unsigned long fkt, arg1, arg2, arg3;
415 };
416
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,
420                        struct pt_regs regs)
421 {
422         struct illegal_op_return rv;
423         struct siginfo si;
424         char buf[128];
425
426 #ifdef CONFIG_IA64_BRL_EMU
427         {
428                 extern struct illegal_op_return ia64_emulate_brl (struct pt_regs *, unsigned long);
429
430                 rv = ia64_emulate_brl(&regs, ec);
431                 if (rv.fkt != (unsigned long) -1)
432                         return rv;
433         }
434 #endif
435
436         sprintf(buf, "IA-64 Illegal operation fault");
437         die_if_kernel(buf, &regs, 0);
438
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(&regs)->ri);
443         force_sig_info(SIGILL, &si, current);
444         rv.fkt = 0;
445         return rv;
446 }
447
448 void __kprobes
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)
452 {
453         unsigned long code, error = isr, iip;
454         struct siginfo siginfo;
455         char buf[128];
456         int result, sig;
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"
466         };
467
468         if ((isr & IA64_ISR_NA) && ((isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH)) {
469                 /*
470                  * This fault was due to lfetch.fault, set "ed" bit in the psr to cancel
471                  * the lfetch.
472                  */
473                 ia64_psr(&regs)->ed = 1;
474                 return;
475         }
476
477         iip = regs.cr_iip + ia64_psr(&regs)->ri;
478
479         switch (vector) {
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)") : "");
485                 if (code == 8) {
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(&regs)->ri, regs.pr);
490 # endif
491                         return;
492                 }
493                 break;
494
495               case 25: /* Disabled FP-Register */
496                 if (isr & 2) {
497                         disabled_fph_fault(&regs);
498                         return;
499                 }
500                 sprintf(buf, "Disabled FPL fault---not supposed to happen!");
501                 break;
502
503               case 26: /* NaT Consumption */
504                 if (user_mode(&regs)) {
505                         void __user *addr;
506
507                         if (((isr >> 4) & 0xf) == 2) {
508                                 /* NaT page consumption */
509                                 sig = SIGSEGV;
510                                 code = SEGV_ACCERR;
511                                 addr = (void __user *) ifa;
512                         } else {
513                                 /* register NaT consumption */
514                                 sig = SIGILL;
515                                 code = ILL_ILLOPN;
516                                 addr = (void __user *) (regs.cr_iip
517                                                         + ia64_psr(&regs)->ri);
518                         }
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);
527                         return;
528                 } else if (ia64_done_with_exception(&regs))
529                         return;
530                 sprintf(buf, "NaT consumption");
531                 break;
532
533               case 31: /* Unsupported Data Reference */
534                 if (user_mode(&regs)) {
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);
543                         return;
544                 }
545                 sprintf(buf, "Unsupported data reference");
546                 break;
547
548               case 29: /* Debug */
549               case 35: /* Taken Branch Trap */
550               case 36: /* Single Step Trap */
551                 if (fsys_mode(current, &regs)) {
552                         extern char __kernel_syscall_via_break[];
553                         /*
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.
556                          */
557                         if (unlikely(vector == 29)) {
558                                 die("Got debug trap in fsys-mode---not supposed to happen!",
559                                     &regs, 0);
560                                 return;
561                         }
562                         /* re-do the system call via break 0x100000: */
563                         regs.cr_iip = (unsigned long) __kernel_syscall_via_break;
564                         ia64_psr(&regs)->ri = 0;
565                         ia64_psr(&regs)->cpl = 3;
566                         return;
567                 }
568                 switch (vector) {
569                       case 29:
570                         siginfo.si_code = TRAP_HWBKPT;
571 #ifdef CONFIG_ITANIUM
572                         /*
573                          * Erratum 10 (IFA may contain incorrect address) now has
574                          * "NoFix" status.  There are no plans for fixing this.
575                          */
576                         if (ia64_psr(&regs)->is == 0)
577                           ifa = regs.cr_iip;
578 #endif
579                         break;
580                       case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
581                       case 36:
582                               if (notify_die(DIE_SS, "ss", &regs, vector,
583                                              vector, SIGTRAP) == NOTIFY_STOP)
584                                       return;
585                               siginfo.si_code = TRAP_TRACE; ifa = 0; break;
586                 }
587                 siginfo.si_signo = SIGTRAP;
588                 siginfo.si_errno = 0;
589                 siginfo.si_addr  = (void __user *) ifa;
590                 siginfo.si_imm   = 0;
591                 siginfo.si_flags = __ISR_VALID;
592                 siginfo.si_isr   = isr;
593                 force_sig_info(SIGTRAP, &siginfo, current);
594                 return;
595
596               case 32: /* fp fault */
597               case 33: /* fp trap */
598                 result = handle_fpu_swa((vector == 32) ? 1 : 0, &regs, 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;
606                         siginfo.si_imm = 0;
607                         force_sig_info(SIGFPE, &siginfo, current);
608                 }
609                 return;
610
611               case 34:
612                 if (isr & 0x2) {
613                         /* Lower-Privilege Transfer Trap */
614                         /*
615                          * Just clear PSR.lp and then return immediately: all the
616                          * interesting work (e.g., signal delivery is done in the kernel
617                          * exit path).
618                          */
619                         ia64_psr(&regs)->lp = 0;
620                         return;
621                 } else {
622                         /* Unimplemented Instr. Address Trap */
623                         if (user_mode(&regs)) {
624                                 siginfo.si_signo = SIGILL;
625                                 siginfo.si_code = ILL_BADIADDR;
626                                 siginfo.si_errno = 0;
627                                 siginfo.si_flags = 0;
628                                 siginfo.si_isr = 0;
629                                 siginfo.si_imm = 0;
630                                 siginfo.si_addr = (void __user *) iip;
631                                 force_sig_info(SIGILL, &siginfo, current);
632                                 return;
633                         }
634                         sprintf(buf, "Unimplemented Instruction Address fault");
635                 }
636                 break;
637
638               case 45:
639 #ifdef CONFIG_IA32_SUPPORT
640                 if (ia32_exception(&regs, isr) == 0)
641                         return;
642 #endif
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",
645                        iip, ifa, isr);
646                 force_sig(SIGSEGV, current);
647                 break;
648
649               case 46:
650 #ifdef CONFIG_IA32_SUPPORT
651                 if (ia32_intercept(&regs, isr) == 0)
652                         return;
653 #endif
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",
656                        iip, ifa, isr, iim);
657                 force_sig(SIGSEGV, current);
658                 return;
659
660               case 47:
661                 sprintf(buf, "IA-32 Interruption Fault (int 0x%lx)", isr >> 16);
662                 break;
663
664               default:
665                 sprintf(buf, "Fault %lu", vector);
666                 break;
667         }
668         die_if_kernel(buf, &regs, error);
669         force_sig(SIGILL, current);
670 }