testing and gdbstub updates:

- remove docker-armel-cross
   - update i686 and mipsel images to bookworm
   - use docker-all-test-cross for mips64le tests
   - fix duplicated line in docs
   - update gitlab-runner ansible script
   - support MTE in gdbstub for system mode
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmbgye8ACgkQ+9DbCVqe
 KkTesQf/WSTYAelzJWlEo0EPg5agokephfza4vdmweDujOT8MYPF9qxfsxoiTVA8
 GTtTOod9iqmY/4/EPKIqUtZH38oaX5h9on2FhSssOMy+N4lUADJ+CcHHMSj4BuUt
 jTXDSa9e5aj0m/yqg2PjF8U12Sygf7dKJturGLOWoWR5qa3xpQ2a6c3CkfxO3RQK
 yTBfIZk47iOrVvEX8chsRzpkpiXY6/S5hkZZwcqbXcUMKH2s0po9Yg031vE3yN+g
 kxJ7/mFNl49E/fqYdRahhyBDORlltCglCHsacxxa/4a216wOsNKyV3QLCJMjq8yO
 3/SPu0p+UouSFcASwTUt5XIo0G0TcA==
 =7W1s
 -----END PGP SIGNATURE-----

Merge tag 'pull-testing-gdbstub-oct-100924-1' of https://gitlab.com/stsquad/qemu into staging

testing and gdbstub updates:

  - remove docker-armel-cross
  - update i686 and mipsel images to bookworm
  - use docker-all-test-cross for mips64le tests
  - fix duplicated line in docs
  - update gitlab-runner ansible script
  - support MTE in gdbstub for system mode

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmbgye8ACgkQ+9DbCVqe
# KkTesQf/WSTYAelzJWlEo0EPg5agokephfza4vdmweDujOT8MYPF9qxfsxoiTVA8
# GTtTOod9iqmY/4/EPKIqUtZH38oaX5h9on2FhSssOMy+N4lUADJ+CcHHMSj4BuUt
# jTXDSa9e5aj0m/yqg2PjF8U12Sygf7dKJturGLOWoWR5qa3xpQ2a6c3CkfxO3RQK
# yTBfIZk47iOrVvEX8chsRzpkpiXY6/S5hkZZwcqbXcUMKH2s0po9Yg031vE3yN+g
# kxJ7/mFNl49E/fqYdRahhyBDORlltCglCHsacxxa/4a216wOsNKyV3QLCJMjq8yO
# 3/SPu0p+UouSFcASwTUt5XIo0G0TcA==
# =7W1s
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 10 Sep 2024 23:36:31 BST
# gpg:                using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [full]
# Primary key fingerprint: 6685 AE99 E751 67BC AFC8  DF35 FBD0 DB09 5A9E 2A44

* tag 'pull-testing-gdbstub-oct-100924-1' of https://gitlab.com/stsquad/qemu:
  tests/tcg/aarch64: Extend MTE gdbstub tests to system mode
  tests/tcg/aarch64: Improve linker script organization
  tests/guest-debug: Support passing arguments to the GDB test script
  gdbstub: Add support for MTE in system mode
  gdbstub: Use specific MMU index when probing MTE addresses
  scripts/ci: update the gitlab-runner playbook
  docs/devel: fix duplicate line
  tests/docker: use debian-all-test-cross for mips64el tests
  tests/docker: update debian i686 and mipsel images to bookworm
  tests/docker: remove debian-armel-cross

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2024-09-11 13:17:29 +01:00
commit a4eb31c678
18 changed files with 314 additions and 278 deletions

View file

