diff options
author | Ilya Leoshkevich <iii@linux.ibm.com> | 2024-10-01 16:56:18 +0200 |
---|---|---|
committer | Thomas Huth <thuth@redhat.com> | 2024-10-02 13:01:26 +0200 |
commit | e5a007001824f9cde0db58cc960d4efcf1b93f27 (patch) | |
tree | 5366cc51d58ce7c3a2b90cb8427921d4fee5f80b /tests/tcg | |
parent | d9d59149c39d2737e08cb08b5578f09eb9a40e0a (diff) | |
download | qemu-e5a007001824f9cde0db58cc960d4efcf1b93f27.zip qemu-e5a007001824f9cde0db58cc960d4efcf1b93f27.tar.gz qemu-e5a007001824f9cde0db58cc960d4efcf1b93f27.tar.bz2 |
tests/tcg/s390x: Test modifying an EXECUTE target
QEMU correctly implements the tracking of EXECUTE target modifications
by storing the instruction text in env->ex_value and tb->cs_base, the
latter of which is used for lookups.
Still, EXECUTE is a tricky corner of the s390x emulation, which can
benefit from having a regression test.
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-ID: <20241001145634.9786-1-iii@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Diffstat (limited to 'tests/tcg')
-rw-r--r-- | tests/tcg/s390x/Makefile.target | 1 | ||||
-rw-r--r-- | tests/tcg/s390x/ex-smc.c | 57 |
2 files changed, 58 insertions, 0 deletions
diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target index a8f86c9..2dab4f4 100644 --- a/tests/tcg/s390x/Makefile.target +++ b/tests/tcg/s390x/Makefile.target @@ -48,6 +48,7 @@ TESTS+=lae TESTS+=cvd TESTS+=cvb TESTS+=ts +TESTS+=ex-smc cdsg: CFLAGS+=-pthread cdsg: LDFLAGS+=-pthread diff --git a/tests/tcg/s390x/ex-smc.c b/tests/tcg/s390x/ex-smc.c new file mode 100644 index 0000000..f403640 --- /dev/null +++ b/tests/tcg/s390x/ex-smc.c @@ -0,0 +1,57 @@ +/* + * Test modifying an EXECUTE target. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include <assert.h> +#include <stdlib.h> + +/* Make sure we exercise the same EXECUTE instruction. */ +extern void execute(unsigned char *insn, unsigned char mask, + unsigned long *r1_r5); +asm(".globl execute\n" + "execute:\n" + "lg %r1,0(%r4)\n" + "lg %r5,8(%r4)\n" + "ex %r3,0(%r2)\n" + "stg %r5,8(%r4)\n" + "stg %r1,0(%r4)\n" + "br %r14\n"); + +/* Define an RWX EXECUTE target. */ +extern unsigned char lgfi[]; +asm(".pushsection .rwx,\"awx\",@progbits\n" + ".globl lgfi\n" + "lgfi: lgfi %r0,0\n" + ".popsection\n"); + +int main(void) +{ + unsigned long r1_r5[2]; + + /* Create an initial TB. */ + r1_r5[0] = -1; + r1_r5[1] = -1; + execute(lgfi, 1 << 4, r1_r5); + assert(r1_r5[0] == 0); + assert(r1_r5[1] == -1); + + /* Test changing the mask. */ + execute(lgfi, 5 << 4, r1_r5); + assert(r1_r5[0] == 0); + assert(r1_r5[1] == 0); + + /* Test changing the target. */ + lgfi[5] = 42; + execute(lgfi, 5 << 4, r1_r5); + assert(r1_r5[0] == 0); + assert(r1_r5[1] == 42); + + /* Test changing both the mask and the target. */ + lgfi[5] = 24; + execute(lgfi, 1 << 4, r1_r5); + assert(r1_r5[0] == 24); + assert(r1_r5[1] == 42); + + return EXIT_SUCCESS; +} |