testing, gdbstub and plugin updates

- update MAINTAINERS with pointers to foo/next
   - add NOFETCH to help test custom docker builds
   - update microblaze toolchain with atomic fixes
   - update tsan build and documentation
   - don't restrict build-environment by arch unless needed
   - add cross-modifying code test
   - add tracepoints for cpu_step_atomic fallbacks
   - fix defaults for loongarch cross build
   - make check-[dco|patch] a little more verbose
   - fix gdbstub bug preventing aarch64_be-linux-user starting
   - add basic test for aarch64_be
   - clean up some gdbstub test scripts
   - fix qemu_plugin_reset
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmcaDeQACgkQ+9DbCVqe
 KkRTlQgAlFaP1Nxa8y6pRZSL0WY9J3Znf5e2GDnVN3nJbfx1wZg7oZ4/dWieDF/Y
 /9jLfMi8nDJ51tzH24PSASbHQ1xnblhuUfhRMwqAFhSwsZUb0VzdeGdq+FIyXQ5w
 Cy2Ubz7g81qP/x9JRCCUGFfXaM1LSizsY1lNioRsDd533WJLkvxWucmpSN3XhxHJ
 rEa3xI/qAcUah4G3yww47L+DmlKnJQcsihShRBC6Am2tWqxbz+1kBUaVfaVVo1if
 IPN+bBk4eI1EHdRRyWJSsq3nELzqW4FJ3+9V0ifsOFW2KGsnkhbl0qUxqDmW5aBb
 P9flEdpTfSiCbqp+IKG9vxJKuf/BGw==
 =5Wui
 -----END PGP SIGNATURE-----

Merge tag 'pull-maintainer-oct-misc-241024-1' of https://gitlab.com/stsquad/qemu into staging

testing, gdbstub and plugin updates

  - update MAINTAINERS with pointers to foo/next
  - add NOFETCH to help test custom docker builds
  - update microblaze toolchain with atomic fixes
  - update tsan build and documentation
  - don't restrict build-environment by arch unless needed
  - add cross-modifying code test
  - add tracepoints for cpu_step_atomic fallbacks
  - fix defaults for loongarch cross build
  - make check-[dco|patch] a little more verbose
  - fix gdbstub bug preventing aarch64_be-linux-user starting
  - add basic test for aarch64_be
  - clean up some gdbstub test scripts
  - fix qemu_plugin_reset

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmcaDeQACgkQ+9DbCVqe
# KkRTlQgAlFaP1Nxa8y6pRZSL0WY9J3Znf5e2GDnVN3nJbfx1wZg7oZ4/dWieDF/Y
# /9jLfMi8nDJ51tzH24PSASbHQ1xnblhuUfhRMwqAFhSwsZUb0VzdeGdq+FIyXQ5w
# Cy2Ubz7g81qP/x9JRCCUGFfXaM1LSizsY1lNioRsDd533WJLkvxWucmpSN3XhxHJ
# rEa3xI/qAcUah4G3yww47L+DmlKnJQcsihShRBC6Am2tWqxbz+1kBUaVfaVVo1if
# IPN+bBk4eI1EHdRRyWJSsq3nELzqW4FJ3+9V0ifsOFW2KGsnkhbl0qUxqDmW5aBb
# P9flEdpTfSiCbqp+IKG9vxJKuf/BGw==
# =5Wui
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 24 Oct 2024 10:05:40 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-maintainer-oct-misc-241024-1' of https://gitlab.com/stsquad/qemu:
  plugins: fix qemu_plugin_reset
  MAINTAINERS: mention my plugins/next tree
  testing: Enhance gdb probe script
  tests/tcg/aarch64: Use raw strings for regexes in test-mte.py
  tests/tcg: enable basic testing for aarch64_be-linux-user
  config/targets: update aarch64_be-linux-user gdb XML list
  MAINTAINERS: mention my gdbstub/next tree
  gitlab: make check-[dco|patch] a little more verbose
  dockerfiles: fix default targets for debian-loongarch-cross
  accel/tcg: add tracepoints for cpu_loop_exit_atomic
  tests/tcg/x86_64: Add cross-modifying code test
  scripts/ci: remove architecture checks for build-environment updates
  docs/devel: update tsan build documentation
  meson: hide tsan related warnings
  MAINTAINERS: mention my testing/next tree
  tests/docker: add NOFETCH env variable for testing
  tests/docker: Fix microblaze atomics

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2024-10-25 19:12:06 +01:00
commit fdf250e5a3
23 changed files with 273 additions and 58 deletions

