Linux Audio

Check our new training course

Loading...
v4.17
  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	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 */
198static inline void
199disabled_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
240static inline int
241fp_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
279struct fpu_swa_msg {
280	unsigned long count;
281	unsigned long time;
282};
283static DEFINE_PER_CPU(struct fpu_swa_msg, cpulast);
284DECLARE_PER_CPU(struct fpu_swa_msg, cpulast);
285static struct fpu_swa_msg last __cacheline_aligned;
286
287
288/*
289 * Handle floating-point assist faults and traps.
290 */
291static int
292handle_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
395struct illegal_op_return {
396	unsigned long fkt, arg1, arg2, arg3;
397};
398
399struct illegal_op_return
400ia64_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
431void __kprobes
432ia64_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}
v3.1
 
  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
 26fpswa_interface_t *fpswa_interface;
 27EXPORT_SYMBOL(fpswa_interface);
 28
 29void __init
 30trap_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
 37int
 38die (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
 87int
 88die_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
 95void
 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 */
193static inline void
194disabled_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
235static inline int
236fp_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
274struct fpu_swa_msg {
275	unsigned long count;
276	unsigned long time;
277};
278static DEFINE_PER_CPU(struct fpu_swa_msg, cpulast);
279DECLARE_PER_CPU(struct fpu_swa_msg, cpulast);
280static struct fpu_swa_msg last __cacheline_aligned;
281
282
283/*
284 * Handle floating-point assist faults and traps.
285 */
286static int
287handle_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
390struct illegal_op_return {
391	unsigned long fkt, arg1, arg2, arg3;
392};
393
394struct illegal_op_return
395ia64_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
426void __kprobes
427ia64_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}