qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] target/riscv: Fix write_misa vs aligned next_pc
@ 2025-04-25 15:23 Richard Henderson
  2025-04-25 15:23 ` [PATCH 1/7] target/riscv: Pass ra to riscv_csr_write_fn Richard Henderson
                   ` (8 more replies)
  0 siblings, 9 replies; 28+ messages in thread
From: Richard Henderson @ 2025-04-25 15:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza

As discussed, the use of GETPC() within write_misa is wrong.
I've done just enough plumbing to get the helper return address
piped down to write_misa, so that we can make use of unwind data.

AFAIK, nothing in check-tcg or check-functional would test this.
It shouldn't be too hard to write a test akin to issue1060.S,
but I'm going to leave that to someone else.


r~


Richard Henderson (7):
  target/riscv: Pass ra to riscv_csr_write_fn
  target/riscv: Pass ra to riscv_csrrw_do64
  target/riscv: Pass ra to riscv_csrrw_do128
  target/riscv: Pass ra to riscv_csrrw
  target/riscv: Pass ra to riscv_csrrw_i128
  target/riscv: Move insn_len to internals.h
  target/riscv: Fix write_misa vs aligned next_pc

 target/riscv/cpu.h       |  15 ++-
 target/riscv/internals.h |   5 +
 hw/riscv/riscv_hart.c    |   2 +-
 target/riscv/csr.c       | 278 +++++++++++++++++++++------------------
 target/riscv/op_helper.c |  13 +-
 target/riscv/translate.c |   5 -
 6 files changed, 169 insertions(+), 149 deletions(-)

-- 
2.43.0



