traps.c (162e3480246ef69386d4647d2320d86741bf08a2) traps.c (7c83232161f609bbc452a1255f823f41afc411dd)
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>
9#include <linux/sched.h>
10#include <linux/sched/debug.h>
11#include <linux/sched/signal.h>
12#include <linux/signal.h>
13#include <linux/kdebug.h>
14#include <linux/uaccess.h>
15#include <linux/kprobes.h>
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>
9#include <linux/sched.h>
10#include <linux/sched/debug.h>
11#include <linux/sched/signal.h>
12#include <linux/signal.h>
13#include <linux/kdebug.h>
14#include <linux/uaccess.h>
15#include <linux/kprobes.h>
16#include <linux/uprobes.h>
17#include <asm/uprobes.h>
18#include <linux/mm.h>
19#include <linux/module.h>
20#include <linux/irq.h>
21#include <linux/kexec.h>
22#include <linux/entry-common.h>
23
24#include <asm/asm-prototypes.h>
25#include <asm/bug.h>

--- 150 unchanged lines hidden (view full) ---

176 "Oops - illegal instruction");
177
178 irqentry_nmi_exit(regs, state);
179 }
180}
181
182DO_ERROR_INFO(do_trap_load_fault,
183 SIGSEGV, SEGV_ACCERR, "load access fault");
16#include <linux/mm.h>
17#include <linux/module.h>
18#include <linux/irq.h>
19#include <linux/kexec.h>
20#include <linux/entry-common.h>
21
22#include <asm/asm-prototypes.h>
23#include <asm/bug.h>

--- 150 unchanged lines hidden (view full) ---

174 "Oops - illegal instruction");
175
176 irqentry_nmi_exit(regs, state);
177 }
178}
179
180DO_ERROR_INFO(do_trap_load_fault,
181 SIGSEGV, SEGV_ACCERR, "load access fault");
184#ifndef CONFIG_RISCV_M_MODE
185DO_ERROR_INFO(do_trap_load_misaligned,
186 SIGBUS, BUS_ADRALN, "Oops - load address misaligned");
187DO_ERROR_INFO(do_trap_store_misaligned,
188 SIGBUS, BUS_ADRALN, "Oops - store (or AMO) address misaligned");
189#else
190int handle_misaligned_load(struct pt_regs *regs);
191int handle_misaligned_store(struct pt_regs *regs);
192
193asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs *regs)
194{
195 if (user_mode(regs)) {
196 irqentry_enter_from_user_mode(regs);
197
198 if (handle_misaligned_load(regs))
199 do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,

--- 26 unchanged lines hidden (view full) ---

226
227 if (handle_misaligned_store(regs))
228 do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
229 "Oops - store (or AMO) address misaligned");
230
231 irqentry_nmi_exit(regs, state);
232 }
233}
182
183asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs *regs)
184{
185 if (user_mode(regs)) {
186 irqentry_enter_from_user_mode(regs);
187
188 if (handle_misaligned_load(regs))
189 do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,

--- 26 unchanged lines hidden (view full) ---

216
217 if (handle_misaligned_store(regs))
218 do_trap_error(regs, SIGBUS, BUS_ADRALN, regs->epc,
219 "Oops - store (or AMO) address misaligned");
220
221 irqentry_nmi_exit(regs, state);
222 }
223}
234#endif
235DO_ERROR_INFO(do_trap_store_fault,
236 SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault");
237DO_ERROR_INFO(do_trap_ecall_s,
238 SIGILL, ILL_ILLTRP, "environment call from S-mode");
239DO_ERROR_INFO(do_trap_ecall_m,
240 SIGILL, ILL_ILLTRP, "environment call from M-mode");
241
242static inline unsigned long get_break_insn_length(unsigned long pc)
243{
244 bug_insn_t insn;
245
246 if (get_kernel_nofault(insn, (bug_insn_t *)pc))
247 return 0;
248
249 return GET_INSN_LENGTH(insn);
250}
251
224DO_ERROR_INFO(do_trap_store_fault,
225 SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault");
226DO_ERROR_INFO(do_trap_ecall_s,
227 SIGILL, ILL_ILLTRP, "environment call from S-mode");
228DO_ERROR_INFO(do_trap_ecall_m,
229 SIGILL, ILL_ILLTRP, "environment call from M-mode");
230
231static inline unsigned long get_break_insn_length(unsigned long pc)
232{
233 bug_insn_t insn;
234
235 if (get_kernel_nofault(insn, (bug_insn_t *)pc))
236 return 0;
237
238 return GET_INSN_LENGTH(insn);
239}
240
252static bool probe_single_step_handler(struct pt_regs *regs)
253{
254 bool user = user_mode(regs);
255
256 return user ? uprobe_single_step_handler(regs) : kprobe_single_step_handler(regs);
257}
258
259static bool probe_breakpoint_handler(struct pt_regs *regs)
260{
261 bool user = user_mode(regs);
262
263 return user ? uprobe_breakpoint_handler(regs) : kprobe_breakpoint_handler(regs);
264}
265
266void handle_break(struct pt_regs *regs)
267{
241void handle_break(struct pt_regs *regs)
242{
268 if (probe_single_step_handler(regs))
243#ifdef CONFIG_KPROBES
244 if (kprobe_single_step_handler(regs))
269 return;
270
245 return;
246
271 if (probe_breakpoint_handler(regs))
247 if (kprobe_breakpoint_handler(regs))
272 return;
248 return;
249#endif
250#ifdef CONFIG_UPROBES
251 if (uprobe_single_step_handler(regs))
252 return;
273
253
254 if (uprobe_breakpoint_handler(regs))
255 return;
256#endif
274 current->thread.bad_cause = regs->cause;
275
276 if (user_mode(regs))
277 force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->epc);
278#ifdef CONFIG_KGDB
279 else if (notify_die(DIE_TRAP, "EBREAK", regs, 0, regs->cause, SIGTRAP)
280 == NOTIFY_STOP)
281 return;

--- 188 unchanged lines hidden ---
257 current->thread.bad_cause = regs->cause;
258
259 if (user_mode(regs))
260 force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->epc);
261#ifdef CONFIG_KGDB
262 else if (notify_die(DIE_TRAP, "EBREAK", regs, 0, regs->cause, SIGTRAP)
263 == NOTIFY_STOP)
264 return;

--- 188 unchanged lines hidden ---