From 1bbf2d010fc0e5f0a9c5e1967368c44bc64e086a Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Mon, 16 Mar 2020 17:21:28 +0000 Subject: tests/docker: Install tools to cross-debug and build Linux kernels We often run Linux kernels to test QEMU. We sometimes need to build them manually to use non-default features. We only miss the tiny 'bc' tool. The ncurses library is helpful to run 'make menuconfig'. Finally, gdb-multiarch allow us to debug a TCG guest when its architecture is different than the host. Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée Message-Id: <20200212202738.12986-1-philmd@redhat.com> Message-Id: <20200316172155.971-2-alex.bennee@linaro.org> --- tests/docker/dockerfiles/debian10.docker | 3 +++ tests/docker/dockerfiles/debian9.docker | 3 +++ 2 files changed, 6 insertions(+) (limited to 'tests') diff --git a/tests/docker/dockerfiles/debian10.docker b/tests/docker/dockerfiles/debian10.docker index 5de79ae552..2fcdc406e8 100644 --- a/tests/docker/dockerfiles/debian10.docker +++ b/tests/docker/dockerfiles/debian10.docker @@ -17,14 +17,17 @@ RUN apt update && \ DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \ DEBIAN_FRONTEND=noninteractive eatmydata \ apt install -y --no-install-recommends \ + bc \ bison \ build-essential \ ca-certificates \ clang \ dbus \ flex \ + gdb-multiarch \ gettext \ git \ + libncurses5-dev \ pkg-config \ psmisc \ python3 \ diff --git a/tests/docker/dockerfiles/debian9.docker b/tests/docker/dockerfiles/debian9.docker index 8cbd742bb5..92edbbf0f4 100644 --- a/tests/docker/dockerfiles/debian9.docker +++ b/tests/docker/dockerfiles/debian9.docker @@ -17,13 +17,16 @@ RUN apt update && \ DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \ DEBIAN_FRONTEND=noninteractive eatmydata \ apt install -y --no-install-recommends \ + bc \ bison \ build-essential \ ca-certificates \ clang \ flex \ + gdb-multiarch \ gettext \ git \ + libncurses5-dev \ pkg-config \ psmisc \ python3 \ -- cgit v1.2.3-55-g7522 From 72e3c1dd573a64eb730175ddccf39fb40d39c986 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Mon, 16 Mar 2020 17:21:29 +0000 Subject: tests/docker: Update VirGL git repository URL freedesktop.org is moving to a GitLab instance, use the new url. - https://www.fooishbar.org/blog/gitlab-fdo-introduction/ - https://gitlab.freedesktop.org/freedesktop/freedesktop/-/wikis/home Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée Message-Id: <20200212202709.12665-2-philmd@redhat.com> Message-Id: <20200316172155.971-3-alex.bennee@linaro.org> --- tests/docker/dockerfiles/debian-amd64.docker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/docker/dockerfiles/debian-amd64.docker b/tests/docker/dockerfiles/debian-amd64.docker index 3b860af106..b67fad54cb 100644 --- a/tests/docker/dockerfiles/debian-amd64.docker +++ b/tests/docker/dockerfiles/debian-amd64.docker @@ -27,7 +27,7 @@ RUN apt update && \ libegl1-mesa-dev \ libepoxy-dev \ libgbm-dev -RUN git clone https://anongit.freedesktop.org/git/virglrenderer.git /usr/src/virglrenderer && \ +RUN git clone https://gitlab.freedesktop.org/virgl/virglrenderer.git /usr/src/virglrenderer && \ cd /usr/src/virglrenderer && git checkout virglrenderer-0.7.0 RUN cd /usr/src/virglrenderer && ./autogen.sh && ./configure --with-glx --disable-tests && make install -- cgit v1.2.3-55-g7522 From 5b9d40fafef1d7c9e8ab23939cb309228f32b652 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Mon, 16 Mar 2020 17:21:30 +0000 Subject: tests/docker: Remove obsolete VirGL --with-glx configure option The GLX configure option has been removed in 71c75f201d [*]. We missed that when updating to v0.7.0 in commit fab3220f97. This silents: configure: creating ./config.status config.status: creating virglrenderer.pc ... configure: WARNING: unrecognized options: --with-glx [*] https://gitlab.freedesktop.org/virgl/virglrenderer/commit/71c75f201d Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée Message-Id: <20200212202709.12665-3-philmd@redhat.com> Message-Id: <20200316172155.971-4-alex.bennee@linaro.org> --- tests/docker/dockerfiles/debian-amd64.docker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/docker/dockerfiles/debian-amd64.docker b/tests/docker/dockerfiles/debian-amd64.docker index b67fad54cb..a1d40a56fa 100644 --- a/tests/docker/dockerfiles/debian-amd64.docker +++ b/tests/docker/dockerfiles/debian-amd64.docker @@ -29,7 +29,7 @@ RUN apt update && \ libgbm-dev RUN git clone https://gitlab.freedesktop.org/virgl/virglrenderer.git /usr/src/virglrenderer && \ cd /usr/src/virglrenderer && git checkout virglrenderer-0.7.0 -RUN cd /usr/src/virglrenderer && ./autogen.sh && ./configure --with-glx --disable-tests && make install +RUN cd /usr/src/virglrenderer && ./autogen.sh && ./configure --disable-tests && make install # netmap RUN apt update && \ -- cgit v1.2.3-55-g7522 From d2763944e24e04bf8c6cf9fcd3d11ae6da3ca113 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Mon, 16 Mar 2020 17:21:31 +0000 Subject: tests/docker: Update VirGL to v0.8.0 Building the qemu:debian-amd64 fails when building VirGL: make[2]: Entering directory '/usr/src/virglrenderer/src/gallium/auxiliary' CC cso_cache/cso_cache.lo CC cso_cache/cso_hash.lo CC os/os_misc.lo CC util/u_debug.lo CC util/u_debug_describe.lo CC util/u_format.lo GEN util/u_format_table.c Traceback (most recent call last): File "./util/u_format_table.py", line 168, in main() File "./util/u_format_table.py", line 164, in main write_format_table(formats) File "./util/u_format_table.py", line 132, in write_format_table print(" %s,\t/* is_array */" % (bool_map(format.is_array()),)) File "/usr/src/virglrenderer/src/gallium/auxiliary/util/u_format_parse.py", line 164, in is_array return self.array_element() != None File "/usr/src/virglrenderer/src/gallium/auxiliary/util/u_format_parse.py", line 73, in __eq__ return self.type == other.type and self.norm == other.norm and self.pure == other.pure and self.size == other.size AttributeError: 'NoneType' object has no attribute 'type' make[2]: Leaving directory '/usr/src/virglrenderer/src/gallium/auxiliary' make[2]: *** [Makefile:906: util/u_format_table.c] Error 1 make[1]: *** [Makefile:631: install-recursive] Error 1 VirGL commits a8962eda1..a613dcc82 fix this problem. Update to VirGL 0.8.0 which contains them. Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée Message-Id: <20200212202709.12665-4-philmd@redhat.com> Message-Id: <20200316172155.971-5-alex.bennee@linaro.org> --- tests/docker/dockerfiles/debian-amd64.docker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/docker/dockerfiles/debian-amd64.docker b/tests/docker/dockerfiles/debian-amd64.docker index a1d40a56fa..c70c916343 100644 --- a/tests/docker/dockerfiles/debian-amd64.docker +++ b/tests/docker/dockerfiles/debian-amd64.docker @@ -28,7 +28,7 @@ RUN apt update && \ libepoxy-dev \ libgbm-dev RUN git clone https://gitlab.freedesktop.org/virgl/virglrenderer.git /usr/src/virglrenderer && \ - cd /usr/src/virglrenderer && git checkout virglrenderer-0.7.0 + cd /usr/src/virglrenderer && git checkout virglrenderer-0.8.0 RUN cd /usr/src/virglrenderer && ./autogen.sh && ./configure --disable-tests && make install # netmap -- cgit v1.2.3-55-g7522 From fe185734d0164234b1af1c9fcaaf39aefb089d15 Mon Sep 17 00:00:00 2001 From: Alex Bennée Date: Mon, 16 Mar 2020 17:21:47 +0000 Subject: tests/tcg/aarch64: userspace system register test This tests a bunch of registers that the kernel allows userspace to read including the CPUID registers. We need a SVE aware compiler as we are testing the id_aa64zfr0_el1 register in the set. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson Message-Id: <20200316172155.971-21-alex.bennee@linaro.org> --- tests/tcg/aarch64/Makefile.target | 6 ++ tests/tcg/aarch64/sysregs.c | 172 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 tests/tcg/aarch64/sysregs.c (limited to 'tests') diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target index 8ed477d0d5..a25afc071c 100644 --- a/tests/tcg/aarch64/Makefile.target +++ b/tests/tcg/aarch64/Makefile.target @@ -42,4 +42,10 @@ run-semiconsole: semiconsole run-plugin-semiconsole-with-%: $(call skip-test, $<, "MANUAL ONLY") +ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_SVE),) +# System Registers Tests +AARCH64_TESTS += sysregs +sysregs: CFLAGS+=-march=armv8.1-a+sve +endif + TESTS += $(AARCH64_TESTS) diff --git a/tests/tcg/aarch64/sysregs.c b/tests/tcg/aarch64/sysregs.c new file mode 100644 index 0000000000..40cf8d2877 --- /dev/null +++ b/tests/tcg/aarch64/sysregs.c @@ -0,0 +1,172 @@ +/* + * Check emulated system register access for linux-user mode. + * + * See: https://www.kernel.org/doc/Documentation/arm64/cpu-feature-registers.txt + * + * Copyright (c) 2019 Linaro + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include +#include +#include +#include +#include +#include + +#ifndef HWCAP_CPUID +#define HWCAP_CPUID (1 << 11) +#endif + +int failed_bit_count; + +/* Read and print system register `id' value */ +#define get_cpu_reg(id) ({ \ + unsigned long __val = 0xdeadbeef; \ + asm("mrs %0, "#id : "=r" (__val)); \ + printf("%-20s: 0x%016lx\n", #id, __val); \ + __val; \ + }) + +/* As above but also check no bits outside of `mask' are set*/ +#define get_cpu_reg_check_mask(id, mask) ({ \ + unsigned long __cval = get_cpu_reg(id); \ + unsigned long __extra = __cval & ~mask; \ + if (__extra) { \ + printf("%-20s: 0x%016lx\n", " !!extra bits!!", __extra); \ + failed_bit_count++; \ + } \ +}) + +/* As above but check RAZ */ +#define get_cpu_reg_check_zero(id) ({ \ + unsigned long __val = 0xdeadbeef; \ + asm("mrs %0, "#id : "=r" (__val)); \ + if (__val) { \ + printf("%-20s: 0x%016lx (not RAZ!)\n", #id, __val); \ + failed_bit_count++; \ + } \ +}) + +/* Chunk up mask into 63:48, 47:32, 31:16, 15:0 to ease counting */ +#define _m(a, b, c, d) (0x ## a ## b ## c ## d ##ULL) + +bool should_fail; +int should_fail_count; +int should_not_fail_count; +uintptr_t failed_pc[10]; + +void sigill_handler(int signo, siginfo_t *si, void *data) +{ + ucontext_t *uc = (ucontext_t *)data; + + if (should_fail) { + should_fail_count++; + } else { + uintptr_t pc = (uintptr_t) uc->uc_mcontext.pc; + failed_pc[should_not_fail_count++] = pc; + } + uc->uc_mcontext.pc += 4; +} + +int main(void) +{ + struct sigaction sa; + + /* Hook in a SIGILL handler */ + memset(&sa, 0, sizeof(struct sigaction)); + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = &sigill_handler; + sigemptyset(&sa.sa_mask); + + if (sigaction(SIGILL, &sa, 0) != 0) { + perror("sigaction"); + return 1; + } + + /* Counter values have been exposed since Linux 4.12 */ + printf("Checking Counter registers\n"); + + get_cpu_reg(ctr_el0); + get_cpu_reg(cntvct_el0); + get_cpu_reg(cntfrq_el0); + + /* HWCAP_CPUID indicates we can read feature registers, since Linux 4.11 */ + if (!(getauxval(AT_HWCAP) & HWCAP_CPUID)) { + printf("CPUID registers unavailable\n"); + return 1; + } else { + printf("Checking CPUID registers\n"); + } + + /* + * Some registers only expose some bits to user-space. Anything + * that is IMPDEF is exported as 0 to user-space. The _mask checks + * assert no extra bits are set. + * + * This check is *not* comprehensive as some fields are set to + * minimum valid fields - for the purposes of this check allowed + * to have non-zero values. + */ + get_cpu_reg_check_mask(id_aa64isar0_el1, _m(00ff,ffff,f0ff,fff0)); + get_cpu_reg_check_mask(id_aa64isar1_el1, _m(0000,00f0,ffff,ffff)); + /* TGran4 & TGran64 as pegged to -1 */ + get_cpu_reg_check_mask(id_aa64mmfr0_el1, _m(0000,0000,ff00,0000)); + get_cpu_reg_check_zero(id_aa64mmfr1_el1); + /* EL1/EL0 reported as AA64 only */ + get_cpu_reg_check_mask(id_aa64pfr0_el1, _m(000f,000f,00ff,0011)); + get_cpu_reg_check_mask(id_aa64pfr1_el1, _m(0000,0000,0000,00f0)); + /* all hidden, DebugVer fixed to 0x6 (ARMv8 debug architecture) */ + get_cpu_reg_check_mask(id_aa64dfr0_el1, _m(0000,0000,0000,0006)); + get_cpu_reg_check_zero(id_aa64dfr1_el1); + get_cpu_reg_check_zero(id_aa64zfr0_el1); + + get_cpu_reg_check_zero(id_aa64afr0_el1); + get_cpu_reg_check_zero(id_aa64afr1_el1); + + get_cpu_reg_check_mask(midr_el1, _m(0000,0000,ffff,ffff)); + /* mpidr sets bit 31, everything else hidden */ + get_cpu_reg_check_mask(mpidr_el1, _m(0000,0000,8000,0000)); + /* REVIDR is all IMPDEF so should be all zeros to user-space */ + get_cpu_reg_check_zero(revidr_el1); + + /* + * There are a block of more registers that are RAZ in the rest of + * the Op0=3, Op1=0, CRn=0, CRm=0,4,5,6,7 space. However for + * brevity we don't check stuff that is currently un-allocated + * here. Feel free to add them ;-) + */ + + printf("Remaining registers should fail\n"); + should_fail = true; + + /* Unexposed register access causes SIGILL */ + get_cpu_reg(id_mmfr0_el1); + get_cpu_reg(id_mmfr1_el1); + get_cpu_reg(id_mmfr2_el1); + get_cpu_reg(id_mmfr3_el1); + + get_cpu_reg(mvfr0_el1); + get_cpu_reg(mvfr1_el1); + + if (should_not_fail_count > 0) { + int i; + for (i = 0; i < should_not_fail_count; i++) { + uintptr_t pc = failed_pc[i]; + uint32_t insn = *(uint32_t *) pc; + printf("insn %#x @ %#lx unexpected FAIL\n", insn, pc); + } + return 1; + } + + if (failed_bit_count > 0) { + printf("Extra information leaked to user-space!\n"); + return 1; + } + + return should_fail_count == 6 ? 0 : 1; +} -- cgit v1.2.3-55-g7522 From db2ea0dd1b73c8cfcd53de94bfcec37726587199 Mon Sep 17 00:00:00 2001 From: Alex Bennée Date: Mon, 16 Mar 2020 17:21:49 +0000 Subject: tests/guest-debug: add a simple test runner The test runners job is to start QEMU with guest debug enabled and then spawn a gdb process running a test script that exercises the functionality it wants to test. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson Tested-by: Philippe Mathieu-Daudé Message-Id: <20200316172155.971-23-alex.bennee@linaro.org> --- tests/guest-debug/run-test.py | 57 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100755 tests/guest-debug/run-test.py (limited to 'tests') diff --git a/tests/guest-debug/run-test.py b/tests/guest-debug/run-test.py new file mode 100755 index 0000000000..8c49ee2f22 --- /dev/null +++ b/tests/guest-debug/run-test.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +# +# Run a gdbstub test case +# +# Copyright (c) 2019 Linaro +# +# Author: Alex Bennée +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. +# See the COPYING file in the top-level directory. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import argparse +import subprocess +import shutil +import shlex + +def get_args(): + parser = argparse.ArgumentParser(description="A gdbstub test runner") + parser.add_argument("--qemu", help="Qemu binary for test", + required=True) + parser.add_argument("--qargs", help="Qemu arguments for test") + parser.add_argument("--binary", help="Binary to debug", + required=True) + parser.add_argument("--test", help="GDB test script", + required=True) + parser.add_argument("--gdb", help="The gdb binary to use", default=None) + + return parser.parse_args() + +if __name__ == '__main__': + args = get_args() + + # Search for a gdb we can use + if not args.gdb: + args.gdb = shutil.which("gdb-multiarch") + if not args.gdb: + args.gdb = shutil.which("gdb") + if not args.gdb: + print("We need gdb to run the test") + exit(-1) + + # Launch QEMU with binary + if "system" in args.qemu: + cmd = "%s %s %s -s -S" % (args.qemu, args.qargs, args.binary) + else: + cmd = "%s %s -g 1234 %s" % (args.qemu, args.qargs, args.binary) + + inferior = subprocess.Popen(shlex.split(cmd)) + + # Now launch gdb with our test and collect the result + gdb_cmd = "%s %s -ex 'target remote localhost:1234' -x %s" % (args.gdb, args.binary, args.test) + + result = subprocess.call(gdb_cmd, shell=True); + + exit(result) -- cgit v1.2.3-55-g7522 From cf58773f1c233e3bb43abc4b4b0aaad60ce9a6be Mon Sep 17 00:00:00 2001 From: Alex Bennée Date: Mon, 16 Mar 2020 17:21:50 +0000 Subject: tests/tcg/aarch64: add a gdbstub testcase for SVE registers A very simple test case which sets and reads SVE registers while running a test case. We don't really need to compile a SVE binary for this case but we will later so keep it simple for now. Signed-off-by: Alex Bennée Tested-by: Philippe Mathieu-Daudé Message-Id: <20200316172155.971-24-alex.bennee@linaro.org> --- tests/.gitignore | 1 + tests/tcg/aarch64/Makefile.target | 15 +++++++ tests/tcg/aarch64/gdbstub/test-sve.py | 84 +++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 tests/tcg/aarch64/gdbstub/test-sve.py (limited to 'tests') diff --git a/tests/.gitignore b/tests/.gitignore index 7306866f21..d03c037d77 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -10,6 +10,7 @@ qht-bench rcutorture test-* !test-*.c +!test-*.py !docker/test-* test-qapi-commands.[ch] test-qapi-init-commands.[ch] diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target index a25afc071c..b61b53e4dd 100644 --- a/tests/tcg/aarch64/Makefile.target +++ b/tests/tcg/aarch64/Makefile.target @@ -46,6 +46,21 @@ ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_SVE),) # System Registers Tests AARCH64_TESTS += sysregs sysregs: CFLAGS+=-march=armv8.1-a+sve + +ifneq ($(HAVE_GDB_BIN),) +GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py + +AARCH64_TESTS += gdbstub-sysregs + +.PHONY: gdbstub-sysregs +run-gdbstub-sysregs: sysregs + $(call run-test, $@, $(GDB_SCRIPT) \ + --gdb $(HAVE_GDB_BIN) \ + --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \ + --bin $< --test $(AARCH64_SRC)/gdbstub/test-sve.py, \ + "basic gdbstub SVE support") +endif + endif TESTS += $(AARCH64_TESTS) diff --git a/tests/tcg/aarch64/gdbstub/test-sve.py b/tests/tcg/aarch64/gdbstub/test-sve.py new file mode 100644 index 0000000000..dbe7f2aa93 --- /dev/null +++ b/tests/tcg/aarch64/gdbstub/test-sve.py @@ -0,0 +1,84 @@ +from __future__ import print_function +# +# Test the SVE registers are visable and changeable via gdbstub +# +# This is launched via tests/guest-debug/run-test.py +# + +import gdb +import sys + +MAGIC = 0xDEADBEEF + +failcount = 0 + +def report(cond, msg): + "Report success/fail of test" + if cond: + print ("PASS: %s" % (msg)) + else: + print ("FAIL: %s" % (msg)) + global failcount + failcount += 1 + +def run_test(): + "Run through the tests one by one" + + gdb.execute("info registers") + report(True, "info registers") + + gdb.execute("info registers vector") + report(True, "info registers vector") + + # Now all the zregs + frame = gdb.selected_frame() + for i in range(0, 32): + rname = "z%d" % (i) + zreg = frame.read_register(rname) + report(True, "Reading %s" % rname) + for j in range(0, 4): + cmd = "set $%s.q.u[%d] = 0x%x" % (rname, j, MAGIC) + gdb.execute(cmd) + report(True, "%s" % cmd) + for j in range(0, 4): + reg = "$%s.q.u[%d]" % (rname, j) + v = gdb.parse_and_eval(reg) + report(str(v.type) == "uint128_t", "size of %s" % (reg)) + for j in range(0, 8): + cmd = "set $%s.d.u[%d] = 0x%x" % (rname, j, MAGIC) + gdb.execute(cmd) + report(True, "%s" % cmd) + for j in range(0, 8): + reg = "$%s.d.u[%d]" % (rname, j) + v = gdb.parse_and_eval(reg) + report(str(v.type) == "uint64_t", "size of %s" % (reg)) + report(int(v) == MAGIC, "%s is 0x%x" % (reg, MAGIC)) + +# +# This runs as the script it sourced (via -x, via run-test.py) +# +try: + inferior = gdb.selected_inferior() + if inferior.was_attached == False: + print("SKIPPING (failed to attach)", file=sys.stderr) + exit(0) + arch = inferior.architecture() + report(arch.name() == "aarch64", "connected to aarch64") +except (gdb.error, AttributeError): + print("SKIPPING (not connected)", file=sys.stderr) + exit(0) + +try: + # These are not very useful in scripts + gdb.execute("set pagination off") + gdb.execute("set confirm off") + + # Run the actual tests + run_test() +except: + print ("GDB Exception: %s" % (sys.exc_info()[0])) + failcount += 1 + +print("All tests complete: %d failures" % failcount) + +exit(failcount) -- cgit v1.2.3-55-g7522 From 2b6d6371a94cab1c351fed5a0bc323eb48829cfd Mon Sep 17 00:00:00 2001 From: Alex Bennée Date: Mon, 16 Mar 2020 17:21:51 +0000 Subject: tests/tcg/aarch64: add SVE iotcl test This is a fairly bare-bones test of setting the various vector sizes for SVE which will only fail if the PR_SVE_SET_VL can't reduce the user-space vector length by powers of 2. However we will also be able to use it in a future test which exercises the GDB stub. Signed-off-by: Alex Bennée Tested-by: Philippe Mathieu-Daudé Message-Id: <20200316172155.971-25-alex.bennee@linaro.org> --- tests/tcg/aarch64/Makefile.target | 4 +++ tests/tcg/aarch64/sve-ioctls.c | 70 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 tests/tcg/aarch64/sve-ioctls.c (limited to 'tests') diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target index b61b53e4dd..c879932ff6 100644 --- a/tests/tcg/aarch64/Makefile.target +++ b/tests/tcg/aarch64/Makefile.target @@ -47,6 +47,10 @@ ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_SVE),) AARCH64_TESTS += sysregs sysregs: CFLAGS+=-march=armv8.1-a+sve +# SVE ioctl test +AARCH64_TESTS += sve-ioctls +sve-ioctls: CFLAGS+=-march=armv8.1-a+sve + ifneq ($(HAVE_GDB_BIN),) GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py diff --git a/tests/tcg/aarch64/sve-ioctls.c b/tests/tcg/aarch64/sve-ioctls.c new file mode 100644 index 0000000000..9544dffa0e --- /dev/null +++ b/tests/tcg/aarch64/sve-ioctls.c @@ -0,0 +1,70 @@ +/* + * SVE ioctls tests + * + * Test the SVE width setting ioctls work and provide a base for + * testing the gdbstub. + * + * Copyright (c) 2019 Linaro Ltd + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include +#include +#include +#include +#include +#include + +#ifndef HWCAP_CPUID +#define HWCAP_CPUID (1 << 11) +#endif + +#define SVE_MAX_QUADS (2048 / 128) +#define BYTES_PER_QUAD (128 / 8) + +#define get_cpu_reg(id) ({ \ + unsigned long __val; \ + asm("mrs %0, "#id : "=r" (__val)); \ + __val; \ + }) + +static int do_sve_ioctl_test(void) +{ + int i, res, init_vq; + + res = prctl(PR_SVE_GET_VL, 0, 0, 0, 0); + if (res < 0) { + printf("FAILED to PR_SVE_GET_VL (%d)", res); + return -1; + } + init_vq = res & PR_SVE_VL_LEN_MASK; + + for (i = init_vq; i > 15; i /= 2) { + printf("Checking PR_SVE_SET_VL=%d\n", i); + res = prctl(PR_SVE_SET_VL, i, 0, 0, 0, 0); + if (res < 0) { + printf("FAILED to PR_SVE_SET_VL (%d)", res); + return -1; + } + asm("index z0.b, #0, #1\n" + ".global __sve_ld_done\n" + "__sve_ld_done:\n" + "mov z0.b, #0\n" + : /* no outputs kept */ + : /* no inputs */ + : "memory", "z0"); + } + printf("PASS\n"); + return 0; +} + +int main(int argc, char **argv) +{ + /* we also need to probe for the ioctl support */ + if (getauxval(AT_HWCAP) & HWCAP_SVE) { + return do_sve_ioctl_test(); + } else { + printf("SKIP: no HWCAP_SVE on this system\n"); + return 0; + } +} -- cgit v1.2.3-55-g7522 From f4a23e1797dcfbcec9f6e3e7a64865ac07aabf06 Mon Sep 17 00:00:00 2001 From: Alex Bennée Date: Mon, 16 Mar 2020 17:21:52 +0000 Subject: tests/tcg/aarch64: add test-sve-ioctl guest-debug test This test exercises the gdbstub while runing the sve-iotcl test. I haven't plubmed it into make system as we need a way of verifying if gdb has the right support for SVE. Signed-off-by: Alex Bennée Message-Id: <20200316172155.971-26-alex.bennee@linaro.org> --- tests/tcg/aarch64/Makefile.target | 11 +++- tests/tcg/aarch64/gdbstub/test-sve-ioctl.py | 85 +++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 tests/tcg/aarch64/gdbstub/test-sve-ioctl.py (limited to 'tests') diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target index c879932ff6..d99b2a9ece 100644 --- a/tests/tcg/aarch64/Makefile.target +++ b/tests/tcg/aarch64/Makefile.target @@ -54,15 +54,22 @@ sve-ioctls: CFLAGS+=-march=armv8.1-a+sve ifneq ($(HAVE_GDB_BIN),) GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py -AARCH64_TESTS += gdbstub-sysregs +AARCH64_TESTS += gdbstub-sysregs gdbstub-sve-ioctls -.PHONY: gdbstub-sysregs +.PHONY: gdbstub-sysregs gdbstub-sve-ioctls run-gdbstub-sysregs: sysregs $(call run-test, $@, $(GDB_SCRIPT) \ --gdb $(HAVE_GDB_BIN) \ --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \ --bin $< --test $(AARCH64_SRC)/gdbstub/test-sve.py, \ "basic gdbstub SVE support") + +run-gdbstub-sve-ioctls: sve-ioctls + $(call run-test, $@, $(GDB_SCRIPT) \ + --gdb $(HAVE_GDB_BIN) \ + --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \ + --bin $< --test $(AARCH64_SRC)/gdbstub/test-sve-ioctl.py, \ + "basic gdbstub SVE ZLEN support") endif endif diff --git a/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py b/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py new file mode 100644 index 0000000000..984fbeb277 --- /dev/null +++ b/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py @@ -0,0 +1,85 @@ +from __future__ import print_function +# +# Test the SVE ZReg reports the right amount of data. It uses the +# sve-ioctl test and examines the register data each time the +# __sve_ld_done breakpoint is hit. +# +# This is launched via tests/guest-debug/run-test.py +# + +import gdb +import sys + +initial_vlen = 0 +failcount = 0 + +def report(cond, msg): + "Report success/fail of test" + if cond: + print ("PASS: %s" % (msg)) + else: + print ("FAIL: %s" % (msg)) + global failcount + failcount += 1 + +class TestBreakpoint(gdb.Breakpoint): + def __init__(self, sym_name="__sve_ld_done"): + super(TestBreakpoint, self).__init__(sym_name) + # self.sym, ok = gdb.lookup_symbol(sym_name) + + def stop(self): + val_i = gdb.parse_and_eval('i') + global initial_vlen + try: + for i in range(0, int(val_i)): + val_z = gdb.parse_and_eval("$z0.b.u[%d]" % i) + report(int(val_z) == i, "z0.b.u[%d] == %d" % (i, i)) + for i in range(i + 1, initial_vlen): + val_z = gdb.parse_and_eval("$z0.b.u[%d]" % i) + report(int(val_z) == 0, "z0.b.u[%d] == 0" % (i)) + except gdb.error: + report(False, "checking zregs (out of range)") + + +def run_test(): + "Run through the tests one by one" + + print ("Setup breakpoint") + bp = TestBreakpoint() + + global initial_vlen + vg = gdb.parse_and_eval("$vg") + initial_vlen = int(vg) * 8 + + gdb.execute("c") + +# +# This runs as the script it sourced (via -x, via run-test.py) +# +try: + inferior = gdb.selected_inferior() + if inferior.was_attached == False: + print("SKIPPING (failed to attach)", file=sys.stderr) + exit(0) + arch = inferior.architecture() + report(arch.name() == "aarch64", "connected to aarch64") +except (gdb.error, AttributeError): + print("SKIPPING (not connected)", file=sys.stderr) + exit(0) + +try: + # These are not very useful in scripts + gdb.execute("set pagination off") + gdb.execute("set confirm off") + + # Run the actual tests + run_test() +except: + print ("GDB Exception: %s" % (sys.exc_info()[0])) + failcount += 1 + import code + code.InteractiveConsole(locals=globals()).interact() + raise + +print("All tests complete: %d failures" % failcount) +exit(failcount) -- cgit v1.2.3-55-g7522