^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 1/7] target/riscv: Pass ra to riscv_csr_write_fn
  2025-04-25 15:23 [PATCH 0/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
@ 2025-04-25 15:23 ` Richard Henderson
  2025-04-25 22:28   ` Philippe Mathieu-Daudé
  2025-04-28 22:33   ` Alistair Francis
  2025-04-25 15:23 ` [PATCH 2/7] target/riscv: Pass ra to riscv_csrrw_do64 Richard Henderson
                   ` (7 subsequent siblings)
  8 siblings, 2 replies; 28+ messages in thread
From: Richard Henderson @ 2025-04-25 15:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/cpu.h |   3 +-
 target/riscv/csr.c | 226 +++++++++++++++++++++++----------------------
 2 files changed, 118 insertions(+), 111 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 167909c89b..4d41a66d72 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -841,7 +841,8 @@ typedef RISCVException (*riscv_csr_predicate_fn)(CPURISCVState *env,
 typedef RISCVException (*riscv_csr_read_fn)(CPURISCVState *env, int csrno,
                                             target_ulong *ret_value);
 typedef RISCVException (*riscv_csr_write_fn)(CPURISCVState *env, int csrno,
-                                             target_ulong new_value);
+                                             target_ulong new_value,
+                                             uintptr_t ra);
 typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
                                           target_ulong *ret_value,
                                           target_ulong new_value,
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index c52c87faae..6f1f69eba6 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -830,13 +830,15 @@ static RISCVException seed(CPURISCVState *env, int csrno)
 }
 
 /* zicfiss CSR_SSP read and write */
-static int read_ssp(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_ssp(CPURISCVState *env, int csrno,
+                               target_ulong *val)
 {
     *val = env->ssp;
     return RISCV_EXCP_NONE;
 }
 
-static int write_ssp(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_ssp(CPURISCVState *env, int csrno,
+                                target_ulong val, uintptr_t ra)
 {
     env->ssp = val;
     return RISCV_EXCP_NONE;
@@ -851,7 +853,7 @@ static RISCVException read_fflags(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_fflags(CPURISCVState *env, int csrno,
-                                   target_ulong val)
+                                   target_ulong val, uintptr_t ra)
 {
 #if !defined(CONFIG_USER_ONLY)
     if (riscv_has_ext(env, RVF)) {
@@ -870,7 +872,7 @@ static RISCVException read_frm(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_frm(CPURISCVState *env, int csrno,
-                                target_ulong val)
+                                target_ulong val, uintptr_t ra)
 {
 #if !defined(CONFIG_USER_ONLY)
     if (riscv_has_ext(env, RVF)) {
@@ -890,7 +892,7 @@ static RISCVException read_fcsr(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_fcsr(CPURISCVState *env, int csrno,
-                                 target_ulong val)
+                                 target_ulong val, uintptr_t ra)
 {
 #if !defined(CONFIG_USER_ONLY)
     if (riscv_has_ext(env, RVF)) {
@@ -942,7 +944,7 @@ static RISCVException read_vxrm(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_vxrm(CPURISCVState *env, int csrno,
-                                 target_ulong val)
+                                 target_ulong val, uintptr_t ra)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->mstatus |= MSTATUS_VS;
@@ -959,7 +961,7 @@ static RISCVException read_vxsat(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_vxsat(CPURISCVState *env, int csrno,
-                                  target_ulong val)
+                                  target_ulong val, uintptr_t ra)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->mstatus |= MSTATUS_VS;
@@ -976,7 +978,7 @@ static RISCVException read_vstart(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_vstart(CPURISCVState *env, int csrno,
-                                   target_ulong val)
+                                   target_ulong val, uintptr_t ra)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->mstatus |= MSTATUS_VS;
@@ -997,7 +999,7 @@ static RISCVException read_vcsr(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_vcsr(CPURISCVState *env, int csrno,
-                                 target_ulong val)
+                                 target_ulong val, uintptr_t ra)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->mstatus |= MSTATUS_VS;
@@ -1055,7 +1057,7 @@ static RISCVException read_mcyclecfg(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mcyclecfg(CPURISCVState *env, int csrno,
-                                      target_ulong val)
+                                      target_ulong val, uintptr_t ra)
 {
     uint64_t inh_avail_mask;
 
@@ -1084,7 +1086,7 @@ static RISCVException read_mcyclecfgh(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mcyclecfgh(CPURISCVState *env, int csrno,
-                                       target_ulong val)
+                                       target_ulong val, uintptr_t ra)
 {
     target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
                                                  MCYCLECFGH_BIT_MINH);
@@ -1109,7 +1111,7 @@ static RISCVException read_minstretcfg(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_minstretcfg(CPURISCVState *env, int csrno,
-                                        target_ulong val)
+                                        target_ulong val, uintptr_t ra)
 {
     uint64_t inh_avail_mask;
 
@@ -1136,7 +1138,7 @@ static RISCVException read_minstretcfgh(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_minstretcfgh(CPURISCVState *env, int csrno,
-                                         target_ulong val)
+                                         target_ulong val, uintptr_t ra)
 {
     target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
                                                  MINSTRETCFGH_BIT_MINH);
@@ -1163,7 +1165,7 @@ static RISCVException read_mhpmevent(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mhpmevent(CPURISCVState *env, int csrno,
-                                      target_ulong val)
+                                      target_ulong val, uintptr_t ra)
 {
     int evt_index = csrno - CSR_MCOUNTINHIBIT;
     uint64_t mhpmevt_val = val;
@@ -1201,7 +1203,7 @@ static RISCVException read_mhpmeventh(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mhpmeventh(CPURISCVState *env, int csrno,
-                                       target_ulong val)
+                                       target_ulong val, uintptr_t ra)
 {
     int evt_index = csrno - CSR_MHPMEVENT3H + 3;
     uint64_t mhpmevth_val;
@@ -1343,14 +1345,16 @@ static RISCVException riscv_pmu_write_ctrh(CPURISCVState *env, target_ulong val,
     return RISCV_EXCP_NONE;
 }
 
-static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mhpmcounter(CPURISCVState *env, int csrno,
+                                        target_ulong val, uintptr_t ra)
 {
     int ctr_idx = csrno - CSR_MCYCLE;
 
     return riscv_pmu_write_ctr(env, val, ctr_idx);
 }
 
-static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mhpmcounterh(CPURISCVState *env, int csrno,
+                                         target_ulong val, uintptr_t ra)
 {
     int ctr_idx = csrno - CSR_MCYCLEH;
 
@@ -1661,7 +1665,7 @@ static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
-                                      target_ulong val)
+                                      target_ulong val, uintptr_t ra)
 {
     if (riscv_cpu_mxl(env) == MXL_RV32) {
         env->vstimecmp = deposit64(env->vstimecmp, 0, 32, (uint64_t)val);
@@ -1676,7 +1680,7 @@ static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_vstimecmph(CPURISCVState *env, int csrno,
-                                       target_ulong val)
+                                       target_ulong val, uintptr_t ra)
 {
     env->vstimecmp = deposit64(env->vstimecmp, 32, 32, (uint64_t)val);
     riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
@@ -1710,13 +1714,13 @@ static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
-                                     target_ulong val)
+                                     target_ulong val, uintptr_t ra)
 {
     if (env->virt_enabled) {
         if (env->hvictl & HVICTL_VTI) {
             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
         }
-        return write_vstimecmp(env, csrno, val);
+        return write_vstimecmp(env, csrno, val, ra);
     }
 
     if (riscv_cpu_mxl(env) == MXL_RV32) {
@@ -1731,13 +1735,13 @@ static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
-                                      target_ulong val)
+                                      target_ulong val, uintptr_t ra)
 {
     if (env->virt_enabled) {
         if (env->hvictl & HVICTL_VTI) {
             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
         }
-        return write_vstimecmph(env, csrno, val);
+        return write_vstimecmph(env, csrno, val, ra);
     }
 
     env->stimecmp = deposit64(env->stimecmp, 32, 32, (uint64_t)val);
@@ -1842,7 +1846,7 @@ static RISCVException read_zero(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_ignore(CPURISCVState *env, int csrno,
-                                   target_ulong val)
+                                   target_ulong val, uintptr_t ra)
 {
     return RISCV_EXCP_NONE;
 }
@@ -1963,7 +1967,7 @@ static target_ulong legalize_mpp(CPURISCVState *env, target_ulong old_mpp,
 }
 
 static RISCVException write_mstatus(CPURISCVState *env, int csrno,
-                                    target_ulong val)
+                                    target_ulong val, uintptr_t ra)
 {
     uint64_t mstatus = env->mstatus;
     uint64_t mask = 0;
@@ -2042,7 +2046,7 @@ static RISCVException read_mstatush(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mstatush(CPURISCVState *env, int csrno,
-                                     target_ulong val)
+                                     target_ulong val, uintptr_t ra)
 {
     uint64_t valh = (uint64_t)val << 32;
     uint64_t mask = riscv_has_ext(env, RVH) ? MSTATUS_MPV | MSTATUS_GVA : 0;
@@ -2096,7 +2100,7 @@ static RISCVException read_misa(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_misa(CPURISCVState *env, int csrno,
-                                 target_ulong val)
+                                 target_ulong val, uintptr_t ra)
 {
     RISCVCPU *cpu = env_archcpu(env);
     uint32_t orig_misa_ext = env->misa_ext;
@@ -2160,7 +2164,7 @@ static RISCVException read_medeleg(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_medeleg(CPURISCVState *env, int csrno,
-                                    target_ulong val)
+                                    target_ulong val, uintptr_t ra)
 {
     env->medeleg = (env->medeleg & ~DELEGABLE_EXCPS) | (val & DELEGABLE_EXCPS);
     return RISCV_EXCP_NONE;
@@ -2955,7 +2959,7 @@ static RISCVException read_mtvec(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mtvec(CPURISCVState *env, int csrno,
-                                  target_ulong val)
+                                  target_ulong val, uintptr_t ra)
 {
     /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
     if ((val & 3) < 2) {
@@ -2974,7 +2978,7 @@ static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
-                                          target_ulong val)
+                                          target_ulong val, uintptr_t ra)
 {
     int cidx;
     PMUCTRState *counter;
@@ -3049,10 +3053,9 @@ static RISCVException read_scountinhibit(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_scountinhibit(CPURISCVState *env, int csrno,
-                                          target_ulong val)
+                                          target_ulong val, uintptr_t ra)
 {
-    write_mcountinhibit(env, csrno, val & env->mcounteren);
-    return RISCV_EXCP_NONE;
+    return write_mcountinhibit(env, csrno, val & env->mcounteren, ra);
 }
 
 static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
@@ -3063,7 +3066,7 @@ static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
-                                       target_ulong val)
+                                       target_ulong val, uintptr_t ra)
 {
     RISCVCPU *cpu = env_archcpu(env);
 
@@ -3097,7 +3100,7 @@ static RISCVException read_mscratch(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mscratch(CPURISCVState *env, int csrno,
-                                     target_ulong val)
+                                     target_ulong val, uintptr_t ra)
 {
     env->mscratch = val;
     return RISCV_EXCP_NONE;
@@ -3111,7 +3114,7 @@ static RISCVException read_mepc(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mepc(CPURISCVState *env, int csrno,
-                                 target_ulong val)
+                                 target_ulong val, uintptr_t ra)
 {
     env->mepc = val;
     return RISCV_EXCP_NONE;
@@ -3125,7 +3128,7 @@ static RISCVException read_mcause(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mcause(CPURISCVState *env, int csrno,
-                                   target_ulong val)
+                                   target_ulong val, uintptr_t ra)
 {
     env->mcause = val;
     return RISCV_EXCP_NONE;
@@ -3139,7 +3142,7 @@ static RISCVException read_mtval(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mtval(CPURISCVState *env, int csrno,
-                                  target_ulong val)
+                                  target_ulong val, uintptr_t ra)
 {
     env->mtval = val;
     return RISCV_EXCP_NONE;
@@ -3154,9 +3157,9 @@ static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
-                                    target_ulong val);
+                                    target_ulong val, uintptr_t ra);
 static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
-                                    target_ulong val)
+                                    target_ulong val, uintptr_t ra)
 {
     const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
     uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE |
@@ -3188,9 +3191,7 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
         }
     }
     env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
-    write_henvcfg(env, CSR_HENVCFG, env->henvcfg);
-
-    return RISCV_EXCP_NONE;
+    return write_henvcfg(env, CSR_HENVCFG, env->henvcfg, ra);
 }
 
 static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
@@ -3201,9 +3202,9 @@ static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
-                                    target_ulong val);
+                                     target_ulong val, uintptr_t ra);
 static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
-                                     target_ulong val)
+                                     target_ulong val, uintptr_t ra)
 {
     const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
     uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
@@ -3218,9 +3219,7 @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
     }
 
     env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
-    write_henvcfgh(env, CSR_HENVCFGH, env->henvcfg >> 32);
-
-    return RISCV_EXCP_NONE;
+    return write_henvcfgh(env, CSR_HENVCFGH, env->henvcfg >> 32, ra);
 }
 
 static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
@@ -3238,7 +3237,7 @@ static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
-                                    target_ulong val)
+                                    target_ulong val, uintptr_t ra)
 {
     uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
     RISCVException ret;
@@ -3295,7 +3294,7 @@ static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
-                                    target_ulong val)
+                                    target_ulong val, uintptr_t ra)
 {
     uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
     RISCVException ret;
@@ -3350,7 +3349,7 @@ static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
-                                     target_ulong val)
+                                     target_ulong val, uintptr_t ra)
 {
     uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
                                     HENVCFG_ADUE | HENVCFG_DTE);
@@ -3388,7 +3387,7 @@ static RISCVException write_mstateen(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
-                                      target_ulong new_val)
+                                      target_ulong new_val, uintptr_t ra)
 {
     uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
     if (!riscv_has_ext(env, RVF)) {
@@ -3420,7 +3419,7 @@ static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mstateen_1_3(CPURISCVState *env, int csrno,
-                                         target_ulong new_val)
+                                         target_ulong new_val, uintptr_t ra)
 {
     return write_mstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
 }
@@ -3447,7 +3446,7 @@ static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
-                                       target_ulong new_val)
+                                       target_ulong new_val, uintptr_t ra)
 {
     uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
 
@@ -3463,7 +3462,7 @@ static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mstateenh_1_3(CPURISCVState *env, int csrno,
-                                          target_ulong new_val)
+                                          target_ulong new_val, uintptr_t ra)
 {
     return write_mstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
 }
@@ -3492,7 +3491,7 @@ static RISCVException write_hstateen(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
-                                      target_ulong new_val)
+                                      target_ulong new_val, uintptr_t ra)
 {
     uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
 
@@ -3521,7 +3520,7 @@ static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_hstateen_1_3(CPURISCVState *env, int csrno,
-                                         target_ulong new_val)
+                                         target_ulong new_val, uintptr_t ra)
 {
     return write_hstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
 }
@@ -3552,7 +3551,7 @@ static RISCVException write_hstateenh(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
-                                       target_ulong new_val)
+                                       target_ulong new_val, uintptr_t ra)
 {
     uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
 
@@ -3564,7 +3563,7 @@ static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_hstateenh_1_3(CPURISCVState *env, int csrno,
-                                          target_ulong new_val)
+                                          target_ulong new_val, uintptr_t ra)
 {
     return write_hstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
 }
@@ -3603,7 +3602,7 @@ static RISCVException write_sstateen(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
-                                      target_ulong new_val)
+                                      target_ulong new_val, uintptr_t ra)
 {
     uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
 
@@ -3615,7 +3614,7 @@ static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_sstateen_1_3(CPURISCVState *env, int csrno,
-                                      target_ulong new_val)
+                                         target_ulong new_val, uintptr_t ra)
 {
     return write_sstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
 }
@@ -3866,7 +3865,7 @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_sstatus(CPURISCVState *env, int csrno,
-                                    target_ulong val)
+                                    target_ulong val, uintptr_t ra)
 {
     target_ulong mask = (sstatus_v1_10_mask);
 
@@ -3883,7 +3882,7 @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno,
         mask |= SSTATUS_SDT;
     }
     target_ulong newval = (env->mstatus & ~mask) | (val & mask);
-    return write_mstatus(env, CSR_MSTATUS, newval);
+    return write_mstatus(env, CSR_MSTATUS, newval, ra);
 }
 
 static RISCVException rmw_vsie64(CPURISCVState *env, int csrno,
@@ -4035,7 +4034,7 @@ static RISCVException read_stvec(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_stvec(CPURISCVState *env, int csrno,
-                                  target_ulong val)
+                                  target_ulong val, uintptr_t ra)
 {
     /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
     if ((val & 3) < 2) {
@@ -4054,7 +4053,7 @@ static RISCVException read_scounteren(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_scounteren(CPURISCVState *env, int csrno,
-                                       target_ulong val)
+                                       target_ulong val, uintptr_t ra)
 {
     RISCVCPU *cpu = env_archcpu(env);
 
@@ -4088,7 +4087,7 @@ static RISCVException read_sscratch(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_sscratch(CPURISCVState *env, int csrno,
-                                     target_ulong val)
+                                     target_ulong val, uintptr_t ra)
 {
     env->sscratch = val;
     return RISCV_EXCP_NONE;
@@ -4102,7 +4101,7 @@ static RISCVException read_sepc(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_sepc(CPURISCVState *env, int csrno,
-                                 target_ulong val)
+                                 target_ulong val, uintptr_t ra)
 {
     env->sepc = val;
     return RISCV_EXCP_NONE;
@@ -4116,7 +4115,7 @@ static RISCVException read_scause(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_scause(CPURISCVState *env, int csrno,
-                                   target_ulong val)
+                                   target_ulong val, uintptr_t ra)
 {
     env->scause = val;
     return RISCV_EXCP_NONE;
@@ -4130,7 +4129,7 @@ static RISCVException read_stval(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_stval(CPURISCVState *env, int csrno,
-                                  target_ulong val)
+                                  target_ulong val, uintptr_t ra)
 {
     env->stval = val;
     return RISCV_EXCP_NONE;
@@ -4270,7 +4269,7 @@ static RISCVException read_satp(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_satp(CPURISCVState *env, int csrno,
-                                 target_ulong val)
+                                 target_ulong val, uintptr_t ra)
 {
     if (!riscv_cpu_cfg(env)->mmu) {
         return RISCV_EXCP_NONE;
@@ -4492,7 +4491,7 @@ static RISCVException read_hstatus(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_hstatus(CPURISCVState *env, int csrno,
-                                    target_ulong val)
+                                    target_ulong val, uintptr_t ra)
 {
     uint64_t mask = (target_ulong)-1;
     if (!env_archcpu(env)->cfg.ext_svukte) {
@@ -4524,7 +4523,7 @@ static RISCVException read_hedeleg(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_hedeleg(CPURISCVState *env, int csrno,
-                                    target_ulong val)
+                                    target_ulong val, uintptr_t ra)
 {
     env->hedeleg = val & vs_delegable_excps;
     return RISCV_EXCP_NONE;
@@ -4545,7 +4544,7 @@ static RISCVException read_hedelegh(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_hedelegh(CPURISCVState *env, int csrno,
-                                    target_ulong val)
+                                     target_ulong val, uintptr_t ra)
 {
     RISCVException ret;
     ret = smstateen_acc_ok(env, 0, SMSTATEEN0_P1P13);
@@ -4808,7 +4807,7 @@ static RISCVException read_hcounteren(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
-                                       target_ulong val)
+                                       target_ulong val, uintptr_t ra)
 {
     RISCVCPU *cpu = env_archcpu(env);
 
@@ -4828,7 +4827,7 @@ static RISCVException read_hgeie(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_hgeie(CPURISCVState *env, int csrno,
-                                  target_ulong val)
+                                  target_ulong val, uintptr_t ra)
 {
     /* Only GEILEN:1 bits implemented and BIT0 is never implemented */
     val &= ((((target_ulong)1) << env->geilen) - 1) << 1;
@@ -4847,7 +4846,7 @@ static RISCVException read_htval(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_htval(CPURISCVState *env, int csrno,
-                                  target_ulong val)
+                                  target_ulong val, uintptr_t ra)
 {
     env->htval = val;
     return RISCV_EXCP_NONE;
@@ -4861,7 +4860,7 @@ static RISCVException read_htinst(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_htinst(CPURISCVState *env, int csrno,
-                                   target_ulong val)
+                                   target_ulong val, uintptr_t ra)
 {
     return RISCV_EXCP_NONE;
 }
@@ -4883,7 +4882,7 @@ static RISCVException read_hgatp(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_hgatp(CPURISCVState *env, int csrno,
-                                  target_ulong val)
+                                  target_ulong val, uintptr_t ra)
 {
     env->hgatp = legalize_xatp(env, env->hgatp, val);
     return RISCV_EXCP_NONE;
@@ -4901,7 +4900,7 @@ static RISCVException read_htimedelta(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
-                                       target_ulong val)
+                                       target_ulong val, uintptr_t ra)
 {
     if (!env->rdtime_fn) {
         return RISCV_EXCP_ILLEGAL_INST;
@@ -4933,7 +4932,7 @@ static RISCVException read_htimedeltah(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
-                                        target_ulong val)
+                                        target_ulong val, uintptr_t ra)
 {
     if (!env->rdtime_fn) {
         return RISCV_EXCP_ILLEGAL_INST;
@@ -4957,7 +4956,7 @@ static RISCVException read_hvictl(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_hvictl(CPURISCVState *env, int csrno,
-                                   target_ulong val)
+                                   target_ulong val, uintptr_t ra)
 {
     env->hvictl = val & HVICTL_VALID_MASK;
     return RISCV_EXCP_NONE;
@@ -5022,7 +5021,7 @@ static RISCVException read_hviprio1(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_hviprio1(CPURISCVState *env, int csrno,
-                                     target_ulong val)
+                                     target_ulong val, uintptr_t ra)
 {
     return write_hvipriox(env, 0, env->hviprio, val);
 }
@@ -5034,7 +5033,7 @@ static RISCVException read_hviprio1h(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_hviprio1h(CPURISCVState *env, int csrno,
-                                      target_ulong val)
+                                      target_ulong val, uintptr_t ra)
 {
     return write_hvipriox(env, 4, env->hviprio, val);
 }
@@ -5046,7 +5045,7 @@ static RISCVException read_hviprio2(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_hviprio2(CPURISCVState *env, int csrno,
-                                     target_ulong val)
+                                     target_ulong val, uintptr_t ra)
 {
     return write_hvipriox(env, 8, env->hviprio, val);
 }
@@ -5058,7 +5057,7 @@ static RISCVException read_hviprio2h(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_hviprio2h(CPURISCVState *env, int csrno,
-                                      target_ulong val)
+                                      target_ulong val, uintptr_t ra)
 {
     return write_hvipriox(env, 12, env->hviprio, val);
 }
@@ -5072,7 +5071,7 @@ static RISCVException read_vsstatus(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
-                                     target_ulong val)
+                                     target_ulong val, uintptr_t ra)
 {
     uint64_t mask = (target_ulong)-1;
     if ((val & VSSTATUS64_UXL) == 0) {
@@ -5097,7 +5096,7 @@ static RISCVException read_vstvec(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_vstvec(CPURISCVState *env, int csrno,
-                                   target_ulong val)
+                                   target_ulong val, uintptr_t ra)
 {
     /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
     if ((val & 3) < 2) {
@@ -5116,7 +5115,7 @@ static RISCVException read_vsscratch(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_vsscratch(CPURISCVState *env, int csrno,
-                                      target_ulong val)
+                                      target_ulong val, uintptr_t ra)
 {
     env->vsscratch = val;
     return RISCV_EXCP_NONE;
@@ -5130,7 +5129,7 @@ static RISCVException read_vsepc(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_vsepc(CPURISCVState *env, int csrno,
-                                  target_ulong val)
+                                  target_ulong val, uintptr_t ra)
 {
     env->vsepc = val;
     return RISCV_EXCP_NONE;
@@ -5144,7 +5143,7 @@ static RISCVException read_vscause(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_vscause(CPURISCVState *env, int csrno,
-                                    target_ulong val)
+                                    target_ulong val, uintptr_t ra)
 {
     env->vscause = val;
     return RISCV_EXCP_NONE;
@@ -5158,7 +5157,7 @@ static RISCVException read_vstval(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_vstval(CPURISCVState *env, int csrno,
-                                   target_ulong val)
+                                   target_ulong val, uintptr_t ra)
 {
     env->vstval = val;
     return RISCV_EXCP_NONE;
@@ -5172,7 +5171,7 @@ static RISCVException read_vsatp(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_vsatp(CPURISCVState *env, int csrno,
-                                  target_ulong val)
+                                  target_ulong val, uintptr_t ra)
 {
     env->vsatp = legalize_xatp(env, env->vsatp, val);
     return RISCV_EXCP_NONE;
@@ -5186,7 +5185,7 @@ static RISCVException read_mtval2(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mtval2(CPURISCVState *env, int csrno,
-                                   target_ulong val)
+                                   target_ulong val, uintptr_t ra)
 {
     env->mtval2 = val;
     return RISCV_EXCP_NONE;
@@ -5200,7 +5199,7 @@ static RISCVException read_mtinst(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mtinst(CPURISCVState *env, int csrno,
-                                   target_ulong val)
+                                   target_ulong val, uintptr_t ra)
 {
     env->mtinst = val;
     return RISCV_EXCP_NONE;
@@ -5215,7 +5214,7 @@ static RISCVException read_mseccfg(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
-                                    target_ulong val)
+                                    target_ulong val, uintptr_t ra)
 {
     mseccfg_csr_write(env, val);
     return RISCV_EXCP_NONE;
@@ -5231,7 +5230,7 @@ static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
-                                   target_ulong val)
+                                   target_ulong val, uintptr_t ra)
 {
     uint32_t reg_index = csrno - CSR_PMPCFG0;
 
@@ -5247,7 +5246,7 @@ static RISCVException read_pmpaddr(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
-                                    target_ulong val)
+                                    target_ulong val, uintptr_t ra)
 {
     pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val);
     return RISCV_EXCP_NONE;
@@ -5261,7 +5260,7 @@ static RISCVException read_tselect(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_tselect(CPURISCVState *env, int csrno,
-                                    target_ulong val)
+                                    target_ulong val, uintptr_t ra)
 {
     tselect_csr_write(env, val);
     return RISCV_EXCP_NONE;
@@ -5285,7 +5284,7 @@ static RISCVException read_tdata(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_tdata(CPURISCVState *env, int csrno,
-                                  target_ulong val)
+                                  target_ulong val, uintptr_t ra)
 {
     if (!tdata_available(env, csrno - CSR_TDATA1)) {
         return RISCV_EXCP_ILLEGAL_INST;
@@ -5310,7 +5309,7 @@ static RISCVException read_mcontext(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_mcontext(CPURISCVState *env, int csrno,
-                                     target_ulong val)
+                                     target_ulong val, uintptr_t ra)
 {
     bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
     int32_t mask;
@@ -5334,43 +5333,50 @@ static RISCVException read_mnscratch(CPURISCVState *env, int csrno,
     return RISCV_EXCP_NONE;
 }
 
-static int write_mnscratch(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mnscratch(CPURISCVState *env, int csrno,
+                                      target_ulong val, uintptr_t ra)
 {
     env->mnscratch = val;
     return RISCV_EXCP_NONE;
 }
 
-static int read_mnepc(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mnepc(CPURISCVState *env, int csrno,
+                                 target_ulong *val)
 {
     *val = env->mnepc;
     return RISCV_EXCP_NONE;
 }
 
-static int write_mnepc(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mnepc(CPURISCVState *env, int csrno,
+                                  target_ulong val, uintptr_t ra)
 {
     env->mnepc = val;
     return RISCV_EXCP_NONE;
 }
 
-static int read_mncause(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mncause(CPURISCVState *env, int csrno,
+                                   target_ulong *val)
 {
     *val = env->mncause;
     return RISCV_EXCP_NONE;
 }
 
-static int write_mncause(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mncause(CPURISCVState *env, int csrno,
+                                    target_ulong val, uintptr_t ra)
 {
     env->mncause = val;
     return RISCV_EXCP_NONE;
 }
 
-static int read_mnstatus(CPURISCVState *env, int csrno, target_ulong *val)
+static RISCVException read_mnstatus(CPURISCVState *env, int csrno,
+                                    target_ulong *val)
 {
     *val = env->mnstatus;
     return RISCV_EXCP_NONE;
 }
 
-static int write_mnstatus(CPURISCVState *env, int csrno, target_ulong val)
+static RISCVException write_mnstatus(CPURISCVState *env, int csrno,
+                                     target_ulong val, uintptr_t ra)
 {
     target_ulong mask = (MNSTATUS_NMIE | MNSTATUS_MNPP);
 
@@ -5540,7 +5546,7 @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
     if (write_mask) {
         new_value = (old_value & ~write_mask) | (new_value & write_mask);
         if (csr_ops[csrno].write) {
-            ret = csr_ops[csrno].write(env, csrno, new_value);
+            ret = csr_ops[csrno].write(env, csrno, new_value, 0);
             if (ret != RISCV_EXCP_NONE) {
                 return ret;
             }
@@ -5603,7 +5609,7 @@ static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
             }
         } else if (csr_ops[csrno].write) {
             /* avoids having to write wrappers for all registers */
-            ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value));
+            ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value), 0);
             if (ret != RISCV_EXCP_NONE) {
                 return ret;
             }
@@ -5714,7 +5720,7 @@ static RISCVException read_jvt(CPURISCVState *env, int csrno,
 }
 
 static RISCVException write_jvt(CPURISCVState *env, int csrno,
-                                target_ulong val)
+                                target_ulong val, uintptr_t ra)
 {
     env->jvt = val;
     return RISCV_EXCP_NONE;
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 2/7] target/riscv: Pass ra to riscv_csrrw_do64
  2025-04-25 15:23 [PATCH 0/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
  2025-04-25 15:23 ` [PATCH 1/7] target/riscv: Pass ra to riscv_csr_write_fn Richard Henderson
@ 2025-04-25 15:23 ` Richard Henderson
  2025-04-25 22:29   ` Philippe Mathieu-Daudé
  2025-04-28 22:34   ` Alistair Francis
  2025-04-25 15:23 ` [PATCH 3/7] target/riscv: Pass ra to riscv_csrrw_do128 Richard Henderson
                   ` (6 subsequent siblings)
  8 siblings, 2 replies; 28+ messages in thread
From: Richard Henderson @ 2025-04-25 15:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/csr.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 6f1f69eba6..e9c2f95b6e 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -5516,7 +5516,8 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
 static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
                                        target_ulong *ret_value,
                                        target_ulong new_value,
-                                       target_ulong write_mask)
+                                       target_ulong write_mask,
+                                       uintptr_t ra)
 {
     RISCVException ret;
     target_ulong old_value = 0;
@@ -5546,7 +5547,7 @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
     if (write_mask) {
         new_value = (old_value & ~write_mask) | (new_value & write_mask);
         if (csr_ops[csrno].write) {
-            ret = csr_ops[csrno].write(env, csrno, new_value, 0);
+            ret = csr_ops[csrno].write(env, csrno, new_value, ra);
             if (ret != RISCV_EXCP_NONE) {
                 return ret;
             }
@@ -5569,7 +5570,7 @@ RISCVException riscv_csrr(CPURISCVState *env, int csrno,
         return ret;
     }
 
-    return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
+    return riscv_csrrw_do64(env, csrno, ret_value, 0, 0, 0);
 }
 
 RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
@@ -5581,7 +5582,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
         return ret;
     }
 
-    return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask);
+    return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask, 0);
 }
 
 static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
@@ -5647,9 +5648,7 @@ RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
      * accesses
      */
     target_ulong old_value;
-    ret = riscv_csrrw_do64(env, csrno, &old_value,
-                           (target_ulong)0,
-                           (target_ulong)0);
+    ret = riscv_csrrw_do64(env, csrno, &old_value, 0, 0, 0);
     if (ret == RISCV_EXCP_NONE && ret_value) {
         *ret_value = int128_make64(old_value);
     }
@@ -5681,7 +5680,7 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
     target_ulong old_value;
     ret = riscv_csrrw_do64(env, csrno, &old_value,
                            int128_getlo(new_value),
-                           int128_getlo(write_mask));
+                           int128_getlo(write_mask), 0);
     if (ret == RISCV_EXCP_NONE && ret_value) {
         *ret_value = int128_make64(old_value);
     }
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 3/7] target/riscv: Pass ra to riscv_csrrw_do128
  2025-04-25 15:23 [PATCH 0/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
  2025-04-25 15:23 ` [PATCH 1/7] target/riscv: Pass ra to riscv_csr_write_fn Richard Henderson
  2025-04-25 15:23 ` [PATCH 2/7] target/riscv: Pass ra to riscv_csrrw_do64 Richard Henderson
@ 2025-04-25 15:23 ` Richard Henderson
  2025-04-25 22:29   ` Philippe Mathieu-Daudé
  2025-04-28 22:34   ` Alistair Francis
  2025-04-25 15:23 ` [PATCH 4/7] target/riscv: Pass ra to riscv_csrrw Richard Henderson
                   ` (5 subsequent siblings)
  8 siblings, 2 replies; 28+ messages in thread
From: Richard Henderson @ 2025-04-25 15:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/csr.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index e9c2f95b6e..d62d1aaaee 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -5588,7 +5588,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
 static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
                                         Int128 *ret_value,
                                         Int128 new_value,
-                                        Int128 write_mask)
+                                        Int128 write_mask, uintptr_t ra)
 {
     RISCVException ret;
     Int128 old_value;
@@ -5610,7 +5610,7 @@ static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
             }
         } else if (csr_ops[csrno].write) {
             /* avoids having to write wrappers for all registers */
-            ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value), 0);
+            ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value), ra);
             if (ret != RISCV_EXCP_NONE) {
                 return ret;
             }
