On Mon, May 11, 2026 at 8:27 PM Zishun Yi <[email protected]> wrote: > > According to the RISC-V Privileged Manual: "The Sv32 page-based > virtual-memory scheme described in sv32 supports 34-bit physical > addresses for RV32, so the PMP scheme must support addresses wider than > XLEN for RV32." > > However, the current QEMU implementation uses `target_ulong` (which > resolves to `uint32_t` on RV32) for PMP address variables. When > shifting these addresses left (e.g., `this_addr << 2`), an integer > overflow occurs, truncating the high bits of the 34-bit physical > address. > > Fix this issue by changing the types of PMP address variables > (`this_addr` and `prev_addr`) to `hwaddr`. > > This issue was discovered and reported by SpecHunter, an AI-driven > architecture specification analysis tool. > > Link: > https://github.com/yizishun/rv-isa-sec/blob/master/output/riscv-isa-manual/pr-2472/qemu.txt > Signed-off-by: Zishun Yi <[email protected]>
Reviewed-by: Alistair Francis <[email protected]> Alistair > --- > Changes in v2: > - Changed the types of `this_addr` and `prev_addr` to `hwaddr` instead > of using inline casting, by Daniel's suggestion. > > target/riscv/pmp.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c > index 5391caa59c7d..a71091a316e0 100644 > --- a/target/riscv/pmp.c > +++ b/target/riscv/pmp.c > @@ -227,8 +227,8 @@ static void pmp_decode_napot(hwaddr a, hwaddr *sa, hwaddr > *ea) > void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index) > { > uint8_t this_cfg = env->pmp_state.pmp[pmp_index].cfg_reg; > - target_ulong this_addr = env->pmp_state.pmp[pmp_index].addr_reg; > - target_ulong prev_addr = 0u; > + hwaddr this_addr = env->pmp_state.pmp[pmp_index].addr_reg; > + hwaddr prev_addr = 0u; > hwaddr sa = 0u; > hwaddr ea = 0u; > int g = pmp_get_granularity_g(env); > -- > 2.51.2 > >
