@samitouri / QOSamiQemu / commits / 53cc9747ed

target/riscv/csr.c: fix read of pmpaddr(0-63) CSRs

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 Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20260514123342.2139464-1-daniel.barboza@oss.qualcomm.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Daniel Henrique Barboza committed May 14, 2026 at 09:33 UTC 53cc9747ed7c9b95ba084d614976dd48c9a57a97
1 file changed +17
target/riscv/csr.c
+17
@@ -5365,6 +5365,23 @@ static RISCVException read_pmpaddr(CPURISCVState *env, int csrno,
5365 target_ulong *val)
5366 {
5367 *val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0);
5368 +
5369 + /*
5370 + * For RV64, bits 54-63 of the address registers
5371 + * PMPAADDR(0-63) is a WARL zero field (priv spec,
5372 + * section "Physical Memory Protection CSRs").
5373 + *
5374 + * We'll have to add an annoying TARGET_RISCV64 gate
5375 + * here to avoid complaints about masking bits 0-53
5376 + * of a potential 32 bit target_ulong '*var'.
5377 + */
5378 +#ifdef TARGET_RISCV64
5379 + if (env->misa_mxl == MXL_RV64
5380 + && csrno >= CSR_PMPADDR0 && csrno <= CSR_PMPADDR63) {
5381 + target_ulong read_mask = MAKE_64BIT_MASK(0, 54);
5382 + *val &= read_mask;
5383 + }
5384 +#endif
5385 return RISCV_EXCP_NONE;
5386 }
5387