diff mbox series

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

Message ID 20230316164428.275147-13-iii@linux.ibm.com (mailing list archive)
State New, archived
Headers show
Series target/s390x: Handle unaligned accesses | expand

Commit Message

Ilya Leoshkevich March 16, 2023, 4:44 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     | 15 ++++++--
 tests/tcg/s390x/Makefile.target             |  8 +++++
 tests/tcg/s390x/br-odd.S                    | 16 +++++++++
 tests/tcg/s390x/cgrl-unaligned.S            | 16 +++++++++
 tests/tcg/s390x/clrl-unaligned.S            | 16 +++++++++
 tests/tcg/s390x/crl-unaligned.S             | 16 +++++++++
 tests/tcg/s390x/ex-odd.S                    | 17 +++++++++
 tests/tcg/s390x/lgrl-unaligned.S            | 16 +++++++++
 tests/tcg/s390x/llgfrl-unaligned.S          | 16 +++++++++
 tests/tcg/s390x/lpswe-unaligned.S           | 18 ++++++++++
 tests/tcg/s390x/lrl-unaligned.S             | 16 +++++++++
 tests/tcg/s390x/pgm-specification-softmmu.S | 40 +++++++++++++++++++++
 tests/tcg/s390x/pgm-specification-user.c    | 37 +++++++++++++++++++
 tests/tcg/s390x/pgm-specification.mak       | 15 ++++++++
 tests/tcg/s390x/softmmu.ld                  | 20 +++++++++++
 tests/tcg/s390x/stgrl-unaligned.S           | 16 +++++++++
 tests/tcg/s390x/strl-unaligned.S            | 16 +++++++++
 17 files changed, 311 insertions(+), 3 deletions(-)
 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-softmmu.S
 create mode 100644 tests/tcg/s390x/pgm-specification-user.c
 create mode 100644 tests/tcg/s390x/pgm-specification.mak
 create mode 100644 tests/tcg/s390x/softmmu.ld
 create mode 100644 tests/tcg/s390x/stgrl-unaligned.S
 create mode 100644 tests/tcg/s390x/strl-unaligned.S

Comments

Thomas Huth March 17, 2023, 8:43 a.m. UTC | #1
On 16/03/2023 17.44, 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>
> ---

Thanks for reworking this! It looks much nicer now, indeed!

