1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/sched.h>
22#include <linux/sched/debug.h>
23#include <linux/signal.h>
24#include <linux/kernel.h>
25#include <linux/mm.h>
26#include <linux/module.h>
27#include <linux/user.h>
28#include <linux/string.h>
29#include <linux/linkage.h>
30#include <linux/init.h>
31#include <linux/ptrace.h>
32#include <linux/kallsyms.h>
33
34#include <asm/setup.h>
35#include <asm/fpu.h>
36#include <linux/uaccess.h>
37#include <asm/traps.h>
38#include <asm/machdep.h>
39#include <asm/siginfo.h>
40#include <asm/tlbflush.h>
41
42static const char *vec_names[] = {
43 [VEC_RESETSP] = "RESET SP",
44 [VEC_RESETPC] = "RESET PC",
45 [VEC_BUSERR] = "BUS ERROR",
46 [VEC_ADDRERR] = "ADDRESS ERROR",
47 [VEC_ILLEGAL] = "ILLEGAL INSTRUCTION",
48 [VEC_ZERODIV] = "ZERO DIVIDE",
49 [VEC_CHK] = "CHK",
50 [VEC_TRAP] = "TRAPcc",
51 [VEC_PRIV] = "PRIVILEGE VIOLATION",
52 [VEC_TRACE] = "TRACE",
53 [VEC_LINE10] = "LINE 1010",
54 [VEC_LINE11] = "LINE 1111",
55 [VEC_RESV12] = "UNASSIGNED RESERVED 12",
56 [VEC_COPROC] = "COPROCESSOR PROTOCOL VIOLATION",
57 [VEC_FORMAT] = "FORMAT ERROR",
58 [VEC_UNINT] = "UNINITIALIZED INTERRUPT",
59 [VEC_RESV16] = "UNASSIGNED RESERVED 16",
60 [VEC_RESV17] = "UNASSIGNED RESERVED 17",
61 [VEC_RESV18] = "UNASSIGNED RESERVED 18",
62 [VEC_RESV19] = "UNASSIGNED RESERVED 19",
63 [VEC_RESV20] = "UNASSIGNED RESERVED 20",
64 [VEC_RESV21] = "UNASSIGNED RESERVED 21",
65 [VEC_RESV22] = "UNASSIGNED RESERVED 22",
66 [VEC_RESV23] = "UNASSIGNED RESERVED 23",
67 [VEC_SPUR] = "SPURIOUS INTERRUPT",
68 [VEC_INT1] = "LEVEL 1 INT",
69 [VEC_INT2] = "LEVEL 2 INT",
70 [VEC_INT3] = "LEVEL 3 INT",
71 [VEC_INT4] = "LEVEL 4 INT",
72 [VEC_INT5] = "LEVEL 5 INT",
73 [VEC_INT6] = "LEVEL 6 INT",
74 [VEC_INT7] = "LEVEL 7 INT",
75 [VEC_SYS] = "SYSCALL",
76 [VEC_TRAP1] = "TRAP #1",
77 [VEC_TRAP2] = "TRAP #2",
78 [VEC_TRAP3] = "TRAP #3",
79 [VEC_TRAP4] = "TRAP #4",
80 [VEC_TRAP5] = "TRAP #5",
81 [VEC_TRAP6] = "TRAP #6",
82 [VEC_TRAP7] = "TRAP #7",
83 [VEC_TRAP8] = "TRAP #8",
84 [VEC_TRAP9] = "TRAP #9",
85 [VEC_TRAP10] = "TRAP #10",
86 [VEC_TRAP11] = "TRAP #11",
87 [VEC_TRAP12] = "TRAP #12",
88 [VEC_TRAP13] = "TRAP #13",
89 [VEC_TRAP14] = "TRAP #14",
90 [VEC_TRAP15] = "TRAP #15",
91 [VEC_FPBRUC] = "FPCP BSUN",
92 [VEC_FPIR] = "FPCP INEXACT",
93 [VEC_FPDIVZ] = "FPCP DIV BY 0",
94 [VEC_FPUNDER] = "FPCP UNDERFLOW",
95 [VEC_FPOE] = "FPCP OPERAND ERROR",
96 [VEC_FPOVER] = "FPCP OVERFLOW",
97 [VEC_FPNAN] = "FPCP SNAN",
98 [VEC_FPUNSUP] = "FPCP UNSUPPORTED OPERATION",
99 [VEC_MMUCFG] = "MMU CONFIGURATION ERROR",
100 [VEC_MMUILL] = "MMU ILLEGAL OPERATION ERROR",
101 [VEC_MMUACC] = "MMU ACCESS LEVEL VIOLATION ERROR",
102 [VEC_RESV59] = "UNASSIGNED RESERVED 59",
103 [VEC_UNIMPEA] = "UNASSIGNED RESERVED 60",
104 [VEC_UNIMPII] = "UNASSIGNED RESERVED 61",
105 [VEC_RESV62] = "UNASSIGNED RESERVED 62",
106 [VEC_RESV63] = "UNASSIGNED RESERVED 63",
107};
108
109static const char *space_names[] = {
110 [0] = "Space 0",
111 [USER_DATA] = "User Data",
112 [USER_PROGRAM] = "User Program",
113#ifndef CONFIG_SUN3
114 [3] = "Space 3",
115#else
116 [FC_CONTROL] = "Control",
117#endif
118 [4] = "Space 4",
119 [SUPER_DATA] = "Super Data",
120 [SUPER_PROGRAM] = "Super Program",
121 [CPU_SPACE] = "CPU"
122};
123
124void die_if_kernel(char *,struct pt_regs *,int);
125asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
126 unsigned long error_code);
127int send_fault_sig(struct pt_regs *regs);
128
129asmlinkage void trap_c(struct frame *fp);
130
131#if defined (CONFIG_M68060)
132static inline void access_error060 (struct frame *fp)
133{
134 unsigned long fslw = fp->un.fmt4.pc;
135
136 pr_debug("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr);
137
138 if (fslw & MMU060_BPE) {
139
140 __asm__ __volatile__ ("movec %/cacr,%/d0\n\t"
141 "orl #0x00400000,%/d0\n\t"
142 "movec %/d0,%/cacr"
143 : : : "d0" );
144
145 if (!(fslw & MMU060_ERR_BITS) && !(fslw & MMU060_SEE))
146 return;
147 }
148
149 if (fslw & (MMU060_DESC_ERR | MMU060_WP | MMU060_SP)) {
150 unsigned long errorcode;
151 unsigned long addr = fp->un.fmt4.effaddr;
152
153 if (fslw & MMU060_MA)
154 addr = (addr + PAGE_SIZE - 1) & PAGE_MASK;
155
156 errorcode = 1;
157 if (fslw & MMU060_DESC_ERR) {
158 __flush_tlb040_one(addr);
159 errorcode = 0;
160 }
161 if (fslw & MMU060_W)
162 errorcode |= 2;
163 pr_debug("errorcode = %ld\n", errorcode);
164 do_page_fault(&fp->ptregs, addr, errorcode);
165 } else if (fslw & (MMU060_SEE)){
166
167
168
169 send_fault_sig(&fp->ptregs);
170 } else if (!(fslw & (MMU060_RE|MMU060_WE)) ||
171 send_fault_sig(&fp->ptregs) > 0) {
172 pr_err("pc=%#lx, fa=%#lx\n", fp->ptregs.pc,
173 fp->un.fmt4.effaddr);
174 pr_err("68060 access error, fslw=%lx\n", fslw);
175 trap_c( fp );
176 }
177}
178#endif
179
180#if defined (CONFIG_M68040)
181static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs)
182{
183 unsigned long mmusr;
184 mm_segment_t old_fs = get_fs();
185
186 set_fs(MAKE_MM_SEG(wbs));
187
188 if (iswrite)
189 asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr));
190 else
191 asm volatile (".chip 68040; ptestr (%0); .chip 68k" : : "a" (addr));
192
193 asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr));
194
195 set_fs(old_fs);
196
197 return mmusr;
198}
199
200static inline int do_040writeback1(unsigned short wbs, unsigned long wba,
201 unsigned long wbd)
202{
203 int res = 0;
204 mm_segment_t old_fs = get_fs();
205
206
207 set_fs(MAKE_MM_SEG(wbs));
208
209 switch (wbs & WBSIZ_040) {
210 case BA_SIZE_BYTE:
211 res = put_user(wbd & 0xff, (char __user *)wba);
212 break;
213 case BA_SIZE_WORD:
214 res = put_user(wbd & 0xffff, (short __user *)wba);
215 break;
216 case BA_SIZE_LONG:
217 res = put_user(wbd, (int __user *)wba);
218 break;
219 }
220
221
222 set_fs(old_fs);
223
224
225 pr_debug("do_040writeback1, res=%d\n", res);
226
227 return res;
228}
229
230
231
232
233
234static inline void fix_xframe040(struct frame *fp, unsigned long wba, unsigned short wbs)
235{
236 fp->un.fmt7.faddr = wba;
237 fp->un.fmt7.ssw = wbs & 0xff;
238 if (wba != current->thread.faddr)
239 fp->un.fmt7.ssw |= MA_040;
240}
241
242static inline void do_040writebacks(struct frame *fp)
243{
244 int res = 0;
245#if 0
246 if (fp->un.fmt7.wb1s & WBV_040)
247 pr_err("access_error040: cannot handle 1st writeback. oops.\n");
248#endif
249
250 if ((fp->un.fmt7.wb2s & WBV_040) &&
251 !(fp->un.fmt7.wb2s & WBTT_040)) {
252 res = do_040writeback1(fp->un.fmt7.wb2s, fp->un.fmt7.wb2a,
253 fp->un.fmt7.wb2d);
254 if (res)
255 fix_xframe040(fp, fp->un.fmt7.wb2a, fp->un.fmt7.wb2s);
256 else
257 fp->un.fmt7.wb2s = 0;
258 }
259
260
261 if (fp->un.fmt7.wb3s & WBV_040 && (!res || fp->un.fmt7.wb3s & 4)) {
262 res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a,
263 fp->un.fmt7.wb3d);
264 if (res)
265 {
266 fix_xframe040(fp, fp->un.fmt7.wb3a, fp->un.fmt7.wb3s);
267
268 fp->un.fmt7.wb2s = fp->un.fmt7.wb3s;
269 fp->un.fmt7.wb3s &= (~WBV_040);
270 fp->un.fmt7.wb2a = fp->un.fmt7.wb3a;
271 fp->un.fmt7.wb2d = fp->un.fmt7.wb3d;
272 }
273 else
274 fp->un.fmt7.wb3s = 0;
275 }
276
277 if (res)
278 send_fault_sig(&fp->ptregs);
279}
280
281
282
283
284
285
286
287asmlinkage void berr_040cleanup(struct frame *fp)
288{
289 fp->un.fmt7.wb2s &= ~4;
290 fp->un.fmt7.wb3s &= ~4;
291
292 do_040writebacks(fp);
293}
294
295static inline void access_error040(struct frame *fp)
296{
297 unsigned short ssw = fp->un.fmt7.ssw;
298 unsigned long mmusr;
299
300 pr_debug("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr);
301 pr_debug("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s,
302 fp->un.fmt7.wb2s, fp->un.fmt7.wb3s);
303 pr_debug("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n",
304 fp->un.fmt7.wb2a, fp->un.fmt7.wb3a,
305 fp->un.fmt7.wb2d, fp->un.fmt7.wb3d);
306
307 if (ssw & ATC_040) {
308 unsigned long addr = fp->un.fmt7.faddr;
309 unsigned long errorcode;
310
311
312
313
314
315 if (ssw & MA_040)
316 addr = (addr + 7) & -8;
317
318
319 mmusr = probe040(!(ssw & RW_040), addr, ssw);
320 pr_debug("mmusr = %lx\n", mmusr);
321 errorcode = 1;
322 if (!(mmusr & MMU_R_040)) {
323
324 __flush_tlb040_one(addr);
325 errorcode = 0;
326 }
327
328
329
330 if (!(ssw & RW_040) || (ssw & LK_040))
331 errorcode |= 2;
332
333 if (do_page_fault(&fp->ptregs, addr, errorcode)) {
334 pr_debug("do_page_fault() !=0\n");
335 if (user_mode(&fp->ptregs)){
336
337 pr_debug(".. was usermode - return\n");
338 return;
339 }
340
341
342
343
344disable_wb:
345 pr_debug(".. disabling wb2\n");
346 if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr)
347 fp->un.fmt7.wb2s &= ~WBV_040;
348 if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr)
349 fp->un.fmt7.wb3s &= ~WBV_040;
350 }
351 } else {
352
353
354
355
356 current->thread.signo = SIGBUS;
357 current->thread.faddr = fp->un.fmt7.faddr;
358 if (send_fault_sig(&fp->ptregs) >= 0)
359 pr_err("68040 bus error (ssw=%x, faddr=%lx)\n", ssw,
360 fp->un.fmt7.faddr);
361 goto disable_wb;
362 }
363
364 do_040writebacks(fp);
365}
366#endif
367
368#if defined(CONFIG_SUN3)
369#include <asm/sun3mmu.h>
370
371extern int mmu_emu_handle_fault (unsigned long, int, int);
372
373
374
375static inline void bus_error030 (struct frame *fp)
376{
377 unsigned char buserr_type = sun3_get_buserr ();
378 unsigned long addr, errorcode;
379 unsigned short ssw = fp->un.fmtb.ssw;
380 extern unsigned long _sun3_map_test_start, _sun3_map_test_end;
381
382 if (ssw & (FC | FB))
383 pr_debug("Instruction fault at %#010lx\n",
384 ssw & FC ?
385 fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
386 :
387 fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
388 if (ssw & DF)
389 pr_debug("Data %s fault at %#010lx in %s (pc=%#lx)\n",
390 ssw & RW ? "read" : "write",
391 fp->un.fmtb.daddr,
392 space_names[ssw & DFC], fp->ptregs.pc);
393
394
395
396
397
398
399
400 if ((ssw & DF)
401 && (buserr_type & (SUN3_BUSERR_PROTERR | SUN3_BUSERR_INVALID))) {
402 if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 0))
403 return;
404 }
405
406
407 if (fp->ptregs.sr & PS_S) {
408
409 if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) {
410
411 if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 1))
412 return;
413
414 if (ssw & (FC | FB))
415 pr_err("Instruction fault at %#010lx\n",
416 fp->ptregs.pc);
417 if (ssw & DF) {
418
419 if((fp->ptregs.pc >= (unsigned long)&_sun3_map_test_start) &&
420 (fp->ptregs.pc <= (unsigned long)&_sun3_map_test_end)) {
421 send_fault_sig(&fp->ptregs);
422 return;
423 }
424
425 pr_err("Data %s fault at %#010lx in %s (pc=%#lx)\n",
426 ssw & RW ? "read" : "write",
427 fp->un.fmtb.daddr,
428 space_names[ssw & DFC], fp->ptregs.pc);
429 }
430 pr_err("BAD KERNEL BUSERR\n");
431
432 die_if_kernel("Oops", &fp->ptregs,0);
433 force_sig(SIGKILL);
434 return;
435 }
436 } else {
437
438 if (!(ssw & (FC | FB)) && !(ssw & DF))
439
440 panic ("USER BUSERR w/o instruction or data fault");
441 }
442
443
444
445 if (ssw & DF) {
446 addr = fp->un.fmtb.daddr;
447
448
449
450
451
452
453
454 if (buserr_type & SUN3_BUSERR_PROTERR)
455 errorcode = 0x01;
456 else if (buserr_type & SUN3_BUSERR_INVALID)
457 errorcode = 0x00;
458 else {
459 pr_debug("*** unexpected busfault type=%#04x\n",
460 buserr_type);
461 pr_debug("invalid %s access at %#lx from pc %#lx\n",
462 !(ssw & RW) ? "write" : "read", addr,
463 fp->ptregs.pc);
464 die_if_kernel ("Oops", &fp->ptregs, buserr_type);
465 force_sig (SIGBUS);
466 return;
467 }
468
469
470 if (!(ssw & RW) || ssw & RM)
471 errorcode |= 0x02;
472
473
474 do_page_fault (&fp->ptregs, addr, errorcode);
475
476
477 return;
478 }
479
480
481
482
483 if (fp->ptregs.format == 0xA)
484 addr = fp->ptregs.pc + 4;
485 else
486 addr = fp->un.fmtb.baddr;
487 if (ssw & FC)
488 addr -= 2;
489
490 if (buserr_type & SUN3_BUSERR_INVALID) {
491 if (!mmu_emu_handle_fault(addr, 1, 0))
492 do_page_fault (&fp->ptregs, addr, 0);
493 } else {
494 pr_debug("protection fault on insn access (segv).\n");
495 force_sig (SIGSEGV);
496 }
497}
498#else
499#if defined(CPU_M68020_OR_M68030)
500static inline void bus_error030 (struct frame *fp)
501{
502 volatile unsigned short temp;
503 unsigned short mmusr;
504 unsigned long addr, errorcode;
505 unsigned short ssw = fp->un.fmtb.ssw;
506#ifdef DEBUG
507 unsigned long desc;
508#endif
509
510 pr_debug("pid = %x ", current->pid);
511 pr_debug("SSW=%#06x ", ssw);
512
513 if (ssw & (FC | FB))
514 pr_debug("Instruction fault at %#010lx\n",
515 ssw & FC ?
516 fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
517 :
518 fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
519 if (ssw & DF)
520 pr_debug("Data %s fault at %#010lx in %s (pc=%#lx)\n",
521 ssw & RW ? "read" : "write",
522 fp->un.fmtb.daddr,
523 space_names[ssw & DFC], fp->ptregs.pc);
524
525
526
527
528
529 if (ssw & DF) {
530 addr = fp->un.fmtb.daddr;
531
532#ifdef DEBUG
533 asm volatile ("ptestr %3,%2@,#7,%0\n\t"
534 "pmove %%psr,%1"
535 : "=a&" (desc), "=m" (temp)
536 : "a" (addr), "d" (ssw));
537 pr_debug("mmusr is %#x for addr %#lx in task %p\n",
538 temp, addr, current);
539 pr_debug("descriptor address is 0x%p, contents %#lx\n",
540 __va(desc), *(unsigned long *)__va(desc));
541#else
542 asm volatile ("ptestr %2,%1@,#7\n\t"
543 "pmove %%psr,%0"
544 : "=m" (temp) : "a" (addr), "d" (ssw));
545#endif
546 mmusr = temp;
547 errorcode = (mmusr & MMU_I) ? 0 : 1;
548 if (!(ssw & RW) || (ssw & RM))
549 errorcode |= 2;
550
551 if (mmusr & (MMU_I | MMU_WP)) {
552 if (ssw & 4) {
553 pr_err("Data %s fault at %#010lx in %s (pc=%#lx)\n",
554 ssw & RW ? "read" : "write",
555 fp->un.fmtb.daddr,
556 space_names[ssw & DFC], fp->ptregs.pc);
557 goto buserr;
558 }
559
560
561 if (do_page_fault (&fp->ptregs, addr, errorcode) < 0)
562 return;
563 } else if (!(mmusr & MMU_I)) {
564
565 if (!(ssw & RM) && send_fault_sig(&fp->ptregs) > 0)
566 pr_err("unexpected bus error (%#x,%#x)\n", ssw,
567 mmusr);
568 } else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
569 pr_err("invalid %s access at %#lx from pc %#lx\n",
570 !(ssw & RW) ? "write" : "read", addr,
571 fp->ptregs.pc);
572 die_if_kernel("Oops",&fp->ptregs,mmusr);
573 force_sig(SIGSEGV);
574 return;
575 } else {
576#if 0
577 static volatile long tlong;
578#endif
579
580 pr_err("weird %s access at %#lx from pc %#lx (ssw is %#x)\n",
581 !(ssw & RW) ? "write" : "read", addr,
582 fp->ptregs.pc, ssw);
583 asm volatile ("ptestr #1,%1@,#0\n\t"
584 "pmove %%psr,%0"
585 : "=m" (temp)
586 : "a" (addr));
587 mmusr = temp;
588
589 pr_err("level 0 mmusr is %#x\n", mmusr);
590#if 0
591 asm volatile ("pmove %%tt0,%0"
592 : "=m" (tlong));
593 pr_debug("tt0 is %#lx, ", tlong);
594 asm volatile ("pmove %%tt1,%0"
595 : "=m" (tlong));
596 pr_debug("tt1 is %#lx\n", tlong);
597#endif
598 pr_debug("Unknown SIGSEGV - 1\n");
599 die_if_kernel("Oops",&fp->ptregs,mmusr);
600 force_sig(SIGSEGV);
601 return;
602 }
603
604
605 if (!(ssw & RW) || (ssw & RM))
606 asm volatile ("ploadw %1,%0@" :
607 : "a" (addr), "d" (ssw));
608 else
609 asm volatile ("ploadr %1,%0@" :
610 : "a" (addr), "d" (ssw));
611 }
612
613
614
615 if (!(ssw & (FC|FB)))
616 return;
617
618 if (fp->ptregs.sr & PS_S) {
619 pr_err("Instruction fault at %#010lx\n", fp->ptregs.pc);
620 buserr:
621 pr_err("BAD KERNEL BUSERR\n");
622 die_if_kernel("Oops",&fp->ptregs,0);
623 force_sig(SIGKILL);
624 return;
625 }
626
627
628 if (fp->ptregs.format == 10)
629 addr = fp->ptregs.pc + 4;
630 else
631 addr = fp->un.fmtb.baddr;
632 if (ssw & FC)
633 addr -= 2;
634
635 if ((ssw & DF) && ((addr ^ fp->un.fmtb.daddr) & PAGE_MASK) == 0)
636
637
638 goto create_atc_entry;
639
640#ifdef DEBUG
641 asm volatile ("ptestr #1,%2@,#7,%0\n\t"
642 "pmove %%psr,%1"
643 : "=a&" (desc), "=m" (temp)
644 : "a" (addr));
645 pr_debug("mmusr is %#x for addr %#lx in task %p\n",
646 temp, addr, current);
647 pr_debug("descriptor address is 0x%p, contents %#lx\n",
648 __va(desc), *(unsigned long *)__va(desc));
649#else
650 asm volatile ("ptestr #1,%1@,#7\n\t"
651 "pmove %%psr,%0"
652 : "=m" (temp) : "a" (addr));
653#endif
654 mmusr = temp;
655 if (mmusr & MMU_I)
656 do_page_fault (&fp->ptregs, addr, 0);
657 else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
658 pr_err("invalid insn access at %#lx from pc %#lx\n",
659 addr, fp->ptregs.pc);
660 pr_debug("Unknown SIGSEGV - 2\n");
661 die_if_kernel("Oops",&fp->ptregs,mmusr);
662 force_sig(SIGSEGV);
663 return;
664 }
665
666create_atc_entry:
667
668 asm volatile ("ploadr #2,%0@" :
669 : "a" (addr));
670}
671#endif
672#endif
673
674#if defined(CONFIG_COLDFIRE) && defined(CONFIG_MMU)
675#include <asm/mcfmmu.h>
676
677
678
679
680
681
682static const unsigned char fs_err_code[] = {
683 0,
684 0,
685 0,
686 0,
687 1,
688 0,
689 0,
690 0,
691 2,
692 3,
693 2,
694 0,
695 1,
696 1,
697 0,
698 0
699};
700
701static inline void access_errorcf(unsigned int fs, struct frame *fp)
702{
703 unsigned long mmusr, addr;
704 unsigned int err_code;
705 int need_page_fault;
706
707 mmusr = mmu_read(MMUSR);
708 addr = mmu_read(MMUAR);
709
710
711
712
713
714
715 switch (fs) {
716 case 5:
717 need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 0, 0);
718 addr = fp->ptregs.pc;
719 break;
720 case 6:
721 need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 0, 1);
722 addr = fp->ptregs.pc + sizeof(long);
723 break;
724 case 10:
725 need_page_fault = cf_tlb_miss(&fp->ptregs, 1, 1, 0);
726 break;
727 case 14:
728 need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 1, 0);
729 break;
730 default:
731
732
733
734
735
736
737
738
739
740
741
742
743 need_page_fault = 1;
744 break;
745 }
746
747 if (need_page_fault) {
748 err_code = fs_err_code[fs];
749 if ((fs == 13) && (mmusr & MMUSR_WF))
750 err_code |= 2;
751 do_page_fault(&fp->ptregs, addr, err_code);
752 }
753}
754#endif
755
756asmlinkage void buserr_c(struct frame *fp)
757{
758
759 if (user_mode(&fp->ptregs))
760 current->thread.esp0 = (unsigned long) fp;
761
762 pr_debug("*** Bus Error *** Format is %x\n", fp->ptregs.format);
763
764#if defined(CONFIG_COLDFIRE) && defined(CONFIG_MMU)
765 if (CPU_IS_COLDFIRE) {
766 unsigned int fs;
767 fs = (fp->ptregs.vector & 0x3) |
768 ((fp->ptregs.vector & 0xc00) >> 8);
769 switch (fs) {
770 case 0x5:
771 case 0x6:
772 case 0x7:
773 case 0x9:
774 case 0xa:
775 case 0xd:
776 case 0xe:
777 case 0xf:
778 access_errorcf(fs, fp);
779 return;
780 default:
781 break;
782 }
783 }
784#endif
785
786 switch (fp->ptregs.format) {
787#if defined (CONFIG_M68060)
788 case 4:
789 access_error060 (fp);
790 break;
791#endif
792#if defined (CONFIG_M68040)
793 case 0x7:
794 access_error040 (fp);
795 break;
796#endif
797#if defined (CPU_M68020_OR_M68030)
798 case 0xa:
799 case 0xb:
800 bus_error030 (fp);
801 break;
802#endif
803 default:
804 die_if_kernel("bad frame format",&fp->ptregs,0);
805 pr_debug("Unknown SIGSEGV - 4\n");
806 force_sig(SIGSEGV);
807 }
808}
809
810
811static int kstack_depth_to_print = 48;
812
813static void show_trace(unsigned long *stack, const char *loglvl)
814{
815 unsigned long *endstack;
816 unsigned long addr;
817 int i;
818
819 printk("%sCall Trace:", loglvl);
820 addr = (unsigned long)stack + THREAD_SIZE - 1;
821 endstack = (unsigned long *)(addr & -THREAD_SIZE);
822 i = 0;
823 while (stack + 1 <= endstack) {
824 addr = *stack++;
825
826
827
828
829
830
831
832
833 if (__kernel_text_address(addr)) {
834#ifndef CONFIG_KALLSYMS
835 if (i % 5 == 0)
836 pr_cont("\n ");
837#endif
838 pr_cont(" [<%08lx>] %pS\n", addr, (void *)addr);
839 i++;
840 }
841 }
842 pr_cont("\n");
843}
844
845void show_registers(struct pt_regs *regs)
846{
847 struct frame *fp = (struct frame *)regs;
848 u16 c, *cp;
849 unsigned long addr;
850 int i;
851
852 print_modules();
853 pr_info("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc);
854 pr_info("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2);
855 pr_info("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
856 regs->d0, regs->d1, regs->d2, regs->d3);
857 pr_info("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
858 regs->d4, regs->d5, regs->a0, regs->a1);
859
860 pr_info("Process %s (pid: %d, task=%p)\n",
861 current->comm, task_pid_nr(current), current);
862 addr = (unsigned long)&fp->un;
863 pr_info("Frame format=%X ", regs->format);
864 switch (regs->format) {
865 case 0x2:
866 pr_cont("instr addr=%08lx\n", fp->un.fmt2.iaddr);
867 addr += sizeof(fp->un.fmt2);
868 break;
869 case 0x3:
870 pr_cont("eff addr=%08lx\n", fp->un.fmt3.effaddr);
871 addr += sizeof(fp->un.fmt3);
872 break;
873 case 0x4:
874 if (CPU_IS_060)
875 pr_cont("fault addr=%08lx fslw=%08lx\n",
876 fp->un.fmt4.effaddr, fp->un.fmt4.pc);
877 else
878 pr_cont("eff addr=%08lx pc=%08lx\n",
879 fp->un.fmt4.effaddr, fp->un.fmt4.pc);
880 addr += sizeof(fp->un.fmt4);
881 break;
882 case 0x7:
883 pr_cont("eff addr=%08lx ssw=%04x faddr=%08lx\n",
884 fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr);
885 pr_info("wb 1 stat/addr/data: %04x %08lx %08lx\n",
886 fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0);
887 pr_info("wb 2 stat/addr/data: %04x %08lx %08lx\n",
888 fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d);
889 pr_info("wb 3 stat/addr/data: %04x %08lx %08lx\n",
890 fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d);
891 pr_info("push data: %08lx %08lx %08lx %08lx\n",
892 fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2,
893 fp->un.fmt7.pd3);
894 addr += sizeof(fp->un.fmt7);
895 break;
896 case 0x9:
897 pr_cont("instr addr=%08lx\n", fp->un.fmt9.iaddr);
898 addr += sizeof(fp->un.fmt9);
899 break;
900 case 0xa:
901 pr_cont("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
902 fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb,
903 fp->un.fmta.daddr, fp->un.fmta.dobuf);
904 addr += sizeof(fp->un.fmta);
905 break;
906 case 0xb:
907 pr_cont("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
908 fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb,
909 fp->un.fmtb.daddr, fp->un.fmtb.dobuf);
910 pr_info("baddr=%08lx dibuf=%08lx ver=%x\n",
911 fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver);
912 addr += sizeof(fp->un.fmtb);
913 break;
914 default:
915 pr_cont("\n");
916 }
917 show_stack(NULL, (unsigned long *)addr, KERN_INFO);
918
919 pr_info("Code:");
920 cp = (u16 *)regs->pc;
921 for (i = -8; i < 16; i++) {
922 if (get_kernel_nofault(c, cp + i) && i >= 0) {
923 pr_cont(" Bad PC value.");
924 break;
925 }
926 if (i)
927 pr_cont(" %04x", c);
928 else
929 pr_cont(" <%04x>", c);
930 }
931 pr_cont("\n");
932}
933
934void show_stack(struct task_struct *task, unsigned long *stack,
935 const char *loglvl)
936{
937 unsigned long *p;
938 unsigned long *endstack;
939 int i;
940
941 if (!stack) {
942 if (task)
943 stack = (unsigned long *)task->thread.esp0;
944 else
945 stack = (unsigned long *)&stack;
946 }
947 endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE);
948
949 printk("%sStack from %08lx:", loglvl, (unsigned long)stack);
950 p = stack;
951 for (i = 0; i < kstack_depth_to_print; i++) {
952 if (p + 1 > endstack)
953 break;
954 if (i % 8 == 0)
955 pr_cont("\n ");
956 pr_cont(" %08lx", *p++);
957 }
958 pr_cont("\n");
959 show_trace(stack, loglvl);
960}
961
962
963
964
965
966
967
968
969
970void bad_super_trap (struct frame *fp)
971{
972 int vector = (fp->ptregs.vector >> 2) & 0xff;
973
974 console_verbose();
975 if (vector < ARRAY_SIZE(vec_names))
976 pr_err("*** %s *** FORMAT=%X\n",
977 vec_names[vector],
978 fp->ptregs.format);
979 else
980 pr_err("*** Exception %d *** FORMAT=%X\n",
981 vector, fp->ptregs.format);
982 if (vector == VEC_ADDRERR && CPU_IS_020_OR_030) {
983 unsigned short ssw = fp->un.fmtb.ssw;
984
985 pr_err("SSW=%#06x ", ssw);
986
987 if (ssw & RC)
988 pr_err("Pipe stage C instruction fault at %#010lx\n",
989 (fp->ptregs.format) == 0xA ?
990 fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2);
991 if (ssw & RB)
992 pr_err("Pipe stage B instruction fault at %#010lx\n",
993 (fp->ptregs.format) == 0xA ?
994 fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
995 if (ssw & DF)
996 pr_err("Data %s fault at %#010lx in %s (pc=%#lx)\n",
997 ssw & RW ? "read" : "write",
998 fp->un.fmtb.daddr, space_names[ssw & DFC],
999 fp->ptregs.pc);
1000 }
1001 pr_err("Current process id is %d\n", task_pid_nr(current));
1002 die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
1003}
1004
1005asmlinkage void trap_c(struct frame *fp)
1006{
1007 int sig, si_code;
1008 void __user *addr;
1009 int vector = (fp->ptregs.vector >> 2) & 0xff;
1010
1011 if (fp->ptregs.sr & PS_S) {
1012 if (vector == VEC_TRACE) {
1013
1014
1015
1016 return;
1017 }
1018#ifdef CONFIG_MMU
1019 if (fixup_exception(&fp->ptregs))
1020 return;
1021#endif
1022 bad_super_trap(fp);
1023 return;
1024 }
1025
1026
1027 switch (vector) {
1028 case VEC_ADDRERR:
1029 si_code = BUS_ADRALN;
1030 sig = SIGBUS;
1031 break;
1032 case VEC_ILLEGAL:
1033 case VEC_LINE10:
1034 case VEC_LINE11:
1035 si_code = ILL_ILLOPC;
1036 sig = SIGILL;
1037 break;
1038 case VEC_PRIV:
1039 si_code = ILL_PRVOPC;
1040 sig = SIGILL;
1041 break;
1042 case VEC_COPROC:
1043 si_code = ILL_COPROC;
1044 sig = SIGILL;
1045 break;
1046 case VEC_TRAP1:
1047 case VEC_TRAP2:
1048 case VEC_TRAP3:
1049 case VEC_TRAP4:
1050 case VEC_TRAP5:
1051 case VEC_TRAP6:
1052 case VEC_TRAP7:
1053 case VEC_TRAP8:
1054 case VEC_TRAP9:
1055 case VEC_TRAP10:
1056 case VEC_TRAP11:
1057 case VEC_TRAP12:
1058 case VEC_TRAP13:
1059 case VEC_TRAP14:
1060 si_code = ILL_ILLTRP;
1061 sig = SIGILL;
1062 break;
1063 case VEC_FPBRUC:
1064 case VEC_FPOE:
1065 case VEC_FPNAN:
1066 si_code = FPE_FLTINV;
1067 sig = SIGFPE;
1068 break;
1069 case VEC_FPIR:
1070 si_code = FPE_FLTRES;
1071 sig = SIGFPE;
1072 break;
1073 case VEC_FPDIVZ:
1074 si_code = FPE_FLTDIV;
1075 sig = SIGFPE;
1076 break;
1077 case VEC_FPUNDER:
1078 si_code = FPE_FLTUND;
1079 sig = SIGFPE;
1080 break;
1081 case VEC_FPOVER:
1082 si_code = FPE_FLTOVF;
1083 sig = SIGFPE;
1084 break;
1085 case VEC_ZERODIV:
1086 si_code = FPE_INTDIV;
1087 sig = SIGFPE;
1088 break;
1089 case VEC_CHK:
1090 case VEC_TRAP:
1091 si_code = FPE_INTOVF;
1092 sig = SIGFPE;
1093 break;
1094 case VEC_TRACE:
1095 si_code = TRAP_TRACE;
1096 sig = SIGTRAP;
1097 break;
1098 case VEC_TRAP15:
1099 si_code = TRAP_BRKPT;
1100 sig = SIGTRAP;
1101 break;
1102 default:
1103 si_code = ILL_ILLOPC;
1104 sig = SIGILL;
1105 break;
1106 }
1107 switch (fp->ptregs.format) {
1108 default:
1109 addr = (void __user *) fp->ptregs.pc;
1110 break;
1111 case 2:
1112 addr = (void __user *) fp->un.fmt2.iaddr;
1113 break;
1114 case 7:
1115 addr = (void __user *) fp->un.fmt7.effaddr;
1116 break;
1117 case 9:
1118 addr = (void __user *) fp->un.fmt9.iaddr;
1119 break;
1120 case 10:
1121 addr = (void __user *) fp->un.fmta.daddr;
1122 break;
1123 case 11:
1124 addr = (void __user*) fp->un.fmtb.daddr;
1125 break;
1126 }
1127 force_sig_fault(sig, si_code, addr);
1128}
1129
1130void die_if_kernel (char *str, struct pt_regs *fp, int nr)
1131{
1132 if (!(fp->sr & PS_S))
1133 return;
1134
1135 console_verbose();
1136 pr_crit("%s: %08x\n", str, nr);
1137 show_registers(fp);
1138 add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
1139 do_exit(SIGSEGV);
1140}
1141
1142asmlinkage void set_esp0(unsigned long ssp)
1143{
1144 current->thread.esp0 = ssp;
1145}
1146
1147
1148
1149
1150
1151asmlinkage void fpsp040_die(void)
1152{
1153 do_exit(SIGSEGV);
1154}
1155
1156#ifdef CONFIG_M68KFPU_EMU
1157asmlinkage void fpemu_signal(int signal, int code, void *addr)
1158{
1159 force_sig_fault(signal, code, addr);
1160}
1161#endif
1162