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