diff mbox series

[v3,12/12] tests/tcg/s390x: Test unaligned accesses

Message ID 20230315232624.107329-13-iii@linux.ibm.com
State New
Headers show
Series target/s390x: Handle unaligned accesses | expand

Commit Message

Ilya Leoshkevich March 15, 2023, 11:26 p.m. UTC
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

Comments

Thomas Huth March 16, 2023, 10:33 a.m. UTC | #1
On 16/03/2023 00.26, Ilya Leoshkevich wrote:
> 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>
> ---
...
> diff --git a/tests/tcg/s390x/pgm-specification.inc b/tests/tcg/s390x/pgm-specification.inc
> new file mode 100644
> index 00000000000..e3899ed4718
> --- /dev/null
> +++ b/tests/tcg/s390x/pgm-specification.inc
> @@ -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

Honestly, this looks like quite a ugly pre-processor magic to me. Wouldn't 
it be possible to have the test code in normal .S files instead and then 
link it once with the C code for the linux-user binaries, and once with the 
assembly startup code for the system binaries?

  Thomas
diff mbox series

Patch

diff --git a/tests/tcg/s390x/Makefile.softmmu-target b/tests/tcg/s390x/Makefile.softmmu-target
index 725b6c598db..f32b7872e51 100644
--- a/tests/tcg/s390x/Makefile.softmmu-target
+++ b/tests/tcg/s390x/Makefile.softmmu-target
@@ -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
diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
index cf93b966862..cd207237f17 100644
--- a/tests/tcg/s390x/Makefile.target
+++ b/tests/tcg/s390x/Makefile.target
@@ -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)
diff --git a/tests/tcg/s390x/asm-const.h b/tests/tcg/s390x/asm-const.h
new file mode 100644
index 00000000000..c7e2d6ddc45
--- /dev/null
+++ b/tests/tcg/s390x/asm-const.h
@@ -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
diff --git a/tests/tcg/s390x/br-odd.S b/tests/tcg/s390x/br-odd.S
new file mode 100644
index 00000000000..9848c18d6e0
--- /dev/null
+++ b/tests/tcg/s390x/br-odd.S
@@ -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"
diff --git a/tests/tcg/s390x/cgrl-unaligned.S b/tests/tcg/s390x/cgrl-unaligned.S
new file mode 100644
index 00000000000..573eaa5c849
--- /dev/null
+++ b/tests/tcg/s390x/cgrl-unaligned.S
@@ -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"
diff --git a/tests/tcg/s390x/clrl-unaligned.S b/tests/tcg/s390x/clrl-unaligned.S
new file mode 100644
index 00000000000..bd0c02fac73
--- /dev/null
+++ b/tests/tcg/s390x/clrl-unaligned.S
@@ -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"
diff --git a/tests/tcg/s390x/crl-unaligned.S b/tests/tcg/s390x/crl-unaligned.S
new file mode 100644
index 00000000000..8446be13efc
--- /dev/null
+++ b/tests/tcg/s390x/crl-unaligned.S
@@ -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"
diff --git a/tests/tcg/s390x/ex-odd.S b/tests/tcg/s390x/ex-odd.S
new file mode 100644
index 00000000000..43b7926603c
--- /dev/null
+++ b/tests/tcg/s390x/ex-odd.S
@@ -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"
diff --git a/tests/tcg/s390x/lgrl-unaligned.S b/tests/tcg/s390x/lgrl-unaligned.S
new file mode 100644
index 00000000000..8afb350f0fd
--- /dev/null
+++ b/tests/tcg/s390x/lgrl-unaligned.S
@@ -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"
diff --git a/tests/tcg/s390x/llgfrl-unaligned.S b/tests/tcg/s390x/llgfrl-unaligned.S
new file mode 100644
index 00000000000..4b22a31c267
--- /dev/null
+++ b/tests/tcg/s390x/llgfrl-unaligned.S
@@ -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"
diff --git a/tests/tcg/s390x/lpswe-unaligned.S b/tests/tcg/s390x/lpswe-unaligned.S
new file mode 100644
index 00000000000..3aa1da7298f
--- /dev/null
+++ b/tests/tcg/s390x/lpswe-unaligned.S
@@ -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"
diff --git a/tests/tcg/s390x/lrl-unaligned.S b/tests/tcg/s390x/lrl-unaligned.S
new file mode 100644
index 00000000000..a7f75a78d7d
--- /dev/null
+++ b/tests/tcg/s390x/lrl-unaligned.S
@@ -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"
diff --git a/tests/tcg/s390x/pgm-specification.inc b/tests/tcg/s390x/pgm-specification.inc
new file mode 100644
index 00000000000..e3899ed4718
--- /dev/null
+++ b/tests/tcg/s390x/pgm-specification.inc
@@ -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
diff --git a/tests/tcg/s390x/pgm-specification.mak b/tests/tcg/s390x/pgm-specification.mak
new file mode 100644
index 00000000000..6f8684901d5
--- /dev/null
+++ b/tests/tcg/s390x/pgm-specification.mak
@@ -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)
diff --git a/tests/tcg/s390x/stgrl-unaligned.S b/tests/tcg/s390x/stgrl-unaligned.S
new file mode 100644
index 00000000000..f105560c5c4
--- /dev/null
+++ b/tests/tcg/s390x/stgrl-unaligned.S
@@ -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"
diff --git a/tests/tcg/s390x/strl-unaligned.S b/tests/tcg/s390x/strl-unaligned.S
new file mode 100644
index 00000000000..896708cebd1
--- /dev/null
+++ b/tests/tcg/s390x/strl-unaligned.S
@@ -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"