@ -1,179 +0,0 @@
# THIS FILE WAS AUTO-GENERATED
#
# $ lcitool dockerfile --layers all --cross-arch armv6l debian-11 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
FROM docker.io/library/debian:11-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install -y eatmydata && \
eatmydata apt-get dist-upgrade -y && \
eatmydata apt-get install --no-install-recommends -y \
bash \
bc \
bison \
bsdextrautils \
bzip2 \
ca-certificates \
ccache \
dbus \
debianutils \
diffutils \
exuberant-ctags \
findutils \
flex \
gcc \
gcovr \
gettext \
git \
hostname \
libglib2.0-dev \
libgtk-vnc-2.0-dev \
libpcre2-dev \
libsndio-dev \
libspice-protocol-dev \
llvm \
locales \
make \
meson \
mtools \
ncat \
ninja-build \
openssh-client \
pkgconf \
python3 \
python3-numpy \
python3-opencv \
python3-pillow \
python3-pip \
python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
python3-venv \
python3-wheel \
python3-yaml \
rpm2cpio \
sed \
socat \
sparse \
tar \
tesseract-ocr \
tesseract-ocr-eng \
xorriso \
zstd && \
eatmydata apt-get autoremove -y && \
eatmydata apt-get autoclean -y && \
sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
RUN /usr/bin/pip3 install tomli
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
ENV NINJA "/usr/bin/ninja"
ENV PYTHON "/usr/bin/python3"
RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg --add-architecture armel && \
eatmydata apt-get update && \
eatmydata apt-get dist-upgrade -y && \
eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
eatmydata apt-get install --no-install-recommends -y \
gcc-arm-linux-gnueabi \
libaio-dev:armel \
libasan6:armel \
libasound2-dev:armel \
libattr1-dev:armel \
libbpf-dev:armel \
libbrlapi-dev:armel \
libbz2-dev:armel \
libc6-dev:armel \
libcacard-dev:armel \
libcap-ng-dev:armel \
libcapstone-dev:armel \
libcmocka-dev:armel \
libcurl4-gnutls-dev:armel \
libdaxctl-dev:armel \
libdrm-dev:armel \
libepoxy-dev:armel \
libfdt-dev:armel \
libffi-dev:armel \
libfuse3-dev:armel \
libgbm-dev:armel \
libgcrypt20-dev:armel \
libglib2.0-dev:armel \
libglusterfs-dev:armel \
libgnutls28-dev:armel \
libgtk-3-dev:armel \
libibverbs-dev:armel \
libiscsi-dev:armel \
libjemalloc-dev:armel \
libjpeg62-turbo-dev:armel \
libjson-c-dev:armel \
liblttng-ust-dev:armel \
liblzo2-dev:armel \
libncursesw5-dev:armel \
libnfs-dev:armel \
libnuma-dev:armel \
libpam0g-dev:armel \
libpipewire-0.3-dev:armel \
libpixman-1-dev:armel \
libpng-dev:armel \
libpulse-dev:armel \
librbd-dev:armel \
librdmacm-dev:armel \
libsasl2-dev:armel \
libsdl2-dev:armel \
libsdl2-image-dev:armel \
libseccomp-dev:armel \
libselinux1-dev:armel \
libslirp-dev:armel \
libsnappy-dev:armel \
libspice-server-dev:armel \
libssh-gcrypt-dev:armel \
libsystemd-dev:armel \
libtasn1-6-dev:armel \
libubsan1:armel \
libudev-dev:armel \
liburing-dev:armel \
libusb-1.0-0-dev:armel \
libusbredirhost-dev:armel \
libvdeplug-dev:armel \
libvirglrenderer-dev:armel \
libvte-2.91-dev:armel \
libzstd-dev:armel \
nettle-dev:armel \
systemtap-sdt-dev:armel \
zlib1g-dev:armel && \
eatmydata apt-get autoremove -y && \
eatmydata apt-get autoclean -y && \
mkdir -p /usr/local/share/meson/cross && \
printf "[binaries]\n\
c = '/usr/bin/arm-linux-gnueabi-gcc'\n\
ar = '/usr/bin/arm-linux-gnueabi-gcc-ar'\n\
strip = '/usr/bin/arm-linux-gnueabi-strip'\n\
pkgconfig = '/usr/bin/arm-linux-gnueabi-pkg-config'\n\
\n\
[host_machine]\n\
system = 'linux'\n\
cpu_family = 'arm'\n\
cpu = 'arm'\n\
endian = 'little'\n" > /usr/local/share/meson/cross/arm-linux-gnueabi && \
dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
mkdir -p /usr/libexec/ccache-wrappers && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabi-cc && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabi-gcc
ENV ABI "arm-linux-gnueabi"
ENV MESON_OPTS "--cross-file=arm-linux-gnueabi"
ENV QEMU_CONFIGURE_OPTS --cross-prefix=arm-linux-gnueabi-
ENV DEF_TARGET_LIST arm-softmmu,arm-linux-user,armeb-linux-user
# As a final step configure the user (if env is defined)
ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi

View file