Reviewed-by: Thomas Huth <thuth@redhat.com>
Thomas Huth March 17, 2023, 10:54 a.m. UTC | #2
On 16/03/2023 17.44, 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/Makefile.softmmu-target b/tests/tcg/s390x/Makefile.softmmu-target
> index 725b6c598db..6d8bf299b28 100644
> --- a/tests/tcg/s390x/Makefile.softmmu-target
> +++ b/tests/tcg/s390x/Makefile.softmmu-target
> @@ -1,11 +1,20 @@
>   S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
>   VPATH+=$(S390X_SRC)
>   QEMU_OPTS=-action panic=exit-failure -kernel
> +LINK_SCRIPT=$(S390X_SRC)/softmmu.ld
> +LDFLAGS=-nostdlib -static -Wl,-T$(LINK_SCRIPT)
>   
> -%: %.S
> -	$(CC) -march=z13 -m64 -nostdlib -static -Wl,-Ttext=0 \
> -		-Wl,--build-id=none $< -o $@
> +%.o: %.S
> +	$(CC) -march=z13 -m64 -c $< -o $@
> +
> +%: %.o $(LINK_SCRIPT)
> +	$(CC) $< -o $@ $(LDFLAGS)
>   
>   TESTS += unaligned-lowcore
>   TESTS += bal
>   TESTS += sam
> +
> +include $(S390X_SRC)/pgm-specification.mak
> +$(PGM_SPECIFICATION_TESTS): pgm-specification-softmmu.o
> +$(PGM_SPECIFICATION_TESTS): LDFLAGS+=pgm-specification-softmmu.o
> +TESTS += $(PGM_SPECIFICATION_TESTS)
> diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
> index cf93b966862..1002ab79886 100644
> --- a/tests/tcg/s390x/Makefile.target
> +++ b/tests/tcg/s390x/Makefile.target
> @@ -2,6 +2,9 @@ S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
>   VPATH+=$(S390X_SRC)
>   CFLAGS+=-march=zEC12 -m64
>   
> +%.o: %.c
> +	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
> +
>   config-cc.mak: Makefile
>   	$(quiet-@)( \
>   	    $(call cc-option,-march=z14, CROSS_CC_HAS_Z14); \
> @@ -33,6 +36,11 @@ TESTS+=chrl
>   cdsg: CFLAGS+=-pthread
>   cdsg: LDFLAGS+=-pthread
>   
> +include $(S390X_SRC)/pgm-specification.mak
> +$(PGM_SPECIFICATION_TESTS): pgm-specification-user.o
> +$(PGM_SPECIFICATION_TESTS): LDFLAGS+=pgm-specification-user.o
> +TESTS += $(PGM_SPECIFICATION_TESTS)
...
> diff --git a/tests/tcg/s390x/softmmu.ld b/tests/tcg/s390x/softmmu.ld
> new file mode 100644
> index 00000000000..ea944eaa3cb
> --- /dev/null
> +++ b/tests/tcg/s390x/softmmu.ld
> @@ -0,0 +1,20 @@
> +/*
> + * Linker script for the softmmu test kernels.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +ENTRY(_start)
> +
> +SECTIONS {
> +    . = 0;
> +
> +    .text : {
> +        *(.head)
> +        *(.text)
> +    }
> +
> +    /DISCARD/ : {
> +        *(*)
> +    }
> +}

I just gave it a try, and while it's basically working, I see a lot of these 
messages in the console:

/usr/bin/ld: warning: .note.gnu.build-id section discarded, --build-id ignored

I think you should either pass --build-id=none to the linker, or add a 
.note.gnu.build-id section to the linker script?

  Thomas
Thomas Huth March 17, 2023, 11 a.m. UTC | #3
On 17/03/2023 11.54, Thomas Huth wrote:
> On 16/03/2023 17.44, 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/Makefile.softmmu-target 
>> b/tests/tcg/s390x/Makefile.softmmu-target
>> index 725b6c598db..6d8bf299b28 100644
>> --- a/tests/tcg/s390x/Makefile.softmmu-target
>> +++ b/tests/tcg/s390x/Makefile.softmmu-target
>> @@ -1,11 +1,20 @@
>>   S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
>>   VPATH+=$(S390X_SRC)
>>   QEMU_OPTS=-action panic=exit-failure -kernel
>> +LINK_SCRIPT=$(S390X_SRC)/softmmu.ld
>> +LDFLAGS=-nostdlib -static -Wl,-T$(LINK_SCRIPT)
>> -%: %.S
>> -    $(CC) -march=z13 -m64 -nostdlib -static -Wl,-Ttext=0 \
>> -        -Wl,--build-id=none $< -o $@
>> +%.o: %.S
>> +    $(CC) -march=z13 -m64 -c $< -o $@
>> +
>> +%: %.o $(LINK_SCRIPT)
>> +    $(CC) $< -o $@ $(LDFLAGS)
>>   TESTS += unaligned-lowcore
>>   TESTS += bal
>>   TESTS += sam
>> +
>> +include $(S390X_SRC)/pgm-specification.mak
>> +$(PGM_SPECIFICATION_TESTS): pgm-specification-softmmu.o
>> +$(PGM_SPECIFICATION_TESTS): LDFLAGS+=pgm-specification-softmmu.o
>> +TESTS += $(PGM_SPECIFICATION_TESTS)
>> diff --git a/tests/tcg/s390x/Makefile.target 
>> b/tests/tcg/s390x/Makefile.target
>> index cf93b966862..1002ab79886 100644
>> --- a/tests/tcg/s390x/Makefile.target
>> +++ b/tests/tcg/s390x/Makefile.target
>> @@ -2,6 +2,9 @@ S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
>>   VPATH+=$(S390X_SRC)
>>   CFLAGS+=-march=zEC12 -m64
>> +%.o: %.c
>> +    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
>> +
>>   config-cc.mak: Makefile
>>       $(quiet-@)( \
>>           $(call cc-option,-march=z14, CROSS_CC_HAS_Z14); \
>> @@ -33,6 +36,11 @@ TESTS+=chrl
>>   cdsg: CFLAGS+=-pthread
>>   cdsg: LDFLAGS+=-pthread
>> +include $(S390X_SRC)/pgm-specification.mak
>> +$(PGM_SPECIFICATION_TESTS): pgm-specification-user.o
>> +$(PGM_SPECIFICATION_TESTS): LDFLAGS+=pgm-specification-user.o
>> +TESTS += $(PGM_SPECIFICATION_TESTS)
> ...
>> diff --git a/tests/tcg/s390x/softmmu.ld b/tests/tcg/s390x/softmmu.ld
>> new file mode 100644
>> index 00000000000..ea944eaa3cb
>> --- /dev/null
>> +++ b/tests/tcg/s390x/softmmu.ld
>> @@ -0,0 +1,20 @@
>> +/*
>> + * Linker script for the softmmu test kernels.
>> + *
>> + * SPDX-License-Identifier: GPL-2.0-or-later
>> + */
>> +
>> +ENTRY(_start)
>> +
>> +SECTIONS {
>> +    . = 0;
>> +
>> +    .text : {
>> +        *(.head)
>> +        *(.text)
>> +    }
>> +
>> +    /DISCARD/ : {
>> +        *(*)
>> +    }
>> +}
> 
> I just gave it a try, and while it's basically working, I see a lot of these 
> messages in the console:
> 
> /usr/bin/ld: warning: .note.gnu.build-id section discarded, --build-id ignored
> 
> I think you should either pass --build-id=none to the linker, or add a 
> .note.gnu.build-id section to the linker script?

This seems to work:

diff --git a/tests/tcg/s390x/Makefile.softmmu-target b/tests/tcg/s390x/Makefile.softmmu-target
--- a/tests/tcg/s390x/Makefile.softmmu-target
+++ b/tests/tcg/s390x/Makefile.softmmu-target
@@ -2,7 +2,7 @@ S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
  VPATH+=$(S390X_SRC)
  QEMU_OPTS=-action panic=exit-failure -kernel
  LINK_SCRIPT=$(S390X_SRC)/softmmu.ld
-LDFLAGS=-nostdlib -static -Wl,-T$(LINK_SCRIPT)
+LDFLAGS=-nostdlib -static -Wl,-T$(LINK_SCRIPT) -Wl,--build-id=none
  
  %.o: %.S
         $(CC) -march=z13 -m64 -c $< -o $@

I'll squash that in ... no need to resend.

  Thomas
Ilya Leoshkevich March 17, 2023, 11:02 a.m. UTC | #4
On Fri, 2023-03-17 at 12:00 +0100, Thomas Huth wrote:
> On 17/03/2023 11.54, Thomas Huth wrote:
> > On 16/03/2023 17.44, 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/Makefile.softmmu-target 
> > > b/tests/tcg/s390x/Makefile.softmmu-target
> > > index 725b6c598db..6d8bf299b28 100644
> > > --- a/tests/tcg/s390x/Makefile.softmmu-target
> > > +++ b/tests/tcg/s390x/Makefile.softmmu-target
> > > @@ -1,11 +1,20 @@
> > >   S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
> > >   VPATH+=$(S390X_SRC)
> > >   QEMU_OPTS=-action panic=exit-failure -kernel
> > > +LINK_SCRIPT=$(S390X_SRC)/softmmu.ld
> > > +LDFLAGS=-nostdlib -static -Wl,-T$(LINK_SCRIPT)
> > > -%: %.S
> > > -    $(CC) -march=z13 -m64 -nostdlib -static -Wl,-Ttext=0 \
> > > -        -Wl,--build-id=none $< -o $@
> > > +%.o: %.S
> > > +    $(CC) -march=z13 -m64 -c $< -o $@
> > > +
> > > +%: %.o $(LINK_SCRIPT)
> > > +    $(CC) $< -o $@ $(LDFLAGS)
> > >   TESTS += unaligned-lowcore
> > >   TESTS += bal
> > >   TESTS += sam
> > > +
> > > +include $(S390X_SRC)/pgm-specification.mak
> > > +$(PGM_SPECIFICATION_TESTS): pgm-specification-softmmu.o
> > > +$(PGM_SPECIFICATION_TESTS): LDFLAGS+=pgm-specification-softmmu.o
> > > +TESTS += $(PGM_SPECIFICATION_TESTS)
> > > diff --git a/tests/tcg/s390x/Makefile.target 
> > > b/tests/tcg/s390x/Makefile.target
> > > index cf93b966862..1002ab79886 100644
> > > --- a/tests/tcg/s390x/Makefile.target
> > > +++ b/tests/tcg/s390x/Makefile.target
> > > @@ -2,6 +2,9 @@ S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
> > >   VPATH+=$(S390X_SRC)
> > >   CFLAGS+=-march=zEC12 -m64
> > > +%.o: %.c
> > > +    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
> > > +
> > >   config-cc.mak: Makefile
> > >       $(quiet-@)( \
> > >           $(call cc-option,-march=z14, CROSS_CC_HAS_Z14); \
> > > @@ -33,6 +36,11 @@ TESTS+=chrl
> > >   cdsg: CFLAGS+=-pthread
> > >   cdsg: LDFLAGS+=-pthread
> > > +include $(S390X_SRC)/pgm-specification.mak
> > > +$(PGM_SPECIFICATION_TESTS): pgm-specification-user.o
> > > +$(PGM_SPECIFICATION_TESTS): LDFLAGS+=pgm-specification-user.o
> > > +TESTS += $(PGM_SPECIFICATION_TESTS)
> > ...
> > > diff --git a/tests/tcg/s390x/softmmu.ld
> > > b/tests/tcg/s390x/softmmu.ld
> > > new file mode 100644
> > > index 00000000000..ea944eaa3cb
> > > --- /dev/null
> > > +++ b/tests/tcg/s390x/softmmu.ld
> > > @@ -0,0 +1,20 @@
> > > +/*
> > > + * Linker script for the softmmu test kernels.
> > > + *
> > > + * SPDX-License-Identifier: GPL-2.0-or-later
> > > + */
> > > +
> > > +ENTRY(_start)
> > > +
> > > +SECTIONS {
> > > +    . = 0;
> > > +
> > > +    .text : {
> > > +        *(.head)
> > > +        *(.text)
> > > +    }
> > > +
> > > +    /DISCARD/ : {
> > > +        *(*)
> > > +    }
> > > +}
> > 
> > I just gave it a try, and while it's basically working, I see a lot
> > of these 
> > messages in the console:
> > 
> > /usr/bin/ld: warning: .note.gnu.build-id section discarded, --
> > build-id ignored
> > 
> > I think you should either pass --build-id=none to the linker, or
> > add a 
> > .note.gnu.build-id section to the linker script?
> 
> This seems to work:
> 
> diff --git a/tests/tcg/s390x/Makefile.softmmu-target
> b/tests/tcg/s390x/Makefile.softmmu-target
> --- a/tests/tcg/s390x/Makefile.softmmu-target
> +++ b/tests/tcg/s390x/Makefile.softmmu-target
> @@ -2,7 +2,7 @@ S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
>   VPATH+=$(S390X_SRC)
>   QEMU_OPTS=-action panic=exit-failure -kernel
>   LINK_SCRIPT=$(S390X_SRC)/softmmu.ld
> -LDFLAGS=-nostdlib -static -Wl,-T$(LINK_SCRIPT)
> +LDFLAGS=-nostdlib -static -Wl,-T$(LINK_SCRIPT) -Wl,--build-id=none
>   
>   %.o: %.S
>          $(CC) -march=z13 -m64 -c $< -o $@
> 
> I'll squash that in ... no need to resend.
> 
>   Thomas

Thanks! The Makefile used to have this, but I thought that the linker
script would replace this (since it /DISCARD/s the build id), and I did
not notice the warnings.

Your diff looks good to me.
diff mbox series

Patch

diff --git a/tests/tcg/s390x/Makefile.softmmu-target b/tests/tcg/s390x/Makefile.softmmu-target
index 725b6c598db..6d8bf299b28 100644
--- a/tests/tcg/s390x/Makefile.softmmu-target
+++ b/tests/tcg/s390x/Makefile.softmmu-target
@@ -1,11 +1,20 @@ 
 S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
 VPATH+=$(S390X_SRC)
 QEMU_OPTS=-action panic=exit-failure -kernel
+LINK_SCRIPT=$(S390X_SRC)/softmmu.ld
+LDFLAGS=-nostdlib -static -Wl,-T$(LINK_SCRIPT)
 
-%: %.S
-	$(CC) -march=z13 -m64 -nostdlib -static -Wl,-Ttext=0 \
-		-Wl,--build-id=none $< -o $@
+%.o: %.S
+	$(CC) -march=z13 -m64 -c $< -o $@
+
+%: %.o $(LINK_SCRIPT)
+	$(CC) $< -o $@ $(LDFLAGS)
 
 TESTS += unaligned-lowcore
 TESTS += bal
 TESTS += sam
+
+include $(S390X_SRC)/pgm-specification.mak
+$(PGM_SPECIFICATION_TESTS): pgm-specification-softmmu.o
+$(PGM_SPECIFICATION_TESTS): LDFLAGS+=pgm-specification-softmmu.o
+TESTS += $(PGM_SPECIFICATION_TESTS)
diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
index cf93b966862..1002ab79886 100644
--- a/tests/tcg/s390x/Makefile.target
+++ b/tests/tcg/s390x/Makefile.target
@@ -2,6 +2,9 @@  S390X_SRC=$(SRC_PATH)/tests/tcg/s390x
 VPATH+=$(S390X_SRC)
 CFLAGS+=-march=zEC12 -m64
 
+%.o: %.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
+
 config-cc.mak: Makefile
 	$(quiet-@)( \
 	    $(call cc-option,-march=z14, CROSS_CC_HAS_Z14); \
@@ -33,6 +36,11 @@  TESTS+=chrl
 cdsg: CFLAGS+=-pthread
 cdsg: LDFLAGS+=-pthread
 
+include $(S390X_SRC)/pgm-specification.mak
+$(PGM_SPECIFICATION_TESTS): pgm-specification-user.o
+$(PGM_SPECIFICATION_TESTS): LDFLAGS+=pgm-specification-user.o
+TESTS += $(PGM_SPECIFICATION_TESTS)
+
 Z13_TESTS=vistr
 $(Z13_TESTS): CFLAGS+=-march=z13 -O2
 TESTS+=$(Z13_TESTS)
diff --git a/tests/tcg/s390x/br-odd.S b/tests/tcg/s390x/br-odd.S
new file mode 100644
index 00000000000..2fae47a9e34
--- /dev/null
+++ b/tests/tcg/s390x/br-odd.S
@@ -0,0 +1,16 @@ 
+/*
+ * Test BRanching to a non-mapped odd address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+    .globl test
+test:
+    lgrl %r1,odd_addr
+    br %r1
+
+    .align 8
+odd_addr:
+    .quad 0xDDDDDDDDDDDDDDDD
+    .globl expected_old_psw
+expected_old_psw:
+    .quad 0x180000000,0xDDDDDDDDDDDDDDDD
diff --git a/tests/tcg/s390x/cgrl-unaligned.S b/tests/tcg/s390x/cgrl-unaligned.S
new file mode 100644
index 00000000000..164d68f2e64
--- /dev/null
+++ b/tests/tcg/s390x/cgrl-unaligned.S
@@ -0,0 +1,16 @@ 
+/*
+ * Test CGRL with a non-doubleword aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+    .globl test
+test:
+    cgrl %r1,unaligned
+
+    .align 8
+    .globl expected_old_psw
+expected_old_psw:
+    .quad 0x180000000,test
+    .long 0
+unaligned:
+    .quad 0
diff --git a/tests/tcg/s390x/clrl-unaligned.S b/tests/tcg/s390x/clrl-unaligned.S
new file mode 100644
index 00000000000..182b1b6462f
--- /dev/null
+++ b/tests/tcg/s390x/clrl-unaligned.S
@@ -0,0 +1,16 @@ 
+/*
+ * Test CLRL with a non-word aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+    .globl test
+test:
+    clrl %r1,unaligned
+
+    .align 8
+    .globl expected_old_psw
+expected_old_psw:
+    .quad 0x180000000,test
+    .short 0
+unaligned:
+    .long 0
diff --git a/tests/tcg/s390x/crl-unaligned.S b/tests/tcg/s390x/crl-unaligned.S
new file mode 100644
index 00000000000..b86fbe0ef3f
--- /dev/null
+++ b/tests/tcg/s390x/crl-unaligned.S
@@ -0,0 +1,16 @@ 
+/*
+ * Test CRL with a non-word aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+    .globl test
+test:
+    crl %r1,unaligned
+
+    .align 8
+    .globl expected_old_psw
+expected_old_psw:
+    .quad 0x180000000,test
+    .short 0
+unaligned:
+    .long 0
diff --git a/tests/tcg/s390x/ex-odd.S b/tests/tcg/s390x/ex-odd.S
new file mode 100644
index 00000000000..4e42a47df34
--- /dev/null
+++ b/tests/tcg/s390x/ex-odd.S
@@ -0,0 +1,17 @@ 
+/*
+ * Test EXECUTing a non-mapped odd address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+    .globl test
+test:
+    lgrl %r1,odd_addr
+fail:
+    ex 0,0(%r1)
+
+    .align 8
+odd_addr:
+    .quad 0xDDDDDDDDDDDDDDDD
+    .globl expected_old_psw
+expected_old_psw:
+    .quad 0x180000000,fail
diff --git a/tests/tcg/s390x/lgrl-unaligned.S b/tests/tcg/s390x/lgrl-unaligned.S
new file mode 100644
index 00000000000..ef8d51d47c9
--- /dev/null
+++ b/tests/tcg/s390x/lgrl-unaligned.S
@@ -0,0 +1,16 @@ 
+/*
+ * Test LGRL from a non-doubleword aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+    .globl test
+test:
+    lgrl %r1,unaligned
+
+    .align 8
+    .globl expected_old_psw
+expected_old_psw:
+    .quad 0x180000000,test
+    .long 0
+unaligned:
+    .quad 0
diff --git a/tests/tcg/s390x/llgfrl-unaligned.S b/tests/tcg/s390x/llgfrl-unaligned.S
new file mode 100644
index 00000000000..c9b4eeaecf5
--- /dev/null
+++ b/tests/tcg/s390x/llgfrl-unaligned.S
@@ -0,0 +1,16 @@ 
+/*
+ * Test LLGFRL from a non-word aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+    .globl test
+test:
+    llgfrl %r1,unaligned
+
+    .align 8
+    .globl expected_old_psw
+expected_old_psw:
+    .quad 0x180000000,test
+    .short 0
+unaligned:
+    .long 0
diff --git a/tests/tcg/s390x/lpswe-unaligned.S b/tests/tcg/s390x/lpswe-unaligned.S
new file mode 100644
index 00000000000..989f249a6ad
--- /dev/null
+++ b/tests/tcg/s390x/lpswe-unaligned.S
@@ -0,0 +1,18 @@ 
+/*
+ * Test LPSWE from a non-doubleword aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+    .globl test
+test:
+    larl %r1,unaligned
+fail:
+    lpswe 0(%r1)
+
+    .align 8
+    .globl expected_old_psw
+expected_old_psw:
+    .quad 0x180000000,fail
+    .long 0
+unaligned:
+    .quad 0
diff --git a/tests/tcg/s390x/lrl-unaligned.S b/tests/tcg/s390x/lrl-unaligned.S
new file mode 100644
index 00000000000..11eb07f93a7
--- /dev/null
+++ b/tests/tcg/s390x/lrl-unaligned.S
@@ -0,0 +1,16 @@ 
+/*
+ * Test LRL from a non-word aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+    .globl test
+test:
+    lrl %r1,unaligned
+
+    .align 8
+    .globl expected_old_psw
+expected_old_psw:
+    .quad 0x180000000,test
+    .short 0
+unaligned:
+    .long 0
diff --git a/tests/tcg/s390x/pgm-specification-softmmu.S b/tests/tcg/s390x/pgm-specification-softmmu.S
new file mode 100644
index 00000000000..d534f4e505d
--- /dev/null
+++ b/tests/tcg/s390x/pgm-specification-softmmu.S
@@ -0,0 +1,40 @@ 
+/*
+ * Common softmmu code for specification exception testing.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+    .section .head
+    .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 test_psw
+
+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
+test_psw:
+    .quad 0x180000000,test             /* 64-bit mode */
+success_psw:
+    .quad 0x2000180000000,0xfff        /* see is_special_wait_psw() */
+failure_psw:
+    .quad 0x2000180000000,0            /* disabled wait */
diff --git a/tests/tcg/s390x/pgm-specification-user.c b/tests/tcg/s390x/pgm-specification-user.c
new file mode 100644
index 00000000000..9ee6907b7c2
--- /dev/null
+++ b/tests/tcg/s390x/pgm-specification-user.c
@@ -0,0 +1,37 @@ 
+/*
+ * Common user code for specification exception testing.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include <assert.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+extern void test(void);
+extern long expected_old_psw[2];
+
+static void handle_sigill(int sig, siginfo_t *info, void *ucontext)
+{
+    if ((long)info->si_addr != expected_old_psw[1]) {
+        _exit(EXIT_FAILURE);
+    }
+    _exit(EXIT_SUCCESS);
+}
+
+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);
+
+    test();
+
+    return EXIT_FAILURE;
+}
diff --git a/tests/tcg/s390x/pgm-specification.mak b/tests/tcg/s390x/pgm-specification.mak
new file mode 100644
index 00000000000..2999aee26e6
--- /dev/null
+++ b/tests/tcg/s390x/pgm-specification.mak
@@ -0,0 +1,15 @@ 
+# SPDX-License-Identifier: GPL-2.0-or-later
+# List of specification exception tests.
+# Shared between the softmmu and the user makefiles.
+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
diff --git a/tests/tcg/s390x/softmmu.ld b/tests/tcg/s390x/softmmu.ld
new file mode 100644
index 00000000000..ea944eaa3cb
--- /dev/null
+++ b/tests/tcg/s390x/softmmu.ld
@@ -0,0 +1,20 @@ 
+/*
+ * Linker script for the softmmu test kernels.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+ENTRY(_start)
+
+SECTIONS {
+    . = 0;
+
+    .text : {
+        *(.head)
+        *(.text)
+    }
+
+    /DISCARD/ : {
+        *(*)
+    }
+}
diff --git a/tests/tcg/s390x/stgrl-unaligned.S b/tests/tcg/s390x/stgrl-unaligned.S
new file mode 100644
index 00000000000..32df37780ad
--- /dev/null
+++ b/tests/tcg/s390x/stgrl-unaligned.S
@@ -0,0 +1,16 @@ 
+/*
+ * Test STGRL to a non-doubleword aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+    .globl test
+test:
+    stgrl %r1,unaligned
+
+    .align 8
+    .globl expected_old_psw
+expected_old_psw:
+    .quad 0x180000000,test
+    .long 0
+unaligned:
+    .quad 0
diff --git a/tests/tcg/s390x/strl-unaligned.S b/tests/tcg/s390x/strl-unaligned.S
new file mode 100644
index 00000000000..1d248819f02
--- /dev/null
+++ b/tests/tcg/s390x/strl-unaligned.S
@@ -0,0 +1,16 @@ 
+/*
+ * Test STRL to a non-word aligned address.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+    .globl test
+test:
+    strl %r1,unaligned
+
+    .align 8
+    .globl expected_old_psw
+expected_old_psw:
+    .quad 0x180000000,test
+    .short 0
+unaligned:
+    .long 0