View File

@ -19,10 +19,9 @@ cwd = os.getcwd()
reponame = os.path.basename(cwd)
repourl = "https://gitlab.com/%s/%s.git" % (namespace, reponame)
print(f"adding upstream git repo @ {repourl}")
subprocess.check_call(["git", "remote", "add", "check-dco", repourl])
subprocess.check_call(["git", "fetch", "check-dco", "master"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
subprocess.check_call(["git", "fetch", "check-dco", "master"])
ancestor = subprocess.check_output(["git", "merge-base",
"check-dco/master", "HEAD"],

View File

@ -19,13 +19,12 @@ cwd = os.getcwd()
reponame = os.path.basename(cwd)
repourl = "https://gitlab.com/%s/%s.git" % (namespace, reponame)
print(f"adding upstream git repo @ {repourl}")
# GitLab CI environment does not give us any direct info about the
# base for the user's branch. We thus need to figure out a common
# ancestor between the user's branch and current git master.
subprocess.check_call(["git", "remote", "add", "check-patch", repourl])
subprocess.check_call(["git", "fetch", "check-patch", "master"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
subprocess.check_call(["git", "fetch", "check-patch", "master"])
ancestor = subprocess.check_output(["git", "merge-base",
"check-patch/master", "HEAD"],

View File

@ -2985,6 +2985,7 @@ F: gdb-xml/
F: tests/tcg/multiarch/gdbstub/*
F: scripts/feature_to_c.py
F: scripts/probe-gdb-support.py
T: git https://gitlab.com/stsquad/qemu gdbstub/next
Memory API
M: Paolo Bonzini <pbonzini@redhat.com>
@ -3708,6 +3709,7 @@ F: include/tcg/
TCG Plugins
M: Alex Bennée <alex.bennee@linaro.org>
T: git https://gitlab.com/stsquad/qemu plugins/next
R: Alexandre Iooss <erdnaxe@crans.org>
R: Mahmoud Mandour <ma.mandourr@gmail.com>
R: Pierrick Bouvier <pierrick.bouvier@linaro.org>
@ -4081,6 +4083,7 @@ Build and test automation
-------------------------
Build and test automation, general continuous integration
M: Alex Bennée <alex.bennee@linaro.org>
T: git https://gitlab.com/stsquad/qemu testing/next
M: Philippe Mathieu-Daudé <philmd@linaro.org>
M: Thomas Huth <thuth@redhat.com>
R: Wainer dos Santos Moschetta <wainersm@redhat.com>

View File

@ -168,6 +168,7 @@ static uint64_t load_atomic8_or_exit(CPUState *cpu, uintptr_t ra, void *pv)
#endif
/* Ultimate fallback: re-execute in serial context. */
trace_load_atom8_or_exit_fallback(ra);
cpu_loop_exit_atomic(cpu, ra);
}
@ -212,6 +213,7 @@ static Int128 load_atomic16_or_exit(CPUState *cpu, uintptr_t ra, void *pv)
}
/* Ultimate fallback: re-execute in serial context. */
trace_load_atom16_or_exit_fallback(ra);
cpu_loop_exit_atomic(cpu, ra);
}
@ -519,6 +521,7 @@ static uint64_t load_atom_8(CPUState *cpu, uintptr_t ra,
if (HAVE_al8) {
return load_atom_extract_al8x2(pv);
}
trace_load_atom8_fallback(memop, ra);
cpu_loop_exit_atomic(cpu, ra);
default:
g_assert_not_reached();
@ -563,6 +566,7 @@ static Int128 load_atom_16(CPUState *cpu, uintptr_t ra,
break;
case MO_64:
if (!HAVE_al8) {
trace_load_atom16_fallback(memop, ra);
cpu_loop_exit_atomic(cpu, ra);
}
a = load_atomic8(pv);
@ -570,6 +574,7 @@ static Int128 load_atom_16(CPUState *cpu, uintptr_t ra,
break;
case -MO_64:
if (!HAVE_al8) {
trace_load_atom16_fallback(memop, ra);
cpu_loop_exit_atomic(cpu, ra);
}
a = load_atom_extract_al8x2(pv);
@ -897,6 +902,7 @@ static void store_atom_2(CPUState *cpu, uintptr_t ra,
g_assert_not_reached();
}
trace_store_atom2_fallback(memop, ra);
cpu_loop_exit_atomic(cpu, ra);
}
@ -961,6 +967,7 @@ static void store_atom_4(CPUState *cpu, uintptr_t ra,
return;
}
}
trace_store_atom4_fallback(memop, ra);
cpu_loop_exit_atomic(cpu, ra);
default:
g_assert_not_reached();
@ -1029,6 +1036,7 @@ static void store_atom_8(CPUState *cpu, uintptr_t ra,
default:
g_assert_not_reached();
}
trace_store_atom8_fallback(memop, ra);
cpu_loop_exit_atomic(cpu, ra);
}
@ -1107,5 +1115,6 @@ static void store_atom_16(CPUState *cpu, uintptr_t ra,
default:
g_assert_not_reached();
}
trace_store_atom16_fallback(memop, ra);
cpu_loop_exit_atomic(cpu, ra);
}

View File

@ -467,4 +467,8 @@ void plugin_gen_tb_end(CPUState *cpu, size_t num_insns)
/* inject the instrumentation at the appropriate places */
plugin_gen_inject(ptb);
/* reset plugin translation state (plugin_tb is reused between blocks) */
tcg_ctx->plugin_db = NULL;
tcg_ctx->plugin_insn = NULL;
}

View File

@ -12,3 +12,15 @@ memory_notdirty_set_dirty(uint64_t vaddr) "0x%" PRIx64
# translate-all.c
translate_block(void *tb, uintptr_t pc, const void *tb_code) "tb:%p, pc:0x%"PRIxPTR", tb_code:%p"
# ldst_atomicity
load_atom2_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""
load_atom4_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""
load_atom8_or_exit_fallback(uintptr_t ra) "ra:0x%"PRIxPTR""
load_atom8_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""
load_atom16_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""
load_atom16_or_exit_fallback(uintptr_t ra) "ra:0x%"PRIxPTR""
store_atom2_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""
store_atom4_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""
store_atom8_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""
store_atom16_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""

View File

@ -29,7 +29,7 @@
#include "exec/page-protection.h"
#include "exec/helper-proto.h"
#include "qemu/atomic128.h"
#include "trace/trace-root.h"
#include "trace.h"
#include "tcg/tcg-ldst.h"
#include "internal-common.h"
#include "internal-target.h"

View File

@ -1,7 +1,7 @@
TARGET_ARCH=aarch64
TARGET_BASE_ARCH=arm
TARGET_BIG_ENDIAN=y
TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/aarch64-pauth.xml
TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/aarch64-pauth.xml gdb-xml/aarch64-mte.xml
TARGET_HAS_BFLT=y
CONFIG_SEMIHOSTING=y
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y

5
configure vendored
View File

@ -1418,6 +1418,7 @@ probe_target_compiler() {
target_arch=${1%%-*}
case $target_arch in
aarch64) container_hosts="x86_64 aarch64" ;;
aarch64_be) container_hosts="x86_64 aarch64" ;;
alpha) container_hosts=x86_64 ;;
arm) container_hosts="x86_64 aarch64" ;;
hexagon) container_hosts=x86_64 ;;
@ -1447,6 +1448,10 @@ probe_target_compiler() {
case $target_arch in
# debian-all-test-cross architectures
aarch64_be)
container_image=debian-all-test-cross
container_cross_prefix=aarch64-linux-gnu-
;;
hppa|m68k|mips|riscv64|sparc64)
container_image=debian-all-test-cross
;;