@@ -5637,7 +5637,7 @@ RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
 
     if (csr_ops[csrno].read128) {
         return riscv_csrrw_do128(env, csrno, ret_value,
-                                 int128_zero(), int128_zero());
+                                 int128_zero(), int128_zero(), 0);
     }
 
     /*
@@ -5667,7 +5667,8 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
     }
 
     if (csr_ops[csrno].read128) {
-        return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask);
+        return riscv_csrrw_do128(env, csrno, ret_value,
+                                 new_value, write_mask, 0);
     }
 
     /*
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 4/7] target/riscv: Pass ra to riscv_csrrw
  2025-04-25 15:23 [PATCH 0/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
                   ` (2 preceding siblings ...)
  2025-04-25 15:23 ` [PATCH 3/7] target/riscv: Pass ra to riscv_csrrw_do128 Richard Henderson
@ 2025-04-25 15:23 ` Richard Henderson
  2025-04-25 22:31   ` Philippe Mathieu-Daudé
  2025-04-28 22:36   ` Alistair Francis
  2025-04-25 15:23 ` [PATCH 5/7] target/riscv: Pass ra to riscv_csrrw_i128 Richard Henderson
                   ` (4 subsequent siblings)
  8 siblings, 2 replies; 28+ messages in thread
From: Richard Henderson @ 2025-04-25 15:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/cpu.h       | 8 ++++----
 hw/riscv/riscv_hart.c    | 2 +-
 target/riscv/csr.c       | 8 ++++----
 target/riscv/op_helper.c | 4 ++--
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4d41a66d72..2c0524d0be 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -816,8 +816,8 @@ RISCVException riscv_csrr(CPURISCVState *env, int csrno,
                           target_ulong *ret_value);
 
 RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
-                           target_ulong *ret_value,
-                           target_ulong new_value, target_ulong write_mask);
+                           target_ulong *ret_value, target_ulong new_value,
+                           target_ulong write_mask, uintptr_t ra);
 RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
                                  target_ulong *ret_value,
                                  target_ulong new_value,
@@ -826,13 +826,13 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
 static inline void riscv_csr_write(CPURISCVState *env, int csrno,
                                    target_ulong val)
 {
-    riscv_csrrw(env, csrno, NULL, val, MAKE_64BIT_MASK(0, TARGET_LONG_BITS));
+    riscv_csrrw(env, csrno, NULL, val, MAKE_64BIT_MASK(0, TARGET_LONG_BITS), 0);
 }
 
 static inline target_ulong riscv_csr_read(CPURISCVState *env, int csrno)
 {
     target_ulong val = 0;
-    riscv_csrrw(env, csrno, &val, 0, 0);
+    riscv_csrrw(env, csrno, &val, 0, 0, 0);
     return val;
 }
 
diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index a55d156668..2ebbf41b18 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -72,7 +72,7 @@ static void csr_call(char *cmd, uint64_t cpu_num, int csrno, uint64_t *val)
         ret = riscv_csrr(env, csrno, (target_ulong *)val);
     } else if (strcmp(cmd, "set_csr") == 0) {
         ret = riscv_csrrw(env, csrno, NULL, *(target_ulong *)val,
-                MAKE_64BIT_MASK(0, TARGET_LONG_BITS));
+                          MAKE_64BIT_MASK(0, TARGET_LONG_BITS), 0);
     }
 
     g_assert(ret == RISCV_EXCP_NONE);
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d62d1aaaee..097640e25d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -5574,15 +5574,15 @@ RISCVException riscv_csrr(CPURISCVState *env, int csrno,
 }
 
 RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
-                           target_ulong *ret_value,
-                           target_ulong new_value, target_ulong write_mask)
+                           target_ulong *ret_value, target_ulong new_value,
+                           target_ulong write_mask, uintptr_t ra)
 {
     RISCVException ret = riscv_csrrw_check(env, csrno, true);
     if (ret != RISCV_EXCP_NONE) {
         return ret;
     }
 
-    return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask, 0);
+    return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask, ra);
 }
 
 static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
@@ -5704,7 +5704,7 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
     if (!write_mask) {
         ret = riscv_csrr(env, csrno, ret_value);
     } else {
-        ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
+        ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask, 0);
     }
 #if !defined(CONFIG_USER_ONLY)
     env->debugger = false;
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 5b0db2c45a..aee16e2e3a 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -71,7 +71,7 @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
 void helper_csrw(CPURISCVState *env, int csr, target_ulong src)
 {
     target_ulong mask = env->xl == MXL_RV32 ? UINT32_MAX : (target_ulong)-1;
-    RISCVException ret = riscv_csrrw(env, csr, NULL, src, mask);
+    RISCVException ret = riscv_csrrw(env, csr, NULL, src, mask, GETPC());
 
     if (ret != RISCV_EXCP_NONE) {
         riscv_raise_exception(env, ret, GETPC());
@@ -82,7 +82,7 @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
                           target_ulong src, target_ulong write_mask)
 {
     target_ulong val = 0;
-    RISCVException ret = riscv_csrrw(env, csr, &val, src, write_mask);
+    RISCVException ret = riscv_csrrw(env, csr, &val, src, write_mask, GETPC());
 
     if (ret != RISCV_EXCP_NONE) {
         riscv_raise_exception(env, ret, GETPC());
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 5/7] target/riscv: Pass ra to riscv_csrrw_i128
  2025-04-25 15:23 [PATCH 0/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
                   ` (3 preceding siblings ...)
  2025-04-25 15:23 ` [PATCH 4/7] target/riscv: Pass ra to riscv_csrrw Richard Henderson
@ 2025-04-25 15:23 ` Richard Henderson
  2025-04-25 22:32   ` Philippe Mathieu-Daudé
  2025-04-28 22:37   ` Alistair Francis
  2025-04-25 15:23 ` [PATCH 6/7] target/riscv: Move insn_len to internals.h Richard Henderson
                   ` (3 subsequent siblings)
  8 siblings, 2 replies; 28+ messages in thread
From: Richard Henderson @ 2025-04-25 15:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/cpu.h       | 4 ++--
 target/riscv/csr.c       | 8 ++++----
 target/riscv/op_helper.c | 9 +++++----
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 2c0524d0be..8b84793b15 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -851,8 +851,8 @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
 RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
                                Int128 *ret_value);
 RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
-                                Int128 *ret_value,
-                                Int128 new_value, Int128 write_mask);
+                                Int128 *ret_value, Int128 new_value,
+                                Int128 write_mask, uintptr_t ra);
 
 typedef RISCVException (*riscv_csr_read128_fn)(CPURISCVState *env, int csrno,
                                                Int128 *ret_value);
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 097640e25d..a663f527a4 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -5656,8 +5656,8 @@ RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
 }
 
 RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
-                                Int128 *ret_value,
-                                Int128 new_value, Int128 write_mask)
+                                Int128 *ret_value, Int128 new_value,
+                                Int128 write_mask, uintptr_t ra)
 {
     RISCVException ret;
 
@@ -5668,7 +5668,7 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
 
     if (csr_ops[csrno].read128) {
         return riscv_csrrw_do128(env, csrno, ret_value,
-                                 new_value, write_mask, 0);
+                                 new_value, write_mask, ra);
     }
 
     /*
@@ -5681,7 +5681,7 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
     target_ulong old_value;
     ret = riscv_csrrw_do64(env, csrno, &old_value,
                            int128_getlo(new_value),
-                           int128_getlo(write_mask), 0);
+                           int128_getlo(write_mask), ra);
     if (ret == RISCV_EXCP_NONE && ret_value) {
         *ret_value = int128_make64(old_value);
     }
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index aee16e2e3a..e3770a2655 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -108,7 +108,7 @@ void helper_csrw_i128(CPURISCVState *env, int csr,
 {
     RISCVException ret = riscv_csrrw_i128(env, csr, NULL,
                                           int128_make128(srcl, srch),
-                                          UINT128_MAX);
+                                          UINT128_MAX, GETPC());
 
     if (ret != RISCV_EXCP_NONE) {
         riscv_raise_exception(env, ret, GETPC());
@@ -116,13 +116,14 @@ void helper_csrw_i128(CPURISCVState *env, int csr,
 }
 
 target_ulong helper_csrrw_i128(CPURISCVState *env, int csr,
-                       target_ulong srcl, target_ulong srch,
-                       target_ulong maskl, target_ulong maskh)
+                               target_ulong srcl, target_ulong srch,
+                               target_ulong maskl, target_ulong maskh)
 {
     Int128 rv = int128_zero();
     RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
                                           int128_make128(srcl, srch),
-                                          int128_make128(maskl, maskh));
+                                          int128_make128(maskl, maskh),
+                                          GETPC());
 
     if (ret != RISCV_EXCP_NONE) {
         riscv_raise_exception(env, ret, GETPC());
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 6/7] target/riscv: Move insn_len to internals.h
  2025-04-25 15:23 [PATCH 0/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
                   ` (4 preceding siblings ...)
  2025-04-25 15:23 ` [PATCH 5/7] target/riscv: Pass ra to riscv_csrrw_i128 Richard Henderson
@ 2025-04-25 15:23 ` Richard Henderson
  2025-04-25 22:33   ` Philippe Mathieu-Daudé
  2025-04-28 22:37   ` Alistair Francis
  2025-04-25 15:23 ` [PATCH 7/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
                   ` (2 subsequent siblings)
  8 siblings, 2 replies; 28+ messages in thread
From: Richard Henderson @ 2025-04-25 15:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/internals.h | 5 +++++
 target/riscv/translate.c | 5 -----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 213aff31d8..4570bd50be 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -201,4 +201,9 @@ static inline target_ulong adjust_addr_virt(CPURISCVState *env,
     return adjust_addr_body(env, addr, true);
 }
 
+static inline int insn_len(uint16_t first_word)
+{
+    return (first_word & 3) == 3 ? 4 : 2;
+}
+
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index cef61b5b29..9836ab8c20 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1210,11 +1210,6 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
 /* The specification allows for longer insns, but not supported by qemu. */
 #define MAX_INSN_LEN  4
 
