We must detect the correct amount to increment sepc, as it may have been
a compressed instruction that triggered the fault.
Details
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Passed - Unit
No Test Coverage - Build Status
Buildable 49421 Build 46311: arc lint + arc unit
Event Timeline
sys/cddl/dev/dtrace/riscv/dtrace_subr.c | ||
---|---|---|
227–231 | Here we assume 4-byte alignment, so I guess it's ok to assume that the faulting instruction won't be compressed? | |
228 | It looks like this tests whether the low three bits of the instr are 0x1, but why does that work? It doesn't seem to line up with the MASK/MATCH_C constants defined in encoding.h. |
sys/cddl/dev/dtrace/riscv/dtrace_subr.c | ||
---|---|---|
227–231 | Hmm, no, I was definitely seeing faults caused by compressed instructions, but misaligned access is emulated by M-mode firmware. I will reduce this to a uint16_t load. | |
228 | *the low two bits The instruction encoding space is set up so that all standard length instructions begin with the two lowest bits set to 1. Compressed instructions have a two-bit opcodes that can use any of the other patterns. There isn't anything defined in encoding.h to precisely match for "any" compressed instruction. Essentially, the MASK definition for each specific instruction is too wide. This interface is a little obtuse, but is already used elsewhere in this file, so I tried to roll with it. Still, I realize that I have got it wrong and this will only match some, but not all compressed instructions. It should become: if (match_opcode(insn, 0x3, 0x3)) frame->tf_sepc += INSN_SIZE; else frame->tf_sepc += INSN_C_SIZE; |