View File

@ -628,20 +628,38 @@ Building and Testing with TSan
It is possible to build and test with TSan, with a few additional steps.
These steps are normally done automatically in the docker.
There is a one time patch needed in clang-9 or clang-10 at this time:
TSan is supported for clang and gcc.
One particularity of sanitizers is that all the code, including shared objects
dependencies, should be built with it.
In the case of TSan, any synchronization primitive from glib (GMutex for
instance) will not be recognized, and will lead to false positives.
To build a tsan version of glib:
.. code::
sed -i 's/^const/static const/g' \
/usr/lib/llvm-10/lib/clang/10.0.0/include/sanitizer/tsan_interface.h
$ git clone --depth=1 --branch=2.81.0 https://github.com/GNOME/glib.git
$ cd glib
$ CFLAGS="-O2 -g -fsanitize=thread" meson build
$ ninja -C build
To configure the build for TSan:
.. code::
../configure --enable-tsan --cc=clang-10 --cxx=clang++-10 \
../configure --enable-tsan \
--disable-werror --extra-cflags="-O0"
When executing qemu, don't forget to point to tsan glib:
.. code::
$ glib_dir=/path/to/glib
$ export LD_LIBRARY_PATH=$glib_dir/build/gio:$glib_dir/build/glib:$glib_dir/build/gmodule:$glib_dir/build/gobject:$glib_dir/build/gthread
# check correct version is used
$ ldd build/qemu-x86_64 | grep glib
$ qemu-system-x86_64 ...
The runtime behavior of TSAN is controlled by the TSAN_OPTIONS environment
variable.

