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/signal.h>
23#include <linux/kernel.h>
24#include <linux/mm.h>
25#include <linux/module.h>
26#include <linux/user.h>
27#include <linux/string.h>
28#include <linux/linkage.h>
29#include <linux/init.h>
30#include <linux/ptrace.h>
31#include <linux/kallsyms.h>
32
33#include <asm/setup.h>
34#include <asm/fpu.h>
35#include <asm/uaccess.h>
36#include <asm/traps.h>
37#include <asm/pgalloc.h>
38#include <asm/machdep.h>
39#include <asm/siginfo.h>
40
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, current);
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, current);
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, current);
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, current);
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, current);
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, current);
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, current);
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, current);
807 }
808}
809
810
811static int kstack_depth_to_print = 48;
812
813void show_trace(unsigned long *stack)
814{
815 unsigned long *endstack;
816 unsigned long addr;
817 int i;
818
819 pr_info("Call Trace:");
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 mm_segment_t old_fs = get_fs();
849 u16 c, *cp;
850 unsigned long addr;
851 int i;
852
853 print_modules();
854 pr_info("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc);
855 pr_info("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2);
856 pr_info("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
857 regs->d0, regs->d1, regs->d2, regs->d3);
858 pr_info("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
859 regs->d4, regs->d5, regs->a0, regs->a1);
860
861 pr_info("Process %s (pid: %d, task=%p)\n",
862 current->comm, task_pid_nr(current), current);
863 addr = (unsigned long)&fp->un;
864 pr_info("Frame format=%X ", regs->format);
865 switch (regs->format) {
866 case 0x2:
867 pr_cont("instr addr=%08lx\n", fp->un.fmt2.iaddr);
868 addr += sizeof(fp->un.fmt2);
869 break;
870 case 0x3:
871 pr_cont("eff addr=%08lx\n", fp->un.fmt3.effaddr);
872 addr += sizeof(fp->un.fmt3);
873 break;
874 case 0x4:
875 if (CPU_IS_060)
876 pr_cont("fault addr=%08lx fslw=%08lx\n",
877 fp->un.fmt4.effaddr, fp->un.fmt4.pc);
878 else
879 pr_cont("eff addr=%08lx pc=%08lx\n",
880 fp->un.fmt4.effaddr, fp->un.fmt4.pc);
881 addr += sizeof(fp->un.fmt4);
882 break;
883 case 0x7:
884 pr_cont("eff addr=%08lx ssw=%04x faddr=%08lx\n",
885 fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr);
886 pr_info("wb 1 stat/addr/data: %04x %08lx %08lx\n",
887 fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0);
888 pr_info("wb 2 stat/addr/data: %04x %08lx %08lx\n",
889 fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d);
890 pr_info("wb 3 stat/addr/data: %04x %08lx %08lx\n",
891 fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d);
892 pr_info("push data: %08lx %08lx %08lx %08lx\n",
893 fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2,
894 fp->un.fmt7.pd3);
895 addr += sizeof(fp->un.fmt7);
896 break;
897 case 0x9:
898 pr_cont("instr addr=%08lx\n", fp->un.fmt9.iaddr);
899 addr += sizeof(fp->un.fmt9);
900 break;
901 case 0xa:
902 pr_cont("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
903 fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb,
904 fp->un.fmta.daddr, fp->un.fmta.dobuf);
905 addr += sizeof(fp->un.fmta);
906 break;
907 case 0xb:
908 pr_cont("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
909 fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb,
910 fp->un.fmtb.daddr, fp->un.fmtb.dobuf);
911 pr_info("baddr=%08lx dibuf=%08lx ver=%x\n",
912 fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver);
913 addr += sizeof(fp->un.fmtb);
914 break;
915 default:
916 pr_cont("\n");
917 }
918 show_stack(NULL, (unsigned long *)addr);
919
920 pr_info("Code:");
921 set_fs(KERNEL_DS);
922 cp = (u16 *)regs->pc;
923 for (i = -8; i < 16; i++) {
924 if (get_user(c, cp + i) && i >= 0) {
925 pr_cont(" Bad PC value.");
926 break;
927 }
928 if (i)
929 pr_cont(" %04x", c);
930 else
931 pr_cont(" <%04x>", c);
932 }
933 set_fs(old_fs);
934 pr_cont("\n");
935}
936
937void show_stack(struct task_struct *task, unsigned long *stack)
938{
939 unsigned long *p;
940 unsigned long *endstack;
941 int i;
942
943 if (!stack) {
944 if (task)
945 stack = (unsigned long *)task->thread.esp0;
946 else
947 stack = (unsigned long *)&stack;
948 }
949 endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE);
950
951 pr_info("Stack from %08lx:", (unsigned long)stack);
952 p = stack;
953 for (i = 0; i < kstack_depth_to_print; i++) {
954 if (p + 1 > endstack)
955 break;
956 if (i % 8 == 0)
957 pr_cont("\n ");
958 pr_cont(" %08lx", *p++);
959 }
960 pr_cont("\n");
961 show_trace(stack);
962}
963
964
965
966
967
968
969
970
971
972void bad_super_trap (struct frame *fp)
973{
974 int vector = (fp->ptregs.vector >> 2) & 0xff;
975
976 console_verbose();
977 if (vector < ARRAY_SIZE(vec_names))
978 pr_err("*** %s *** FORMAT=%X\n",
979 vec_names[vector],
980 fp->ptregs.format);
981 else
982 pr_err("*** Exception %d *** FORMAT=%X\n",
983 vector, fp->ptregs.format);
984 if (vector == VEC_ADDRERR && CPU_IS_020_OR_030) {
985 unsigned short ssw = fp->un.fmtb.ssw;
986
987 pr_err("SSW=%#06x ", ssw);
988
989 if (ssw & RC)
990 pr_err("Pipe stage C instruction fault at %#010lx\n",
991 (fp->ptregs.format) == 0xA ?
992 fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2);
993 if (ssw & RB)
994 pr_err("Pipe stage B instruction fault at %#010lx\n",
995 (fp->ptregs.format) == 0xA ?
996 fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
997 if (ssw & DF)
998 pr_err("Data %s fault at %#010lx in %s (pc=%#lx)\n",
999 ssw & RW ? "read" : "write",
1000 fp->un.fmtb.daddr, space_names[ssw & DFC],
1001 fp->ptregs.pc);
1002 }
1003 pr_err("Current process id is %d\n", task_pid_nr(current));
1004 die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
1005}
1006
1007asmlinkage void trap_c(struct frame *fp)
1008{
1009 int sig;
1010 int vector = (fp->ptregs.vector >> 2) & 0xff;
1011 siginfo_t info;
1012
1013 if (fp->ptregs.sr & PS_S) {
1014 if (vector == VEC_TRACE) {
1015
1016
1017
1018 } else if (!handle_kernel_fault(&fp->ptregs))
1019 bad_super_trap(fp);
1020 return;
1021 }
1022
1023
1024 switch (vector) {
1025 case VEC_ADDRERR:
1026 info.si_code = BUS_ADRALN;
1027 sig = SIGBUS;
1028 break;
1029 case VEC_ILLEGAL:
1030 case VEC_LINE10:
1031 case VEC_LINE11:
1032 info.si_code = ILL_ILLOPC;
1033 sig = SIGILL;
1034 break;
1035 case VEC_PRIV:
1036 info.si_code = ILL_PRVOPC;
1037 sig = SIGILL;
1038 break;
1039 case VEC_COPROC:
1040 info.si_code = ILL_COPROC;
1041 sig = SIGILL;
1042 break;
1043 case VEC_TRAP1:
1044 case VEC_TRAP2:
1045 case VEC_TRAP3:
1046 case VEC_TRAP4:
1047 case VEC_TRAP5:
1048 case VEC_TRAP6:
1049 case VEC_TRAP7:
1050 case VEC_TRAP8:
1051 case VEC_TRAP9:
1052 case VEC_TRAP10:
1053 case VEC_TRAP11:
1054 case VEC_TRAP12:
1055 case VEC_TRAP13:
1056 case VEC_TRAP14:
1057 info.si_code = ILL_ILLTRP;
1058 sig = SIGILL;
1059 break;
1060 case VEC_FPBRUC:
1061 case VEC_FPOE:
1062 case VEC_FPNAN:
1063 info.si_code = FPE_FLTINV;
1064 sig = SIGFPE;
1065 break;
1066 case VEC_FPIR:
1067 info.si_code = FPE_FLTRES;
1068 sig = SIGFPE;
1069 break;
1070 case VEC_FPDIVZ:
1071 info.si_code = FPE_FLTDIV;
1072 sig = SIGFPE;
1073 break;
1074 case VEC_FPUNDER:
1075 info.si_code = FPE_FLTUND;
1076 sig = SIGFPE;
1077 break;
1078 case VEC_FPOVER:
1079 info.si_code = FPE_FLTOVF;
1080 sig = SIGFPE;
1081 break;
1082 case VEC_ZERODIV:
1083 info.si_code = FPE_INTDIV;
1084 sig = SIGFPE;
1085 break;
1086 case VEC_CHK:
1087 case VEC_TRAP:
1088 info.si_code = FPE_INTOVF;
1089 sig = SIGFPE;
1090 break;
1091 case VEC_TRACE:
1092 info.si_code = TRAP_TRACE;
1093 sig = SIGTRAP;
1094 break;
1095 case VEC_TRAP15:
1096 info.si_code = TRAP_BRKPT;
1097 sig = SIGTRAP;
1098 break;
1099 default:
1100 info.si_code = ILL_ILLOPC;
1101 sig = SIGILL;
1102 break;
1103 }
1104 info.si_signo = sig;
1105 info.si_errno = 0;
1106 switch (fp->ptregs.format) {
1107 default:
1108 info.si_addr = (void *) fp->ptregs.pc;
1109 break;
1110 case 2:
1111 info.si_addr = (void *) fp->un.fmt2.iaddr;
1112 break;
1113 case 7:
1114 info.si_addr = (void *) fp->un.fmt7.effaddr;
1115 break;
1116 case 9:
1117 info.si_addr = (void *) fp->un.fmt9.iaddr;
1118 break;
1119 case 10:
1120 info.si_addr = (void *) fp->un.fmta.daddr;
1121 break;
1122 case 11:
1123 info.si_addr = (void *) fp->un.fmtb.daddr;
1124 break;
1125 }
1126 force_sig_info (sig, &info, current);
1127}
1128
1129void die_if_kernel (char *str, struct pt_regs *fp, int nr)
1130{
1131 if (!(fp->sr & PS_S))
1132 return;
1133
1134 console_verbose();
1135 pr_crit("%s: %08x\n", str, nr);
1136 show_registers(fp);
1137 add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
1138 do_exit(SIGSEGV);
1139}
1140
1141asmlinkage void set_esp0(unsigned long ssp)
1142{
1143 current->thread.esp0 = ssp;
1144}
1145
1146
1147
1148
1149
1150asmlinkage void fpsp040_die(void)
1151{
1152 do_exit(SIGSEGV);
1153}
1154
1155#ifdef CONFIG_M68KFPU_EMU
1156asmlinkage void fpemu_signal(int signal, int code, void *addr)
1157{
1158 siginfo_t info;
1159
1160 info.si_signo = signal;
1161 info.si_errno = 0;
1162 info.si_code = code;
1163 info.si_addr = addr;
1164 force_sig_info(signal, &info, current);
1165}
1166#endif
1167