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 <vulab@iscas.ac.cn>
---
v2: add a missing space after the Link tag clon
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