@@ -4,8 +4,10 @@ QEMU_OPTS=-action panic=exit-failure -kernel
%: %.S
$(CC) -march=z13 -m64 -nostdlib -static -Wl,-Ttext=0 \
- -Wl,--build-id=none $< -o $@
+ -Wl,--build-id=none -D__ASSEMBLY__ -DCONFIG_SOFTMMU $< -o $@
TESTS += unaligned-lowcore
TESTS += bal
TESTS += sam
+
+include $(S390X_SRC)/pgm-specification.mak
@@ -33,6 +33,9 @@ TESTS+=chrl
cdsg: CFLAGS+=-pthread
cdsg: LDFLAGS+=-pthread
+include $(S390X_SRC)/pgm-specification.mak
+$(PGM_SPECIFICATION_TESTS): CFLAGS+=-x c
+
Z13_TESTS=vistr
$(Z13_TESTS): CFLAGS+=-march=z13 -O2
TESTS+=$(Z13_TESTS)
new file mode 100644
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Based on linux kernel's arch/s390/include/asm/asm-const.h . */
+#ifndef ASM_CONST_H
+#define ASM_CONST_H
+
+#ifdef __ASSEMBLY__
+#define stringify_in_c(...) __VA_ARGS__
+#else
+#define __stringify_in_c(...) #__VA_ARGS__
+#define stringify_in_c(...) __stringify_in_c(__VA_ARGS__) " "
+#endif
+
+#endif
new file mode 100644
@@ -0,0 +1,18 @@
+/*
+ * Test BRanching to a non-mapped odd address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "asm-const.h"
+
+#define CODE \
+ stringify_in_c( lgrl %r1,addr;) \
+ stringify_in_c( br %r1;)
+
+#define DATA \
+ stringify_in_c(addr:;) \
+ stringify_in_c( .quad 0xDDDDDDDDDDDDDDDD;)
+
+#define EXPECTED_OLD_PSWA 0xDDDDDDDDDDDDDDDD
+
+#include "pgm-specification.inc"
new file mode 100644
@@ -0,0 +1,17 @@
+/*
+ * Test CGRL with a non-doubleword aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "asm-const.h"
+
+#define CODE \
+ stringify_in_c(expected_old_pswa:;) \
+ stringify_in_c( cgrl %r1,unaligned;)
+
+#define DATA \
+ stringify_in_c( .long 0;) \
+ stringify_in_c(unaligned:;) \
+ stringify_in_c( .quad 0;)
+
+#include "pgm-specification.inc"
new file mode 100644
@@ -0,0 +1,15 @@
+/*
+ * Test CLRL with a non-word aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "asm-const.h"
+
+#define CODE \
+ stringify_in_c(expected_old_pswa: clrl %r1,unaligned;)
+
+#define DATA \
+ stringify_in_c(.short 0;) \
+ stringify_in_c(unaligned: .long 0;)
+
+#include "pgm-specification.inc"
new file mode 100644
@@ -0,0 +1,17 @@
+/*
+ * Test CRL with a non-word aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "asm-const.h"
+
+#define CODE \
+ stringify_in_c(expected_old_pswa:;) \
+ stringify_in_c( crl %r1,unaligned;)
+
+#define DATA \
+ stringify_in_c( .short 0;) \
+ stringify_in_c(unaligned:;) \
+ stringify_in_c( .long 0;)
+
+#include "pgm-specification.inc"
new file mode 100644
@@ -0,0 +1,17 @@
+/*
+ * Test EXECUTEing a non-mapped odd address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "asm-const.h"
+
+#define CODE \
+ stringify_in_c( lgrl %r1,odd_addr;) \
+ stringify_in_c(expected_old_pswa:;) \
+ stringify_in_c( ex 0,0(%r1);)
+
+#define DATA \
+ stringify_in_c(odd_addr:;) \
+ stringify_in_c( .quad 0xDDDDDDDDDDDDDDDD;)
+
+#include "pgm-specification.inc"
new file mode 100644
@@ -0,0 +1,17 @@
+/*
+ * Test LGRL from a non-doubleword aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "asm-const.h"
+
+#define CODE \
+ stringify_in_c(expected_old_pswa:;) \
+ stringify_in_c( lgrl %r1,unaligned;)
+
+#define DATA \
+ stringify_in_c( .long 0;) \
+ stringify_in_c(unaligned:) \
+ stringify_in_c( .quad 0;)
+
+#include "pgm-specification.inc"
new file mode 100644
@@ -0,0 +1,17 @@
+/*
+ * Test LLGFRL from a non-word aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "asm-const.h"
+
+#define CODE \
+ stringify_in_c(expected_old_pswa:;) \
+ stringify_in_c( llgfrl %r1,unaligned;)
+
+#define DATA \
+ stringify_in_c( .short 0;) \
+ stringify_in_c(unaligned:;) \
+ stringify_in_c( .long 0;)
+
+#include "pgm-specification.inc"
new file mode 100644
@@ -0,0 +1,17 @@
+/*
+ * Test LPSWE from a non-doubleword aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "asm-const.h"
+
+#define CODE \
+ stringify_in_c(expected_old_pswa:;) \
+ stringify_in_c( lpswe unaligned;)
+
+#define DATA \
+ stringify_in_c( .long 0;) \
+ stringify_in_c(unaligned:) \
+ stringify_in_c( .quad 0, 0;)
+
+#include "pgm-specification.inc"
new file mode 100644
@@ -0,0 +1,17 @@
+/*
+ * Test LRL from a non-word aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "asm-const.h"
+
+#define CODE \
+ stringify_in_c(expected_old_pswa:;) \
+ stringify_in_c( lrl %r1,unaligned;)
+
+#define DATA \
+ stringify_in_c( .short 0;) \
+ stringify_in_c(unaligned:;) \
+ stringify_in_c( .long 0;)
+
+#include "pgm-specification.inc"
new file mode 100644
@@ -0,0 +1,90 @@
+/*
+ * Common code for specification exception testing.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifdef CONFIG_SOFTMMU
+ .org 0x8d
+ilc:
+ .org 0x8e
+program_interruption_code:
+ .org 0x150
+program_old_psw:
+ .org 0x1D0 /* program new PSW */
+ .quad 0x180000000,pgm /* 64-bit mode */
+ .org 0x200 /* lowcore padding */
+
+ .globl _start
+_start:
+ lpswe start64_psw
+start64:
+ CODE
+ j failure
+
+pgm:
+ chhsi program_interruption_code,0x6 /* PGM_SPECIFICATION? */
+ jne failure
+ lg %r0,expected_old_psw+8 /* ilc adjustment */
+ llgc %r1,ilc
+ agr %r0,%r1
+ stg %r0,expected_old_psw+8
+ clc expected_old_psw(16),program_old_psw /* correct location? */
+ jne failure
+ lpswe success_psw
+failure:
+ lpswe failure_psw
+
+ .align 8
+start64_psw:
+ .quad 0x180000000,start64 /* 64-bit mode */
+expected_old_psw:
+#ifndef EXPECTED_OLD_PSWA
+#define EXPECTED_OLD_PSWA expected_old_pswa
+#endif
+ .quad 0x180000000,EXPECTED_OLD_PSWA
+success_psw:
+ .quad 0x2000180000000,0xfff /* see is_special_wait_psw() */
+failure_psw:
+ .quad 0x2000180000000,0 /* disabled wait */
+ DATA
+#else
+#include <assert.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifndef EXPECTED_OLD_PSWA
+extern char expected_old_pswa[];
+#define EXPECTED_OLD_PSWA (long)expected_old_pswa
+#endif
+
+static void handle_sigill(int sig, siginfo_t *info, void *ucontext)
+{
+ if ((long)info->si_addr != EXPECTED_OLD_PSWA) {
+ _exit(EXIT_FAILURE);
+ }
+ _exit(EXIT_SUCCESS);
+}
+
+asm(" .data\n"
+ " .align 8\n"
+ DATA
+ " .previous\n");
+
+int main(void)
+{
+ struct sigaction act;
+ int err;
+
+ memset(&act, 0, sizeof(act));
+ act.sa_sigaction = handle_sigill;
+ act.sa_flags = SA_SIGINFO;
+ err = sigaction(SIGILL, &act, NULL);
+ assert(err == 0);
+
+ asm volatile(CODE);
+
+ return EXIT_FAILURE;
+}
+#endif
new file mode 100644
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+PGM_SPECIFICATION_TESTS = \
+ br-odd \
+ cgrl-unaligned \
+ clrl-unaligned \
+ crl-unaligned \
+ ex-odd \
+ lgrl-unaligned \
+ llgfrl-unaligned \
+ lpswe-unaligned \
+ lrl-unaligned \
+ stgrl-unaligned \
+ strl-unaligned
+$(PGM_SPECIFICATION_TESTS) : asm-const.h pgm-specification.inc
+TESTS += $(PGM_SPECIFICATION_TESTS)
new file mode 100644
@@ -0,0 +1,17 @@
+/*
+ * Test STGRL to a non-doubleword aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "asm-const.h"
+
+#define CODE \
+ stringify_in_c(expected_old_pswa:) \
+ stringify_in_c( stgrl %r1,unaligned)
+
+#define DATA \
+ stringify_in_c( .long 0;) \
+ stringify_in_c(unaligned:;) \
+ stringify_in_c( .quad 0;)
+
+#include "pgm-specification.inc"
new file mode 100644
@@ -0,0 +1,17 @@
+/*
+ * Test STRL to a non-word aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "asm-const.h"
+
+#define CODE \
+ stringify_in_c(expected_old_pswa:;) \
+ stringify_in_c( strl %r1,unaligned;)
+
+#define DATA \
+ stringify_in_c( .short 0;) \
+ stringify_in_c(unaligned:;) \
+ stringify_in_c( .long 0;)
+
+#include "pgm-specification.inc"
Add a number of small test that check whether accessing unaligned addresses in various ways leads to a specification exception. Run these test both in softmmu and user configurations; expect a PGM in one case and SIGILL in the other. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> --- tests/tcg/s390x/Makefile.softmmu-target | 4 +- tests/tcg/s390x/Makefile.target | 3 + tests/tcg/s390x/asm-const.h | 13 ++++ tests/tcg/s390x/br-odd.S | 18 +++++ tests/tcg/s390x/cgrl-unaligned.S | 17 +++++ tests/tcg/s390x/clrl-unaligned.S | 15 +++++ tests/tcg/s390x/crl-unaligned.S | 17 +++++ tests/tcg/s390x/ex-odd.S | 17 +++++ tests/tcg/s390x/lgrl-unaligned.S | 17 +++++ tests/tcg/s390x/llgfrl-unaligned.S | 17 +++++ tests/tcg/s390x/lpswe-unaligned.S | 17 +++++ tests/tcg/s390x/lrl-unaligned.S | 17 +++++ tests/tcg/s390x/pgm-specification.inc | 90 +++++++++++++++++++++++++ tests/tcg/s390x/pgm-specification.mak | 15 +++++ tests/tcg/s390x/stgrl-unaligned.S | 17 +++++ tests/tcg/s390x/strl-unaligned.S | 17 +++++ 16 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 tests/tcg/s390x/asm-const.h create mode 100644 tests/tcg/s390x/br-odd.S create mode 100644 tests/tcg/s390x/cgrl-unaligned.S create mode 100644 tests/tcg/s390x/clrl-unaligned.S create mode 100644 tests/tcg/s390x/crl-unaligned.S create mode 100644 tests/tcg/s390x/ex-odd.S create mode 100644 tests/tcg/s390x/lgrl-unaligned.S create mode 100644 tests/tcg/s390x/llgfrl-unaligned.S create mode 100644 tests/tcg/s390x/lpswe-unaligned.S create mode 100644 tests/tcg/s390x/lrl-unaligned.S create mode 100644 tests/tcg/s390x/pgm-specification.inc create mode 100644 tests/tcg/s390x/pgm-specification.mak create mode 100644 tests/tcg/s390x/stgrl-unaligned.S create mode 100644 tests/tcg/s390x/strl-unaligned.S