From: Brian Cain <brian.cain@oss.qualcomm.com>
To: qemu-devel@nongnu.org
Cc: Brian Cain <brian.cain@oss.qualcomm.com>,
Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Subject: [PATCH v3 3/5] tests/tcg/hexagon: add vgather/vscatter region-length tests
Date: Thu, 3 Sep 2026 18:22:31 -0700 [thread overview]
Message-ID: <20260904012233.3607547-4-brian.cain@oss.qualcomm.com> (raw)
In-Reply-To: <20260904012233.3607547-1-brian.cain@oss.qualcomm.com>
Cover the case where an offset lies beyond the region length: it
must be dropped rather than read/written.
Place one dropped gather offset on a PROT_NONE page to verify that
the instruction does not access memory for that lane.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
tests/tcg/hexagon/scatter_gather.c | 137 ++++++++++++++++++++++++++++-
1 file changed, 136 insertions(+), 1 deletion(-)
diff --git a/tests/tcg/hexagon/scatter_gather.c b/tests/tcg/hexagon/scatter_gather.c
index bf8b5e03172..40f00cc6cf5 100644
--- a/tests/tcg/hexagon/scatter_gather.c
+++ b/tests/tcg/hexagon/scatter_gather.c
@@ -31,7 +31,11 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <assert.h>
#include <inttypes.h>
+#include <sys/mman.h>
+#include <hexagon_types.h>
+#include <hvx_hexagon_protos.h>
typedef long HVX_Vector __attribute__((__vector_size__(128)))
__attribute__((aligned(128)));
@@ -85,6 +89,23 @@ unsigned int word_predicates[MATRIX_SIZE] __attribute__((aligned(128)));
/* make this big enough for all the operations */
const size_t region_len = sizeof(vtcm);
+/* Mu (region length - 1); offset is kept iff offset <= Mu */
+#define REGION_LEN_TEST_MU 127
+#define GATHER_LEN_TEST_PAGE_SIZE 4096
+static unsigned char *gather_len_test_src;
+static unsigned char gather_len_test_dst[128] __attribute__((aligned(128)));
+static unsigned char gather_len_test_dst_ref[128];
+
+/* The dropped offset must remain in the backing destination buffer. */
+#define SCATTER_LEN_TEST_DST_SIZE 512
+static unsigned char scatter_len_test_dst[SCATTER_LEN_TEST_DST_SIZE]
+ __attribute__((aligned(128)));
+static unsigned char scatter_len_test_dst_ref[SCATTER_LEN_TEST_DST_SIZE];
+static unsigned short region_len_test_offsets[MATRIX_SIZE]
+ __attribute__((aligned(128)));
+static unsigned short scatter_len_test_values[MATRIX_SIZE]
+ __attribute__((aligned(128)));
+
/* optionally add sync instructions */
#define SYNC_VECTOR 1
@@ -96,7 +117,7 @@ static void sync_scatter(void *addr)
* synchronization. Normally the dummy load would be deferred as
* long as possible to minimize stalls.
*/
- asm volatile("vmem(%0 + #0):scatter_release\n" : : "r"(addr));
+ asm volatile("vmem(%[addr] + #0):scatter_release\n" : : [addr] "r"(addr));
/* use volatile to force the load */
volatile HVX_Vector vDummy = *(HVX_Vector *)addr; vDummy = vDummy;
#endif
@@ -855,6 +876,112 @@ void check_gather_16_32_masked(void)
MATRIX_SIZE * sizeof(unsigned short));
}
+static void init_region_len_test_offsets(void)
+{
+ memset(region_len_test_offsets, 0, sizeof(region_len_test_offsets));
+ region_len_test_offsets[0] = 0; /* in region */
+ region_len_test_offsets[1] = REGION_LEN_TEST_MU - 1; /* in region */
+ region_len_test_offsets[2] = REGION_LEN_TEST_MU; /* in region */
+ region_len_test_offsets[3] = REGION_LEN_TEST_MU + 1; /* dropped */
+ region_len_test_offsets[4] = 256; /* dropped */
+}
+
+/* vgather must drop elements whose offset is beyond the region */
+void create_gather_region_len_test(void)
+{
+ unsigned char *mapping;
+
+ mapping = mmap(NULL, 2 * GATHER_LEN_TEST_PAGE_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ assert(mapping != MAP_FAILED);
+ assert(mprotect(mapping + GATHER_LEN_TEST_PAGE_SIZE,
+ GATHER_LEN_TEST_PAGE_SIZE, PROT_NONE) == 0);
+ gather_len_test_src = mapping + GATHER_LEN_TEST_PAGE_SIZE - 256;
+
+ for (int i = 0; i < 256; i++) {
+ gather_len_test_src[i] = (unsigned char)(13 + 7 * i);
+ }
+ init_region_len_test_offsets();
+ memset(gather_len_test_dst, FILL_CHAR, sizeof(gather_len_test_dst));
+}
+
+/* gather with a region shorter than the source buffer, using HVX */
+void vector_gather_region_len(void)
+{
+ HVX_Vector voff = *(HVX_Vector *)region_len_test_offsets;
+
+ Q6_vgather_ARMVh((HVX_Vector *)gather_len_test_dst,
+ (int)(uintptr_t)gather_len_test_src,
+ REGION_LEN_TEST_MU, voff);
+
+ sync_gather(gather_len_test_dst);
+}
+
+/* gather with a region shorter than the source buffer, using C */
+void scalar_gather_region_len(unsigned char *dst)
+{
+ for (int i = 0; i < MATRIX_SIZE; i++) {
+ unsigned short off = region_len_test_offsets[i];
+ if (off <= REGION_LEN_TEST_MU) {
+ dst[2 * i] = gather_len_test_src[off];
+ dst[2 * i + 1] = gather_len_test_src[off + 1];
+ }
+ }
+}
+
+void check_gather_region_len(void)
+{
+ memset(gather_len_test_dst_ref, FILL_CHAR,
+ sizeof(gather_len_test_dst_ref));
+ scalar_gather_region_len(gather_len_test_dst_ref);
+ check_buffer(__func__, gather_len_test_dst, gather_len_test_dst_ref,
+ sizeof(gather_len_test_dst_ref));
+}
+
+/* vscatter must drop elements whose offset is beyond the region */
+void create_scatter_region_len_test(void)
+{
+ init_region_len_test_offsets();
+ for (int i = 0; i < MATRIX_SIZE; i++) {
+ scatter_len_test_values[i] = 0x4100 + i;
+ }
+ memset(scatter_len_test_dst, FILL_CHAR, sizeof(scatter_len_test_dst));
+}
+
+/* scatter with a region shorter than the destination buffer, using HVX */
+void vector_scatter_region_len(void)
+{
+ HVX_Vector voff = *(HVX_Vector *)region_len_test_offsets;
+ HVX_Vector vval = *(HVX_Vector *)scatter_len_test_values;
+
+ Q6_vscatter_RMVhV((int)(uintptr_t)scatter_len_test_dst,
+ REGION_LEN_TEST_MU, voff, vval);
+
+ sync_scatter(scatter_len_test_dst);
+}
+
+/* scatter with a region shorter than the destination buffer, using C */
+void scalar_scatter_region_len(unsigned char *dst)
+{
+ for (int i = 0; i < MATRIX_SIZE; i++) {
+ unsigned short off = region_len_test_offsets[i];
+ if (off <= REGION_LEN_TEST_MU) {
+ memcpy(dst + off, &scatter_len_test_values[i],
+ sizeof(scatter_len_test_values[i]));
+ }
+ }
+}
+
+void check_scatter_region_len(void)
+{
+ memset(scatter_len_test_dst_ref, FILL_CHAR,
+ sizeof(scatter_len_test_dst_ref));
+ scalar_scatter_region_len(scatter_len_test_dst_ref);
+ check_buffer(__func__, scatter_len_test_dst, scatter_len_test_dst_ref,
+ sizeof(scatter_len_test_dst_ref));
+}
+
/* print scatter16 buffer */
void print_scatter16_buffer(void)
{
@@ -1035,6 +1162,14 @@ int main()
print_scatter16_32_buffer();
check_scatter_16_32_masked();
+ create_gather_region_len_test();
+ vector_gather_region_len();
+ check_gather_region_len();
+
+ create_scatter_region_len_test();
+ vector_scatter_region_len();
+ check_scatter_region_len();
+
puts(err ? "FAIL" : "PASS");
return err;
}
--
2.34.1
next prev parent reply other threads:[~2026-09-04 1:24 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-04 1:22 [PATCH v3 0/5] hexagon: fix HVX scatter gather, BE host Brian Cain
2026-09-04 1:22 ` [PATCH v3 1/5] target/hexagon: fix HVX big-endian byte access Brian Cain
2026-09-04 1:22 ` [PATCH v3 2/5] target/hexagon: fix HVX scatter/gather region-length check Brian Cain
2026-09-04 10:33 ` Philippe Mathieu-Daudé
2026-09-04 22:22 ` Brian Cain
2026-09-04 1:22 ` Brian Cain [this message]
2026-09-04 5:50 ` [PATCH v3 3/5] tests/tcg/hexagon: add vgather/vscatter region-length tests Pierrick Bouvier
2026-09-04 1:22 ` [PATCH v3 4/5] target/hexagon: fix HVX predicate save size for histogram ops Brian Cain
2026-09-04 1:22 ` [PATCH v3 5/5] tests/tcg/hexagon: check the two HVX predicate build paths agree Brian Cain
2026-09-04 5:51 ` Pierrick Bouvier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260904012233.3607547-4-brian.cain@oss.qualcomm.com \
--to=brian.cain@oss.qualcomm.com \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.