[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