On Thu, May 14, 2026 at 10:35 PM Daniel Henrique Barboza <[email protected]> wrote: > > The priv spec defines, for RV64, that the upper 10 bits of > pmpaddr0-pmpaddr63 are WARL and are supposed to be cleared. > > After this patch, using the bug reproducer in [1], writing > ffffffffffffffff in pmpaddr0 and reading it back now results in > 003fffffffffffff. Here's the 'diff -cp' dump before and after > this change: > > *************** IN: > *** 5272,5278 **** > pmpcfg10 0000000000000000 > pmpcfg12 0000000000000000 > pmpcfg14 0000000000000000 > ! pmpaddr0 ffffffffffffffff > pmpaddr1 0000000000000000 > pmpaddr2 0000000000000000 > pmpaddr3 0000000000000000 > --- 5545,5551 ---- > pmpcfg10 0000000000000000 > pmpcfg12 0000000000000000 > pmpcfg14 0000000000000000 > ! pmpaddr0 003fffffffffffff > pmpaddr1 0000000000000000 > pmpaddr2 0000000000000000 > pmpaddr3 0000000000000000 > > [1] https://gitlab.com/qemu-project/qemu/-/work_items/3362 > > Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3362 > Signed-off-by: Daniel Henrique Barboza <[email protected]>
Reviewed-by: Alistair Francis <[email protected]> Alistair > --- > target/riscv/csr.c | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > > diff --git a/target/riscv/csr.c b/target/riscv/csr.c > index e1cd4a299c..476a620035 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -5362,6 +5362,23 @@ static RISCVException read_pmpaddr(CPURISCVState *env, > int csrno, > target_ulong *val) > { > *val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0); > + > + /* > + * For RV64, bits 54-63 of the address registers > + * PMPAADDR(0-63) is a WARL zero field (priv spec, > + * section "Physical Memory Protection CSRs"). > + * > + * We'll have to add an annoying TARGET_RISCV64 gate > + * here to avoid complaints about masking bits 0-53 > + * of a potential 32 bit target_ulong '*var'. > + */ > +#ifdef TARGET_RISCV64 > + if (env->misa_mxl == MXL_RV64 > + && csrno >= CSR_PMPADDR0 && csrno <= CSR_PMPADDR63) { > + target_ulong read_mask = MAKE_64BIT_MASK(0, 54); > + *val &= read_mask; > + } > +#endif > return RISCV_EXCP_NONE; > } > > -- > 2.43.0 > >
