Add a bare-metal test for vector fault-only-first loads whose
first-element probe crosses a page boundary. The test covers a body
access that crosses the boundary after the first element, and a first
element that itself straddles the boundary, checking that both cases
report a full vl and vstart of 0 rather than faulting on a mapped page.

Signed-off-by: Max Chou <[email protected]>
---
 tests/tcg/riscv64/Makefile.softmmu-target |  9 ++-
 tests/tcg/riscv64/test-rvv-ldst-ff-page.S | 83 +++++++++++++++++++++++
 2 files changed, 90 insertions(+), 2 deletions(-)
 create mode 100644 tests/tcg/riscv64/test-rvv-ldst-ff-page.S

diff --git a/tests/tcg/riscv64/Makefile.softmmu-target 
b/tests/tcg/riscv64/Makefile.softmmu-target
index 9e0e0490753..93c4e58e0c2 100644
--- a/tests/tcg/riscv64/Makefile.softmmu-target
+++ b/tests/tcg/riscv64/Makefile.softmmu-target
@@ -86,14 +86,16 @@ run-test-vle32ff: test-vle32ff
 test-vle32ff: CFLAGS += -march=rv64gcv
 
 RVV_LDST_MARCH = -march=rv64gcv
-RVV_LDST_TESTS = test-rvv-ldst-ff-pmp test-rvv-ldst-us-pmp
+RVV_LDST_TESTS = test-rvv-ldst-ff-pmp test-rvv-ldst-us-pmp \
+       test-rvv-ldst-ff-page
 CLEANFILES += $(RVV_LDST_TESTS)
 
 $(RVV_LDST_TESTS): %: %.S rvv-ldst.inc $(LINK_SCRIPT)
        $(CC) $(CFLAGS) $(RVV_LDST_MARCH) $< -Wa,--noexecstack -c -o [email protected]
        $(LD) $(LDFLAGS) [email protected] -o $@
 
-EXTRA_RUNS += run-test-rvv-ldst-ff-pmp run-test-rvv-ldst-us-pmp
+EXTRA_RUNS += run-test-rvv-ldst-ff-pmp run-test-rvv-ldst-us-pmp \
+       run-test-rvv-ldst-ff-page
 
 run-test-rvv-ldst-ff-pmp: test-rvv-ldst-ff-pmp
        $(call run-test, $<, $(QEMU) -cpu 
rv64$(comma)v=true$(comma)vlen=128$(comma)elen=64$(comma)vext_spec=v1.0$(comma)rvv_ta_all_1s=true$(comma)rvv_ma_all_1s=true
 $(QEMU_OPTS)$<)
@@ -101,5 +103,8 @@ run-test-rvv-ldst-ff-pmp: test-rvv-ldst-ff-pmp
 run-test-rvv-ldst-us-pmp: test-rvv-ldst-us-pmp
        $(call run-test, $<, $(QEMU) -cpu 
rv64$(comma)v=true$(comma)vlen=128$(comma)elen=64$(comma)vext_spec=v1.0$(comma)rvv_ta_all_1s=true$(comma)rvv_ma_all_1s=true
 $(QEMU_OPTS)$<)
 
+run-test-rvv-ldst-ff-page: test-rvv-ldst-ff-page
+       $(call run-test, $<, $(QEMU) -cpu 
rv64$(comma)v=true$(comma)vlen=128$(comma)elen=64$(comma)vext_spec=v1.0 
$(QEMU_OPTS)$<)
+
 # We don't currently support the multiarch system tests
 undefine MULTIARCH_TESTS
diff --git a/tests/tcg/riscv64/test-rvv-ldst-ff-page.S 
b/tests/tcg/riscv64/test-rvv-ldst-ff-page.S
new file mode 100644
index 00000000000..63b1e0ac8a8
--- /dev/null
+++ b/tests/tcg/riscv64/test-rvv-ldst-ff-page.S
@@ -0,0 +1,83 @@
+/*
+ * RISC-V vector fault-only-first probe page-crossing tests
+ *
+ * A first-element probe validates the mapping only for the bytes that
+ * the first (fault-only) element itself touches, then lets the
+ * remaining elements of the vector body fault normally.  An
+ * implementation that instead probes the whole multi-element access
+ * range as one host operation aborts as soon as that range crosses a
+ * page boundary, even though every page involved is in fact mapped.
+ *
+ * Case 1 crosses the page boundary only in the vector body, after the
+ * first element.  Case 2 crosses it inside the first element itself,
+ * so the first-element probe must span both pages it touches.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+    #include "rvv-ldst.inc"
+
+    .text
+    .global _start
+_start:
+    RVV_ENABLE
+    lla             t0, trap_handler
+    csrw            mtvec, t0
+
+    /*
+     * Case 1: the body crosses the page boundary; the first element does not.
+     */
+    CASE    1
+    li              t0, 3
+    vsetvli         t1, t0, e8, m1, tu, mu
+    lla             a0, cross_segment
+    vlseg2e8ff.v    v2, (a0)
+    csrr            t0, vl
+    ASSERT_EQ       t0, 3
+    csrr            t0, vstart
+    ASSERT_EQ       t0, 0
+    lla             a0, output
+    vsseg2e8.v      v2, (a0)
+    lbu             t0, 5(a0)
+    ASSERT_EQ       t0, 0x66
+
+    /*
+     * Case 2: the first segment element itself straddles the page boundary.
+     */
+    CASE    2
+    li              t0, 3
+    vsetvli         t1, t0, e8, m1, tu, mu
+    lla             a0, straddle_segment
+    vlseg2e8ff.v    v2, (a0)
+    csrr            t0, vl
+    ASSERT_EQ       t0, 3
+    csrr            t0, vstart
+    ASSERT_EQ       t0, 0
+    lla             a0, output
+    vsseg2e8.v      v2, (a0)
+    lbu             t0, 5(a0)
+    ASSERT_EQ       t0, 0xf6
+    li              a0, 0
+exit:
+    SEMI_EXIT
+    FAIL
+
+    /*
+     * No trap is expected: a spurious fault from the page-crossing probe
+     * is the very thing under test.  Report the case number rather than
+     * vectoring to the reset value of mtvec and hanging until the
+     * harness timeout.
+     */
+    .balign 4
+trap_handler:
+    j               fail
+
+    .data
+    .balign 16
+semiargs: .space 16
+    .balign 4096
+    .space 4094
+cross_segment: .byte 0x11, 0x22, 0x33, 0x44, 0x55, 0x66
+output: .space 6
+    .balign 4096
+    .space 4095
+straddle_segment: .byte 0xa1, 0xb2, 0xc3, 0xd4, 0xe5, 0xf6
-- 
2.43.0


Reply via email to