@samitouri / QOSamiQemu / commits / 45199fb0a0

tests/tcg: add test for MTE_STORE_ONLY

Added a test that checks that MTE checks are not performed on loads when MTE_STORE_ONLY is enabled. Signed-off-by: Gabriel Brookman <brookmangabriel@gmail.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260529-feat-mte4-v7-15-ccbd3c14eb3c@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Gabriel Brookman committed May 29, 2026 at 12:52 UTC 45199fb0a0c48cc9f69a64465e1abbae9b15c6de
3 files changed +52 -3
tests/tcg/aarch64/Makefile.target
+1 -1
@@ -64,7 +64,7 @@ AARCH64_TESTS += bti-2
64
65 # MTE Tests
66 ifneq ($(CROSS_CC_HAS_ARMV8_MTE),)
67 -AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-5 mte-6 mte-7 mte-8 mte-9
67 +AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-5 mte-6 mte-7 mte-8 mte-9 mte-10
68 mte-%: CFLAGS += $(CROSS_CC_HAS_ARMV8_MTE)
69 endif
70
tests/tcg/aarch64/mte-10.c new
+49
@@ -0,0 +1,49 @@
1 +/*
2 + * Memory tagging, write-only tag checking
3 + *
4 + * SPDX-License-Identifier: GPL-2.0-or-later
5 + */
6 +
7 +#include "mte.h"
8 +
9 +void pass(int sig, siginfo_t *info, void *uc)
10 +{
11 + exit(0);
12 +}
13 +
14 +int main(int ac, char **av)
15 +{
16 + struct sigaction sa;
17 + int *p0, *p1, *p2;
18 + long excl = 1;
19 +
20 + enable_mte(PR_MTE_TCF_SYNC | PR_MTE_STORE_ONLY);
21 + p0 = alloc_mte_mem(sizeof(*p0));
22 +
23 + /* Create two differently tagged pointers. */
24 + asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(excl));
25 + asm("gmi %0,%1,%0" : "+r"(excl) : "r" (p1));
26 + assert(excl != 1);
27 + asm("irg %0,%1,%2" : "=r"(p2) : "r"(p0), "r"(excl));
28 + assert(p1 != p2);
29 +
30 + /* Store the tag from the first pointer. */
31 + asm("stg %0, [%0]" : : "r"(p1));
32 +
33 + /*
34 + * We write to p1 (stg above makes this check pass) and read from
35 + * p2 (improperly tagged, but since it's a read, we don't care).
36 + */
37 + *p1 = *p2;
38 +
39 + /* enable handler */
40 + memset(&sa, 0, sizeof(sa));
41 + sa.sa_sigaction = pass;
42 + sa.sa_flags = SA_SIGINFO;
43 + sigaction(SIGSEGV, &sa, NULL);
44 +
45 + /* now we write to badly tagged p2, should fault. */
46 + *p2 = 0;
47 +
48 + abort();
49 +}
tests/tcg/aarch64/mte.h
+2 -2
@@ -40,10 +40,10 @@
40 # define SEGV_MTESERR 9
41 #endif
42
43 -static void enable_mte(int tcf)
43 +static void enable_mte(int flags)
44 {
45 int r = prctl(PR_SET_TAGGED_ADDR_CTRL,
46 - PR_TAGGED_ADDR_ENABLE | tcf | (0xfffe << PR_MTE_TAG_SHIFT),
46 + PR_TAGGED_ADDR_ENABLE | flags | (0xfffe << PR_MTE_TAG_SHIFT),
47 0, 0, 0);
48 if (r < 0) {
49 perror("PR_SET_TAGGED_ADDR_CTRL");