Date: Wed, 15 Feb 2023 16:43:04 GMT From: Mitchell Horne <mhorne@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 2f0fc9ab8912 - stable/13 - dtrace: handle page faults in riscv dtrace_trap() Message-ID: <202302151643.31FGh4Zc002076@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by mhorne: URL: https://cgit.FreeBSD.org/src/commit/?id=2f0fc9ab8912d3446ba67ed28bc7f6d226b16144 commit 2f0fc9ab8912d3446ba67ed28bc7f6d226b16144 Author: Mitchell Horne <mhorne@FreeBSD.org> AuthorDate: 2023-02-06 18:08:35 +0000 Commit: Mitchell Horne <mhorne@FreeBSD.org> CommitDate: 2023-02-15 16:41:39 +0000 dtrace: handle page faults in riscv dtrace_trap() We must detect the correct amount to increment sepc, as it may have been a compressed instruction that triggered the fault. Reviewed by: markj MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D38299 (cherry picked from commit 06faad1de2c9aadcfd606d5f7121b201dbfbaa9d) --- sys/cddl/dev/dtrace/riscv/dtrace_subr.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/sys/cddl/dev/dtrace/riscv/dtrace_subr.c b/sys/cddl/dev/dtrace/riscv/dtrace_subr.c index 1e24a88f6c75..f32bb3a2343e 100644 --- a/sys/cddl/dev/dtrace/riscv/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/riscv/dtrace_subr.c @@ -63,6 +63,8 @@ typedef struct dtrace_invop_hdlr { dtrace_invop_hdlr_t *dtrace_invop_hdlr; +static int match_opcode(uint32_t insn, int match, int mask); + int dtrace_invop(uintptr_t addr, struct trapframe *frame) { @@ -188,6 +190,8 @@ dtrace_gethrestime(void) int dtrace_trap(struct trapframe *frame, u_int type) { + uint16_t insn; + /* * A trap can occur while DTrace executes a probe. Before * executing the probe, DTrace blocks re-scheduling and sets @@ -196,9 +200,7 @@ dtrace_trap(struct trapframe *frame, u_int type) * flag is cleared and finally re-scheduling is enabled. * * Check if DTrace has enabled 'no-fault' mode: - * */ - if ((cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT) != 0) { /* * There are only a couple of trap types that are expected. @@ -208,15 +210,24 @@ dtrace_trap(struct trapframe *frame, u_int type) case SCAUSE_LOAD_ACCESS_FAULT: case SCAUSE_STORE_ACCESS_FAULT: case SCAUSE_INST_ACCESS_FAULT: + case SCAUSE_INST_PAGE_FAULT: + case SCAUSE_LOAD_PAGE_FAULT: + case SCAUSE_STORE_PAGE_FAULT: /* Flag a bad address. */ cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_BADADDR; - cpu_core[curcpu].cpuc_dtrace_illval = 0; + cpu_core[curcpu].cpuc_dtrace_illval = frame->tf_stval; /* * Offset the instruction pointer to the instruction - * following the one causing the fault. + * following the one causing the fault. Check if the + * instruction is compressed or not. Standard + * instructions always have bits [1:0] == 11. */ - frame->tf_sepc += 4; + insn = *(uint16_t *)frame->tf_sepc; + if (match_opcode(insn, 0x3, 0x3)) + frame->tf_sepc += INSN_SIZE; + else + frame->tf_sepc += INSN_C_SIZE; return (1); default:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202302151643.31FGh4Zc002076>