A breakpoint trap taken in the middle of an LR/SC sequence clears the load reservation, so an SC following the probed instruction always fails and the enclosing retry loop re-enters the breakpoint, livelocking the CPU. This series makes the RISC-V kprobes implementation reject probes placed on an LR/SC instruction or between them, following arm64's approach for its equivalent exclusive load/store instructions.
Changes since v6: - Fix an off-by-one in the LR/SC tracking window: a constrained loop holds at most 16 instructions (the LR, the SC, and up to 14 between them), and the walk now stops tracking after 14 intermediate instructions, as the spec requires. - Use the existing RV_EXTRACT_FUNCT3()/RV_EXTRACT_RS2_REG() helpers and add RV_EXTRACT_FUNCT5() in riscv_insn_is_lr()/riscv_insn_is_sc() to avoid code duplication. - Rename test_kprobes_lrsc_offsets[] and split it into separate test_kprobes_lrsc_allowed_addresses[]/test_kprobes_lrsc_rejected_ addresses[] so that adding an entry does not force a change in a parallel reject[] table. - Add a KUnit boundary case pinning the 16-instruction tracking window: the 15th instruction after an LR must be rejected and the 16th must be accepted (this fails without the off-by-one fix). Verified by cross-compiling for RISC-V and running the kprobes KUnit test in QEMU (ok 2 kprobes_riscv). Xiaofeng Yuan (2): riscv: kprobes: reject probes inside LR/SC sequences riscv: kprobes: add KUnit test for LR/SC sequence rejection arch/riscv/include/asm/insn.h | 63 ++++++++++++++---- arch/riscv/kernel/probes/decode-insn.c | 2 + arch/riscv/kernel/probes/kprobes.c | 65 +++++++++++++++---- .../kernel/tests/kprobes/test-kprobes-asm.S | 60 +++++++++++++++++ .../riscv/kernel/tests/kprobes/test-kprobes.c | 34 ++++++++++ .../riscv/kernel/tests/kprobes/test-kprobes.h | 6 ++ 6 files changed, 207 insertions(+), 23 deletions(-) -- 2.34.1