View File

@ -538,7 +538,15 @@ if get_option('tsan')
prefix: '#include <sanitizer/tsan_interface.h>')
error('Cannot enable TSAN due to missing fiber annotation interface')
endif
qemu_cflags = ['-fsanitize=thread'] + qemu_cflags
tsan_warn_suppress = []
# gcc (>=11) will report constructions not supported by tsan:
# "error: atomic_thread_fence is not supported with -fsanitize=thread"
# https://gcc.gnu.org/gcc-11/changes.html
# However, clang does not support this warning and this triggers an error.
if cc.has_argument('-Wno-tsan')
tsan_warn_suppress = ['-Wno-tsan']
endif
qemu_cflags = ['-fsanitize=thread'] + tsan_warn_suppress + qemu_cflags
qemu_ldflags = ['-fsanitize=thread'] + qemu_ldflags
endif

View File

@ -39,7 +39,6 @@
when:
- ansible_facts['distribution'] == 'Ubuntu'
- ansible_facts['distribution_version'] == '22.04'
- ansible_facts['architecture'] == 'aarch64' or ansible_facts['architecture'] == 'x86_64'
- name: Install packages for QEMU on Ubuntu 22.04
package:
@ -47,7 +46,6 @@
when:
- ansible_facts['distribution'] == 'Ubuntu'
- ansible_facts['distribution_version'] == '22.04'
- ansible_facts['architecture'] == 'aarch64' or ansible_facts['architecture'] == 'x86_64'
- name: Install armhf cross-compile packages to build QEMU on AArch64 Ubuntu 22.04
package:

View File

