[RFC PATCH 05/18] target/arm: Probe second page earlier in allocation_tag_mem_internal

Richard Henderson <[email protected]>
Newsgroups org.nongnu.qemu-arm,org.nongnu.qemu-devel,org.nongnu.qemu-riscv
Message-ID <[email protected]>
Translation faults have priority over everything else in
this function.  We were failing to trap for the second page
entirely in the user-only case, and when tag access is disabled
on the first page for the system case.

Signed-off-by: Richard Henderson <[email protected]>
---
 target/arm/tcg/mte_helper.c | 55 ++++++++++++++++++++++---------------
 1 file changed, 33 insertions(+), 22 deletions(-)

diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c
index 31bf58c937..399bca30c9 100644
--- a/target/arm/tcg/mte_helper.c
+++ b/target/arm/tcg/mte_helper.c
@@ -130,6 +130,13 @@ allocation_tag_mem_internal(CPUARMState *env, int ptr_mmu_idx,
             g_assert_not_reached();
         }
     }
+    if (atm_kind == ATM_NORMAL) {
+        int in_page = -(ptr | TARGET_PAGE_MASK);
+        if (unlikely(ptr_size > in_page)) {
+            probe_access(env, ptr + in_page, ptr_size - in_page,
+                         ptr_access, MMU_USER_IDX, ra);
+        }
+    }
 
     /* Require both MAP_ANON and PROT_MTE for the page. */
     if ((flags & PAGE_ANON) && (flags & PAGE_MTE)) {
@@ -148,6 +155,7 @@ allocation_tag_mem_internal(CPUARMState *env, int ptr_mmu_idx,
     MemoryRegion *mr;
     ARMASIdx tag_asi;
     AddressSpace *tag_as;
+    uint8_t pte_attrs;
 
     /*
      * Probe the first byte of the virtual address.  This raises an
@@ -161,9 +169,32 @@ allocation_tag_mem_internal(CPUARMState *env, int ptr_mmu_idx,
         assert(atm_kind == ATM_PROBE_PAGES);
         goto fini;
     }
+
+    /*
+     * Remember these across the second lookup below,
+     * which may invalidate this pointer via tlb resize.
+     */
+    ptr_paddr = full->phys_addr | (ptr & ~TARGET_PAGE_MASK);
+    pte_attrs = full->extra.arm.pte_attrs;
     ret.attrs = full->attrs;
 
-    switch (full->extra.arm.pte_attrs) {
+    /*
+     * The Normal memory access can extend to the next page.  E.g. a single
+     * 8-byte access to the last byte of a page will check only the last
+     * tag on the first page.
+     * Any page access exception has priority over tag check exception.
+     */
+    if (atm_kind == ATM_NORMAL) {
+        int in_page = -(ptr | TARGET_PAGE_MASK);
+        if (unlikely(ptr_size > in_page)) {
+            void *discard_mem;
+            ret.flags |= probe_access_full(env, ptr + in_page, 0, ptr_access,
+                                           ptr_mmu_idx, false,
+                                           &discard_mem, &full, ra);
+        }
+    }
+
+    switch (pte_attrs) {
     case 0xf0: /* Tagged */
         break;
 
@@ -193,28 +224,8 @@ allocation_tag_mem_internal(CPUARMState *env, int ptr_mmu_idx,
         goto fini;
     }
 
-    /*
-     * Remember this across the second lookup below,
-     * which may invalidate this pointer via tlb resize.
-     */
-    ptr_paddr = full->phys_addr | (ptr & ~TARGET_PAGE_MASK);
-
-    /*
-     * The Normal memory access can extend to the next page.  E.g. a single
-     * 8-byte access to the last byte of a page will check only the last
-     * tag on the first page.
-     * Any page access exception has priority over tag check exception.
-     */
+    /* Any debug exception has priority over a tag check exception. */
     if (atm_kind == ATM_NORMAL) {
-        int in_page = -(ptr | TARGET_PAGE_MASK);
-        if (unlikely(ptr_size > in_page)) {
-            void *discard_mem;
-            ret.flags |= probe_access_full(env, ptr + in_page, 0, ptr_access,
-                                           ptr_mmu_idx, false,
-                                           &discard_mem, &full, ra);
-        }
-
-        /* Any debug exception has priority over a tag check exception. */
         if (unlikely(ret.flags & TLB_WATCHPOINT)) {
             int wp = ptr_access == MMU_DATA_LOAD ? BP_MEM_READ : BP_MEM_WRITE;
             cpu_check_watchpoint(env_cpu(env), ptr, ptr_size,
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.