-static inline int insn_len(uint16_t first_word)
-{
-    return (first_word & 3) == 3 ? 4 : 2;
-}
-
 const RISCVDecoder decoder_table[] = {
     { always_true_p, decode_insn32 },
     { has_xthead_p, decode_xthead},
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 7/7] target/riscv: Fix write_misa vs aligned next_pc
  2025-04-25 15:23 [PATCH 0/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
                   ` (5 preceding siblings ...)
  2025-04-25 15:23 ` [PATCH 6/7] target/riscv: Move insn_len to internals.h Richard Henderson
@ 2025-04-25 15:23 ` Richard Henderson
  2025-04-25 22:33   ` Philippe Mathieu-Daudé
                     ` (3 more replies)
  2025-04-26  8:25 ` [PATCH 0/7] " Daniel Henrique Barboza
  2025-04-28 22:46 ` Alistair Francis
  8 siblings, 4 replies; 28+ messages in thread
From: Richard Henderson @ 2025-04-25 15:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza

Do not examine a random host return address, but
properly compute the next pc for the guest cpu.

Fixes: f18637cd611 ("RISC-V: Add misa runtime write support")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/csr.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index a663f527a4..85f9b4c3d2 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -30,6 +30,8 @@
 #include "exec/icount.h"
 #include "qemu/guest-random.h"
 #include "qapi/error.h"
+#include "tcg/insn-start-words.h"
+#include "internals.h"
 #include <stdbool.h>
 
 /* CSR function table public API */
@@ -2099,6 +2101,19 @@ static RISCVException read_misa(CPURISCVState *env, int csrno,
     return RISCV_EXCP_NONE;
 }
 
+static target_ulong get_next_pc(CPURISCVState *env, uintptr_t ra)
+{
+    uint64_t data[TARGET_INSN_START_WORDS];
+
+    /* Outside of a running cpu, env contains the next pc. */
+    if (ra == 0 || !cpu_unwind_state_data(env_cpu(env), ra, data)) {
+        return env->pc;
+    }
+
+    /* Within unwind data, [0] is pc and [1] is the opcode. */
+    return data[0] + insn_len(data[1]);
+}
+
 static RISCVException write_misa(CPURISCVState *env, int csrno,
                                  target_ulong val, uintptr_t ra)
 {
@@ -2114,11 +2129,8 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
     /* Mask extensions that are not supported by this hart */
     val &= env->misa_ext_mask;
 
-    /*
-     * Suppress 'C' if next instruction is not aligned
-     * TODO: this should check next_pc
-     */
-    if ((val & RVC) && (GETPC() & ~3) != 0) {
+    /* Suppress 'C' if next instruction is not aligned. */
+    if ((val & RVC) && (get_next_pc(env, ra) & ~3) != 0) {
         val &= ~RVC;
     }
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/7] target/riscv: Pass ra to riscv_csr_write_fn
  2025-04-25 15:23 ` [PATCH 1/7] target/riscv: Pass ra to riscv_csr_write_fn Richard Henderson
@ 2025-04-25 22:28   ` Philippe Mathieu-Daudé
  2025-04-28 22:33   ` Alistair Francis
  1 sibling, 0 replies; 28+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-04-25 22:28 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza

On 25/4/25 17:23, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/riscv/cpu.h |   3 +-
>   target/riscv/csr.c | 226 +++++++++++++++++++++++----------------------
>   2 files changed, 118 insertions(+), 111 deletions(-)
> 
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 167909c89b..4d41a66d72 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -841,7 +841,8 @@ typedef RISCVException (*riscv_csr_predicate_fn)(CPURISCVState *env,
>   typedef RISCVException (*riscv_csr_read_fn)(CPURISCVState *env, int csrno,
>                                               target_ulong *ret_value);
>   typedef RISCVException (*riscv_csr_write_fn)(CPURISCVState *env, int csrno,
> -                                             target_ulong new_value);
> +                                             target_ulong new_value,
> +                                             uintptr_t ra);
>   typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
>                                             target_ulong *ret_value,
>                                             target_ulong new_value,
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index c52c87faae..6f1f69eba6 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -830,13 +830,15 @@ static RISCVException seed(CPURISCVState *env, int csrno)
>   }
>   
>   /* zicfiss CSR_SSP read and write */
> -static int read_ssp(CPURISCVState *env, int csrno, target_ulong *val)
> +static RISCVException read_ssp(CPURISCVState *env, int csrno,
> +                               target_ulong *val)
>   {
>       *val = env->ssp;
>       return RISCV_EXCP_NONE;
>   }
>   
> -static int write_ssp(CPURISCVState *env, int csrno, target_ulong val)
> +static RISCVException write_ssp(CPURISCVState *env, int csrno,
> +                                target_ulong val, uintptr_t ra)

I like the RISCVException type correction.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/7] target/riscv: Pass ra to riscv_csrrw_do64
  2025-04-25 15:23 ` [PATCH 2/7] target/riscv: Pass ra to riscv_csrrw_do64 Richard Henderson
@ 2025-04-25 22:29   ` Philippe Mathieu-Daudé
  2025-04-28 22:34   ` Alistair Francis
  1 sibling, 0 replies; 28+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-04-25 22:29 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza

On 25/4/25 17:23, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/riscv/csr.c | 15 +++++++--------
>   1 file changed, 7 insertions(+), 8 deletions(-)


> @@ -5647,9 +5648,7 @@ RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
>        * accesses
>        */
>       target_ulong old_value;
> -    ret = riscv_csrrw_do64(env, csrno, &old_value,
> -                           (target_ulong)0,
> -                           (target_ulong)0);
> +    ret = riscv_csrrw_do64(env, csrno, &old_value, 0, 0, 0);

:)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 3/7] target/riscv: Pass ra to riscv_csrrw_do128
  2025-04-25 15:23 ` [PATCH 3/7] target/riscv: Pass ra to riscv_csrrw_do128 Richard Henderson
@ 2025-04-25 22:29   ` Philippe Mathieu-Daudé
  2025-04-28 22:34   ` Alistair Francis
  1 sibling, 0 replies; 28+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-04-25 22:29 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza

On 25/4/25 17:23, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/riscv/csr.c | 9 +++++----
>   1 file changed, 5 insertions(+), 4 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 4/7] target/riscv: Pass ra to riscv_csrrw
  2025-04-25 15:23 ` [PATCH 4/7] target/riscv: Pass ra to riscv_csrrw Richard Henderson
@ 2025-04-25 22:31   ` Philippe Mathieu-Daudé
  2025-04-28 22:36   ` Alistair Francis
  1 sibling, 0 replies; 28+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-04-25 22:31 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza

On 25/4/25 17:23, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/riscv/cpu.h       | 8 ++++----
>   hw/riscv/riscv_hart.c    | 2 +-
>   target/riscv/csr.c       | 8 ++++----
>   target/riscv/op_helper.c | 4 ++--
>   4 files changed, 11 insertions(+), 11 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 5/7] target/riscv: Pass ra to riscv_csrrw_i128
  2025-04-25 15:23 ` [PATCH 5/7] target/riscv: Pass ra to riscv_csrrw_i128 Richard Henderson
@ 2025-04-25 22:32   ` Philippe Mathieu-Daudé
  2025-04-28 22:37   ` Alistair Francis
  1 sibling, 0 replies; 28+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-04-25 22:32 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza

