diff options
author | Atul Khare <atulkhare@rivosinc.com> | 2023-05-16 15:11:44 -0700 |
---|---|---|
committer | Atul Khare <atulkhare@rivosinc.com> | 2023-05-24 09:15:27 -0700 |
commit | d9e30bb6970c3e387d719b3fd0808937889ca3a6 (patch) | |
tree | f4734165397f34106df5c02fc95bcbd5b56f4c56 /riscv/triggers.cc | |
parent | 31f5ede662303183d93f80e869379e49b7a01608 (diff) | |
download | riscv-isa-sim-d9e30bb6970c3e387d719b3fd0808937889ca3a6.zip riscv-isa-sim-d9e30bb6970c3e387d719b3fd0808937889ca3a6.tar.gz riscv-isa-sim-d9e30bb6970c3e387d719b3fd0808937889ca3a6.tar.bz2 |
triggers: Fix etrigger match on exceptions
The etrigger match on exceptions doesn't work properly in cases like
the following:
1) M-mode delegates ECALLs to S-mode
2) A CPU hardware point mechanism is used to place a breakpoint on the
Umode instruction that executes the ECALL from Umode to Smode. In
effect, this creates a breakpoint etrigger based on Umode.
In the above, the expectation is that #2 will first cause an exit to
the Smode handler (stvec), and the hardware breakpoint exception will
be triggered following an entry into the handler.
However, since etrigger currently checks the current privilege mode, we
will never get a match on conditions like #2.
The patch attempts to address the issue by using the stashed version of
the previous privilege mode for the etrigger match.
cc: YenHaoChen <howard25336284@gmail.com>
Signed-off-by: Atul Khare <atulkhare@rivosinc.com>
Diffstat (limited to 'riscv/triggers.cc')
-rw-r--r-- | riscv/triggers.cc | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/riscv/triggers.cc b/riscv/triggers.cc index 51dcf18..65ba4c9 100644 --- a/riscv/triggers.cc +++ b/riscv/triggers.cc @@ -55,9 +55,11 @@ void trigger_t::tdata3_write(processor_t * const proc, const reg_t val) noexcept sselect = (sselect_t)((proc->extension_enabled_const('S') && get_field(val, CSR_TEXTRA_SSELECT(xlen)) <= SSELECT_MAXVAL) ? get_field(val, CSR_TEXTRA_SSELECT(xlen)) : SSELECT_IGNORE); } -bool trigger_t::common_match(processor_t * const proc) const noexcept { +bool trigger_t::common_match(processor_t * const proc, bool use_prev_prv) const noexcept { auto state = proc->get_state(); - return mode_match(state->prv, state->v) && textra_match(proc); + auto prv = use_prev_prv ? state->prev_prv : state->prv; + auto v = use_prev_prv ? state->prev_v : state->v; + return mode_match(prv, v) && textra_match(proc); } bool trigger_t::mode_match(reg_t prv, bool v) const noexcept @@ -398,7 +400,8 @@ void itrigger_t::tdata1_write(processor_t * const proc, const reg_t val, const b std::optional<match_result_t> trap_common_t::detect_trap_match(processor_t * const proc, const trap_t& t) noexcept { - if (!common_match(proc)) + // Use the previous privilege for matching + if (!common_match(proc, true)) return std::nullopt; auto xlen = proc->get_xlen(); |