traps.c (c9f289701540baeef9ac7c9977d67a7259f404db) | traps.c (956d705dd279f70d5a222375fa97b637d6e8c43d) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2012 Regents of the University of California 4 */ 5 6#include <linux/cpu.h> 7#include <linux/kernel.h> 8#include <linux/init.h> --- 83 unchanged lines hidden (view full) --- 92DO_ERROR_INFO(do_trap_unknown, 93 SIGILL, ILL_ILLTRP, "unknown exception"); 94DO_ERROR_INFO(do_trap_insn_misaligned, 95 SIGBUS, BUS_ADRALN, "instruction address misaligned"); 96DO_ERROR_INFO(do_trap_insn_fault, 97 SIGSEGV, SEGV_ACCERR, "instruction access fault"); 98DO_ERROR_INFO(do_trap_insn_illegal, 99 SIGILL, ILL_ILLOPC, "illegal instruction"); | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2012 Regents of the University of California 4 */ 5 6#include <linux/cpu.h> 7#include <linux/kernel.h> 8#include <linux/init.h> --- 83 unchanged lines hidden (view full) --- 92DO_ERROR_INFO(do_trap_unknown, 93 SIGILL, ILL_ILLTRP, "unknown exception"); 94DO_ERROR_INFO(do_trap_insn_misaligned, 95 SIGBUS, BUS_ADRALN, "instruction address misaligned"); 96DO_ERROR_INFO(do_trap_insn_fault, 97 SIGSEGV, SEGV_ACCERR, "instruction access fault"); 98DO_ERROR_INFO(do_trap_insn_illegal, 99 SIGILL, ILL_ILLOPC, "illegal instruction"); |
100DO_ERROR_INFO(do_trap_load_misaligned, 101 SIGBUS, BUS_ADRALN, "load address misaligned"); | |
102DO_ERROR_INFO(do_trap_load_fault, 103 SIGSEGV, SEGV_ACCERR, "load access fault"); | 100DO_ERROR_INFO(do_trap_load_fault, 101 SIGSEGV, SEGV_ACCERR, "load access fault"); |
102#ifndef CONFIG_RISCV_M_MODE 103DO_ERROR_INFO(do_trap_load_misaligned, 104 SIGBUS, BUS_ADRALN, "Oops - load address misaligned"); |
|
104DO_ERROR_INFO(do_trap_store_misaligned, | 105DO_ERROR_INFO(do_trap_store_misaligned, |
105 SIGBUS, BUS_ADRALN, "store (or AMO) address misaligned"); | 106 SIGBUS, BUS_ADRALN, "Oops - store (or AMO) address misaligned"); 107#else 108int handle_misaligned_load(struct pt_regs *regs); 109int handle_misaligned_store(struct pt_regs *regs); 110 111asmlinkage void do_trap_load_misaligned(struct pt_regs *regs) 112{ 113 if (!handle_misaligned_load(regs)) 114 return; 115 do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc, 116 "Oops - load address misaligned"); 117} 118 119asmlinkage void do_trap_store_misaligned(struct pt_regs *regs) 120{ 121 if (!handle_misaligned_store(regs)) 122 return; 123 do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc, 124 "Oops - store (or AMO) address misaligned"); 125} 126#endif |
106DO_ERROR_INFO(do_trap_store_fault, 107 SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault"); 108DO_ERROR_INFO(do_trap_ecall_u, 109 SIGILL, ILL_ILLTRP, "environment call from U-mode"); 110DO_ERROR_INFO(do_trap_ecall_s, 111 SIGILL, ILL_ILLTRP, "environment call from S-mode"); 112DO_ERROR_INFO(do_trap_ecall_m, 113 SIGILL, ILL_ILLTRP, "environment call from M-mode"); 114 115static inline unsigned long get_break_insn_length(unsigned long pc) 116{ 117 bug_insn_t insn; 118 119 if (probe_kernel_address((bug_insn_t *)pc, insn)) 120 return 0; | 127DO_ERROR_INFO(do_trap_store_fault, 128 SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault"); 129DO_ERROR_INFO(do_trap_ecall_u, 130 SIGILL, ILL_ILLTRP, "environment call from U-mode"); 131DO_ERROR_INFO(do_trap_ecall_s, 132 SIGILL, ILL_ILLTRP, "environment call from S-mode"); 133DO_ERROR_INFO(do_trap_ecall_m, 134 SIGILL, ILL_ILLTRP, "environment call from M-mode"); 135 136static inline unsigned long get_break_insn_length(unsigned long pc) 137{ 138 bug_insn_t insn; 139 140 if (probe_kernel_address((bug_insn_t *)pc, insn)) 141 return 0; |
121 return (((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) ? 4UL : 2UL); | 142 143 return GET_INSN_LENGTH(insn); |
122} 123 124asmlinkage __visible void do_trap_break(struct pt_regs *regs) 125{ 126 if (user_mode(regs)) 127 force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->epc); 128 else if (report_bug(regs->epc, regs) == BUG_TRAP_TYPE_WARN) 129 regs->epc += get_break_insn_length(regs->epc); --- 12 unchanged lines hidden (view full) --- 142 return 0; 143 if ((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) 144 return (insn == __BUG_INSN_32); 145 else 146 return ((insn & __COMPRESSED_INSN_MASK) == __BUG_INSN_16); 147} 148#endif /* CONFIG_GENERIC_BUG */ 149 | 144} 145 146asmlinkage __visible void do_trap_break(struct pt_regs *regs) 147{ 148 if (user_mode(regs)) 149 force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->epc); 150 else if (report_bug(regs->epc, regs) == BUG_TRAP_TYPE_WARN) 151 regs->epc += get_break_insn_length(regs->epc); --- 12 unchanged lines hidden (view full) --- 164 return 0; 165 if ((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) 166 return (insn == __BUG_INSN_32); 167 else 168 return ((insn & __COMPRESSED_INSN_MASK) == __BUG_INSN_16); 169} 170#endif /* CONFIG_GENERIC_BUG */ 171 |
150void __init trap_init(void) | 172void trap_init(void) |
151{ 152 /* 153 * Set sup0 scratch register to 0, indicating to exception vector 154 * that we are presently executing in the kernel 155 */ 156 csr_write(CSR_SCRATCH, 0); 157 /* Set the exception vector address */ 158 csr_write(CSR_TVEC, &handle_exception); 159 /* Enable interrupts */ 160 csr_write(CSR_IE, IE_SIE | IE_EIE); 161} | 173{ 174 /* 175 * Set sup0 scratch register to 0, indicating to exception vector 176 * that we are presently executing in the kernel 177 */ 178 csr_write(CSR_SCRATCH, 0); 179 /* Set the exception vector address */ 180 csr_write(CSR_TVEC, &handle_exception); 181 /* Enable interrupts */ 182 csr_write(CSR_IE, IE_SIE | IE_EIE); 183} |