diff options
Diffstat (limited to 'sys/cddl/dev/dtrace/riscv/dtrace_subr.c')
-rw-r--r-- | sys/cddl/dev/dtrace/riscv/dtrace_subr.c | 51 |
1 files changed, 23 insertions, 28 deletions
diff --git a/sys/cddl/dev/dtrace/riscv/dtrace_subr.c b/sys/cddl/dev/dtrace/riscv/dtrace_subr.c index c1ac339b3a26..3a6aacd86fcd 100644 --- a/sys/cddl/dev/dtrace/riscv/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/riscv/dtrace_subr.c @@ -21,26 +21,22 @@ * * Portions Copyright 2016-2018 Ruslan Bukin <br@bsdpad.com> * - * $FreeBSD$ - * */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/systm.h> -#include <sys/types.h> #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/kmem.h> +#include <sys/proc.h> #include <sys/smp.h> #include <sys/dtrace_impl.h> #include <sys/dtrace_bsd.h> +#include <cddl/dev/dtrace/dtrace_cddl.h> #include <machine/vmparam.h> #include <machine/encoding.h> #include <machine/riscvreg.h> @@ -68,14 +64,18 @@ dtrace_invop_hdlr_t *dtrace_invop_hdlr; int dtrace_invop(uintptr_t addr, struct trapframe *frame) { + struct thread *td; dtrace_invop_hdlr_t *hdlr; int rval; + rval = 0; + td = curthread; + td->t_dtrace_trapframe = frame; for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next) if ((rval = hdlr->dtih_func(addr, frame, 0)) != 0) - return (rval); - - return (0); + break; + td->t_dtrace_trapframe = NULL; + return (rval); } void @@ -162,7 +162,7 @@ dtrace_sync(void) * Returns nanoseconds since boot. */ uint64_t -dtrace_gethrtime() +dtrace_gethrtime(void) { struct timespec curtime; @@ -194,9 +194,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. @@ -206,15 +204,19 @@ 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. */ - frame->tf_sepc += 4; + frame->tf_sepc += + dtrace_instr_size((uint8_t *)frame->tf_sepc); return (1); default: @@ -238,16 +240,6 @@ dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which, } static int -match_opcode(uint32_t insn, int match, int mask) -{ - - if (((insn ^ match) & mask) == 0) - return (1); - - return (0); -} - -static int dtrace_invop_start(struct trapframe *frame) { register_t *sp; @@ -259,7 +251,7 @@ dtrace_invop_start(struct trapframe *frame) if (invop == 0) return (-1); - if (match_opcode(invop, (MATCH_SD | RS2_RA | RS1_SP), + if (dtrace_match_opcode(invop, (MATCH_SD | RS2_RA | RS1_SP), (MASK_SD | RS2_MASK | RS1_MASK))) { /* Non-compressed store of ra to sp */ imm = (invop >> 7) & 0x1f; @@ -270,14 +262,14 @@ dtrace_invop_start(struct trapframe *frame) return (0); } - if (match_opcode(invop, (MATCH_JALR | (X_RA << RS1_SHIFT)), + if (dtrace_match_opcode(invop, (MATCH_JALR | (X_RA << RS1_SHIFT)), (MASK_JALR | RD_MASK | RS1_MASK | IMM_MASK))) { /* Non-compressed ret */ frame->tf_sepc = frame->tf_ra; return (0); } - if (match_opcode(invop, (MATCH_C_SDSP | RS2_C_RA), + if (dtrace_match_opcode(invop, (MATCH_C_SDSP | RS2_C_RA), (MASK_C_SDSP | RS2_C_MASK))) { /* 'C'-compressed store of ra to sp */ uimm = ((invop >> 10) & 0x7) << 3; @@ -288,13 +280,16 @@ dtrace_invop_start(struct trapframe *frame) return (0); } - if (match_opcode(invop, (MATCH_C_JR | (X_RA << RD_SHIFT)), + if (dtrace_match_opcode(invop, (MATCH_C_JR | (X_RA << RD_SHIFT)), (MASK_C_JR | RD_MASK))) { /* 'C'-compressed ret */ frame->tf_sepc = frame->tf_ra; return (0); } + if (dtrace_match_opcode(invop, MATCH_C_NOP, MASK_C_NOP)) + return (0); + #ifdef INVARIANTS panic("Instruction %x doesn't match any opcode.", invop); #endif |