On 25/4/25 17:23, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/riscv/cpu.h       | 4 ++--
>   target/riscv/csr.c       | 8 ++++----
>   target/riscv/op_helper.c | 9 +++++----
>   3 files changed, 11 insertions(+), 10 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 6/7] target/riscv: Move insn_len to internals.h
  2025-04-25 15:23 ` [PATCH 6/7] target/riscv: Move insn_len to internals.h Richard Henderson
@ 2025-04-25 22:33   ` Philippe Mathieu-Daudé
  2025-04-28 22:37   ` Alistair Francis
  1 sibling, 0 replies; 28+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-04-25 22:33 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza

On 25/4/25 17:23, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/riscv/internals.h | 5 +++++
>   target/riscv/translate.c | 5 -----
>   2 files changed, 5 insertions(+), 5 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 7/7] target/riscv: Fix write_misa vs aligned next_pc
  2025-04-25 15:23 ` [PATCH 7/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
@ 2025-04-25 22:33   ` Philippe Mathieu-Daudé
  2025-04-28 22:39   ` Alistair Francis
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 28+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-04-25 22:33 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza

On 25/4/25 17:23, Richard Henderson wrote:
> Do not examine a random host return address, but
> properly compute the next pc for the guest cpu.
> 
> Fixes: f18637cd611 ("RISC-V: Add misa runtime write support")
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/riscv/csr.c | 22 +++++++++++++++++-----
>   1 file changed, 17 insertions(+), 5 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 0/7] target/riscv: Fix write_misa vs aligned next_pc
  2025-04-25 15:23 [PATCH 0/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
                   ` (6 preceding siblings ...)
  2025-04-25 15:23 ` [PATCH 7/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
@ 2025-04-26  8:25 ` Daniel Henrique Barboza
  2025-04-28 22:46 ` Alistair Francis
  8 siblings, 0 replies; 28+ messages in thread
From: Daniel Henrique Barboza @ 2025-04-26  8:25 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis



On 4/25/25 12:23 PM, Richard Henderson wrote:
> As discussed, the use of GETPC() within write_misa is wrong.
> I've done just enough plumbing to get the helper return address
> piped down to write_misa, so that we can make use of unwind data.
> 
> AFAIK, nothing in check-tcg or check-functional would test this.
> It shouldn't be too hard to write a test akin to issue1060.S,
> but I'm going to leave that to someone else.

All patches:

Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>

> 
> 
> r~
> 
> 
> Richard Henderson (7):
>    target/riscv: Pass ra to riscv_csr_write_fn
>    target/riscv: Pass ra to riscv_csrrw_do64
>    target/riscv: Pass ra to riscv_csrrw_do128
>    target/riscv: Pass ra to riscv_csrrw
>    target/riscv: Pass ra to riscv_csrrw_i128
>    target/riscv: Move insn_len to internals.h
>    target/riscv: Fix write_misa vs aligned next_pc
> 
>   target/riscv/cpu.h       |  15 ++-
>   target/riscv/internals.h |   5 +
>   hw/riscv/riscv_hart.c    |   2 +-
>   target/riscv/csr.c       | 278 +++++++++++++++++++++------------------
>   target/riscv/op_helper.c |  13 +-
>   target/riscv/translate.c |   5 -
>   6 files changed, 169 insertions(+), 149 deletions(-)
> 



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/7] target/riscv: Pass ra to riscv_csr_write_fn
  2025-04-25 15:23 ` [PATCH 1/7] target/riscv: Pass ra to riscv_csr_write_fn Richard Henderson
  2025-04-25 22:28   ` Philippe Mathieu-Daudé
@ 2025-04-28 22:33   ` Alistair Francis
  1 sibling, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2025-04-28 22:33 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, qemu-riscv, alistair.francis, dbarboza

On Sat, Apr 26, 2025 at 1:24 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.h |   3 +-
>  target/riscv/csr.c | 226 +++++++++++++++++++++++----------------------
>  2 files changed, 118 insertions(+), 111 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 167909c89b..4d41a66d72 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -841,7 +841,8 @@ typedef RISCVException (*riscv_csr_predicate_fn)(CPURISCVState *env,
>  typedef RISCVException (*riscv_csr_read_fn)(CPURISCVState *env, int csrno,
>                                              target_ulong *ret_value);
>  typedef RISCVException (*riscv_csr_write_fn)(CPURISCVState *env, int csrno,
> -                                             target_ulong new_value);
> +                                             target_ulong new_value,
> +                                             uintptr_t ra);
>  typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
>                                            target_ulong *ret_value,
>                                            target_ulong new_value,
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index c52c87faae..6f1f69eba6 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -830,13 +830,15 @@ static RISCVException seed(CPURISCVState *env, int csrno)
>  }
>
>  /* zicfiss CSR_SSP read and write */
> -static int read_ssp(CPURISCVState *env, int csrno, target_ulong *val)
> +static RISCVException read_ssp(CPURISCVState *env, int csrno,
> +                               target_ulong *val)
>  {
>      *val = env->ssp;
>      return RISCV_EXCP_NONE;
>  }
>
> -static int write_ssp(CPURISCVState *env, int csrno, target_ulong val)
> +static RISCVException write_ssp(CPURISCVState *env, int csrno,
> +                                target_ulong val, uintptr_t ra)
>  {
>      env->ssp = val;
>      return RISCV_EXCP_NONE;
> @@ -851,7 +853,7 @@ static RISCVException read_fflags(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_fflags(CPURISCVState *env, int csrno,
> -                                   target_ulong val)
> +                                   target_ulong val, uintptr_t ra)
>  {
>  #if !defined(CONFIG_USER_ONLY)
>      if (riscv_has_ext(env, RVF)) {
> @@ -870,7 +872,7 @@ static RISCVException read_frm(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_frm(CPURISCVState *env, int csrno,
> -                                target_ulong val)
> +                                target_ulong val, uintptr_t ra)
>  {
>  #if !defined(CONFIG_USER_ONLY)
>      if (riscv_has_ext(env, RVF)) {
> @@ -890,7 +892,7 @@ static RISCVException read_fcsr(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_fcsr(CPURISCVState *env, int csrno,
> -                                 target_ulong val)
> +                                 target_ulong val, uintptr_t ra)
>  {
>  #if !defined(CONFIG_USER_ONLY)
>      if (riscv_has_ext(env, RVF)) {
> @@ -942,7 +944,7 @@ static RISCVException read_vxrm(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_vxrm(CPURISCVState *env, int csrno,
> -                                 target_ulong val)
> +                                 target_ulong val, uintptr_t ra)
>  {
>  #if !defined(CONFIG_USER_ONLY)
>      env->mstatus |= MSTATUS_VS;
> @@ -959,7 +961,7 @@ static RISCVException read_vxsat(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_vxsat(CPURISCVState *env, int csrno,
> -                                  target_ulong val)
> +                                  target_ulong val, uintptr_t ra)
>  {
>  #if !defined(CONFIG_USER_ONLY)
>      env->mstatus |= MSTATUS_VS;
> @@ -976,7 +978,7 @@ static RISCVException read_vstart(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_vstart(CPURISCVState *env, int csrno,
> -                                   target_ulong val)
> +                                   target_ulong val, uintptr_t ra)
>  {
>  #if !defined(CONFIG_USER_ONLY)
>      env->mstatus |= MSTATUS_VS;
> @@ -997,7 +999,7 @@ static RISCVException read_vcsr(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_vcsr(CPURISCVState *env, int csrno,
> -                                 target_ulong val)
> +                                 target_ulong val, uintptr_t ra)
>  {
>  #if !defined(CONFIG_USER_ONLY)
>      env->mstatus |= MSTATUS_VS;
> @@ -1055,7 +1057,7 @@ static RISCVException read_mcyclecfg(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mcyclecfg(CPURISCVState *env, int csrno,
> -                                      target_ulong val)
> +                                      target_ulong val, uintptr_t ra)
>  {
>      uint64_t inh_avail_mask;
>
> @@ -1084,7 +1086,7 @@ static RISCVException read_mcyclecfgh(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mcyclecfgh(CPURISCVState *env, int csrno,
> -                                       target_ulong val)
> +                                       target_ulong val, uintptr_t ra)
>  {
>      target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
>                                                   MCYCLECFGH_BIT_MINH);
> @@ -1109,7 +1111,7 @@ static RISCVException read_minstretcfg(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_minstretcfg(CPURISCVState *env, int csrno,
> -                                        target_ulong val)
> +                                        target_ulong val, uintptr_t ra)
>  {
>      uint64_t inh_avail_mask;
>
> @@ -1136,7 +1138,7 @@ static RISCVException read_minstretcfgh(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_minstretcfgh(CPURISCVState *env, int csrno,
> -                                         target_ulong val)
> +                                         target_ulong val, uintptr_t ra)
>  {
>      target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
>                                                   MINSTRETCFGH_BIT_MINH);
> @@ -1163,7 +1165,7 @@ static RISCVException read_mhpmevent(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mhpmevent(CPURISCVState *env, int csrno,
> -                                      target_ulong val)
> +                                      target_ulong val, uintptr_t ra)
>  {
>      int evt_index = csrno - CSR_MCOUNTINHIBIT;
>      uint64_t mhpmevt_val = val;
> @@ -1201,7 +1203,7 @@ static RISCVException read_mhpmeventh(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mhpmeventh(CPURISCVState *env, int csrno,
> -                                       target_ulong val)
> +                                       target_ulong val, uintptr_t ra)
>  {
>      int evt_index = csrno - CSR_MHPMEVENT3H + 3;
>      uint64_t mhpmevth_val;
> @@ -1343,14 +1345,16 @@ static RISCVException riscv_pmu_write_ctrh(CPURISCVState *env, target_ulong val,
>      return RISCV_EXCP_NONE;
>  }
>
> -static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val)
> +static RISCVException write_mhpmcounter(CPURISCVState *env, int csrno,
> +                                        target_ulong val, uintptr_t ra)
>  {
>      int ctr_idx = csrno - CSR_MCYCLE;
>
>      return riscv_pmu_write_ctr(env, val, ctr_idx);
>  }
>
> -static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val)
> +static RISCVException write_mhpmcounterh(CPURISCVState *env, int csrno,
> +                                         target_ulong val, uintptr_t ra)
>  {
>      int ctr_idx = csrno - CSR_MCYCLEH;
>
> @@ -1661,7 +1665,7 @@ static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
> -                                      target_ulong val)
> +                                      target_ulong val, uintptr_t ra)
>  {
>      if (riscv_cpu_mxl(env) == MXL_RV32) {
>          env->vstimecmp = deposit64(env->vstimecmp, 0, 32, (uint64_t)val);
> @@ -1676,7 +1680,7 @@ static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_vstimecmph(CPURISCVState *env, int csrno,
> -                                       target_ulong val)
> +                                       target_ulong val, uintptr_t ra)
>  {
>      env->vstimecmp = deposit64(env->vstimecmp, 32, 32, (uint64_t)val);
>      riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
> @@ -1710,13 +1714,13 @@ static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
> -                                     target_ulong val)
> +                                     target_ulong val, uintptr_t ra)
>  {
>      if (env->virt_enabled) {
>          if (env->hvictl & HVICTL_VTI) {
>              return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
>          }
> -        return write_vstimecmp(env, csrno, val);
> +        return write_vstimecmp(env, csrno, val, ra);
>      }
>
>      if (riscv_cpu_mxl(env) == MXL_RV32) {
> @@ -1731,13 +1735,13 @@ static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
> -                                      target_ulong val)
> +                                      target_ulong val, uintptr_t ra)
>  {
>      if (env->virt_enabled) {
>          if (env->hvictl & HVICTL_VTI) {
>              return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
>          }
> -        return write_vstimecmph(env, csrno, val);
> +        return write_vstimecmph(env, csrno, val, ra);
>      }
>
>      env->stimecmp = deposit64(env->stimecmp, 32, 32, (uint64_t)val);
> @@ -1842,7 +1846,7 @@ static RISCVException read_zero(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_ignore(CPURISCVState *env, int csrno,
> -                                   target_ulong val)
> +                                   target_ulong val, uintptr_t ra)
>  {
>      return RISCV_EXCP_NONE;
>  }
> @@ -1963,7 +1967,7 @@ static target_ulong legalize_mpp(CPURISCVState *env, target_ulong old_mpp,
>  }
>
>  static RISCVException write_mstatus(CPURISCVState *env, int csrno,
> -                                    target_ulong val)
> +                                    target_ulong val, uintptr_t ra)
>  {
>      uint64_t mstatus = env->mstatus;
>      uint64_t mask = 0;
> @@ -2042,7 +2046,7 @@ static RISCVException read_mstatush(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mstatush(CPURISCVState *env, int csrno,
> -                                     target_ulong val)
> +                                     target_ulong val, uintptr_t ra)
>  {
>      uint64_t valh = (uint64_t)val << 32;
>      uint64_t mask = riscv_has_ext(env, RVH) ? MSTATUS_MPV | MSTATUS_GVA : 0;
> @@ -2096,7 +2100,7 @@ static RISCVException read_misa(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_misa(CPURISCVState *env, int csrno,
> -                                 target_ulong val)
> +                                 target_ulong val, uintptr_t ra)
>  {
>      RISCVCPU *cpu = env_archcpu(env);
>      uint32_t orig_misa_ext = env->misa_ext;
> @@ -2160,7 +2164,7 @@ static RISCVException read_medeleg(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_medeleg(CPURISCVState *env, int csrno,
> -                                    target_ulong val)
> +                                    target_ulong val, uintptr_t ra)
>  {
>      env->medeleg = (env->medeleg & ~DELEGABLE_EXCPS) | (val & DELEGABLE_EXCPS);
>      return RISCV_EXCP_NONE;
> @@ -2955,7 +2959,7 @@ static RISCVException read_mtvec(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mtvec(CPURISCVState *env, int csrno,
> -                                  target_ulong val)
> +                                  target_ulong val, uintptr_t ra)
>  {
>      /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
>      if ((val & 3) < 2) {
> @@ -2974,7 +2978,7 @@ static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
> -                                          target_ulong val)
> +                                          target_ulong val, uintptr_t ra)
>  {
>      int cidx;
>      PMUCTRState *counter;
> @@ -3049,10 +3053,9 @@ static RISCVException read_scountinhibit(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_scountinhibit(CPURISCVState *env, int csrno,
> -                                          target_ulong val)
> +                                          target_ulong val, uintptr_t ra)
>  {
> -    write_mcountinhibit(env, csrno, val & env->mcounteren);
> -    return RISCV_EXCP_NONE;
> +    return write_mcountinhibit(env, csrno, val & env->mcounteren, ra);
>  }
>
>  static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
> @@ -3063,7 +3066,7 @@ static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
> -                                       target_ulong val)
> +                                       target_ulong val, uintptr_t ra)
>  {
>      RISCVCPU *cpu = env_archcpu(env);
>
> @@ -3097,7 +3100,7 @@ static RISCVException read_mscratch(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mscratch(CPURISCVState *env, int csrno,
> -                                     target_ulong val)
> +                                     target_ulong val, uintptr_t ra)
>  {
>      env->mscratch = val;
>      return RISCV_EXCP_NONE;
> @@ -3111,7 +3114,7 @@ static RISCVException read_mepc(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mepc(CPURISCVState *env, int csrno,
> -                                 target_ulong val)
> +                                 target_ulong val, uintptr_t ra)
>  {
>      env->mepc = val;
>      return RISCV_EXCP_NONE;
> @@ -3125,7 +3128,7 @@ static RISCVException read_mcause(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mcause(CPURISCVState *env, int csrno,
> -                                   target_ulong val)
> +                                   target_ulong val, uintptr_t ra)
>  {
>      env->mcause = val;
>      return RISCV_EXCP_NONE;
> @@ -3139,7 +3142,7 @@ static RISCVException read_mtval(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mtval(CPURISCVState *env, int csrno,
> -                                  target_ulong val)
> +                                  target_ulong val, uintptr_t ra)
>  {
>      env->mtval = val;
>      return RISCV_EXCP_NONE;
> @@ -3154,9 +3157,9 @@ static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
> -                                    target_ulong val);
> +                                    target_ulong val, uintptr_t ra);
>  static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
> -                                    target_ulong val)
> +                                    target_ulong val, uintptr_t ra)
>  {
>      const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
>      uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE |
> @@ -3188,9 +3191,7 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
>          }
>      }
>      env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
> -    write_henvcfg(env, CSR_HENVCFG, env->henvcfg);
> -
> -    return RISCV_EXCP_NONE;
> +    return write_henvcfg(env, CSR_HENVCFG, env->henvcfg, ra);
>  }
>
>  static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
> @@ -3201,9 +3202,9 @@ static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
> -                                    target_ulong val);
> +                                     target_ulong val, uintptr_t ra);
>  static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
> -                                     target_ulong val)
> +                                     target_ulong val, uintptr_t ra)
>  {
>      const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
>      uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
> @@ -3218,9 +3219,7 @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
>      }
>
>      env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
> -    write_henvcfgh(env, CSR_HENVCFGH, env->henvcfg >> 32);
> -
> -    return RISCV_EXCP_NONE;
> +    return write_henvcfgh(env, CSR_HENVCFGH, env->henvcfg >> 32, ra);
>  }
>
>  static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
> @@ -3238,7 +3237,7 @@ static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
> -                                    target_ulong val)
> +                                    target_ulong val, uintptr_t ra)
>  {
>      uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
>      RISCVException ret;
> @@ -3295,7 +3294,7 @@ static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
> -                                    target_ulong val)
> +                                    target_ulong val, uintptr_t ra)
>  {
>      uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
>      RISCVException ret;
> @@ -3350,7 +3349,7 @@ static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
> -                                     target_ulong val)
> +                                     target_ulong val, uintptr_t ra)
>  {
>      uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
>                                      HENVCFG_ADUE | HENVCFG_DTE);
> @@ -3388,7 +3387,7 @@ static RISCVException write_mstateen(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
> -                                      target_ulong new_val)
> +                                      target_ulong new_val, uintptr_t ra)
>  {
>      uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
>      if (!riscv_has_ext(env, RVF)) {
> @@ -3420,7 +3419,7 @@ static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mstateen_1_3(CPURISCVState *env, int csrno,
> -                                         target_ulong new_val)
> +                                         target_ulong new_val, uintptr_t ra)
>  {
>      return write_mstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
>  }
> @@ -3447,7 +3446,7 @@ static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
> -                                       target_ulong new_val)
> +                                       target_ulong new_val, uintptr_t ra)
>  {
>      uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
>
> @@ -3463,7 +3462,7 @@ static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mstateenh_1_3(CPURISCVState *env, int csrno,
> -                                          target_ulong new_val)
> +                                          target_ulong new_val, uintptr_t ra)
>  {
>      return write_mstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
>  }
> @@ -3492,7 +3491,7 @@ static RISCVException write_hstateen(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
> -                                      target_ulong new_val)
> +                                      target_ulong new_val, uintptr_t ra)
>  {
>      uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
>
> @@ -3521,7 +3520,7 @@ static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_hstateen_1_3(CPURISCVState *env, int csrno,
> -                                         target_ulong new_val)
> +                                         target_ulong new_val, uintptr_t ra)
>  {
>      return write_hstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
>  }
> @@ -3552,7 +3551,7 @@ static RISCVException write_hstateenh(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
> -                                       target_ulong new_val)
> +                                       target_ulong new_val, uintptr_t ra)
>  {
>      uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
>
> @@ -3564,7 +3563,7 @@ static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_hstateenh_1_3(CPURISCVState *env, int csrno,
> -                                          target_ulong new_val)
> +                                          target_ulong new_val, uintptr_t ra)
>  {
>      return write_hstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
>  }
> @@ -3603,7 +3602,7 @@ static RISCVException write_sstateen(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
> -                                      target_ulong new_val)
> +                                      target_ulong new_val, uintptr_t ra)
>  {
>      uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
>
> @@ -3615,7 +3614,7 @@ static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_sstateen_1_3(CPURISCVState *env, int csrno,
> -                                      target_ulong new_val)
> +                                         target_ulong new_val, uintptr_t ra)
>  {
>      return write_sstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
>  }
> @@ -3866,7 +3865,7 @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_sstatus(CPURISCVState *env, int csrno,
> -                                    target_ulong val)
> +                                    target_ulong val, uintptr_t ra)
>  {
>      target_ulong mask = (sstatus_v1_10_mask);
>
> @@ -3883,7 +3882,7 @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno,
>          mask |= SSTATUS_SDT;
>      }
>      target_ulong newval = (env->mstatus & ~mask) | (val & mask);
> -    return write_mstatus(env, CSR_MSTATUS, newval);
> +    return write_mstatus(env, CSR_MSTATUS, newval, ra);
>  }
>
>  static RISCVException rmw_vsie64(CPURISCVState *env, int csrno,
> @@ -4035,7 +4034,7 @@ static RISCVException read_stvec(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_stvec(CPURISCVState *env, int csrno,
> -                                  target_ulong val)
> +                                  target_ulong val, uintptr_t ra)
>  {
>      /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
>      if ((val & 3) < 2) {
> @@ -4054,7 +4053,7 @@ static RISCVException read_scounteren(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_scounteren(CPURISCVState *env, int csrno,
> -                                       target_ulong val)
> +                                       target_ulong val, uintptr_t ra)
>  {
>      RISCVCPU *cpu = env_archcpu(env);
>
> @@ -4088,7 +4087,7 @@ static RISCVException read_sscratch(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_sscratch(CPURISCVState *env, int csrno,
> -                                     target_ulong val)
> +                                     target_ulong val, uintptr_t ra)
>  {
>      env->sscratch = val;
>      return RISCV_EXCP_NONE;
> @@ -4102,7 +4101,7 @@ static RISCVException read_sepc(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_sepc(CPURISCVState *env, int csrno,
> -                                 target_ulong val)
> +                                 target_ulong val, uintptr_t ra)
>  {
>      env->sepc = val;
>      return RISCV_EXCP_NONE;
> @@ -4116,7 +4115,7 @@ static RISCVException read_scause(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_scause(CPURISCVState *env, int csrno,
> -                                   target_ulong val)
> +                                   target_ulong val, uintptr_t ra)
>  {
>      env->scause = val;
>      return RISCV_EXCP_NONE;
> @@ -4130,7 +4129,7 @@ static RISCVException read_stval(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_stval(CPURISCVState *env, int csrno,
> -                                  target_ulong val)
> +                                  target_ulong val, uintptr_t ra)
>  {
>      env->stval = val;
>      return RISCV_EXCP_NONE;
> @@ -4270,7 +4269,7 @@ static RISCVException read_satp(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_satp(CPURISCVState *env, int csrno,
> -                                 target_ulong val)
> +                                 target_ulong val, uintptr_t ra)
>  {
>      if (!riscv_cpu_cfg(env)->mmu) {
>          return RISCV_EXCP_NONE;
> @@ -4492,7 +4491,7 @@ static RISCVException read_hstatus(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_hstatus(CPURISCVState *env, int csrno,
> -                                    target_ulong val)
> +                                    target_ulong val, uintptr_t ra)
>  {
>      uint64_t mask = (target_ulong)-1;
>      if (!env_archcpu(env)->cfg.ext_svukte) {
> @@ -4524,7 +4523,7 @@ static RISCVException read_hedeleg(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_hedeleg(CPURISCVState *env, int csrno,
> -                                    target_ulong val)
> +                                    target_ulong val, uintptr_t ra)
>  {
>      env->hedeleg = val & vs_delegable_excps;
>      return RISCV_EXCP_NONE;
> @@ -4545,7 +4544,7 @@ static RISCVException read_hedelegh(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_hedelegh(CPURISCVState *env, int csrno,
> -                                    target_ulong val)
> +                                     target_ulong val, uintptr_t ra)
>  {
>      RISCVException ret;
>      ret = smstateen_acc_ok(env, 0, SMSTATEEN0_P1P13);
> @@ -4808,7 +4807,7 @@ static RISCVException read_hcounteren(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_hcounteren(CPURISCVState *env, int csrno,
> -                                       target_ulong val)
> +                                       target_ulong val, uintptr_t ra)
>  {
>      RISCVCPU *cpu = env_archcpu(env);
>
> @@ -4828,7 +4827,7 @@ static RISCVException read_hgeie(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_hgeie(CPURISCVState *env, int csrno,
> -                                  target_ulong val)
> +                                  target_ulong val, uintptr_t ra)
>  {
>      /* Only GEILEN:1 bits implemented and BIT0 is never implemented */
>      val &= ((((target_ulong)1) << env->geilen) - 1) << 1;
> @@ -4847,7 +4846,7 @@ static RISCVException read_htval(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_htval(CPURISCVState *env, int csrno,
> -                                  target_ulong val)
> +                                  target_ulong val, uintptr_t ra)
>  {
>      env->htval = val;
>      return RISCV_EXCP_NONE;
> @@ -4861,7 +4860,7 @@ static RISCVException read_htinst(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_htinst(CPURISCVState *env, int csrno,
> -                                   target_ulong val)
> +                                   target_ulong val, uintptr_t ra)
>  {
>      return RISCV_EXCP_NONE;
>  }
> @@ -4883,7 +4882,7 @@ static RISCVException read_hgatp(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_hgatp(CPURISCVState *env, int csrno,
> -                                  target_ulong val)
> +                                  target_ulong val, uintptr_t ra)
>  {
>      env->hgatp = legalize_xatp(env, env->hgatp, val);
>      return RISCV_EXCP_NONE;
> @@ -4901,7 +4900,7 @@ static RISCVException read_htimedelta(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
> -                                       target_ulong val)
> +                                       target_ulong val, uintptr_t ra)
>  {
>      if (!env->rdtime_fn) {
>          return RISCV_EXCP_ILLEGAL_INST;
> @@ -4933,7 +4932,7 @@ static RISCVException read_htimedeltah(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
> -                                        target_ulong val)
> +                                        target_ulong val, uintptr_t ra)
>  {
>      if (!env->rdtime_fn) {
>          return RISCV_EXCP_ILLEGAL_INST;
> @@ -4957,7 +4956,7 @@ static RISCVException read_hvictl(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_hvictl(CPURISCVState *env, int csrno,
> -                                   target_ulong val)
> +                                   target_ulong val, uintptr_t ra)
>  {
>      env->hvictl = val & HVICTL_VALID_MASK;
>      return RISCV_EXCP_NONE;
> @@ -5022,7 +5021,7 @@ static RISCVException read_hviprio1(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_hviprio1(CPURISCVState *env, int csrno,
> -                                     target_ulong val)
> +                                     target_ulong val, uintptr_t ra)
>  {
>      return write_hvipriox(env, 0, env->hviprio, val);
>  }
> @@ -5034,7 +5033,7 @@ static RISCVException read_hviprio1h(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_hviprio1h(CPURISCVState *env, int csrno,
> -                                      target_ulong val)
> +                                      target_ulong val, uintptr_t ra)
>  {
>      return write_hvipriox(env, 4, env->hviprio, val);
>  }
> @@ -5046,7 +5045,7 @@ static RISCVException read_hviprio2(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_hviprio2(CPURISCVState *env, int csrno,
> -                                     target_ulong val)
> +                                     target_ulong val, uintptr_t ra)
>  {
>      return write_hvipriox(env, 8, env->hviprio, val);
>  }
> @@ -5058,7 +5057,7 @@ static RISCVException read_hviprio2h(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_hviprio2h(CPURISCVState *env, int csrno,
> -                                      target_ulong val)
> +                                      target_ulong val, uintptr_t ra)
>  {
>      return write_hvipriox(env, 12, env->hviprio, val);
>  }
> @@ -5072,7 +5071,7 @@ static RISCVException read_vsstatus(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
> -                                     target_ulong val)
> +                                     target_ulong val, uintptr_t ra)
>  {
>      uint64_t mask = (target_ulong)-1;
>      if ((val & VSSTATUS64_UXL) == 0) {
> @@ -5097,7 +5096,7 @@ static RISCVException read_vstvec(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_vstvec(CPURISCVState *env, int csrno,
> -                                   target_ulong val)
> +                                   target_ulong val, uintptr_t ra)
>  {
>      /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
>      if ((val & 3) < 2) {
> @@ -5116,7 +5115,7 @@ static RISCVException read_vsscratch(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_vsscratch(CPURISCVState *env, int csrno,
> -                                      target_ulong val)
> +                                      target_ulong val, uintptr_t ra)
>  {
>      env->vsscratch = val;
>      return RISCV_EXCP_NONE;
> @@ -5130,7 +5129,7 @@ static RISCVException read_vsepc(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_vsepc(CPURISCVState *env, int csrno,
> -                                  target_ulong val)
> +                                  target_ulong val, uintptr_t ra)
>  {
>      env->vsepc = val;
>      return RISCV_EXCP_NONE;
> @@ -5144,7 +5143,7 @@ static RISCVException read_vscause(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_vscause(CPURISCVState *env, int csrno,
> -                                    target_ulong val)
> +                                    target_ulong val, uintptr_t ra)
>  {
>      env->vscause = val;
>      return RISCV_EXCP_NONE;
> @@ -5158,7 +5157,7 @@ static RISCVException read_vstval(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_vstval(CPURISCVState *env, int csrno,
> -                                   target_ulong val)
> +                                   target_ulong val, uintptr_t ra)
>  {
>      env->vstval = val;
>      return RISCV_EXCP_NONE;
> @@ -5172,7 +5171,7 @@ static RISCVException read_vsatp(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_vsatp(CPURISCVState *env, int csrno,
> -                                  target_ulong val)
> +                                  target_ulong val, uintptr_t ra)
>  {
>      env->vsatp = legalize_xatp(env, env->vsatp, val);
>      return RISCV_EXCP_NONE;
> @@ -5186,7 +5185,7 @@ static RISCVException read_mtval2(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mtval2(CPURISCVState *env, int csrno,
> -                                   target_ulong val)
> +                                   target_ulong val, uintptr_t ra)
>  {
>      env->mtval2 = val;
>      return RISCV_EXCP_NONE;
> @@ -5200,7 +5199,7 @@ static RISCVException read_mtinst(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mtinst(CPURISCVState *env, int csrno,
> -                                   target_ulong val)
> +                                   target_ulong val, uintptr_t ra)
>  {
>      env->mtinst = val;
>      return RISCV_EXCP_NONE;
> @@ -5215,7 +5214,7 @@ static RISCVException read_mseccfg(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
> -                                    target_ulong val)
> +                                    target_ulong val, uintptr_t ra)
>  {
>      mseccfg_csr_write(env, val);
>      return RISCV_EXCP_NONE;
> @@ -5231,7 +5230,7 @@ static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
> -                                   target_ulong val)
> +                                   target_ulong val, uintptr_t ra)
>  {
>      uint32_t reg_index = csrno - CSR_PMPCFG0;
>
> @@ -5247,7 +5246,7 @@ static RISCVException read_pmpaddr(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
> -                                    target_ulong val)
> +                                    target_ulong val, uintptr_t ra)
>  {
>      pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val);
>      return RISCV_EXCP_NONE;
> @@ -5261,7 +5260,7 @@ static RISCVException read_tselect(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_tselect(CPURISCVState *env, int csrno,
> -                                    target_ulong val)
> +                                    target_ulong val, uintptr_t ra)
>  {
>      tselect_csr_write(env, val);
>      return RISCV_EXCP_NONE;
> @@ -5285,7 +5284,7 @@ static RISCVException read_tdata(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_tdata(CPURISCVState *env, int csrno,
> -                                  target_ulong val)
> +                                  target_ulong val, uintptr_t ra)
>  {
>      if (!tdata_available(env, csrno - CSR_TDATA1)) {
>          return RISCV_EXCP_ILLEGAL_INST;
> @@ -5310,7 +5309,7 @@ static RISCVException read_mcontext(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_mcontext(CPURISCVState *env, int csrno,
> -                                     target_ulong val)
> +                                     target_ulong val, uintptr_t ra)
>  {
>      bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
>      int32_t mask;
> @@ -5334,43 +5333,50 @@ static RISCVException read_mnscratch(CPURISCVState *env, int csrno,
>      return RISCV_EXCP_NONE;
>  }
>
> -static int write_mnscratch(CPURISCVState *env, int csrno, target_ulong val)
> +static RISCVException write_mnscratch(CPURISCVState *env, int csrno,
> +                                      target_ulong val, uintptr_t ra)
>  {
>      env->mnscratch = val;
>      return RISCV_EXCP_NONE;
>  }
>
> -static int read_mnepc(CPURISCVState *env, int csrno, target_ulong *val)
> +static RISCVException read_mnepc(CPURISCVState *env, int csrno,
> +                                 target_ulong *val)
>  {
>      *val = env->mnepc;
>      return RISCV_EXCP_NONE;
>  }
>
> -static int write_mnepc(CPURISCVState *env, int csrno, target_ulong val)
> +static RISCVException write_mnepc(CPURISCVState *env, int csrno,
> +                                  target_ulong val, uintptr_t ra)
>  {
>      env->mnepc = val;
>      return RISCV_EXCP_NONE;
>  }
>
> -static int read_mncause(CPURISCVState *env, int csrno, target_ulong *val)
> +static RISCVException read_mncause(CPURISCVState *env, int csrno,
> +                                   target_ulong *val)
>  {
>      *val = env->mncause;
>      return RISCV_EXCP_NONE;
>  }
>
> -static int write_mncause(CPURISCVState *env, int csrno, target_ulong val)
> +static RISCVException write_mncause(CPURISCVState *env, int csrno,
> +                                    target_ulong val, uintptr_t ra)
>  {
>      env->mncause = val;
>      return RISCV_EXCP_NONE;
>  }
>
> -static int read_mnstatus(CPURISCVState *env, int csrno, target_ulong *val)
> +static RISCVException read_mnstatus(CPURISCVState *env, int csrno,
> +                                    target_ulong *val)
>  {
>      *val = env->mnstatus;
>      return RISCV_EXCP_NONE;
>  }
>
> -static int write_mnstatus(CPURISCVState *env, int csrno, target_ulong val)
> +static RISCVException write_mnstatus(CPURISCVState *env, int csrno,
> +                                     target_ulong val, uintptr_t ra)
>  {
>      target_ulong mask = (MNSTATUS_NMIE | MNSTATUS_MNPP);
>
> @@ -5540,7 +5546,7 @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
>      if (write_mask) {
>          new_value = (old_value & ~write_mask) | (new_value & write_mask);
>          if (csr_ops[csrno].write) {
> -            ret = csr_ops[csrno].write(env, csrno, new_value);
> +            ret = csr_ops[csrno].write(env, csrno, new_value, 0);
>              if (ret != RISCV_EXCP_NONE) {
>                  return ret;
>              }
> @@ -5603,7 +5609,7 @@ static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
>              }
>          } else if (csr_ops[csrno].write) {
>              /* avoids having to write wrappers for all registers */
> -            ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value));
> +            ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value), 0);
>              if (ret != RISCV_EXCP_NONE) {
>                  return ret;
>              }
> @@ -5714,7 +5720,7 @@ static RISCVException read_jvt(CPURISCVState *env, int csrno,
>  }
>
>  static RISCVException write_jvt(CPURISCVState *env, int csrno,
> -                                target_ulong val)
> +                                target_ulong val, uintptr_t ra)
>  {
>      env->jvt = val;
>      return RISCV_EXCP_NONE;
> --
> 2.43.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/7] target/riscv: Pass ra to riscv_csrrw_do64
  2025-04-25 15:23 ` [PATCH 2/7] target/riscv: Pass ra to riscv_csrrw_do64 Richard Henderson
  2025-04-25 22:29   ` Philippe Mathieu-Daudé
@ 2025-04-28 22:34   ` Alistair Francis
  1 sibling, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2025-04-28 22:34 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, qemu-riscv, alistair.francis, dbarboza

On Sat, Apr 26, 2025 at 1:25 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/csr.c | 15 +++++++--------
>  1 file changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 6f1f69eba6..e9c2f95b6e 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -5516,7 +5516,8 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
>  static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
>                                         target_ulong *ret_value,
>                                         target_ulong new_value,
> -                                       target_ulong write_mask)
> +                                       target_ulong write_mask,
> +                                       uintptr_t ra)
>  {
>      RISCVException ret;
>      target_ulong old_value = 0;
> @@ -5546,7 +5547,7 @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
>      if (write_mask) {
>          new_value = (old_value & ~write_mask) | (new_value & write_mask);
>          if (csr_ops[csrno].write) {
> -            ret = csr_ops[csrno].write(env, csrno, new_value, 0);
> +            ret = csr_ops[csrno].write(env, csrno, new_value, ra);
>              if (ret != RISCV_EXCP_NONE) {
>                  return ret;
>              }
> @@ -5569,7 +5570,7 @@ RISCVException riscv_csrr(CPURISCVState *env, int csrno,
>          return ret;
>      }
>
> -    return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
> +    return riscv_csrrw_do64(env, csrno, ret_value, 0, 0, 0);
>  }
>
>  RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> @@ -5581,7 +5582,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
>          return ret;
>      }
>
> -    return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask);
> +    return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask, 0);
>  }
>
>  static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
> @@ -5647,9 +5648,7 @@ RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
>       * accesses
>       */
>      target_ulong old_value;
> -    ret = riscv_csrrw_do64(env, csrno, &old_value,
> -                           (target_ulong)0,
> -                           (target_ulong)0);
> +    ret = riscv_csrrw_do64(env, csrno, &old_value, 0, 0, 0);
>      if (ret == RISCV_EXCP_NONE && ret_value) {
>          *ret_value = int128_make64(old_value);
>      }
> @@ -5681,7 +5680,7 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
>      target_ulong old_value;
>      ret = riscv_csrrw_do64(env, csrno, &old_value,
>                             int128_getlo(new_value),
> -                           int128_getlo(write_mask));
> +                           int128_getlo(write_mask), 0);
>      if (ret == RISCV_EXCP_NONE && ret_value) {
>          *ret_value = int128_make64(old_value);
>      }
> --
> 2.43.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 3/7] target/riscv: Pass ra to riscv_csrrw_do128
  2025-04-25 15:23 ` [PATCH 3/7] target/riscv: Pass ra to riscv_csrrw_do128 Richard Henderson
  2025-04-25 22:29   ` Philippe Mathieu-Daudé
