traps.c revision e868d61272caa648214046a096e5a6bfc068dc8c
1/*
2 * 'traps.c' handles hardware traps and faults after we have saved some
3 * state in 'entry.S'.
4 *
5 *  SuperH version: Copyright (C) 1999 Niibe Yutaka
6 *                  Copyright (C) 2000 Philipp Rumpf
7 *                  Copyright (C) 2000 David Howells
8 *                  Copyright (C) 2002 - 2007 Paul Mundt
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License.  See the file "COPYING" in the main directory of this archive
12 * for more details.
13 */
14#include <linux/kernel.h>
15#include <linux/ptrace.h>
16#include <linux/init.h>
17#include <linux/spinlock.h>
18#include <linux/module.h>
19#include <linux/kallsyms.h>
20#include <linux/io.h>
21#include <linux/bug.h>
22#include <linux/debug_locks.h>
23#include <linux/kdebug.h>
24#include <linux/limits.h>
25#include <asm/system.h>
26#include <asm/uaccess.h>
27
28#ifdef CONFIG_SH_KGDB
29#include <asm/kgdb.h>
30#define CHK_REMOTE_DEBUG(regs)			\
31{						\
32	if (kgdb_debug_hook && !user_mode(regs))\
33		(*kgdb_debug_hook)(regs);       \
34}
35#else
36#define CHK_REMOTE_DEBUG(regs)
37#endif
38
39#ifdef CONFIG_CPU_SH2
40# define TRAP_RESERVED_INST	4
41# define TRAP_ILLEGAL_SLOT_INST	6
42# define TRAP_ADDRESS_ERROR	9
43# ifdef CONFIG_CPU_SH2A
44#  define TRAP_DIVZERO_ERROR	17
45#  define TRAP_DIVOVF_ERROR	18
46# endif
47#else
48#define TRAP_RESERVED_INST	12
49#define TRAP_ILLEGAL_SLOT_INST	13
50#endif
51
52static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
53{
54	unsigned long p;
55	int i;
56
57	printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
58
59	for (p = bottom & ~31; p < top; ) {
60		printk("%04lx: ", p & 0xffff);
61
62		for (i = 0; i < 8; i++, p += 4) {
63			unsigned int val;
64
65			if (p < bottom || p >= top)
66				printk("         ");
67			else {
68				if (__get_user(val, (unsigned int __user *)p)) {
69					printk("\n");
70					return;
71				}
72				printk("%08x ", val);
73			}
74		}
75		printk("\n");
76	}
77}
78
79static DEFINE_SPINLOCK(die_lock);
80
81void die(const char * str, struct pt_regs * regs, long err)
82{
83	static int die_counter;
84
85	console_verbose();
86	spin_lock_irq(&die_lock);
87	bust_spinlocks(1);
88
89	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
90
91	CHK_REMOTE_DEBUG(regs);
92	print_modules();
93	show_regs(regs);
94
95	printk("Process: %s (pid: %d, stack limit = %p)\n",
96	       current->comm, current->pid, task_stack_page(current) + 1);
97
98	if (!user_mode(regs) || in_interrupt())
99		dump_mem("Stack: ", regs->regs[15], THREAD_SIZE +
100			 (unsigned long)task_stack_page(current));
101
102	bust_spinlocks(0);
103	spin_unlock_irq(&die_lock);
104	do_exit(SIGSEGV);
105}
106
107static inline void die_if_kernel(const char *str, struct pt_regs *regs,
108				 long err)
109{
110	if (!user_mode(regs))
111		die(str, regs, err);
112}
113
114/*
115 * try and fix up kernelspace address errors
116 * - userspace errors just cause EFAULT to be returned, resulting in SEGV
117 * - kernel/userspace interfaces cause a jump to an appropriate handler
118 * - other kernel errors are bad
119 * - return 0 if fixed-up, -EFAULT if non-fatal (to the kernel) fault
120 */
121static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
122{
123	if (!user_mode(regs)) {
124		const struct exception_table_entry *fixup;
125		fixup = search_exception_tables(regs->pc);
126		if (fixup) {
127			regs->pc = fixup->fixup;
128			return 0;
129		}
130		die(str, regs, err);
131	}
132	return -EFAULT;
133}
134
135/*
136 * handle an instruction that does an unaligned memory access by emulating the
137 * desired behaviour
138 * - note that PC _may not_ point to the faulting instruction
139 *   (if that instruction is in a branch delay slot)
140 * - return 0 if emulation okay, -EFAULT on existential error
141 */
142static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs)
143{
144	int ret, index, count;
145	unsigned long *rm, *rn;
146	unsigned char *src, *dst;
147
148	index = (instruction>>8)&15;	/* 0x0F00 */
149	rn = &regs->regs[index];
150
151	index = (instruction>>4)&15;	/* 0x00F0 */
152	rm = &regs->regs[index];
153
154	count = 1<<(instruction&3);
155
156	ret = -EFAULT;
157	switch (instruction>>12) {
158	case 0: /* mov.[bwl] to/from memory via r0+rn */
159		if (instruction & 8) {
160			/* from memory */
161			src = (unsigned char*) *rm;
162			src += regs->regs[0];
163			dst = (unsigned char*) rn;
164			*(unsigned long*)dst = 0;
165
166#ifdef __LITTLE_ENDIAN__
167			if (copy_from_user(dst, src, count))
168				goto fetch_fault;
169
170			if ((count == 2) && dst[1] & 0x80) {
171				dst[2] = 0xff;
172				dst[3] = 0xff;
173			}
174#else
175			dst += 4-count;
176
177			if (__copy_user(dst, src, count))
178				goto fetch_fault;
179
180			if ((count == 2) && dst[2] & 0x80) {
181				dst[0] = 0xff;
182				dst[1] = 0xff;
183			}
184#endif
185		} else {
186			/* to memory */
187			src = (unsigned char*) rm;
188#if !defined(__LITTLE_ENDIAN__)
189			src += 4-count;
190#endif
191			dst = (unsigned char*) *rn;
192			dst += regs->regs[0];
193
194			if (copy_to_user(dst, src, count))
195				goto fetch_fault;
196		}
197		ret = 0;
198		break;
199
200	case 1: /* mov.l Rm,@(disp,Rn) */
201		src = (unsigned char*) rm;
202		dst = (unsigned char*) *rn;
203		dst += (instruction&0x000F)<<2;
204
205		if (copy_to_user(dst,src,4))
206			goto fetch_fault;
207		ret = 0;
208		break;
209
210	case 2: /* mov.[bwl] to memory, possibly with pre-decrement */
211		if (instruction & 4)
212			*rn -= count;
213		src = (unsigned char*) rm;
214		dst = (unsigned char*) *rn;
215#if !defined(__LITTLE_ENDIAN__)
216		src += 4-count;
217#endif
218		if (copy_to_user(dst, src, count))
219			goto fetch_fault;
220		ret = 0;
221		break;
222
223	case 5: /* mov.l @(disp,Rm),Rn */
224		src = (unsigned char*) *rm;
225		src += (instruction&0x000F)<<2;
226		dst = (unsigned char*) rn;
227		*(unsigned long*)dst = 0;
228
229		if (copy_from_user(dst,src,4))
230			goto fetch_fault;
231		ret = 0;
232		break;
233
234	case 6:	/* mov.[bwl] from memory, possibly with post-increment */
235		src = (unsigned char*) *rm;
236		if (instruction & 4)
237			*rm += count;
238		dst = (unsigned char*) rn;
239		*(unsigned long*)dst = 0;
240
241#ifdef __LITTLE_ENDIAN__
242		if (copy_from_user(dst, src, count))
243			goto fetch_fault;
244
245		if ((count == 2) && dst[1] & 0x80) {
246			dst[2] = 0xff;
247			dst[3] = 0xff;
248		}
249#else
250		dst += 4-count;
251
252		if (copy_from_user(dst, src, count))
253			goto fetch_fault;
254
255		if ((count == 2) && dst[2] & 0x80) {
256			dst[0] = 0xff;
257			dst[1] = 0xff;
258		}
259#endif
260		ret = 0;
261		break;
262
263	case 8:
264		switch ((instruction&0xFF00)>>8) {
265		case 0x81: /* mov.w R0,@(disp,Rn) */
266			src = (unsigned char*) &regs->regs[0];
267#if !defined(__LITTLE_ENDIAN__)
268			src += 2;
269#endif
270			dst = (unsigned char*) *rm; /* called Rn in the spec */
271			dst += (instruction&0x000F)<<1;
272
273			if (copy_to_user(dst, src, 2))
274				goto fetch_fault;
275			ret = 0;
276			break;
277
278		case 0x85: /* mov.w @(disp,Rm),R0 */
279			src = (unsigned char*) *rm;
280			src += (instruction&0x000F)<<1;
281			dst = (unsigned char*) &regs->regs[0];
282			*(unsigned long*)dst = 0;
283
284#if !defined(__LITTLE_ENDIAN__)
285			dst += 2;
286#endif
287
288			if (copy_from_user(dst, src, 2))
289				goto fetch_fault;
290
291#ifdef __LITTLE_ENDIAN__
292			if (dst[1] & 0x80) {
293				dst[2] = 0xff;
294				dst[3] = 0xff;
295			}
296#else
297			if (dst[2] & 0x80) {
298				dst[0] = 0xff;
299				dst[1] = 0xff;
300			}
301#endif
302			ret = 0;
303			break;
304		}
305		break;
306	}
307	return ret;
308
309 fetch_fault:
310	/* Argh. Address not only misaligned but also non-existent.
311	 * Raise an EFAULT and see if it's trapped
312	 */
313	return die_if_no_fixup("Fault in unaligned fixup", regs, 0);
314}
315
316/*
317 * emulate the instruction in the delay slot
318 * - fetches the instruction from PC+2
319 */
320static inline int handle_unaligned_delayslot(struct pt_regs *regs)
321{
322	u16 instruction;
323
324	if (copy_from_user(&instruction, (u16 *)(regs->pc+2), 2)) {
325		/* the instruction-fetch faulted */
326		if (user_mode(regs))
327			return -EFAULT;
328
329		/* kernel */
330		die("delay-slot-insn faulting in handle_unaligned_delayslot",
331		    regs, 0);
332	}
333
334	return handle_unaligned_ins(instruction,regs);
335}
336
337/*
338 * handle an instruction that does an unaligned memory access
339 * - have to be careful of branch delay-slot instructions that fault
340 *  SH3:
341 *   - if the branch would be taken PC points to the branch
342 *   - if the branch would not be taken, PC points to delay-slot
343 *  SH4:
344 *   - PC always points to delayed branch
345 * - return 0 if handled, -EFAULT if failed (may not return if in kernel)
346 */
347
348/* Macros to determine offset from current PC for branch instructions */
349/* Explicit type coercion is used to force sign extension where needed */
350#define SH_PC_8BIT_OFFSET(instr) ((((signed char)(instr))*2) + 4)
351#define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4)
352
353/*
354 * XXX: SH-2A needs this too, but it needs an overhaul thanks to mixed 32-bit
355 * opcodes..
356 */
357#ifndef CONFIG_CPU_SH2A
358static int handle_unaligned_notify_count = 10;
359
360static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
361{
362	u_int rm;
363	int ret, index;
364
365	index = (instruction>>8)&15;	/* 0x0F00 */
366	rm = regs->regs[index];
367
368	/* shout about the first ten userspace fixups */
369	if (user_mode(regs) && handle_unaligned_notify_count>0) {
370		handle_unaligned_notify_count--;
371
372		printk(KERN_NOTICE "Fixing up unaligned userspace access "
373		       "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
374		       current->comm,current->pid,(u16*)regs->pc,instruction);
375	}
376
377	ret = -EFAULT;
378	switch (instruction&0xF000) {
379	case 0x0000:
380		if (instruction==0x000B) {
381			/* rts */
382			ret = handle_unaligned_delayslot(regs);
383			if (ret==0)
384				regs->pc = regs->pr;
385		}
386		else if ((instruction&0x00FF)==0x0023) {
387			/* braf @Rm */
388			ret = handle_unaligned_delayslot(regs);
389			if (ret==0)
390				regs->pc += rm + 4;
391		}
392		else if ((instruction&0x00FF)==0x0003) {
393			/* bsrf @Rm */
394			ret = handle_unaligned_delayslot(regs);
395			if (ret==0) {
396				regs->pr = regs->pc + 4;
397				regs->pc += rm + 4;
398			}
399		}
400		else {
401			/* mov.[bwl] to/from memory via r0+rn */
402			goto simple;
403		}
404		break;
405
406	case 0x1000: /* mov.l Rm,@(disp,Rn) */
407		goto simple;
408
409	case 0x2000: /* mov.[bwl] to memory, possibly with pre-decrement */
410		goto simple;
411
412	case 0x4000:
413		if ((instruction&0x00FF)==0x002B) {
414			/* jmp @Rm */
415			ret = handle_unaligned_delayslot(regs);
416			if (ret==0)
417				regs->pc = rm;
418		}
419		else if ((instruction&0x00FF)==0x000B) {
420			/* jsr @Rm */
421			ret = handle_unaligned_delayslot(regs);
422			if (ret==0) {
423				regs->pr = regs->pc + 4;
424				regs->pc = rm;
425			}
426		}
427		else {
428			/* mov.[bwl] to/from memory via r0+rn */
429			goto simple;
430		}
431		break;
432
433	case 0x5000: /* mov.l @(disp,Rm),Rn */
434		goto simple;
435
436	case 0x6000: /* mov.[bwl] from memory, possibly with post-increment */
437		goto simple;
438
439	case 0x8000: /* bf lab, bf/s lab, bt lab, bt/s lab */
440		switch (instruction&0x0F00) {
441		case 0x0100: /* mov.w R0,@(disp,Rm) */
442			goto simple;
443		case 0x0500: /* mov.w @(disp,Rm),R0 */
444			goto simple;
445		case 0x0B00: /* bf   lab - no delayslot*/
446			break;
447		case 0x0F00: /* bf/s lab */
448			ret = handle_unaligned_delayslot(regs);
449			if (ret==0) {
450#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)
451				if ((regs->sr & 0x00000001) != 0)
452					regs->pc += 4; /* next after slot */
453				else
454#endif
455					regs->pc += SH_PC_8BIT_OFFSET(instruction);
456			}
457			break;
458		case 0x0900: /* bt   lab - no delayslot */
459			break;
460		case 0x0D00: /* bt/s lab */
461			ret = handle_unaligned_delayslot(regs);
462			if (ret==0) {
463#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)
464				if ((regs->sr & 0x00000001) == 0)
465					regs->pc += 4; /* next after slot */
466				else
467#endif
468					regs->pc += SH_PC_8BIT_OFFSET(instruction);
469			}
470			break;
471		}
472		break;
473
474	case 0xA000: /* bra label */
475		ret = handle_unaligned_delayslot(regs);
476		if (ret==0)
477			regs->pc += SH_PC_12BIT_OFFSET(instruction);
478		break;
479
480	case 0xB000: /* bsr label */
481		ret = handle_unaligned_delayslot(regs);
482		if (ret==0) {
483			regs->pr = regs->pc + 4;
484			regs->pc += SH_PC_12BIT_OFFSET(instruction);
485		}
486		break;
487	}
488	return ret;
489
490	/* handle non-delay-slot instruction */
491 simple:
492	ret = handle_unaligned_ins(instruction,regs);
493	if (ret==0)
494		regs->pc += instruction_size(instruction);
495	return ret;
496}
497#endif /* CONFIG_CPU_SH2A */
498
499#ifdef CONFIG_CPU_HAS_SR_RB
500#define lookup_exception_vector(x)	\
501	__asm__ __volatile__ ("stc r2_bank, %0\n\t" : "=r" ((x)))
502#else
503#define lookup_exception_vector(x)	\
504	__asm__ __volatile__ ("mov r4, %0\n\t" : "=r" ((x)))
505#endif
506
507/*
508 * Handle various address error exceptions:
509 *  - instruction address error:
510 *       misaligned PC
511 *       PC >= 0x80000000 in user mode
512 *  - data address error (read and write)
513 *       misaligned data access
514 *       access to >= 0x80000000 is user mode
515 * Unfortuntaly we can't distinguish between instruction address error
516 * and data address errors caused by read accesses.
517 */
518asmlinkage void do_address_error(struct pt_regs *regs,
519				 unsigned long writeaccess,
520				 unsigned long address)
521{
522	unsigned long error_code = 0;
523	mm_segment_t oldfs;
524	siginfo_t info;
525#ifndef CONFIG_CPU_SH2A
526	u16 instruction;
527	int tmp;
528#endif
529
530	/* Intentional ifdef */
531#ifdef CONFIG_CPU_HAS_SR_RB
532	lookup_exception_vector(error_code);
533#endif
534
535	oldfs = get_fs();
536
537	if (user_mode(regs)) {
538		int si_code = BUS_ADRERR;
539
540		local_irq_enable();
541
542		/* bad PC is not something we can fix */
543		if (regs->pc & 1) {
544			si_code = BUS_ADRALN;
545			goto uspace_segv;
546		}
547
548#ifndef CONFIG_CPU_SH2A
549		set_fs(USER_DS);
550		if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) {
551			/* Argh. Fault on the instruction itself.
552			   This should never happen non-SMP
553			*/
554			set_fs(oldfs);
555			goto uspace_segv;
556		}
557
558		tmp = handle_unaligned_access(instruction, regs);
559		set_fs(oldfs);
560
561		if (tmp==0)
562			return; /* sorted */
563#endif
564
565uspace_segv:
566		printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned "
567		       "access (PC %lx PR %lx)\n", current->comm, regs->pc,
568		       regs->pr);
569
570		info.si_signo = SIGBUS;
571		info.si_errno = 0;
572		info.si_code = si_code;
573		info.si_addr = (void *) address;
574		force_sig_info(SIGBUS, &info, current);
575	} else {
576		if (regs->pc & 1)
577			die("unaligned program counter", regs, error_code);
578
579#ifndef CONFIG_CPU_SH2A
580		set_fs(KERNEL_DS);
581		if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) {
582			/* Argh. Fault on the instruction itself.
583			   This should never happen non-SMP
584			*/
585			set_fs(oldfs);
586			die("insn faulting in do_address_error", regs, 0);
587		}
588
589		handle_unaligned_access(instruction, regs);
590		set_fs(oldfs);
591#else
592		printk(KERN_NOTICE "Killing process \"%s\" due to unaligned "
593		       "access\n", current->comm);
594
595		force_sig(SIGSEGV, current);
596#endif
597	}
598}
599
600#ifdef CONFIG_SH_DSP
601/*
602 *	SH-DSP support gerg@snapgear.com.
603 */
604int is_dsp_inst(struct pt_regs *regs)
605{
606	unsigned short inst;
607
608	/*
609	 * Safe guard if DSP mode is already enabled or we're lacking
610	 * the DSP altogether.
611	 */
612	if (!(current_cpu_data.flags & CPU_HAS_DSP) || (regs->sr & SR_DSP))
613		return 0;
614
615	get_user(inst, ((unsigned short *) regs->pc));
616
617	inst &= 0xf000;
618
619	/* Check for any type of DSP or support instruction */
620	if ((inst == 0xf000) || (inst == 0x4000))
621		return 1;
622
623	return 0;
624}
625#else
626#define is_dsp_inst(regs)	(0)
627#endif /* CONFIG_SH_DSP */
628
629#ifdef CONFIG_CPU_SH2A
630asmlinkage void do_divide_error(unsigned long r4, unsigned long r5,
631				unsigned long r6, unsigned long r7,
632				struct pt_regs __regs)
633{
634	struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
635	siginfo_t info;
636
637	switch (r4) {
638	case TRAP_DIVZERO_ERROR:
639		info.si_code = FPE_INTDIV;
640		break;
641	case TRAP_DIVOVF_ERROR:
642		info.si_code = FPE_INTOVF;
643		break;
644	}
645
646	force_sig_info(SIGFPE, &info, current);
647}
648#endif
649
650/* arch/sh/kernel/cpu/sh4/fpu.c */
651extern int do_fpu_inst(unsigned short, struct pt_regs *);
652extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5,
653		unsigned long r6, unsigned long r7, struct pt_regs __regs);
654
655asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
656				unsigned long r6, unsigned long r7,
657				struct pt_regs __regs)
658{
659	struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
660	unsigned long error_code;
661	struct task_struct *tsk = current;
662
663#ifdef CONFIG_SH_FPU_EMU
664	unsigned short inst = 0;
665	int err;
666
667	get_user(inst, (unsigned short*)regs->pc);
668
669	err = do_fpu_inst(inst, regs);
670	if (!err) {
671		regs->pc += instruction_size(inst);
672		return;
673	}
674	/* not a FPU inst. */
675#endif
676
677#ifdef CONFIG_SH_DSP
678	/* Check if it's a DSP instruction */
679	if (is_dsp_inst(regs)) {
680		/* Enable DSP mode, and restart instruction. */
681		regs->sr |= SR_DSP;
682		return;
683	}
684#endif
685
686	lookup_exception_vector(error_code);
687
688	local_irq_enable();
689	CHK_REMOTE_DEBUG(regs);
690	force_sig(SIGILL, tsk);
691	die_if_no_fixup("reserved instruction", regs, error_code);
692}
693
694#ifdef CONFIG_SH_FPU_EMU
695static int emulate_branch(unsigned short inst, struct pt_regs* regs)
696{
697	/*
698	 * bfs: 8fxx: PC+=d*2+4;
699	 * bts: 8dxx: PC+=d*2+4;
700	 * bra: axxx: PC+=D*2+4;
701	 * bsr: bxxx: PC+=D*2+4  after PR=PC+4;
702	 * braf:0x23: PC+=Rn*2+4;
703	 * bsrf:0x03: PC+=Rn*2+4 after PR=PC+4;
704	 * jmp: 4x2b: PC=Rn;
705	 * jsr: 4x0b: PC=Rn      after PR=PC+4;
706	 * rts: 000b: PC=PR;
707	 */
708	if ((inst & 0xfd00) == 0x8d00) {
709		regs->pc += SH_PC_8BIT_OFFSET(inst);
710		return 0;
711	}
712
713	if ((inst & 0xe000) == 0xa000) {
714		regs->pc += SH_PC_12BIT_OFFSET(inst);
715		return 0;
716	}
717
718	if ((inst & 0xf0df) == 0x0003) {
719		regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4;
720		return 0;
721	}
722
723	if ((inst & 0xf0df) == 0x400b) {
724		regs->pc = regs->regs[(inst & 0x0f00) >> 8];
725		return 0;
726	}
727
728	if ((inst & 0xffff) == 0x000b) {
729		regs->pc = regs->pr;
730		return 0;
731	}
732
733	return 1;
734}
735#endif
736
737asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
738				unsigned long r6, unsigned long r7,
739				struct pt_regs __regs)
740{
741	struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
742	unsigned long error_code;
743	struct task_struct *tsk = current;
744#ifdef CONFIG_SH_FPU_EMU
745	unsigned short inst = 0;
746
747	get_user(inst, (unsigned short *)regs->pc + 1);
748	if (!do_fpu_inst(inst, regs)) {
749		get_user(inst, (unsigned short *)regs->pc);
750		if (!emulate_branch(inst, regs))
751			return;
752		/* fault in branch.*/
753	}
754	/* not a FPU inst. */
755#endif
756
757	lookup_exception_vector(error_code);
758
759	local_irq_enable();
760	CHK_REMOTE_DEBUG(regs);
761	force_sig(SIGILL, tsk);
762	die_if_no_fixup("illegal slot instruction", regs, error_code);
763}
764
765asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
766				   unsigned long r6, unsigned long r7,
767				   struct pt_regs __regs)
768{
769	struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
770	long ex;
771
772	lookup_exception_vector(ex);
773	die_if_kernel("exception", regs, ex);
774}
775
776#if defined(CONFIG_SH_STANDARD_BIOS)
777void *gdb_vbr_vector;
778
779static inline void __init gdb_vbr_init(void)
780{
781	register unsigned long vbr;
782
783	/*
784	 * Read the old value of the VBR register to initialise
785	 * the vector through which debug and BIOS traps are
786	 * delegated by the Linux trap handler.
787	 */
788	asm volatile("stc vbr, %0" : "=r" (vbr));
789
790	gdb_vbr_vector = (void *)(vbr + 0x100);
791	printk("Setting GDB trap vector to 0x%08lx\n",
792	       (unsigned long)gdb_vbr_vector);
793}
794#endif
795
796void __init per_cpu_trap_init(void)
797{
798	extern void *vbr_base;
799
800#ifdef CONFIG_SH_STANDARD_BIOS
801	gdb_vbr_init();
802#endif
803
804	/* NOTE: The VBR value should be at P1
805	   (or P2, virtural "fixed" address space).
806	   It's definitely should not in physical address.  */
807
808	asm volatile("ldc	%0, vbr"
809		     : /* no output */
810		     : "r" (&vbr_base)
811		     : "memory");
812}
813
814void *set_exception_table_vec(unsigned int vec, void *handler)
815{
816	extern void *exception_handling_table[];
817	void *old_handler;
818
819	old_handler = exception_handling_table[vec];
820	exception_handling_table[vec] = handler;
821	return old_handler;
822}
823
824extern asmlinkage void address_error_handler(unsigned long r4, unsigned long r5,
825					     unsigned long r6, unsigned long r7,
826					     struct pt_regs __regs);
827
828void __init trap_init(void)
829{
830	set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst);
831	set_exception_table_vec(TRAP_ILLEGAL_SLOT_INST, do_illegal_slot_inst);
832
833#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_FPU) || \
834    defined(CONFIG_SH_FPU_EMU)
835	/*
836	 * For SH-4 lacking an FPU, treat floating point instructions as
837	 * reserved. They'll be handled in the math-emu case, or faulted on
838	 * otherwise.
839	 */
840	set_exception_table_evt(0x800, do_reserved_inst);
841	set_exception_table_evt(0x820, do_illegal_slot_inst);
842#elif defined(CONFIG_SH_FPU)
843	set_exception_table_evt(0x800, do_fpu_state_restore);
844	set_exception_table_evt(0x820, do_fpu_state_restore);
845#endif
846
847#ifdef CONFIG_CPU_SH2
848	set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_handler);
849#endif
850#ifdef CONFIG_CPU_SH2A
851	set_exception_table_vec(TRAP_DIVZERO_ERROR, do_divide_error);
852	set_exception_table_vec(TRAP_DIVOVF_ERROR, do_divide_error);
853#endif
854
855	/* Setup VBR for boot cpu */
856	per_cpu_trap_init();
857}
858
859#ifdef CONFIG_BUG
860void handle_BUG(struct pt_regs *regs)
861{
862	enum bug_trap_type tt;
863	tt = report_bug(regs->pc);
864	if (tt == BUG_TRAP_TYPE_WARN) {
865		regs->pc += 2;
866		return;
867	}
868
869	die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
870}
871
872int is_valid_bugaddr(unsigned long addr)
873{
874	return addr >= PAGE_OFFSET;
875}
876#endif
877
878void show_trace(struct task_struct *tsk, unsigned long *sp,
879		struct pt_regs *regs)
880{
881	unsigned long addr;
882
883	if (regs && user_mode(regs))
884		return;
885
886	printk("\nCall trace: ");
887#ifdef CONFIG_KALLSYMS
888	printk("\n");
889#endif
890
891	while (!kstack_end(sp)) {
892		addr = *sp++;
893		if (kernel_text_address(addr))
894			print_ip_sym(addr);
895	}
896
897	printk("\n");
898
899	if (!tsk)
900		tsk = current;
901
902	debug_show_held_locks(tsk);
903}
904
905void show_stack(struct task_struct *tsk, unsigned long *sp)
906{
907	unsigned long stack;
908
909	if (!tsk)
910		tsk = current;
911	if (tsk == current)
912		sp = (unsigned long *)current_stack_pointer;
913	else
914		sp = (unsigned long *)tsk->thread.sp;
915
916	stack = (unsigned long)sp;
917	dump_mem("Stack: ", stack, THREAD_SIZE +
918		 (unsigned long)task_stack_page(tsk));
919	show_trace(tsk, sp, NULL);
920}
921
922void dump_stack(void)
923{
924	show_stack(NULL, NULL);
925}
926EXPORT_SYMBOL(dump_stack);
927