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