Skip to contentSkip to conversation

s390x: More emulation tests

PATCH In review Janosch Frank 3 participants 13 messages Aug 26, 2019 – Sep 3, 2019

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index 403d967..86dffac 100644
@@ -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
#2 lore raw

PATCH v3 2/5 s390x: Diag288 test

In reply to 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.

---
 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
index d2cd727..4bbb428 100644
@@ -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
index 574a9a2..3453373 100644
@@ -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
index db58bad..9dd288a 100644
@@ -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
#3 lore raw

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.

---
 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
index d2cd727..4bbb428 100644
@@ -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
index 574a9a2..3453373 100644
@@ -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 +80 -0
new file mode 100644
index 0000000..a784338
@@ -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;
+
+	asm volatile("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();
+	asm volatile("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;
+
+	asm volatile("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

#4 lore raw

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
index d2cd727..4bbb428 100644
@@ -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
index 574a9a2..3453373 100644
@@ -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
index db58bad..9dd288a 100644
@@ -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
#6 lore raw

PATCH v3 3/5 s390x: Move stsi to library

In reply to Janosch Frank

It'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
index 4bbb428..5f8f45e 100644
@@ -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;
+
+	asm volatile(
+		"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
index b1e11af..fd4fcc7 100644
@@ -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;
-
-	asm volatile(
-		"	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
#7 lore raw

PATCH v3 4/5 s390x: STSI tests

In reply to Janosch Frank

For 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
index 3453373..76db0bb 100644
@@ -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
index 9dd288a..cc79a4e 100644
@@ -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
Reviewed-by on v3 4/5
#8 lore raw

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.

---
 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
index 3453373..76db0bb 100644
@@ -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 +55 -0
new file mode 100644
index 0000000..b8195b2
@@ -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;
+
+	asm volatile("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
index 9dd288a..cc79a4e 100644

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
#9 lore raw

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.

---

[...]

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
+
+	asm volatile("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 -0
index 9dd288a..cc79a4e 100644

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

#10 lore raw

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.

---

[...]

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
+
+	asm volatile("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.h if we have enough (>=
2) instruction definitions which are shared.

Signature · 3 lines
Thanks,

David / dhildenb
#11 lore raw

Re: [kvm-unit-tests PATCH v3 4/5] s390x: STSI tests

In reply to Janosch Frank
Quoted 21 lines · Janosch Frank
Quoted 5 lines · David Hildenbrand
Quoted 4 lines · Janosch Frank

For now let's concentrate on the error conditions.

---

[...]

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
+
+	asm volatile("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.h if 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

#12 lore raw

PATCH v3 5/5 s390x: Add diag308 subcode 0 testing

In reply to Janosch Frank

By 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
index dedfe80..36f7cab 100644
@@ -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
index f085b1a..6b4ffa6 100644
@@ -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;
-
-	asm volatile (
-		"	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