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