Subject: [PATCH] [FEAT RAS1304] zipl: Add MT dump support for zipl dump tools
From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

Summary:     zipl: Add MT dump support for zipl dump tools
Description: Store register context of threads in case dumped system had
             enabled MT.
             It is necessary to restore the setting of maximum thread ID of
             the previous system in order to access the CPU register contexts
             of all threads.
Upstream-ID: -
Problem-ID:  RAS1304

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 zdump/df_s390.h          |    2 +-
 zipl/boot/eckd2dump_mv.c |    2 +-
 zipl/boot/eckd2dump_sv.c |    2 +-
 zipl/boot/fba2dump.c     |    2 +-
 zipl/boot/s390.h         |    1 +
 zipl/boot/sclp.h         |    8 ++++++--
 zipl/boot/stage2dump.c   |   11 ++++++++---
 7 files changed, 19 insertions(+), 9 deletions(-)

--- a/zdump/df_s390.h
+++ b/zdump/df_s390.h
@@ -105,7 +105,7 @@ struct df_s390_dumper_v2 {
 #define DF_S390_DUMPER_SIZE_V2	0x2000
 
 /*
- * Dump tool structure (version 3)
+ * Dump tool structure (version 3 and 4)
  */
 struct df_s390_dumper_v3 {
 	char	code[0x2ff7 - 0x8];
--- a/zipl/boot/eckd2dump_mv.c
+++ b/zipl/boot/eckd2dump_mv.c
@@ -18,7 +18,7 @@
  * Magic number at start of dump record
  */
 uint64_t magic __attribute__((section(".stage2.head")))
-	= 0x5a4d554c54363403ULL; /* ZMULT64, version 3 */
+	= 0x5a4d554c54363404ULL; /* ZMULT64, version 4 */
 
 /*
  * Parameter format for ECKD MV dumper (13 bytes):
--- a/zipl/boot/eckd2dump_sv.c
+++ b/zipl/boot/eckd2dump_sv.c
@@ -15,7 +15,7 @@
  * Magic number at start of dump record
  */
 uint64_t magic __attribute__((section(".stage2.head"))) =
-	0x5a45434b44363403ULL; /* "ZECKD64", version 3 */
+	0x5a45434b44363404ULL; /* "ZECKD64", version 4 */
 
 /*
  * ECKD parameter block passed by zipl
--- a/zipl/boot/fba2dump.c
+++ b/zipl/boot/fba2dump.c
@@ -18,7 +18,7 @@
  * Magic number at start of dump record
  */
 uint64_t magic __attribute__((section(".stage2.head")))
-	= 0x5a44464241363403ULL; /* ZDFBA64, version 3 */
+	= 0x5a44464241363404ULL; /* ZDFBA64, version 4 */
 
 /*
  * FBA dump device partition specification
--- a/zipl/boot/s390.h
+++ b/zipl/boot/s390.h
@@ -287,6 +287,7 @@ static inline int diag308(unsigned long
  * Signal Processor
  */
 #define SIGP_STOP_AND_STORE_STATUS	9
+#define SIGP_SET_MULTI_THREADING	22
 
 #define SIGP_CC_ORDER_CODE_ACCEPTED	0
 #define SIGP_CC_BUSY			2
--- a/zipl/boot/sclp.h
+++ b/zipl/boot/sclp.h
@@ -127,9 +127,13 @@ struct read_info_sccb {
 	uint8_t      rnsize;
 	uint8_t      _reserved0[24-11];
 	uint8_t      loadparm[8];
-	uint8_t      _reserved1[48-32];
+	uint8_t      reserved1[42-32];
+	uint8_t      fac42;
+	uint8_t      _reserved6[48-43];
 	uint64_t     facilities;
-	uint8_t      _reserved2[84-56];
+	uint8_t      _reserved2[66-56];
+	uint8_t      fac66;
+	uint8_t      _reserved7[84-67];
 	uint8_t      fac84;
 	uint8_t      fac85;
 	uint8_t      _reserved3[91-86];
--- a/zipl/boot/stage2dump.c
+++ b/zipl/boot/stage2dump.c
@@ -133,10 +133,11 @@ void df_s390_em_page_init(unsigned long
 /*
  * Find out memory size
  */
-static void count_mem(void)
+static void mem_and_cpu_init(void)
 {
 	unsigned long mem_size_max, mem_size, addr, rnmax, rzm;
 	struct read_info_sccb *sccb;
+	unsigned int mtid_prev;
 
 	sccb = (void *) get_zeroed_page();
 	/* Get memory max */
@@ -153,6 +154,10 @@ static void count_mem(void)
 			continue;
 		mem_size = addr + rzm;
 	}
+	/* Restore maximum thread ID of previous system */
+	mtid_prev = (sccb->fac42 & 0x80) ? (sccb->fac66 & 31) : 0;
+	sigp(0, SIGP_SET_MULTI_THREADING, mtid_prev, NULL);
+
 	free_page((unsigned long) sccb);
 
 	dump_hdr->mem_size_real = mem_size;
@@ -285,14 +290,14 @@ void panic_notify(unsigned long code)
 void start(void)
 {
 	init_early();
-	store_status();
 	dt_device_parm_setup();
 	sclp_setup(SCLP_INIT);
 	dt_device_enable();
 	df_s390_dump_init();
 	printf("zIPL v%s dump tool (64 bit)", RELEASE_STRING);
 	printf("Dumping 64 bit OS");
-	count_mem();
+	mem_and_cpu_init();
+	store_status();
 	progress_init();
 	dt_dump_mem();
 	printf("Dump successful");
