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 casting the `target_ulong` variables to `hwaddr` before performing the left shift operation. 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]> --- target/riscv/pmp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c index 5391caa59c7d..dfddafcbcb48 100644 --- a/target/riscv/pmp.c +++ b/target/riscv/pmp.c @@ -253,12 +253,12 @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index) sa = ea = 0u; break; } - sa = prev_addr << 2; /* shift up from [xx:0] to [xx+2:2] */ - ea = (this_addr << 2) - 1u; + sa = (hwaddr)prev_addr << 2; /* shift up from [xx:0] to [xx+2:2] */ + ea = ((hwaddr)this_addr << 2) - 1u; break; case PMP_AMATCH_NA4: - sa = this_addr << 2; /* shift up from [xx:0] to [xx+2:2] */ + sa = (hwaddr)this_addr << 2; /* shift up from [xx:0] to [xx+2:2] */ ea = (sa + 4u) - 1u; break; -- 2.51.2