@ 2025-04-28 22:34   ` Alistair Francis
  1 sibling, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2025-04-28 22:34 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, qemu-riscv, alistair.francis, dbarboza

On Sat, Apr 26, 2025 at 1:24 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/csr.c | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index e9c2f95b6e..d62d1aaaee 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -5588,7 +5588,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
>  static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
>                                          Int128 *ret_value,
>                                          Int128 new_value,
> -                                        Int128 write_mask)
> +                                        Int128 write_mask, uintptr_t ra)
>  {
>      RISCVException ret;
>      Int128 old_value;
> @@ -5610,7 +5610,7 @@ static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
>              }
>          } else if (csr_ops[csrno].write) {
>              /* avoids having to write wrappers for all registers */
> -            ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value), 0);
> +            ret = csr_ops[csrno].write(env, csrno, int128_getlo(new_value), ra);
>              if (ret != RISCV_EXCP_NONE) {
>                  return ret;
>              }
> @@ -5637,7 +5637,7 @@ RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
>
>      if (csr_ops[csrno].read128) {
>          return riscv_csrrw_do128(env, csrno, ret_value,
> -                                 int128_zero(), int128_zero());
> +                                 int128_zero(), int128_zero(), 0);
>      }
>
>      /*
> @@ -5667,7 +5667,8 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
>      }
>
>      if (csr_ops[csrno].read128) {
> -        return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask);
> +        return riscv_csrrw_do128(env, csrno, ret_value,
> +                                 new_value, write_mask, 0);
>      }
>
>      /*
> --
> 2.43.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 4/7] target/riscv: Pass ra to riscv_csrrw
  2025-04-25 15:23 ` [PATCH 4/7] target/riscv: Pass ra to riscv_csrrw Richard Henderson
  2025-04-25 22:31   ` Philippe Mathieu-Daudé
@ 2025-04-28 22:36   ` Alistair Francis
  1 sibling, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2025-04-28 22:36 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, qemu-riscv, alistair.francis, dbarboza

