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}