From: Vac Chen <vacant...@gmail.com>

pmp_is_in_range() prefers to match addresses within the interval
[start, end]. To archieve this, pmpaddrX is decremented during the end
address update.

In TOR mode, a rule is ignored if its start address is greater than or
equal to its end address.

However, if pmpaddrX is set to 0, this decrement operation causes the
calulated end address to wrap around to UINT_MAX. In this scenario, the
address guard for this PMP entry would become ineffective.

This patch addresses the issue by moving the guard check earlier,
preventing the problematic wraparound when pmpaddrX is zero.

Signed-off-by: Vac Chen <vacant...@gmail.com>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com>
Message-ID: <20250706065554.42953-1-vacant...@gmail.com>
Signed-off-by: Alistair Francis <alistair.fran...@wdc.com>
(cherry picked from commit 77707bfdf871199bbee665e721ced961aaf3a798)
Signed-off-by: Michael Tokarev <m...@tls.msk.ru>

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index c5f6cdaccb..a9e69de917 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -206,11 +206,12 @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t 
pmp_index)
         break;
 
     case PMP_AMATCH_TOR:
-        sa = prev_addr << 2; /* shift up from [xx:0] to [xx+2:2] */
-        ea = (this_addr << 2) - 1u;
-        if (sa > ea) {
+        if (prev_addr >= this_addr) {
             sa = ea = 0u;
+            break;
         }
+        sa = prev_addr << 2; /* shift up from [xx:0] to [xx+2:2] */
+        ea = (this_addr << 2) - 1u;
         break;
 
     case PMP_AMATCH_NA4:
-- 
2.47.2


Reply via email to