qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/4] target/arm: Fixup contiguous first-fault and no-fault loads


From: LIU Zhiwei
Subject: [PATCH 2/4] target/arm: Fixup contiguous first-fault and no-fault loads
Date: Mon, 7 Dec 2020 12:46:53 +0800

First-fault or no-fault doesn't mean only access one page.

When cross pages, for first-fault, if there is no fault in the first access,
the second page should be accessed. And for no-fault, the second page
should always be accessed.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/arm/sve_helper.c | 35 ++++++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index 91d1d24725..700a8a7585 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -4916,17 +4916,6 @@ void sve_ldnfff1_r(CPUARMState *env, void *vg, const 
target_ulong addr,
         } while (reg_off <= reg_last && (reg_off & 63));
     } while (reg_off <= reg_last);
 
-    /*
-     * MemSingleNF is allowed to fail for any reason.  We have special
-     * code above to handle the first element crossing a page boundary.
-     * As an implementation choice, decline to handle a cross-page element
-     * in any other position.
-     */
-    reg_off = info.reg_off_split;
-    if (reg_off >= 0) {
-        goto do_fault;
-    }
-
  second_page:
     reg_off = info.reg_off_first[1];
     if (likely(reg_off < 0)) {
@@ -4934,6 +4923,30 @@ void sve_ldnfff1_r(CPUARMState *env, void *vg, const 
target_ulong addr,
         return;
     }
 
+    mem_off = info.mem_off_first[1];
+    reg_last = info.reg_off_last[1];
+    host = info.page[1].host;
+
+    do {
+        uint64_t pg = *(uint64_t *)(vg + (reg_off >> 3));
+        do {
+            if ((pg >> (reg_off & 63)) & 1) {
+                if (unlikely(flags & TLB_WATCHPOINT) &&
+                    (cpu_watchpoint_address_matches
+                     (env_cpu(env), addr + mem_off, 1 << msz)
+                     & BP_MEM_READ)) {
+                    goto do_fault;
+                }
+                if (mtedesc && !mte_probe1(env, mtedesc, addr + mem_off)) {
+                    goto do_fault;
+                }
+                host_fn(vd, reg_off, host + mem_off);
+            }
+            reg_off += 1 << esz;
+            mem_off += 1 << msz;
+        } while (reg_off <= reg_last && (reg_off & 63));
+    } while (reg_off <= reg_last);
+
     /*
      * MemSingleNF is allowed to fail for any reason.  As an implementation
      * choice, decline to handle elements on the second page.  This should
-- 
2.23.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]