@ -19,58 +19,61 @@
import argparse
import re
from subprocess import check_output, STDOUT
from subprocess import check_output, STDOUT, CalledProcessError
import sys
# mappings from gdb arch to QEMU target
mappings = {
"alpha" : "alpha",
# Mappings from gdb arch to QEMU target
MAP = {
"alpha" : ["alpha"],
"aarch64" : ["aarch64", "aarch64_be"],
"armv7": "arm",
"armv7": ["arm"],
"armv8-a" : ["aarch64", "aarch64_be"],
"avr" : "avr",
"avr" : ["avr"],
# no hexagon in upstream gdb
"hppa1.0" : "hppa",
"i386" : "i386",
"i386:x86-64" : "x86_64",
"Loongarch64" : "loongarch64",
"m68k" : "m68k",
"MicroBlaze" : "microblaze",
"hppa1.0" : ["hppa"],
"i386" : ["i386"],
"i386:x86-64" : ["x86_64"],
"Loongarch64" : ["loongarch64"],
"m68k" : ["m68k"],
"MicroBlaze" : ["microblaze"],
"mips:isa64" : ["mips64", "mips64el"],
"or1k" : "or1k",
"powerpc:common" : "ppc",
"or1k" : ["or1k"],
"powerpc:common" : ["ppc"],
"powerpc:common64" : ["ppc64", "ppc64le"],
"riscv:rv32" : "riscv32",
"riscv:rv64" : "riscv64",
"s390:64-bit" : "s390x",
"riscv:rv32" : ["riscv32"],
"riscv:rv64" : ["riscv64"],
"s390:64-bit" : ["s390x"],
"sh4" : ["sh4", "sh4eb"],
"sparc": "sparc",
"sparc:v8plus": "sparc32plus",
"sparc:v9a" : "sparc64",
"sparc": ["sparc"],
"sparc:v8plus": ["sparc32plus"],
"sparc:v9a" : ["sparc64"],
# no tricore in upstream gdb
"xtensa" : ["xtensa", "xtensaeb"]
}
def do_probe(gdb):
gdb_out = check_output([gdb,
"-ex", "set architecture",
"-ex", "quit"], stderr=STDOUT)
try:
gdb_out = check_output([gdb,
"-ex", "set architecture",
"-ex", "quit"], stderr=STDOUT, encoding="utf-8")
except (OSError) as e:
sys.exit(e)
except CalledProcessError as e:
sys.exit(f'{e}. Output:\n\n{e.output}')
m = re.search(r"Valid arguments are (.*)",
gdb_out.decode("utf-8"))
found_gdb_archs = re.search(r'Valid arguments are (.*)', gdb_out)
valid_arches = set()
targets = set()
if found_gdb_archs:
gdb_archs = found_gdb_archs.group(1).split(", ")
mapped_gdb_archs = [arch for arch in gdb_archs if arch in MAP]
if m.group(1):
for arch in m.group(1).split(", "):
if arch in mappings:
mapping = mappings[arch]
if isinstance(mapping, str):
valid_arches.add(mapping)
else:
for entry in mapping:
valid_arches.add(entry)
targets = {target for arch in mapped_gdb_archs for target in MAP[arch]}
# QEMU targets
return targets
return valid_arches
def main() -> None:
parser = argparse.ArgumentParser(description='Probe GDB Architectures')

View File

@ -92,10 +92,10 @@ endif
docker-image-alpine: NOUSER=1
debian-toolchain-run = \
$(if $(NOCACHE), \
$(if $(NOCACHE)$(NOFETCH), \
$(call quiet-command, \
$(DOCKER_SCRIPT) build -t qemu/$1 -f $< \
$(if $V,,--quiet) --no-cache \
$(if $V,,--quiet) $(if $(NOCACHE),--no-cache) \
--registry $(DOCKER_REGISTRY) --extra-files \
$(DOCKER_FILES_DIR)/$1.d/build-toolchain.sh, \
"BUILD", $1), \
@ -177,6 +177,7 @@ docker:
@echo ' NETWORK=$$BACKEND Enable virtual network interface with $$BACKEND.'
@echo ' NOUSER=1 Define to disable adding current user to containers passwd.'
@echo ' NOCACHE=1 Ignore cache when build images.'
@echo ' NOFETCH=1 Do not fetch from the registry.'
@echo ' EXECUTABLE=<path> Include executable in image.'
@echo ' EXTRA_FILES="<path> [... <path>]"'
@echo ' Include extra files in image.'

View File

@ -43,8 +43,8 @@ RUN curl -#SL https://github.com/loongson/build-tools/releases/download/2023.08.
ENV PATH $PATH:/opt/cross-tools/bin
ENV LD_LIBRARY_PATH /opt/cross-tools/lib:/opt/cross-tools/loongarch64-unknown-linux-gnu/lib:$LD_LIBRARY_PATH
ENV QEMU_CONFIGURE_OPTS --disable-system --disable-docs --disable-tools
ENV DEF_TARGET_LIST loongarch64-linux-user,loongarch-softmmu
ENV QEMU_CONFIGURE_OPTS --disable-docs --disable-tools
ENV DEF_TARGET_LIST loongarch64-linux-user,loongarch64-softmmu
ENV MAKE /usr/bin/make
# As a final step configure the user (if env is defined)

View File

@ -10,6 +10,8 @@ TOOLCHAIN_INSTALL=/usr/local
TOOLCHAIN_BIN=${TOOLCHAIN_INSTALL}/bin
CROSS_SYSROOT=${TOOLCHAIN_INSTALL}/$TARGET/sys-root
GCC_PATCH0_URL=https://raw.githubusercontent.com/Xilinx/meta-xilinx/refs/tags/xlnx-rel-v2024.1/meta-microblaze/recipes-devtools/gcc/gcc-12/0009-Patch-microblaze-Fix-atomic-boolean-return-value.patch
export PATH=${TOOLCHAIN_BIN}:$PATH
#
@ -31,6 +33,12 @@ mv gcc-11.2.0 src-gcc
mv musl-1.2.2 src-musl
mv linux-5.10.70 src-linux
#
# Patch gcc
#
wget -O - ${GCC_PATCH0_URL} | patch -d src-gcc -p1
mkdir -p bld-hdr bld-binu bld-gcc bld-musl
mkdir -p ${CROSS_SYSROOT}/usr/include

View File

@ -10,6 +10,8 @@ FROM docker.io/library/debian:11-slim
# ??? The build-dep isn't working, missing a number of
# minimal build dependiencies, e.g. libmpc.
RUN sed 's/^deb /deb-src /' </etc/apt/sources.list >/etc/apt/sources.list.d/deb-src.list
RUN apt update && \
DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \
DEBIAN_FRONTEND=noninteractive eatmydata \
@ -33,6 +35,11 @@ RUN cd /root && ./build-toolchain.sh
# and the build trees by restoring the original image,
# then copying the built toolchain from stage 0.
FROM docker.io/library/debian:11-slim
RUN apt update && \
DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \
DEBIAN_FRONTEND=noninteractive eatmydata \
apt install -y --no-install-recommends \
libmpc3
COPY --from=0 /usr/local /usr/local
# As a final step configure the user (if env is defined)
ARG USER

View File

@ -103,9 +103,14 @@ ifeq ($(filter %-softmmu, $(TARGET)),)
# then the target. If there are common tests shared between
# sub-targets (e.g. ARM & AArch64) then it is up to
# $(TARGET_NAME)/Makefile.target to include the common parent
# architecture in its VPATH.
# architecture in its VPATH. However some targets are so minimal we
# can't even build the multiarch tests.
ifneq ($(filter $(TARGET_NAME),aarch64_be),)
-include $(SRC_PATH)/tests/tcg/$(TARGET_NAME)/Makefile.target
else
-include $(SRC_PATH)/tests/tcg/multiarch/Makefile.target
-include $(SRC_PATH)/tests/tcg/$(TARGET_NAME)/Makefile.target
endif
# Add the common build options
CFLAGS+=-Wall -Werror -O0 -g -fno-strict-aliasing

View File

@ -23,8 +23,8 @@ 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]+\\)."
PATTERN_1 = ".*(0x[0-9a-f]+)"
PATTERN_0 = r"Memory tags for address 0x[0-9a-f]+ match \(0x[0-9a-f]+\)."
PATTERN_1 = r".*(0x[0-9a-f]+)"
def run_test():

View File

@ -0,0 +1,17 @@
# -*- Mode: makefile -*-
#
# A super basic AArch64 BE makefile. As we don't have any big-endian
# libc available the best we can do is a basic Hello World.
AARCH64BE_SRC=$(SRC_PATH)/tests/tcg/aarch64_be
VPATH += $(AARCH64BE_SRC)
AARCH64BE_TEST_SRCS=$(notdir $(wildcard $(AARCH64BE_SRC)/*.c))
AARCH64BE_TESTS=$(AARCH64BE_TEST_SRCS:.c=)
#MULTIARCH_TESTS = $(MULTIARCH_SRCS:.c=)
# We need to specify big-endian cflags
CFLAGS +=-mbig-endian -ffreestanding
LDFLAGS +=-nostdlib
TESTS += $(AARCH64BE_TESTS)

View File

@ -0,0 +1,35 @@
/*
* Non-libc syscall hello world for Aarch64 BE
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#define __NR_write 64
#define __NR_exit 93
int write(int fd, char *buf, int len)
{
register int x0 __asm__("x0") = fd;
register char *x1 __asm__("x1") = buf;
register int x2 __asm__("x2") = len;
register int x8 __asm__("x8") = __NR_write;
asm volatile("svc #0" : : "r"(x0), "r"(x1), "r"(x2), "r"(x8));
return len;
}
void exit(int ret)
{
register int x0 __asm__("x0") = ret;
register int x8 __asm__("x8") = __NR_exit;
asm volatile("svc #0" : : "r"(x0), "r"(x8));
__builtin_unreachable();
}
void _start(void)
{
write(1, "Hello World\n", 12);
exit(0);
}

View File

@ -17,6 +17,7 @@ X86_64_TESTS += cmpxchg
X86_64_TESTS += adox
X86_64_TESTS += test-1648
X86_64_TESTS += test-2175
X86_64_TESTS += cross-modifying-code
TESTS=$(MULTIARCH_TESTS) $(X86_64_TESTS) test-x86_64
else
TESTS=$(MULTIARCH_TESTS)
@ -27,6 +28,9 @@ adox: CFLAGS=-O2
run-test-i386-ssse3: QEMU_OPTS += -cpu max
run-plugin-test-i386-ssse3-%: QEMU_OPTS += -cpu max
cross-modifying-code: CFLAGS+=-pthread
cross-modifying-code: LDFLAGS+=-pthread
test-x86_64: LDFLAGS+=-lm -lc
test-x86_64: test-i386.c test-i386.h test-i386-shift.h test-i386-muldiv.h
$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)

View File

@ -0,0 +1,80 @@
/*
* Test patching code, running in one thread, from another thread.
*
* Intel SDM calls this "cross-modifying code" and recommends a special
* sequence, which requires both threads to cooperate.
*
* Linux kernel uses a different sequence that does not require cooperation and
* involves patching the first byte with int3.
*
* Finally, there is user-mode software out there that simply uses atomics, and
* that seems to be good enough in practice. Test that QEMU has no problems
* with this as well.
*/
#include <assert.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdlib.h>
void add1_or_nop(long *x);
asm(".pushsection .rwx,\"awx\",@progbits\n"
".globl add1_or_nop\n"
/* addq $0x1,(%rdi) */
"add1_or_nop: .byte 0x48, 0x83, 0x07, 0x01\n"
"ret\n"
".popsection\n");
#define THREAD_WAIT 0
#define THREAD_PATCH 1
#define THREAD_STOP 2
static void *thread_func(void *arg)
{
int val = 0x0026748d; /* nop */
while (true) {
switch (__atomic_load_n((int *)arg, __ATOMIC_SEQ_CST)) {
case THREAD_WAIT:
break;
case THREAD_PATCH:
val = __atomic_exchange_n((int *)&add1_or_nop, val,
__ATOMIC_SEQ_CST);
break;
case THREAD_STOP:
return NULL;
default:
assert(false);
__builtin_unreachable();
}
}
}
#define INITIAL 42
#define COUNT 1000000
int main(void)
{
int command = THREAD_WAIT;
pthread_t thread;
long x = 0;
int err;
int i;
err = pthread_create(&thread, NULL, &thread_func, &command);
assert(err == 0);
__atomic_store_n(&command, THREAD_PATCH, __ATOMIC_SEQ_CST);
for (i = 0; i < COUNT; i++) {
add1_or_nop(&x);
}
__atomic_store_n(&command, THREAD_STOP, __ATOMIC_SEQ_CST);
err = pthread_join(thread, NULL);
assert(err == 0);
assert(x >= INITIAL);
assert(x <= INITIAL + COUNT);
return EXIT_SUCCESS;
}