On 5/11/2026 7:26 AM, Zishun Yi 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: Daniel Henrique Barboza <[email protected]>
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);