s390x: More emulation tests
v3 cover s390x: More emulation tests
The first patch allows for CECSIM booting via PSW restart. The other ones add diag288 and STSI tests, as well as diag308 subcode 0.
v3:
* Addressed review
* Added review-bys
v2:
* Tested under TCG
* Split out stsi into library
* Addressed review
Janosch Frank (5):
s390x: Support PSW restart boot
s390x: Diag288 test
s390x: Move stsi to library
s390x: STSI tests
s390x: Add diag308 subcode 0 testing
lib/s390x/asm/arch_def.h | 17 +++++ s390x/Makefile | 2 + s390x/cstart64.S | 27 ++++++++ s390x/diag288.c | 130 +++++++++++++++++++++++++++++++++++++++ s390x/diag308.c | 31 +++------- s390x/flat.lds | 14 +++-- s390x/skey.c | 18 ------ s390x/stsi.c | 84 +++++++++++++++++++++++++ s390x/unittests.cfg | 7 +++ 9 files changed, 286 insertions(+), 44 deletions(-) create mode 100644 s390x/diag288.c create mode 100644 s390x/stsi.c
Signature · 1 line
2.17.0
PATCH v3 1/5 s390x: Support PSW restart boot
Add a boot PSW to PSW restart new, so we can also boot via a PSW restart.
--- s390x/flat.lds | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
s390x/flat.lds +9 -5
@@ -1,14 +1,18 @@ SECTIONS { - /* - * Initial short psw for disk boot, with 31 bit addressing for - * non z/Arch environment compatibility and the instruction - * address 0x10000 (cstart64.S .init). - */ .lowcore : { + /* + * Initial short psw for disk boot, with 31 bit addressing for + * non z/Arch environment compatibility and the instruction + * address 0x10000 (cstart64.S .init). + */ . = 0; LONG(0x00080000) LONG(0x80010000) + /* Restart new PSW for booting via PSW restart. */ + . = 0x1a0; + QUAD(0x0000000180000000) + QUAD(0x0000000000010000) } . = 0x10000; .text : {
Signature · 1 line
2.17.0
PATCH v3 2/5 s390x: Diag288 test
In reply to Janosch FrankA small test for the watchdog via diag288.
Minimum timer value is 15 (seconds) and the only supported action with QEMU is restart.
--- lib/s390x/asm/arch_def.h | 1 + s390x/Makefile | 1 + s390x/diag288.c | 130 +++++++++++++++++++++++++++++++++++++++ s390x/unittests.cfg | 4 ++ 4 files changed, 136 insertions(+) create mode 100644 s390x/diag288.c
lib/s390x/asm/arch_def.h +1 -0
@@ -15,6 +15,7 @@ struct psw {uint64_t addr; }; +#define PSW_MASK_EXT 0x0100000000000000UL#define PSW_MASK_DAT 0x0400000000000000UL#define PSW_MASK_PSTATE 0x0001000000000000UL
s390x/Makefile +1 -0
@@ -12,6 +12,7 @@ tests += $(TEST_DIR)/vector.elf tests += $(TEST_DIR)/gs.elf tests += $(TEST_DIR)/iep.elf tests += $(TEST_DIR)/cpumodel.elf +tests += $(TEST_DIR)/diag288.elf tests_binary = $(patsubst %.elf,%.bin,$(tests)) all: directories test_cases test_cases_binary
s390x/diag288.c new file +130 -0
130 lines not on this page · raw message
s390x/unittests.cfg +4 -0
@@ -64,3 +64,7 @@ file = iep.elf [cpumodel] file = cpumodel.elf + +[diag288] +file = diag288.elf +extra_params=-device diag288,id=watchdog0 --watchdog-action inject-nmi
Signature · 1 line
2.17.0
Re: [kvm-unit-tests PATCH v3 2/5] s390x: Diag288 test
Quoted 125 lines · Janosch Frank
A small test for the watchdog via diag288.
Minimum timer value is 15 (seconds) and the only supported action with QEMU is restart.
Signed-off-by Janosch Frank <[email protected]>Reviewed-by Thomas Huth <[email protected]>--- lib/s390x/asm/arch_def.h | 1 + s390x/Makefile | 1 + s390x/diag288.c | 130 +++++++++++++++++++++++++++++++++++++++ s390x/unittests.cfg | 4 ++ 4 files changed, 136 insertions(+) create mode 100644 s390x/diag288.clib/s390x/asm/arch_def.h +1
-0@@ -15,6 +15,7 @@ struct psw {uint64_t addr; }; +#define PSW_MASK_EXT 0x0100000000000000UL#define PSW_MASK_DAT 0x0400000000000000UL#define PSW_MASK_PSTATE 0x0001000000000000ULs390x/Makefile +1
-0@@ -12,6 +12,7 @@ tests += $(TEST_DIR)/vector.elf tests += $(TEST_DIR)/gs.elf tests += $(TEST_DIR)/iep.elf tests += $(TEST_DIR)/cpumodel.elf +tests += $(TEST_DIR)/diag288.elf tests_binary = $(patsubst %.elf,%.bin,$(tests)) all: directories test_cases test_cases_binarys390x/diag288.c new file +80
-0@@ -0,0 +1,130 @@ +/* +* Timer Event DIAG288 test +* +* Copyright (c) 2019 IBM Corp +* +* Authors: +* Janosch Frank <[email protected]> +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU Library General Public License version 2. +*/ + +#include <libcflat.h> +#include <asm/asm-offsets.h> +#include <asm/interrupt.h> + +struct lowcore *lc = (struct lowcore *)0x0 ; + +#define CODE_INIT 0 +#define CODE_CHANGE 1 +#define CODE_CANCEL 2 + +#define ACTION_RESTART 0 + +static inline void diag288 (unsigned long code,unsigned long time, +unsigned long action) +{ + register unsigned long fc asm("0") = code; + register unsigned long tm asm("1") = time; + register unsigned long ac asm("2") = action; + + asmvolatile ("diag %0,%2,0x288" + : :"d" (fc),"d" (tm),"d" (ac)); +} + +static void test_specs (void ) +{ +report_prefix_push ("specification" ); + +report_prefix_push ("uneven" ); +expect_pgm_int (); + asmvolatile ("diag 1,2,0x288" ); +check_pgm_int_code (PGM_INT_CODE_SPECIFICATION ); +report_prefix_pop (); + +report_prefix_push ("unsupported action" ); +expect_pgm_int (); +diag288 (CODE_INIT ,15 ,42 ); +check_pgm_int_code (PGM_INT_CODE_SPECIFICATION ); +report_prefix_pop (); + +report_prefix_push ("unsupported function" ); +expect_pgm_int (); +diag288 (42 ,15 ,ACTION_RESTART ); +check_pgm_int_code (PGM_INT_CODE_SPECIFICATION ); +report_prefix_pop (); + +report_prefix_push ("no init" ); +expect_pgm_int (); +diag288 (CODE_CANCEL ,15 ,ACTION_RESTART ); +check_pgm_int_code (PGM_INT_CODE_SPECIFICATION ); +report_prefix_pop (); + +report_prefix_push ("min timer" ); +expect_pgm_int (); +diag288 (CODE_INIT ,14 ,ACTION_RESTART ); +check_pgm_int_code (PGM_INT_CODE_SPECIFICATION ); +report_prefix_pop (); + +report_prefix_pop (); +} + +static void test_priv (void ) +{ +report_prefix_push ("privileged" ); +expect_pgm_int (); +enter_pstate (); +diag288 (CODE_INIT ,15 ,ACTION_RESTART ); +check_pgm_int_code (PGM_INT_CODE_PRIVILEGED_OPERATION ); +report_prefix_pop ();
s390x/diag288.c line 90
Quoted 10 lines
s390x/diag288.c new file +10
-0+} + +static inline void get_tod_clock_ext (char *clk) +{ +typedef struct {char _[16 ]; }addrtype ; + + asmvolatile ("stcke %0" :"=Q" (*(addrtype *) clk) : :"cc" ); +} + +static inline unsigned long long get_tod_clock (void )
Change the return type to uint64_t, too?
s390x/diag288.c line 96
Quoted 6 lines
s390x/diag288.c new file +6
-0+{ +char clk[16 ]; + +get_tod_clock_ext (clk); +return *((uint64_t *)&clk[1 ]); +}
While this code seems to compile fine with recent versions of GCC, the older version 4.8 complains here:
s390x/diag288.c: In function ‘get_tod_clock’:s390x/diag288.c:95:2: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
return *((uint64_t *)&clk[1]);
^
Looking at the whole code again, I think it would be best to simply use "stck" here instead of "stcke", what do you think?
Thomas
PATCH 1/1 s390x: Diag288 test
A small test for the watchdog via diag288.
Minimum timer value is 15 (seconds) and the only supported action with QEMU is restart.
---
Disclaimer: Written without coffee, but tested
--- lib/s390x/asm/arch_def.h | 1 + s390x/Makefile | 1 + s390x/diag288.c | 114 +++++++++++++++++++++++++++++++++++++++ s390x/unittests.cfg | 4 ++ 4 files changed, 120 insertions(+) create mode 100644 s390x/diag288.c
lib/s390x/asm/arch_def.h +1 -0
@@ -15,6 +15,7 @@ struct psw {uint64_t addr; }; +#define PSW_MASK_EXT 0x0100000000000000UL#define PSW_MASK_DAT 0x0400000000000000UL#define PSW_MASK_PSTATE 0x0001000000000000UL
s390x/Makefile +1 -0
@@ -12,6 +12,7 @@ tests += $(TEST_DIR)/vector.elf tests += $(TEST_DIR)/gs.elf tests += $(TEST_DIR)/iep.elf tests += $(TEST_DIR)/cpumodel.elf +tests += $(TEST_DIR)/diag288.elf tests_binary = $(patsubst %.elf,%.bin,$(tests)) all: directories test_cases test_cases_binary
s390x/diag288.c new file +114 -0
114 lines not on this page · raw message
s390x/unittests.cfg +4 -0
@@ -64,3 +64,7 @@ file = iep.elf [cpumodel] file = cpumodel.elf + +[diag288] +file = diag288.elf +extra_params=-device diag288,id=watchdog0 --watchdog-action inject-nmi
Signature · 1 line
2.17.0
Re: [kvm-unit-tests PATCH] s390x: Diag288 test
Quoted 7 lines · Janosch Frank
A small test for the watchdog via diag288.
Minimum timer value is 15 (seconds) and the only supported action with QEMU is restart.
Signed-off-by Janosch Frank <[email protected]>Reviewed-by Thomas Huth <[email protected]>
Thanks! FYI, I've now queued this patch together with the others to my zkvm tree: https://gitlab.com/huth/kvm-unit-tests/commits/zkvm
Thomas
PATCH v3 3/5 s390x: Move stsi to library
In reply to Janosch FrankIt's needed in multiple tests now.
Return value changes from 0/-1 to the cc.
--- lib/s390x/asm/arch_def.h | 16 ++++++++++++++++ s390x/skey.c | 18 ------------------ 2 files changed, 16 insertions(+), 18 deletions(-)
lib/s390x/asm/arch_def.h +16 -0
@@ -240,4 +240,20 @@ static inline void enter_pstate(void)load_psw_mask (mask); } +static inline int stsi (void *addr,int fc,int sel1,int sel2) +{ + register int r0 asm("0") = (fc << 28) | sel1; + register int r1 asm("1") = sel2; +int cc; + + asmvolatile ( +"stsi 0(%3)\n" +"ipm %[cc]\n" +"srl %[cc],28\n" + :"+d" (r0), [cc]"=d" (cc) + :"d" (r1),"a" (addr) + :"cc" ,"memory" ); + return cc; +} +#endif
s390x/skey.c +0 -18
@@ -70,24 +70,6 @@ static void test_set(void) skey.str.acc == ret.str.acc && skey.str.fp == ret.str.fp); } -static inline int stsi (void *addr,int fc,int sel1,int sel2) -{ - register int r0 asm("0") = (fc << 28) | sel1; - register int r1 asm("1") = sel2; -int rc =0 ; - - asmvolatile ( -" stsi 0(%3)\n" -" jz 0f\n" -" lhi %1,-1\n" -"0:\n" - :"+d" (r0),"+d" (rc) - :"d" (r1),"a" (addr) - :"cc" ,"memory" ); - -return rc; -} -/* Returns true if we are running under z/VM 6.x */ static bool check_for_zvm6 (void ) {
Signature · 1 line
2.17.0
PATCH v3 4/5 s390x: STSI tests
In reply to Janosch FrankFor now let's concentrate on the error conditions.
--- s390x/Makefile | 1 + s390x/stsi.c | 84 +++++++++++++++++++++++++++++++++++++++++++++ s390x/unittests.cfg | 3 ++ 3 files changed, 88 insertions(+) create mode 100644 s390x/stsi.c
s390x/Makefile +1 -0
@@ -13,6 +13,7 @@ tests += $(TEST_DIR)/gs.elf tests += $(TEST_DIR)/iep.elf tests += $(TEST_DIR)/cpumodel.elf tests += $(TEST_DIR)/diag288.elf +tests += $(TEST_DIR)/stsi.elf tests_binary = $(patsubst %.elf,%.bin,$(tests)) all: directories test_cases test_cases_binary
s390x/stsi.c new file +84 -0
84 lines not on this page · raw message
s390x/unittests.cfg +3 -0
@@ -68,3 +68,6 @@ file = cpumodel.elf [diag288] file = diag288.elf extra_params=-device diag288,id=watchdog0 --watchdog-action inject-nmi + +[stsi] +file = stsi.elf
Signature · 1 line
2.17.0
Re: [kvm-unit-tests PATCH v3 4/5] s390x: STSI tests
Quoted 83 lines · Janosch Frank
For now let's concentrate on the error conditions.
Signed-off-by Janosch Frank <[email protected]>--- s390x/Makefile | 1 + s390x/stsi.c | 84 +++++++++++++++++++++++++++++++++++++++++++++ s390x/unittests.cfg | 3 ++ 3 files changed, 88 insertions(+) create mode 100644 s390x/stsi.cs390x/Makefile +1
-0@@ -13,6 +13,7 @@ tests += $(TEST_DIR)/gs.elf tests += $(TEST_DIR)/iep.elf tests += $(TEST_DIR)/cpumodel.elf tests += $(TEST_DIR)/diag288.elf +tests += $(TEST_DIR)/stsi.elf tests_binary = $(patsubst %.elf,%.bin,$(tests)) all: directories test_cases test_cases_binarys390x/stsi.c new file +55
-0@@ -0,0 +1,84 @@ +/* +* Store System Information tests +* +* Copyright (c) 2019 IBM Corp +* +* Authors: +* Janosch Frank <[email protected]> +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU Library General Public License version 2. +*/ + +#include <libcflat.h> +#include <asm/page.h> +#include <asm/asm-offsets.h> +#include <asm/interrupt.h> + +static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2))); + +static void test_specs (void ) +{ +report_prefix_push ("specification" ); + +report_prefix_push ("inv r0" ); +expect_pgm_int (); +stsi (pagebuf,0 ,1 <<8 ,0 ); +check_pgm_int_code (PGM_INT_CODE_SPECIFICATION ); +report_prefix_pop (); + +report_prefix_push ("inv r1" ); +expect_pgm_int (); +stsi (pagebuf,1 ,0 ,1 <<16 ); +check_pgm_int_code (PGM_INT_CODE_SPECIFICATION ); +report_prefix_pop (); + +report_prefix_push ("unaligned" ); +expect_pgm_int (); +stsi (pagebuf +42 ,1 ,0 ,0 ); +check_pgm_int_code (PGM_INT_CODE_SPECIFICATION ); +report_prefix_pop (); + +report_prefix_pop (); +} + +static void test_priv (void ) +{ +report_prefix_push ("privileged" ); +expect_pgm_int (); +enter_pstate (); +stsi (pagebuf,0 ,0 ,0 ); +check_pgm_int_code (PGM_INT_CODE_PRIVILEGED_OPERATION ); +report_prefix_pop (); +} + +static inline unsigned long stsi_get_fc (void *addr)
s390x/stsi.c line 65
Quoted 10 lines
s390x/stsi.c new file +10
-0+{ + register unsigned long r0 asm("0") = 0; + register unsigned long r1 asm("1") = 0; +int cc; + + asmvolatile ("stsi 0(%3)\n" +"ipm %[cc]\n" +"srl %[cc],28\n" + :"+d" (r0), [cc]"=d" (cc) + : "d" (r1), "a" (addr)
maybe [addr], so you can avoid the %3 above
s390x/stsi.c line 68
Quoted 3 lines
s390x/stsi.c new file +3
-0+ : "cc", "memory"); +assert (!cc); +return r0 >>28 ;
I think I'd prefer "get_configuration_level()" and move it to an header
- because the fc actually allows more values (0, 15 ...) - however the level can be used as an fc.
Quoted 22 lines
s390x/stsi.c new file +16
-0+} + +static void test_fc (void ) +{ +report ("invalid fc" ,stsi (pagebuf,7 ,0 ,0 ) ==3 ); +report ("query fc >= 2" ,stsi_get_fc (pagebuf) >=2 ); +} + +int main (void ) +{ +report_prefix_push ("stsi" ); +test_priv (); +test_specs (); +test_fc (); +return report_summary (); +}s390x/unittests.cfg +0
-0
s390x/unittests.cfg file = cpumodel.elf · line 73
Quoted 6 lines
s390x/unittests.cfg +3
-0@@ -68,3 +68,6 @@ file = cpumodel.elf [diag288] file = diag288.elf extra_params=-device diag288,id=watchdog0 --watchdog-action inject-nmi + +[stsi] +file = stsi.elf
Apart from that
Signature · 3 lines
Thanks, David / dhildenb
Re: [kvm-unit-tests PATCH v3 4/5] s390x: STSI tests
Quoted 5 lines · David Hildenbrand
Quoted 4 lines · Janosch Frank
For now let's concentrate on the error conditions.
Signed-off-by Janosch Frank <[email protected]>---
[...]
Quoted 5 lines
Quoted 5 lines
s390x/stsi.c new file +5
-0+static inline unsigned long stsi_get_fc (void *addr) +{ + register unsigned long r0 asm("0") = 0; + register unsigned long r1 asm("1") = 0; +int cc;
Quoted 8 lines
s390x/stsi.c line 65
Quoted 6 lines
s390x/stsi.c new file +6
-0+ + asmvolatile ("stsi 0(%3)\n" +"ipm %[cc]\n" +"srl %[cc],28\n" + :"+d" (r0), [cc]"=d" (cc) + : "d" (r1), "a" (addr)maybe [addr], so you can avoid the %3 above
Sure, maybe Thomas can also fix that on picking for the previous patch?
Quoted 8 lines
s390x/stsi.c line 68
Quoted 4 lines
s390x/stsi.c new file +3
-0+ : "cc", "memory"); +assert (!cc); +return r0 >>28 ;I think I'd prefer "
get_configuration_level()" and move it to an header
- because the fc actually allows more values (0, 15 ...) - however the level can be used as an fc.
The rename works for me, but that's currently used only once, so why should it go to a header file?
I though about starting lib/s390x/asm/misc-instr.h if we have enough (>=
2) instruction definitions which are shared.
Quoted 35 lines
Quoted 24 lines
s390x/stsi.c new file +16
-0+} + +static void test_fc (void ) +{ +report ("invalid fc" ,stsi (pagebuf,7 ,0 ,0 ) ==3 ); +report ("query fc >= 2" ,stsi_get_fc (pagebuf) >=2 ); +} + +int main (void ) +{ +report_prefix_push ("stsi" ); +test_priv (); +test_specs (); +test_fc (); +return report_summary (); +}s390x/unittests.cfg +0
-0s390x/unittests.cfg file = cpumodel.elf · line 73
Quoted 6 lines
s390x/unittests.cfg +3
-0@@ -68,3 +68,6 @@ file = cpumodel.elf [diag288] file = diag288.elf extra_params=-device diag288,id=watchdog0 --watchdog-action inject-nmi + +[stsi] +file = stsi.elfApart from that
Reviewed-by David Hildenbrand <[email protected]>
Re: [kvm-unit-tests PATCH v3 4/5] s390x: STSI tests
Quoted 32 lines · Janosch Frank
Quoted 5 lines · David Hildenbrand
Quoted 4 lines · Janosch Frank
For now let's concentrate on the error conditions.
Signed-off-by Janosch Frank <[email protected]>---
[...]
Quoted 5 lines
Quoted 5 lines
s390x/stsi.c new file +5
-0+static inline unsigned long stsi_get_fc (void *addr) +{ + register unsigned long r0 asm("0") = 0; + register unsigned long r1 asm("1") = 0; +int cc;Quoted 8 lines
s390x/stsi.c line 65
Quoted 6 lines
s390x/stsi.c new file +6
-0+ + asmvolatile ("stsi 0(%3)\n" +"ipm %[cc]\n" +"srl %[cc],28\n" + :"+d" (r0), [cc]"=d" (cc) + : "d" (r1), "a" (addr)maybe [addr], so you can avoid the %3 above
Sure, maybe Thomas can also fix that on picking for the previous patch?
Quoted 8 lines
s390x/stsi.c line 68
Quoted 4 lines
s390x/stsi.c new file +3
-0+ : "cc", "memory"); +assert (!cc); +return r0 >>28 ;I think I'd prefer "
get_configuration_level()" and move it to an header
- because the fc actually allows more values (0, 15 ...) - however the level can be used as an fc.
Quoted 2 lines
The rename works for me, but that's currently used only once, so why should it go to a header file?
No strong opinion about that, I would have moved it out of the test to make the test itself more compact .
Quoted 3 lines
I though about starting
lib/s390x/asm/misc-instr.hif we have enough (>=
2) instruction definitions which are shared.
Signature · 3 lines
Thanks, David / dhildenb
Re: [kvm-unit-tests PATCH v3 4/5] s390x: STSI tests
In reply to Janosch FrankQuoted 21 lines · Janosch Frank
Quoted 5 lines · David Hildenbrand
Quoted 4 lines · Janosch Frank
For now let's concentrate on the error conditions.
Signed-off-by Janosch Frank <[email protected]>---
[...]
Quoted 5 lines
Quoted 5 lines
s390x/stsi.c new file +5
-0+static inline unsigned long stsi_get_fc (void *addr) +{ + register unsigned long r0 asm("0") = 0; + register unsigned long r1 asm("1") = 0; +int cc;Quoted 8 lines
s390x/stsi.c line 65
Quoted 6 lines
s390x/stsi.c new file +6
-0+ + asmvolatile ("stsi 0(%3)\n" +"ipm %[cc]\n" +"srl %[cc],28\n" + :"+d" (r0), [cc]"=d" (cc) + : "d" (r1), "a" (addr)maybe [addr], so you can avoid the %3 above
Quoted 1 line
Sure, maybe Thomas can also fix that on picking for the previous patch?
Yes, I can do that.
Quoted 9 lines
Quoted 8 lines
s390x/stsi.c line 68
Quoted 4 lines
s390x/stsi.c new file +3
-0+ : "cc", "memory"); +assert (!cc); +return r0 >>28 ;I think I'd prefer "
get_configuration_level()" and move it to an header
- because the fc actually allows more values (0, 15 ...) - however the level can be used as an fc.
Quoted 5 lines
The rename works for me, but that's currently used only once, so why should it go to a header file?
I though about starting
lib/s390x/asm/misc-instr.hif we have enough (>=
2) instruction definitions which are shared.
Let's keep it here until we need it in another file, too - then we can still move it to a header instead.
Thomas
PATCH v3 5/5 s390x: Add diag308 subcode 0 testing
In reply to Janosch FrankBy adding a load reset routine to cstart.S we can also test the clear reset done by subcode 0, as we now can restore our registers again.
--- s390x/cstart64.S | 27 +++++++++++++++++++++++++++ s390x/diag308.c | 31 ++++++++++--------------------- 2 files changed, 37 insertions(+), 21 deletions(-)
s390x/cstart64.S +27 -0
@@ -145,6 +145,33 @@ memsetxc: .endm .section .text +/* + * load_reset calling convention: + * %r2 subcode (0 or 1) + */ +.globl diag308_load_reset +diag308_load_reset: + SAVE_REGS + /* Save the first PSW word to the IPL PSW */ + epsw %r0, %r1 + st %r0, 0 + /* Store the address and the bit for 31 bit addressing */ + larl %r0, 0f + oilh %r0, 0x8000 + st %r0, 0x4 + /* Do the reset */ + diag %r0,%r2,0x308 + /* Failure path */ + xgr %r2, %r2 + br %r14 + /* Success path */ + /* We lost cr0 due to the reset */ +0: larl %r1, initial_cr0 + lctlg %c0, %c0, 0(%r1) + RESTORE_REGS + lhi %r2, 1 + br %r14 + pgm_int: SAVE_REGS brasl %r14, handle_pgm_int
s390x/diag308.c +10 -21
@@ -21,32 +21,20 @@ static void test_priv(void)check_pgm_int_code (PGM_INT_CODE_PRIVILEGED_OPERATION ); } +/* -* Check that diag308 with subcode 1 loads the PSW at address 0, i.e. +* Check that diag308 with subcode 0 and 1 loads the PSW at address 0, i.e. * that we can put a pointer into address 4 which then gets executed. */ +extern int diag308_load_reset (u64 ); +static void test_subcode0 (void ) +{ +report ("load modified clear done" ,diag308_load_reset (0 )); +} +static void test_subcode1 (void ) { -uint64_t saved_psw = *(uint64_t *)0 ; -long subcode =1 ; -long ret, tmp; - - asmvolatile ( -" epsw %0,%1\n" -" st %0,0\n" -" larl %0,0f\n" -" oilh %0,0x8000\n" -" st %0,4\n" -" diag 0,%2,0x308\n" -" lghi %0,0\n" -" j 1f\n" -"0: lghi %0,1\n" -"1:" - :"=&d" (ret),"=&d" (tmp) :"d" (subcode) :"memory" ); - - *(uint64_t *)0 = saved_psw; - -report ("load normal reset done" , ret ==1 ); +report ("load normal reset done" ,diag308_load_reset (1 )); }/* Expect a specification exception when using an uneven register */
@@ -107,6 +95,7 @@ static struct {void (*func)(void ); } tests[] = { { "privileged", test_priv }, + { "subcode 0", test_subcode0 }, { "subcode 1", test_subcode1 }, { "subcode 5", test_subcode5 }, { "subcode 6", test_subcode6 },
Signature · 1 line
2.17.0