@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
# $ lcitool dockerfile --layers all --cross-arch i686 debian-11 qemu
# $ lcitool dockerfile --layers all --cross-arch i686 debian-12 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
FROM docker.io/library/debian:11-slim
FROM docker.io/library/debian:12-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@ -48,16 +48,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
python3-venv \
python3-wheel \
python3-yaml \
rpm2cpio \
sed \
socat \
sparse \
swtpm \
tar \
tesseract-ocr \
tesseract-ocr-eng \
@ -69,8 +68,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
RUN /usr/bin/pip3 install tomli
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@ -145,6 +142,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libvdeplug-dev:i386 \
libvirglrenderer-dev:i386 \
libvte-2.91-dev:i386 \
libxdp-dev:i386 \
libzstd-dev:i386 \
nettle-dev:i386 \
systemtap-sdt-dev:i386 \

View file

@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
# $ lcitool dockerfile --layers all --cross-arch mipsel debian-11 qemu
# $ lcitool dockerfile --layers all --cross-arch mipsel debian-12 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
FROM docker.io/library/debian:11-slim
FROM docker.io/library/debian:12-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@ -48,16 +48,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
python3-venv \
python3-wheel \
python3-yaml \
rpm2cpio \
sed \
socat \
sparse \
swtpm \
tar \
tesseract-ocr \
tesseract-ocr-eng \
@ -69,8 +68,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
RUN /usr/bin/pip3 install tomli
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@ -143,6 +140,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libvdeplug-dev:mipsel \
libvirglrenderer-dev:mipsel \
libvte-2.91-dev:mipsel \
libxdp-dev:mipsel \
libzstd-dev:mipsel \
nettle-dev:mipsel \
systemtap-sdt-dev:mipsel \

View file

@ -27,6 +27,10 @@ def get_args():
parser.add_argument("--binary", help="Binary to debug",
required=True)
parser.add_argument("--test", help="GDB test script")
parser.add_argument('test_args', nargs='*',
help="Additional args for GDB test script. "
"The args should be preceded by -- to avoid confusion "
"with flags for runner script")
parser.add_argument("--gdb", help="The gdb binary to use",
default=None)
parser.add_argument("--gdb-args", help="Additional gdb arguments")
@ -91,6 +95,8 @@ if __name__ == '__main__':
gdb_cmd += " -ex 'target remote %s'" % (socket_name)
# finally the test script itself
if args.test:
if args.test_args:
gdb_cmd += f" -ex \"py sys.argv={args.test_args}\""
gdb_cmd += " -x %s" % (args.test)

View file

