qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Gustavo Romero <gustavo.romero@linaro.org>
To: "Alex Bennée" <alex.bennee@linaro.org>
Cc: qemu-devel@nongnu.org, philmd@linaro.org,
	peter.maydell@linaro.org, richard.henderson@linaro.org
Subject: Re: [PATCH v2 9/9] tests/tcg/aarch64: Add MTE gdbstub tests
Date: Fri, 14 Jun 2024 12:58:04 -0300	[thread overview]
Message-ID: <37625bc5-d13b-4f05-26a1-1626314d6869@linaro.org> (raw)
In-Reply-To: <87o783u4wq.fsf@draig.linaro.org>

Hi Alex!

On 6/14/24 8:42 AM, Alex Bennée wrote:
> Gustavo Romero <gustavo.romero@linaro.org> writes:
> 
>> Add tests to exercise the MTE stubs.
>>
>> Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
>> ---
>>   tests/tcg/aarch64/Makefile.target     |  11 ++-
>>   tests/tcg/aarch64/gdbstub/test-mte.py |  86 ++++++++++++++++++++++
>>   tests/tcg/aarch64/mte-8.c             | 102 ++++++++++++++++++++++++++
>>   3 files changed, 197 insertions(+), 2 deletions(-)
>>   create mode 100644 tests/tcg/aarch64/gdbstub/test-mte.py
>>   create mode 100644 tests/tcg/aarch64/mte-8.c
>>
>> diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
>> index 70d728ae9a..d2e3f251eb 100644
>> --- a/tests/tcg/aarch64/Makefile.target
>> +++ b/tests/tcg/aarch64/Makefile.target
>> @@ -62,7 +62,7 @@ AARCH64_TESTS += bti-2
>>   
>>   # MTE Tests
>>   ifneq ($(CROSS_CC_HAS_ARMV8_MTE),)
>> -AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-5 mte-6 mte-7
>> +AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-5 mte-6 mte-7 mte-8
>>   mte-%: CFLAGS += -march=armv8.5-a+memtag
>>   endif
>>   
>> @@ -127,7 +127,14 @@ run-gdbstub-sve-ioctls: sve-ioctls
>>   		--bin $< --test $(AARCH64_SRC)/gdbstub/test-sve-ioctl.py, \
>>   	basic gdbstub SVE ZLEN support)
>>   
>> -EXTRA_RUNS += run-gdbstub-sysregs run-gdbstub-sve-ioctls
>> +run-gdbstub-mte: mte-8
>> +	$(call run-test, $@, $(GDB_SCRIPT) \
>> +		--gdb $(GDB) \
>> +		--qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
>> +		--bin "$< -s" --test $(AARCH64_SRC)/gdbstub/test-mte.py, \
>> +	gdbstub MTE support)
>> +
>> +EXTRA_RUNS += run-gdbstub-sysregs run-gdbstub-sve-ioctls run-gdbstub-mte
>>   endif
>>   endif
>>   
>> diff --git a/tests/tcg/aarch64/gdbstub/test-mte.py b/tests/tcg/aarch64/gdbstub/test-mte.py
>> new file mode 100644
>> index 0000000000..ec49eb8d2b
>> --- /dev/null
>> +++ b/tests/tcg/aarch64/gdbstub/test-mte.py
>> @@ -0,0 +1,86 @@
>> +from __future__ import print_function
>> +#
>> +# Test GDB memory-tag commands that exercise the stubs for the qIsAddressTagged,
>> +# qMemTag, and QMemTag packets. Logical tag-only commands rely on local
>> +# operations, hence don't exercise any stub.
>> +#
>> +# The test consists in breaking just after a atag() call (which sets the
>> +# allocation tag -- see mte-8.c for details) and setting/getting tags in
>> +# different memory locations and ranges starting at the address of the array
>> +# 'a'.
>> +#
>> +# This is launched via tests/guest-debug/run-test.py
>> +#
>> +
>> +
>> +import gdb
>> +import re
>> +from test_gdbstub import main, report
>> +
>> +
>> +PATTERN_0 = "Memory tags for address 0x[0-9a-f]+ match \(0x[0-9a-f]+\)."
>> +PATTERN_1 = ".*(0x[0-9a-f]+)"
>> +
>> +
>> +def run_test():
>> +    gdb.execute("break 99", False, True)
>> +    gdb.execute("continue", False, True)
>> +    try:
>> +        # Test if we can check correctly that the allocation tag for
>> +        # array 'a' matches the logical tag after atag() is called.
>> +        co = gdb.execute("memory-tag check a", False, True)
>> +        tags_match = re.findall(PATTERN_0, co, re.MULTILINE)
>> +        if tags_match:
>> +            report(True, f"{tags_match[0]}")
>> +        else:
>> +            report(False, "Logical and allocation tags don't match!")
>> +
>> +        # Test allocation tag 'set and print' commands. Commands on logical
>> +        # tags rely on local operation and so don't exercise any stub.
>> +
>> +        # Set the allocation tag for the first granule (16 bytes) of
>> +        # address starting at 'a' address to a known value, i.e. 0x04.
>> +        gdb.execute("memory-tag set-allocation-tag a 1 04", False, True)
>> +
>> +        # Then set the allocation tag for the second granule to a known
>> +        # value, i.e. 0x06. This tests that contiguous tag granules are
>> +        # set correct and don't run over each other.
>> +        gdb.execute("memory-tag set-allocation-tag a+16 1 06", False, True)
>> +
>> +        # Read the known values back and check if they remain the same.
>> +
>> +        co = gdb.execute("memory-tag print-allocation-tag a", False, True)
>> +        first_tag = re.match(PATTERN_1, co)[1]
>> +
>> +        co = gdb.execute("memory-tag print-allocation-tag a+16", False, True)
>> +        second_tag = re.match(PATTERN_1, co)[1]
>> +
>> +        if first_tag == "0x4" and second_tag == "0x6":
>> +            report(True, "Allocation tags are correctly set/printed.")
>> +        else:
>> +            report(False, "Can't set/print allocation tags!")
>> +
>> +        # Now test fill pattern by setting a whole page with a pattern.
>> +        gdb.execute("memory-tag set-allocation-tag a 4096 0a0b", False, True)
>> +
>> +        # And read back the tags of the last two granules in page so
>> +        # we also test if the pattern is set correctly up to the end of
>> +        # the page.
>> +        co = gdb.execute("memory-tag print-allocation-tag a+4096-32", False, True)
>> +        tag = re.match(PATTERN_1, co)[1]
>> +
>> +        co = gdb.execute("memory-tag print-allocation-tag a+4096-16", False, True)
>> +        last_tag = re.match(PATTERN_1, co)[1]
>> +
>> +        if tag == "0xa" and last_tag == "0xb":
>> +            report(True, "Fill pattern is ok.")
>> +        else:
>> +            report(False, "Fill pattern failed!")
>> +
>> +    except gdb.error:
>> +        # This usually happens because a GDB version that does not
>> +        # support memory tagging was used to run the test.
>> +        report(False, "'memory-tag' command failed!")
>> +
>> +
>> +main(run_test, expected_arch="aarch64")
>> diff --git a/tests/tcg/aarch64/mte-8.c b/tests/tcg/aarch64/mte-8.c
>> new file mode 100644
>> index 0000000000..367768e6b6
>> --- /dev/null
>> +++ b/tests/tcg/aarch64/mte-8.c
>> @@ -0,0 +1,102 @@
>> +/*
>> + * To be compiled with -march=armv8.5-a+memtag
>> + *
>> + * This test is adapted from a Linux test. Please see:
>> + *
>> + * https://www.kernel.org/doc/html/next/arch/arm64/memory-tagging-extension.html#example-of-correct-usage
>> + */
>> +#include <errno.h>
>> +#include <stdint.h>
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include <unistd.h>
>> +#include <sys/auxv.h>
>> +#include <sys/mman.h>
>> +#include <sys/prctl.h>
>> +#include <string.h>
>> +/*
>> + * From arch/arm64/include/uapi/asm/hwcap.h
>> + */
>> +#define HWCAP2_MTE              (1 << 18)
>> +
>> +/*
>> + * From arch/arm64/include/uapi/asm/mman.h
>> + */
>> +#define PROT_MTE                 0x20
>> +
>> +/*
>> + * Insert a random logical tag into the given pointer.
>> + */
>> +#define insert_random_tag(ptr) ({                   \
>> +    uint64_t __val;                                 \
>> +    asm("irg %0, %1" : "=r" (__val) : "r" (ptr));   \
>> +    __val;                                          \
>> +})
>> +
>> +/*
>> + * Set the allocation tag on the destination address.
>> + */
>> +#define set_tag(tagged_addr) do {                                      \
>> +        asm volatile("stg %0, [%0]" : : "r" (tagged_addr) : "memory"); \
>> +} while (0)
>> +
>> +
>> +int main(int argc, char *argv[])
>> +{
>> +    unsigned char *a;
>> +    unsigned long page_sz = sysconf(_SC_PAGESIZE);
>> +    unsigned long hwcap2 = getauxval(AT_HWCAP2);
>> +
>> +    if (!(argc == 2 && strcmp(argv[1], "-s") == 0)) {
>> +        return 0;
>> +    }
> 
> Whats this trying to do? I would expect the test case to be able to run
> normally without being debugged by gdb, so why do we need a particular
> command line to shortcut it here?

Good catch. This is a leftover. The first versions of the test
would cause a sigsegv, but I simplified it on this final version,
so it runs normally now.

Removed in v3. Thanks


>> +
>> +    /* check if MTE is present */
>> +    if (!(hwcap2 & HWCAP2_MTE))
>> +            return EXIT_FAILURE;
>> +
>> +    /*
>> +     * Enable the tagged address ABI, synchronous or asynchronous MTE
>> +     * tag check faults (based on per-CPU preference) and allow all
>> +     * non-zero tags in the randomly generated set.
>> +     */
>> +    if (prctl(PR_SET_TAGGED_ADDR_CTRL,
>> +              PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC |
>> +              (0xfffe << PR_MTE_TAG_SHIFT),
>> +              0, 0, 0)) {
>> +        perror("prctl() failed");
>> +        return EXIT_FAILURE;
>> +    }
>> +
>> +    a = mmap(0, page_sz, PROT_READ | PROT_WRITE,
>> +             MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
>> +    if (a == MAP_FAILED) {
>> +        perror("mmap() failed");
>> +        return EXIT_FAILURE;
>> +    }
>> +
>> +    printf("a[] address is %p\n", a);
>> +
>> +    /*
>> +     * Enable MTE on the above anonymous mmap. The flag could be passed
>> +     * directly to mmap() and skip this step.
>> +     */
>> +    if (mprotect(a, page_sz, PROT_READ | PROT_WRITE | PROT_MTE)) {
>> +        perror("mprotect() failed");
>> +        return EXIT_FAILURE;
>> +    }
>> +
>> +    /* access with the default tag (0) */
>> +    a[0] = 1;
>> +    a[1] = 2;
>> +
>> +    printf("a[0] = %hhu a[1] = %hhu\n", a[0], a[1]);
>> +
>> +    /* set the logical and allocation tags */
>> +    a = (unsigned char *)insert_random_tag(a);
>> +    set_tag(a);
>> +
>> +    printf("%p\n", a);
>> +
>> +    return 0;
>> +}
> 


  reply	other threads:[~2024-06-14 15:59 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-13 17:20 [PATCH v2 0/9] Add MTE stubs for aarch64 user mode Gustavo Romero
2024-06-13 17:20 ` [PATCH v2 1/9] gdbstub: Clean up process_string_cmd Gustavo Romero
2024-06-14 11:24   ` Alex Bennée
2024-06-13 17:20 ` [PATCH v2 2/9] gdbstub: Move GdbCmdParseEntry into a new header file Gustavo Romero
2024-06-14 11:25   ` Alex Bennée
2024-06-13 17:20 ` [PATCH v2 3/9] gdbstub: Add support for target-specific stubs Gustavo Romero
2024-06-14 11:27   ` Alex Bennée
2024-06-17  6:33     ` Gustavo Romero
2024-06-17  9:41       ` Alex Bennée
2024-06-13 17:20 ` [PATCH v2 4/9] target/arm: Fix exception case in allocation_tag_mem_probe Gustavo Romero
2024-06-14 11:29   ` Alex Bennée
2024-06-13 17:20 ` [PATCH v2 5/9] target/arm: Make some MTE helpers widely available Gustavo Romero
2024-06-13 17:32   ` Philippe Mathieu-Daudé
2024-06-13 18:13     ` Gustavo Romero
2024-06-14 12:34       ` Philippe Mathieu-Daudé
2024-06-17  6:37         ` Gustavo Romero
2024-06-13 17:21 ` [PATCH v2 6/9] target/arm: Factor out code for setting MTE TCF0 field Gustavo Romero
2024-06-13 17:35   ` Philippe Mathieu-Daudé
2024-06-13 18:15     ` Gustavo Romero
2024-06-14  9:02       ` Philippe Mathieu-Daudé
2024-06-17  6:56         ` Gustavo Romero
2024-06-14 11:21   ` Alex Bennée
2024-06-13 17:21 ` [PATCH v2 7/9] gdbstub: Make get cpu and hex conversion functions non-internal Gustavo Romero
2024-06-14 11:34   ` Alex Bennée
2024-06-13 17:21 ` [PATCH v2 8/9] gdbstub: Add support for MTE in user mode Gustavo Romero
2024-06-14 10:51   ` Alex Bennée
2024-06-14 16:16     ` Gustavo Romero
2024-06-13 17:21 ` [PATCH v2 9/9] tests/tcg/aarch64: Add MTE gdbstub tests Gustavo Romero
2024-06-14 11:42   ` Alex Bennée
2024-06-14 15:58     ` Gustavo Romero [this message]
2024-06-14 15:49 ` [PATCH v2 0/9] Add MTE stubs for aarch64 user mode Alex Bennée
2024-06-14 16:01   ` Gustavo Romero
2024-06-17  7:02   ` Gustavo Romero
2024-06-17  9:50     ` Alex Bennée
2024-06-24  5:40       ` Gustavo Romero

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=37625bc5-d13b-4f05-26a1-1626314d6869@linaro.org \
    --to=gustavo.romero@linaro.org \
    --cc=alex.bennee@linaro.org \
    --cc=peter.maydell@linaro.org \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).