The PMSAv7 walk accepted any non-zero region size field, but Armv6-M
requires a minimum of 7 (256 B), Armv7-M requires 4 (32 B) and v7-R
retains its current minimum of 1 (4 B). Introduce rsize_min based on
ARM_FEATURE_M and ARM_FEATURE_V7 and reject smaller values. The PMSAv8
path is handled earlier and remains unchanged.

Suggested-by: Peter Maydell <[email protected]>
Signed-off-by: Gilles Grimaud <[email protected]>
---
 target/arm/ptw.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index a29de0385f..cb9e73fc0a 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -2720,6 +2720,11 @@ static bool get_phys_addr_pmsav7(CPUARMState *env,
     ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
     bool is_user = regime_is_user(mmu_idx);
     bool secure = arm_space_is_secure(ptw->in_space);
+    uint32_t rsize_min = 1;
+
+    if (arm_feature(env, ARM_FEATURE_M)) {
+        rsize_min = arm_feature(env, ARM_FEATURE_V7) ? 4 : 7;
+    }
 
     result->f.phys_addr = address;
     result->f.lg_page_size = TARGET_PAGE_BITS;
@@ -2748,11 +2753,13 @@ static bool get_phys_addr_pmsav7(CPUARMState *env,
                 continue;
             }
 
-            if (!rsize) {
+            if (rsize < rsize_min) {
                 qemu_log_mask(LOG_GUEST_ERROR,
-                              "DRSR[%d]: Rsize field cannot be 0\n", n);
+                              "DRSR[%d]: invalid Rsize field 0x%x\n",
+                              n, rsize);
                 continue;
             }
+
             rsize++;
             rmask = (1ull << rsize) - 1;
 
-- 
2.55.0


Reply via email to