@ -2,6 +2,7 @@
"""
from __future__ import print_function
import argparse
import gdb
import os
import sys
@ -9,6 +10,10 @@ import traceback
fail_count = 0
class arg_parser(argparse.ArgumentParser):
def exit(self, status=None, message=""):
print("Wrong GDB script test argument! " + message)
gdb.execute("exit 1")
def report(cond, msg):
"""Report success/fail of a test"""

View file

@ -154,18 +154,12 @@ try:
trailer=cross_build("aarch64-linux-gnu-",
"aarch64-softmmu,aarch64-linux-user"))
# migration to bookworm stalled: https://lists.debian.org/debian-arm/2023/09/msg00006.html
generate_dockerfile("debian-armel-cross", "debian-11",
cross="armv6l",
trailer=cross_build("arm-linux-gnueabi-",
"arm-softmmu,arm-linux-user,armeb-linux-user"))
generate_dockerfile("debian-armhf-cross", "debian-12",
cross="armv7l",
trailer=cross_build("arm-linux-gnueabihf-",
"arm-softmmu,arm-linux-user"))
generate_dockerfile("debian-i686-cross", "debian-11",
generate_dockerfile("debian-i686-cross", "debian-12",
cross="i686",
trailer=cross_build("i686-linux-gnu-",
"x86_64-softmmu,"
@ -177,7 +171,7 @@ try:
trailer=cross_build("mips64el-linux-gnuabi64-",
"mips64el-softmmu,mips64el-linux-user"))
generate_dockerfile("debian-mipsel-cross", "debian-11",
generate_dockerfile("debian-mipsel-cross", "debian-12",
cross="mipsel",
trailer=cross_build("mipsel-linux-gnu-",
"mipsel-softmmu,mipsel-linux-user"))

View file

@ -2,14 +2,22 @@
# Aarch64 system tests
#
AARCH64_SYSTEM_SRC=$(SRC_PATH)/tests/tcg/aarch64/system
AARCH64_SRC=$(SRC_PATH)/tests/tcg/aarch64
AARCH64_SYSTEM_SRC=$(AARCH64_SRC)/system
VPATH+=$(AARCH64_SYSTEM_SRC)
# These objects provide the basic boot code and helper functions for all tests
CRT_OBJS=boot.o
AARCH64_TEST_SRCS=$(wildcard $(AARCH64_SYSTEM_SRC)/*.c)
AARCH64_TESTS = $(patsubst $(AARCH64_SYSTEM_SRC)/%.c, %, $(AARCH64_TEST_SRCS))
AARCH64_TEST_C_SRCS=$(wildcard $(AARCH64_SYSTEM_SRC)/*.c)
AARCH64_TEST_S_SRCS=$(AARCH64_SYSTEM_SRC)/mte.S
AARCH64_C_TESTS = $(patsubst $(AARCH64_SYSTEM_SRC)/%.c, %, $(AARCH64_TEST_C_SRCS))
AARCH64_S_TESTS = $(patsubst $(AARCH64_SYSTEM_SRC)/%.S, %, $(AARCH64_TEST_S_SRCS))
AARCH64_TESTS = $(AARCH64_C_TESTS)
AARCH64_TESTS += $(AARCH64_S_TESTS)
CRT_PATH=$(AARCH64_SYSTEM_SRC)
LINK_SCRIPT=$(AARCH64_SYSTEM_SRC)/kernel.ld
@ -21,7 +29,8 @@ LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
config-cc.mak: Makefile
$(quiet-@)( \
$(call cc-option,-march=armv8.3-a, CROSS_CC_HAS_ARMV8_3)) 3> config-cc.mak
$(call cc-option,-march=armv8.3-a, CROSS_CC_HAS_ARMV8_3); \
$(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE)) 3> config-cc.mak
-include config-cc.mak
# building head blobs
@ -88,3 +97,35 @@ pauth-3:
run-pauth-3:
$(call skip-test, "RUN of pauth-3", "not built")
endif
ifneq ($(CROSS_CC_HAS_ARMV8_MTE),)
QEMU_MTE_ENABLED_MACHINE=-M virt,mte=on -cpu max -display none
QEMU_OPTS_WITH_MTE_ON = $(QEMU_MTE_ENABLED_MACHINE) $(QEMU_BASE_ARGS) -kernel
mte: CFLAGS+=-march=armv8.5-a+memtag
mte: mte.S $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS)
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
run-mte: QEMU_OPTS=$(QEMU_OPTS_WITH_MTE_ON)
run-mte: mte
ifeq ($(GDB_SUPPORTS_MTE_IN_BAREMETAL),y)
run-gdbstub-mte: QEMU_OPTS=$(QEMU_OPTS_WITH_MTE_ON)
run-gdbstub-mte: mte
$(call run-test, $@, $(GDB_SCRIPT) \
--output run-gdbstub-mte.out \
--gdb $(GDB) \
--qemu $(QEMU) --qargs "-chardev null$(COMMA)id=output $(QEMU_OPTS)" \
--bin $< --test $(AARCH64_SRC)/gdbstub/test-mte.py -- --mode=system, \
gdbstub MTE support)
EXTRA_RUNS += run-gdbstub-mte
else # !GDB_SUPPORTS_MTE_IN_BAREMETAL
run-gdbstub-mte:
$(call skip-test "RUN of gdbstub-mte", "GDB does not support MTE in baremetal!")
endif
else # !CROSS_CC_HAS_ARMV8_MTE
mte:
$(call skip-test, "BUILD of $@", "missing compiler support")
run-mte:
$(call skip-test, "RUN of mte", "not build")
endif

View file

@ -138,7 +138,8 @@ run-gdbstub-mte: mte-8
$(call run-test, $@, $(GDB_SCRIPT) \
--gdb $(GDB) \
--qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
--bin $< --test $(AARCH64_SRC)/gdbstub/test-mte.py, \
--bin $< --test $(AARCH64_SRC)/gdbstub/test-mte.py \
-- --mode=user, \
gdbstub MTE support)
EXTRA_RUNS += run-gdbstub-mte

View file

@ -1,21 +1,26 @@
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.
# qMemTag, and QMemTag packets, which are used for manipulating allocation tags.
# Logical tags-related commands rely on local operations, hence don't exercise
# any stub and so are not used in this test.
#
# 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'.
# The test consists in breaking just after a tag is set in a specific memory
# chunk, and then using the GDB 'memory-tagging' subcommands to set/get tags in
# different memory locations and ranges in the MTE-enabled memory chunk.
#
# This is launched via tests/guest-debug/run-test.py
#
import gdb
try:
import gdb
except ModuleNotFoundError:
from sys import exit
exit("This script must be launched via tests/guest-debug/run-test.py!")
import re
from test_gdbstub import main, report
from sys import argv
from test_gdbstub import arg_parser, main, report
PATTERN_0 = "Memory tags for address 0x[0-9a-f]+ match \\(0x[0-9a-f]+\\)."
@ -23,12 +28,32 @@ PATTERN_1 = ".*(0x[0-9a-f]+)"
def run_test():
gdb.execute("break 95", False, True)
p = arg_parser(prog="test-mte.py", description="TCG MTE tests.")
p.add_argument("--mode", help="Run test for QEMU system or user mode.",
required=True, choices=['system','user'])
args = p.parse_args(args=argv)
if args.mode == "system":
# Break address: where to break before performing the tests
# See mte.S for details about this label.
ba = "main_end"
# Tagged address: the start of the MTE-enabled memory chunk to be tested
# 'tagged_addr' (x1) is a pointer to the MTE-enabled page. See mte.S.
ta = "$x1"
else: # mode="user"
# Line 95 in mte-8.c
ba = "95"
# 'a' array. See mte-8.c
ta = "a"
gdb.execute(f"break {ba}", 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)
# Test if we can check correctly that the allocation tag for the address
# in {ta} matches the logical tag in {ta}.
co = gdb.execute(f"memory-tag check {ta}", False, True)
tags_match = re.findall(PATTERN_0, co, re.MULTILINE)
if tags_match:
report(True, f"{tags_match[0]}")
@ -39,20 +64,20 @@ def run_test():
# 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)
# address starting at {ta} address to a known value, i.e. 0x04.
gdb.execute(f"memory-tag set-allocation-tag {ta} 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)
# set correctly and don't run over each other.
gdb.execute(f"memory-tag set-allocation-tag {ta}+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)
co = gdb.execute(f"memory-tag print-allocation-tag {ta}", False, True)
first_tag = re.match(PATTERN_1, co)[1]
co = gdb.execute("memory-tag print-allocation-tag a+16", False, True)
co = gdb.execute(f"memory-tag print-allocation-tag {ta}+16", False, True)
second_tag = re.match(PATTERN_1, co)[1]
if first_tag == "0x4" and second_tag == "0x6":
@ -61,15 +86,15 @@ def run_test():
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)
gdb.execute(f"memory-tag set-allocation-tag {ta} 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)
co = gdb.execute(f"memory-tag print-allocation-tag {ta}+4096-32", False, True)
tag = re.match(PATTERN_1, co)[1]
co = gdb.execute("memory-tag print-allocation-tag a+4096-16", False, True)
co = gdb.execute(f"memory-tag print-allocation-tag {ta}+4096-16", False, True)
last_tag = re.match(PATTERN_1, co)[1]
if tag == "0xa" and last_tag == "0xb":
@ -78,8 +103,8 @@ def run_test():
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.
# 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!")

View file

@ -135,6 +135,17 @@ __start:
orr x1, x1, x3
str x1, [x2] /* 2nd 2mb (.data & .bss)*/
/* Third block: at 'mte_page', set in kernel.ld */
adrp x1, mte_page
add x1, x1, :lo12:mte_page
bic x1, x1, #(1 << 21) - 1
and x4, x1, x5
add x2, x0, x4, lsr #(21 - 3)
/* attr(AF, NX, block, AttrIndx=Attr1) */
ldr x3, =(3 << 53) | 0x401 | (1 << 2)
orr x1, x1, x3
str x1, [x2]
/* Setup/enable the MMU. */
/*

View file

@ -1,23 +1,32 @@
ENTRY(__start)
SECTIONS
{
/* virt machine, RAM starts at 1gb */
. = (1 << 30);
MEMORY {
/* On virt machine RAM starts at 1 GiB. */
/* Align text and rodata to the 1st 2 MiB chunk. */
TXT (rx) : ORIGIN = 1 << 30, LENGTH = 2M
/* Align r/w data to the 2nd 2 MiB chunk. */
DAT (rw) : ORIGIN = (1 << 30) + 2M, LENGTH = 2M
/* Align the MTE-enabled page to the 3rd 2 MiB chunk. */
TAG (rw) : ORIGIN = (1 << 30) + 4M, LENGTH = 2M
}
SECTIONS {
.text : {
*(.text)
}
.rodata : {
*(.rodata)
}
/* align r/w section to next 2mb */
. = ALIGN(1 << 21);
} >TXT
.data : {
*(.data)
}
.bss : {
*(.bss)
}
} >DAT
.tag : {
/*
* Symbol 'mte_page' is used in boot.S to setup the PTE and in the mte.S
* test as the address that the MTE instructions operate on.
*/
mte_page = .;
} >TAG
/DISCARD/ : {
*(.ARM.attributes)
}

View file

@ -0,0 +1,109 @@
/*
* Code to help test the MTE gdbstubs in system mode.
*
* Copyright (c) 2024 Linaro Limited
*
* Author: Gustavo Romero <gustavo.romero@linaro.org>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#define addr x0 /* Ptr to the start of the MTE-enabled page. */
#define tagged_addr x1 /* 'addr' ptr with a random-generated tag added. */
#define tmp0 x2 /* Scratch register. */
#define tmp1 x3 /* Scratch register. */
#define tmp2 x4 /* Scratch register. */
#define tmp3 x5 /* Sctatch register. */
.file "mte.S"
.text
.align 4
.globl main
.type main, @function
main:
/*
* Set MAIR_EL1 (Memory Attribute Index Register). In boot.S, the
* attribute index for .mte_page is set to point to MAILR_EL field Attr1
* (AttrIndx=Attr1), so set Attr1 as Tagged Normal (MTE) to enable MTE
* on this page.
*
* Attr1 = 0xF0 => Tagged Normal (MTE)
*/
mrs tmp0, mair_el1
orr tmp0, tmp0, (0xF0 << 8)
msr mair_el1, tmp0
/*
* Set TCR_EL1 (Translation Control Registers) to ignore the top byte
* in the translated addresses so it can be used to keep the tags.
*
* TBI0[37] = 0b1 => Top Byte ignored and used for tagged addresses
*/
mrs tmp1, tcr_el1
orr tmp1, tmp1, (1 << 37)
msr tcr_el1, tmp1
/*
* Set SCTLR_EL1 (System Control Register) to enable the use of MTE
* insns., like stg & friends, and to enable synchronous exception in
* case of a tag mismatch, i.e., when the logical tag in 'tagged_addr'
* is different from the allocation tag related to 'addr' address.
*
* ATA[43] = 0b1 => Enable access to allocation tags at EL1
* TCF[41:40] = 0b01 => Tag Check Faults cause a synchronous exception
*
*/
mrs tmp2, sctlr_el1
mov tmp3, (1 << 43) | (1 << 40)
orr tmp2, tmp2, tmp3
msr sctlr_el1, tmp2
isb
/*
* MTE-enabled page resides at the 3rd 2MB chunk in the second 1GB
* block, i.e., at 0x40400000 address. See .mte_page section in boot.S
* and kernel.ld (where the address is effectively computed).
*
* Load .mte_page address into 'addr' register.
*/
adrp addr, mte_page
add addr, addr, :lo12:mte_page
/*
* Set GCR for random tag generation. 0xA5 is just a random value to set
* GCR != 0 so the tag generated by 'irg' insn. is not zero, which is
* more interesting for the tests than when tag is zero.
*/
mov tmp0, 0xA5
msr gcr_el1, tmp0
/*
* Generate a logical tag, add it to 'addr' address and put it into
* 'tagged_addr'.
*/
irg tagged_addr, addr
/*
* Store the generated tag to memory region pointed to by 'addr', i.e.
* set the allocation tag for granule at 'addr'. The tag is extracted
* by stg from tagged_addr pointer.
*/
stg tagged_addr, [addr]
/*
* Store a random value (0xdeadbeef) to tagged_addr address. This must
* not cause any Tag Check Fault since logical tag in tagged_addr and
* allocation tag associated with the memory pointed by tagged_addr are
* set the same, otherwise something is off and the test fails -- an
* exception is generated.
*/
ldr tmp1, =0xdeadbeef
str tmp1, [tagged_addr]
/* This label is used by GDB Python script test-mte.py. */
main_end:
ret