On Sat, Apr 26, 2025 at 1:26 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.h       | 8 ++++----
>  hw/riscv/riscv_hart.c    | 2 +-
>  target/riscv/csr.c       | 8 ++++----
>  target/riscv/op_helper.c | 4 ++--
>  4 files changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 4d41a66d72..2c0524d0be 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -816,8 +816,8 @@ RISCVException riscv_csrr(CPURISCVState *env, int csrno,
>                            target_ulong *ret_value);
>
>  RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> -                           target_ulong *ret_value,
> -                           target_ulong new_value, target_ulong write_mask);
> +                           target_ulong *ret_value, target_ulong new_value,
> +                           target_ulong write_mask, uintptr_t ra);
>  RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
>                                   target_ulong *ret_value,
>                                   target_ulong new_value,
> @@ -826,13 +826,13 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
>  static inline void riscv_csr_write(CPURISCVState *env, int csrno,
>                                     target_ulong val)
>  {
> -    riscv_csrrw(env, csrno, NULL, val, MAKE_64BIT_MASK(0, TARGET_LONG_BITS));
> +    riscv_csrrw(env, csrno, NULL, val, MAKE_64BIT_MASK(0, TARGET_LONG_BITS), 0);
>  }
>
>  static inline target_ulong riscv_csr_read(CPURISCVState *env, int csrno)
>  {
>      target_ulong val = 0;
> -    riscv_csrrw(env, csrno, &val, 0, 0);
> +    riscv_csrrw(env, csrno, &val, 0, 0, 0);
>      return val;
>  }
>
> diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
> index a55d156668..2ebbf41b18 100644
> --- a/hw/riscv/riscv_hart.c
> +++ b/hw/riscv/riscv_hart.c
> @@ -72,7 +72,7 @@ static void csr_call(char *cmd, uint64_t cpu_num, int csrno, uint64_t *val)
>          ret = riscv_csrr(env, csrno, (target_ulong *)val);
>      } else if (strcmp(cmd, "set_csr") == 0) {
>          ret = riscv_csrrw(env, csrno, NULL, *(target_ulong *)val,
> -                MAKE_64BIT_MASK(0, TARGET_LONG_BITS));
> +                          MAKE_64BIT_MASK(0, TARGET_LONG_BITS), 0);
>      }
>
>      g_assert(ret == RISCV_EXCP_NONE);
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index d62d1aaaee..097640e25d 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -5574,15 +5574,15 @@ RISCVException riscv_csrr(CPURISCVState *env, int csrno,
>  }
>
>  RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> -                           target_ulong *ret_value,
> -                           target_ulong new_value, target_ulong write_mask)
> +                           target_ulong *ret_value, target_ulong new_value,
> +                           target_ulong write_mask, uintptr_t ra)
>  {
>      RISCVException ret = riscv_csrrw_check(env, csrno, true);
>      if (ret != RISCV_EXCP_NONE) {
>          return ret;
>      }
>
> -    return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask, 0);
> +    return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask, ra);
>  }
>
>  static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
> @@ -5704,7 +5704,7 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
>      if (!write_mask) {
>          ret = riscv_csrr(env, csrno, ret_value);
>      } else {
> -        ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
> +        ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask, 0);
>      }
>  #if !defined(CONFIG_USER_ONLY)
>      env->debugger = false;
> diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
> index 5b0db2c45a..aee16e2e3a 100644
> --- a/target/riscv/op_helper.c
> +++ b/target/riscv/op_helper.c
> @@ -71,7 +71,7 @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
>  void helper_csrw(CPURISCVState *env, int csr, target_ulong src)
>  {
>      target_ulong mask = env->xl == MXL_RV32 ? UINT32_MAX : (target_ulong)-1;
> -    RISCVException ret = riscv_csrrw(env, csr, NULL, src, mask);
> +    RISCVException ret = riscv_csrrw(env, csr, NULL, src, mask, GETPC());
>
>      if (ret != RISCV_EXCP_NONE) {
>          riscv_raise_exception(env, ret, GETPC());
> @@ -82,7 +82,7 @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
>                            target_ulong src, target_ulong write_mask)
>  {
>      target_ulong val = 0;
> -    RISCVException ret = riscv_csrrw(env, csr, &val, src, write_mask);
> +    RISCVException ret = riscv_csrrw(env, csr, &val, src, write_mask, GETPC());
>
>      if (ret != RISCV_EXCP_NONE) {
>          riscv_raise_exception(env, ret, GETPC());
> --
> 2.43.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 5/7] target/riscv: Pass ra to riscv_csrrw_i128
  2025-04-25 15:23 ` [PATCH 5/7] target/riscv: Pass ra to riscv_csrrw_i128 Richard Henderson
  2025-04-25 22:32   ` Philippe Mathieu-Daudé
@ 2025-04-28 22:37   ` Alistair Francis
  1 sibling, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2025-04-28 22:37 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, qemu-riscv, alistair.francis, dbarboza

On Sat, Apr 26, 2025 at 1:23 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.h       | 4 ++--
>  target/riscv/csr.c       | 8 ++++----
>  target/riscv/op_helper.c | 9 +++++----
>  3 files changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 2c0524d0be..8b84793b15 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -851,8 +851,8 @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
>  RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
>                                 Int128 *ret_value);
>  RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
> -                                Int128 *ret_value,
> -                                Int128 new_value, Int128 write_mask);
> +                                Int128 *ret_value, Int128 new_value,
> +                                Int128 write_mask, uintptr_t ra);
>
>  typedef RISCVException (*riscv_csr_read128_fn)(CPURISCVState *env, int csrno,
>                                                 Int128 *ret_value);
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 097640e25d..a663f527a4 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -5656,8 +5656,8 @@ RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
>  }
>
>  RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
> -                                Int128 *ret_value,
> -                                Int128 new_value, Int128 write_mask)
> +                                Int128 *ret_value, Int128 new_value,
> +                                Int128 write_mask, uintptr_t ra)
>  {
>      RISCVException ret;
>
> @@ -5668,7 +5668,7 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
>
>      if (csr_ops[csrno].read128) {
>          return riscv_csrrw_do128(env, csrno, ret_value,
> -                                 new_value, write_mask, 0);
> +                                 new_value, write_mask, ra);
>      }
>
>      /*
> @@ -5681,7 +5681,7 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
>      target_ulong old_value;
>      ret = riscv_csrrw_do64(env, csrno, &old_value,
>                             int128_getlo(new_value),
> -                           int128_getlo(write_mask), 0);
> +                           int128_getlo(write_mask), ra);
>      if (ret == RISCV_EXCP_NONE && ret_value) {
>          *ret_value = int128_make64(old_value);
>      }
> diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
> index aee16e2e3a..e3770a2655 100644
> --- a/target/riscv/op_helper.c
> +++ b/target/riscv/op_helper.c
> @@ -108,7 +108,7 @@ void helper_csrw_i128(CPURISCVState *env, int csr,
>  {
>      RISCVException ret = riscv_csrrw_i128(env, csr, NULL,
>                                            int128_make128(srcl, srch),
> -                                          UINT128_MAX);
> +                                          UINT128_MAX, GETPC());
>
>      if (ret != RISCV_EXCP_NONE) {
>          riscv_raise_exception(env, ret, GETPC());
> @@ -116,13 +116,14 @@ void helper_csrw_i128(CPURISCVState *env, int csr,
>  }
>
>  target_ulong helper_csrrw_i128(CPURISCVState *env, int csr,
> -                       target_ulong srcl, target_ulong srch,
> -                       target_ulong maskl, target_ulong maskh)
> +                               target_ulong srcl, target_ulong srch,
> +                               target_ulong maskl, target_ulong maskh)
>  {
>      Int128 rv = int128_zero();
>      RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
>                                            int128_make128(srcl, srch),
> -                                          int128_make128(maskl, maskh));
> +                                          int128_make128(maskl, maskh),
> +                                          GETPC());
>
>      if (ret != RISCV_EXCP_NONE) {
>          riscv_raise_exception(env, ret, GETPC());
> --
> 2.43.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 6/7] target/riscv: Move insn_len to internals.h
  2025-04-25 15:23 ` [PATCH 6/7] target/riscv: Move insn_len to internals.h Richard Henderson
  2025-04-25 22:33   ` Philippe Mathieu-Daudé
@ 2025-04-28 22:37   ` Alistair Francis
  1 sibling, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2025-04-28 22:37 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, qemu-riscv, alistair.francis, dbarboza

On Sat, Apr 26, 2025 at 1:24 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/internals.h | 5 +++++
>  target/riscv/translate.c | 5 -----
>  2 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
> index 213aff31d8..4570bd50be 100644
> --- a/target/riscv/internals.h
> +++ b/target/riscv/internals.h
> @@ -201,4 +201,9 @@ static inline target_ulong adjust_addr_virt(CPURISCVState *env,
>      return adjust_addr_body(env, addr, true);
>  }
>
> +static inline int insn_len(uint16_t first_word)
> +{
> +    return (first_word & 3) == 3 ? 4 : 2;
> +}
> +
>  #endif
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index cef61b5b29..9836ab8c20 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -1210,11 +1210,6 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
>  /* The specification allows for longer insns, but not supported by qemu. */
>  #define MAX_INSN_LEN  4
>
> -static inline int insn_len(uint16_t first_word)
> -{
> -    return (first_word & 3) == 3 ? 4 : 2;
> -}
> -
>  const RISCVDecoder decoder_table[] = {
>      { always_true_p, decode_insn32 },
>      { has_xthead_p, decode_xthead},
> --
> 2.43.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 7/7] target/riscv: Fix write_misa vs aligned next_pc
  2025-04-25 15:23 ` [PATCH 7/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
  2025-04-25 22:33   ` Philippe Mathieu-Daudé
@ 2025-04-28 22:39   ` Alistair Francis
  2025-04-29 14:33   ` Richard Henderson
  2025-05-14 21:33   ` Daniel Henrique Barboza
  3 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2025-04-28 22:39 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, qemu-riscv, alistair.francis, dbarboza

On Sat, Apr 26, 2025 at 1:26 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Do not examine a random host return address, but
> properly compute the next pc for the guest cpu.
>
> Fixes: f18637cd611 ("RISC-V: Add misa runtime write support")
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/csr.c | 22 +++++++++++++++++-----
>  1 file changed, 17 insertions(+), 5 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index a663f527a4..85f9b4c3d2 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -30,6 +30,8 @@
>  #include "exec/icount.h"
>  #include "qemu/guest-random.h"
>  #include "qapi/error.h"
> +#include "tcg/insn-start-words.h"
> +#include "internals.h"
>  #include <stdbool.h>
>
>  /* CSR function table public API */
> @@ -2099,6 +2101,19 @@ static RISCVException read_misa(CPURISCVState *env, int csrno,
>      return RISCV_EXCP_NONE;
>  }
>
> +static target_ulong get_next_pc(CPURISCVState *env, uintptr_t ra)
> +{
> +    uint64_t data[TARGET_INSN_START_WORDS];
> +
> +    /* Outside of a running cpu, env contains the next pc. */
> +    if (ra == 0 || !cpu_unwind_state_data(env_cpu(env), ra, data)) {
> +        return env->pc;
> +    }
> +
> +    /* Within unwind data, [0] is pc and [1] is the opcode. */
> +    return data[0] + insn_len(data[1]);
> +}
> +
>  static RISCVException write_misa(CPURISCVState *env, int csrno,
>                                   target_ulong val, uintptr_t ra)
>  {
> @@ -2114,11 +2129,8 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
>      /* Mask extensions that are not supported by this hart */
>      val &= env->misa_ext_mask;
>
> -    /*
> -     * Suppress 'C' if next instruction is not aligned
> -     * TODO: this should check next_pc
> -     */
> -    if ((val & RVC) && (GETPC() & ~3) != 0) {
> +    /* Suppress 'C' if next instruction is not aligned. */
> +    if ((val & RVC) && (get_next_pc(env, ra) & ~3) != 0) {
>          val &= ~RVC;
>      }
>
> --
> 2.43.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 0/7] target/riscv: Fix write_misa vs aligned next_pc
  2025-04-25 15:23 [PATCH 0/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
                   ` (7 preceding siblings ...)
  2025-04-26  8:25 ` [PATCH 0/7] " Daniel Henrique Barboza
@ 2025-04-28 22:46 ` Alistair Francis
  8 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2025-04-28 22:46 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, qemu-riscv, alistair.francis, dbarboza

On Sat, Apr 26, 2025 at 1:25 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> As discussed, the use of GETPC() within write_misa is wrong.
> I've done just enough plumbing to get the helper return address
> piped down to write_misa, so that we can make use of unwind data.

Thanks Richard!

>
> AFAIK, nothing in check-tcg or check-functional would test this.
> It shouldn't be too hard to write a test akin to issue1060.S,
> but I'm going to leave that to someone else.
>
>
> r~
>
>
> Richard Henderson (7):
>   target/riscv: Pass ra to riscv_csr_write_fn
>   target/riscv: Pass ra to riscv_csrrw_do64
>   target/riscv: Pass ra to riscv_csrrw_do128
>   target/riscv: Pass ra to riscv_csrrw
>   target/riscv: Pass ra to riscv_csrrw_i128
>   target/riscv: Move insn_len to internals.h
>   target/riscv: Fix write_misa vs aligned next_pc

Applied to riscv-to-apply.next

Alistair

>
>  target/riscv/cpu.h       |  15 ++-
>  target/riscv/internals.h |   5 +
>  hw/riscv/riscv_hart.c    |   2 +-
>  target/riscv/csr.c       | 278 +++++++++++++++++++++------------------
>  target/riscv/op_helper.c |  13 +-
>  target/riscv/translate.c |   5 -
>  6 files changed, 169 insertions(+), 149 deletions(-)
>
> --
> 2.43.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 7/7] target/riscv: Fix write_misa vs aligned next_pc
  2025-04-25 15:23 ` [PATCH 7/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
  2025-04-25 22:33   ` Philippe Mathieu-Daudé
  2025-04-28 22:39   ` Alistair Francis
@ 2025-04-29 14:33   ` Richard Henderson
  2025-04-30 22:44     ` Alistair Francis
  2025-05-14 21:33   ` Daniel Henrique Barboza
  3 siblings, 1 reply; 28+ messages in thread
From: Richard Henderson @ 2025-04-29 14:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, dbarboza, Alistair Francis

On 4/25/25 08:23, Richard Henderson wrote:
> -    if ((val & RVC) && (GETPC() & ~3) != 0) {
> +    /* Suppress 'C' if next instruction is not aligned. */
> +    if ((val & RVC) && (get_next_pc(env, ra) & ~3) != 0) {

Bah.  I preserved a second bug here: not "& ~3" but "& 3".


r~


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 7/7] target/riscv: Fix write_misa vs aligned next_pc
  2025-04-29 14:33   ` Richard Henderson
@ 2025-04-30 22:44     ` Alistair Francis
  0 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2025-04-30 22:44 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, qemu-riscv, alistair.francis, dbarboza

On Wed, Apr 30, 2025 at 12:34 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 4/25/25 08:23, Richard Henderson wrote:
> > -    if ((val & RVC) && (GETPC() & ~3) != 0) {
> > +    /* Suppress 'C' if next instruction is not aligned. */
> > +    if ((val & RVC) && (get_next_pc(env, ra) & ~3) != 0) {
>
> Bah.  I preserved a second bug here: not "& ~3" but "& 3".

Good catch

I squashed this fix into the patch

Alistair

>
>
> r~
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 7/7] target/riscv: Fix write_misa vs aligned next_pc
  2025-04-25 15:23 ` [PATCH 7/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
                     ` (2 preceding siblings ...)
  2025-04-29 14:33   ` Richard Henderson
@ 2025-05-14 21:33   ` Daniel Henrique Barboza
  2025-05-15  8:10     ` Richard Henderson
  3 siblings, 1 reply; 28+ messages in thread
From: Daniel Henrique Barboza @ 2025-05-14 21:33 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis

Richard,

On 4/25/25 12:23 PM, Richard Henderson wrote:
> Do not examine a random host return address, but
> properly compute the next pc for the guest cpu.
> 
> Fixes: f18637cd611 ("RISC-V: Add misa runtime write support")
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/riscv/csr.c | 22 +++++++++++++++++-----
>   1 file changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index a663f527a4..85f9b4c3d2 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -30,6 +30,8 @@
>   #include "exec/icount.h"
>   #include "qemu/guest-random.h"
>   #include "qapi/error.h"
> +#include "tcg/insn-start-words.h"
> +#include "internals.h"
>   #include <stdbool.h>
>   
>   /* CSR function table public API */
> @@ -2099,6 +2101,19 @@ static RISCVException read_misa(CPURISCVState *env, int csrno,
>       return RISCV_EXCP_NONE;
>   }
>   
> +static target_ulong get_next_pc(CPURISCVState *env, uintptr_t ra)
> +{
> +    uint64_t data[TARGET_INSN_START_WORDS];

Isn't this 'INSN_START_WORDS'?  I'm seeing code in i386 that is similar
to what we're doing here and it's using INSN_START_WORDS:

====
static inline target_ulong get_memio_eip(CPUX86State *env)
{
#ifdef CONFIG_TCG
     uint64_t data[INSN_START_WORDS];
     CPUState *cs = env_cpu(env);

     if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) {
         return env->eip;
     }

     /* Per x86_restore_state_to_opc. */
     if (tcg_cflags_has(cs, CF_PCREL)) {
         return (env->eip & TARGET_PAGE_MASK) | data[0];
     } else {
         return data[0] - env->segs[R_CS].base;
     }
#else
     qemu_build_not_reached();
#endif
}
====

I'm asking because the build in Alistair's branch is failing with this error:


../target/riscv/csr.c: In function ‘get_next_pc’:
../target/riscv/csr.c:2106:19: error: ‘TARGET_INSN_START_WORDS’ undeclared (first use in this function); did you mean ‘TCG_INSN_START_WORDS’?
  2106 |     uint64_t data[TARGET_INSN_START_WORDS];
       |                   ^~~~~~~~~~~~~~~~~~~~~~~
       |                   TCG_INSN_START_WORDS
../target/riscv/csr.c:2106:19: note: each undeclared identifier is reported only once for each function it appears in
../target/riscv/csr.c:2106:14: error: unused variable ‘data’ [-Werror=unused-variable]
  2106 |     uint64_t data[TARGET_INSN_START_WORDS];
       |              ^~~~
../target/riscv/csr.c:2115:1: error: control reaches end of non-void function [-Werror=return-type]
  2115 | }
       | ^
cc1: all warnings being treated as errors
[2206/3000] Compiling C object libqemu-riscv


Changing TARGET_INSN_START_WORDS to INSN_START_WORDS fixes the build issue.
Thanks,


Daniel

> +
> +    /* Outside of a running cpu, env contains the next pc. */
> +    if (ra == 0 || !cpu_unwind_state_data(env_cpu(env), ra, data)) {
> +        return env->pc;
> +    }
> +
> +    /* Within unwind data, [0] is pc and [1] is the opcode. */
> +    return data[0] + insn_len(data[1]);
> +}
> +
>   static RISCVException write_misa(CPURISCVState *env, int csrno,
>                                    target_ulong val, uintptr_t ra)
>   {
> @@ -2114,11 +2129,8 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
>       /* Mask extensions that are not supported by this hart */
>       val &= env->misa_ext_mask;
>   
> -    /*
> -     * Suppress 'C' if next instruction is not aligned
> -     * TODO: this should check next_pc
> -     */
> -    if ((val & RVC) && (GETPC() & ~3) != 0) {
> +    /* Suppress 'C' if next instruction is not aligned. */
> +    if ((val & RVC) && (get_next_pc(env, ra) & ~3) != 0) {
>           val &= ~RVC;
>       }
>   



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 7/7] target/riscv: Fix write_misa vs aligned next_pc
  2025-05-14 21:33   ` Daniel Henrique Barboza
@ 2025-05-15  8:10     ` Richard Henderson
  0 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2025-05-15  8:10 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel; +Cc: qemu-riscv, alistair.francis

On 5/14/25 22:33, Daniel Henrique Barboza wrote:
> Richard,
> 
> On 4/25/25 12:23 PM, Richard Henderson wrote:
>> Do not examine a random host return address, but
>> properly compute the next pc for the guest cpu.
>>
>> Fixes: f18637cd611 ("RISC-V: Add misa runtime write support")
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>   target/riscv/csr.c | 22 +++++++++++++++++-----
>>   1 file changed, 17 insertions(+), 5 deletions(-)
>>
>> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
>> index a663f527a4..85f9b4c3d2 100644
>> --- a/target/riscv/csr.c
>> +++ b/target/riscv/csr.c
>> @@ -30,6 +30,8 @@
>>   #include "exec/icount.h"
>>   #include "qemu/guest-random.h"
>>   #include "qapi/error.h"
>> +#include "tcg/insn-start-words.h"
>> +#include "internals.h"
>>   #include <stdbool.h>
>>   /* CSR function table public API */
>> @@ -2099,6 +2101,19 @@ static RISCVException read_misa(CPURISCVState *env, int csrno,
>>       return RISCV_EXCP_NONE;
>>   }
>> +static target_ulong get_next_pc(CPURISCVState *env, uintptr_t ra)
>> +{
>> +    uint64_t data[TARGET_INSN_START_WORDS];
> 
> Isn't this 'INSN_START_WORDS'?  I'm seeing code in i386 that is similar
> to what we're doing here and it's using INSN_START_WORDS:

Yes, though INSN_START_WORDS is a very recent change.
Probably the week after I posted this patch set.  :-)


r~


^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2025-05-15  8:13 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-25 15:23 [PATCH 0/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
2025-04-25 15:23 ` [PATCH 1/7] target/riscv: Pass ra to riscv_csr_write_fn Richard Henderson
2025-04-25 22:28   ` Philippe Mathieu-Daudé
2025-04-28 22:33   ` Alistair Francis
2025-04-25 15:23 ` [PATCH 2/7] target/riscv: Pass ra to riscv_csrrw_do64 Richard Henderson
2025-04-25 22:29   ` Philippe Mathieu-Daudé
2025-04-28 22:34   ` Alistair Francis
2025-04-25 15:23 ` [PATCH 3/7] target/riscv: Pass ra to riscv_csrrw_do128 Richard Henderson
2025-04-25 22:29   ` Philippe Mathieu-Daudé
2025-04-28 22:34   ` Alistair Francis
2025-04-25 15:23 ` [PATCH 4/7] target/riscv: Pass ra to riscv_csrrw Richard Henderson
2025-04-25 22:31   ` Philippe Mathieu-Daudé
2025-04-28 22:36   ` Alistair Francis
2025-04-25 15:23 ` [PATCH 5/7] target/riscv: Pass ra to riscv_csrrw_i128 Richard Henderson
2025-04-25 22:32   ` Philippe Mathieu-Daudé
2025-04-28 22:37   ` Alistair Francis
2025-04-25 15:23 ` [PATCH 6/7] target/riscv: Move insn_len to internals.h Richard Henderson
2025-04-25 22:33   ` Philippe Mathieu-Daudé
2025-04-28 22:37   ` Alistair Francis
2025-04-25 15:23 ` [PATCH 7/7] target/riscv: Fix write_misa vs aligned next_pc Richard Henderson
2025-04-25 22:33   ` Philippe Mathieu-Daudé
2025-04-28 22:39   ` Alistair Francis
2025-04-29 14:33   ` Richard Henderson
2025-04-30 22:44     ` Alistair Francis
2025-05-14 21:33   ` Daniel Henrique Barboza
2025-05-15  8:10     ` Richard Henderson
2025-04-26  8:25 ` [PATCH 0/7] " Daniel Henrique Barboza
2025-04-28 22:46 ` Alistair Francis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).