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