|
From: | Max Chou |
Subject: | Re: [PATCH v2 13/13] target/riscv: Simplify probing in vext_ldff |
Date: | Mon, 15 Jul 2024 15:06:48 +0800 |
User-agent: | Mozilla Thunderbird |
According to the section 7.7. Unit-stride Fault-Only-First Loads in the v spec (v1.0)The current pairing of tlb_vaddr_to_host with extra is either inefficient (user-only, with page_check_range) or incorrect (system, with probe_pages). For proper non-fault behaviour, use probe_access_flags with its nonfault parameter set to true. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/riscv/vector_helper.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 1b4d5a8e37..4d72eb74d3 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -474,7 +474,6 @@ vext_ldff(void *vd, void *v0, target_ulong base, vext_ldst_elem_fn *ldst_elem, uint32_t log2_esz, uintptr_t ra) { - void *host; uint32_t i, k, vl = 0; uint32_t nf = vext_nf(desc); uint32_t vm = vext_vm(desc); @@ -493,27 +492,31 @@ vext_ldff(void *vd, void *v0, target_ulong base, } addr = adjust_addr(env, base + i * (nf << log2_esz)); if (i == 0) { + /* Allow fault on first element. */ probe_pages(env, addr, nf << log2_esz, ra, MMU_DATA_LOAD); } else { - /* if it triggers an exception, no need to check watchpoint */ remain = nf << log2_esz; while (remain > 0) { + void *host; + int flags; + offset = -(addr | TARGET_PAGE_MASK); - host = tlb_vaddr_to_host(env, addr, MMU_DATA_LOAD, mmu_index); - if (host) { -#ifdef CONFIG_USER_ONLY - if (!page_check_range(addr, offset, PAGE_READ)) { - vl = i; - goto ProbeSuccess; - } -#else - probe_pages(env, addr, offset, ra, MMU_DATA_LOAD); -#endif - } else { + + /* Probe nonfault on subsequent elements. */ + flags = probe_access_flags(env, addr, offset, MMU_DATA_LOAD, + mmu_index, true, &host, 0); + if (flags) {
This break will just break the while loop, so the outside for loop will continue checking the following elements that we may get unexpected vl.+ /* + * Stop any flag bit set: + * invalid (unmapped) + * mmio (transaction failed) + * watchpoint (debug) + * In all cases, handle as the first load next time. + */ vl = i; - goto ProbeSuccess; + break;
} - if (remain <= offset) { + if (remain <= offset) { break; } remain -= offset; @@ -521,7 +524,6 @@ vext_ldff(void *vd, void *v0, target_ulong base, } } } -ProbeSuccess: /* load bytes from guest memory */ if (vl != 0) { env->vl = vl;
Maybe
we can replace the while loop liked below.
[Prev in Thread] | Current Thread | [Next in Thread] |