Linux Audio

Check our new training course

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