ddf19c
From 8350ad9c0f54519a06ec396c2997330615f4b470 Mon Sep 17 00:00:00 2001
ddf19c
From: Thomas Huth <thuth@redhat.com>
ddf19c
Date: Fri, 29 May 2020 05:53:58 -0400
ddf19c
Subject: [PATCH 16/42] pc-bios: s390x: Save iplb location in lowcore
ddf19c
ddf19c
RH-Author: Thomas Huth <thuth@redhat.com>
ddf19c
Message-id: <20200529055420.16855-17-thuth@redhat.com>
ddf19c
Patchwork-id: 97027
ddf19c
O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 16/38] pc-bios: s390x: Save iplb location in lowcore
ddf19c
Bugzilla: 1828317
ddf19c
RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
ddf19c
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
ddf19c
RH-Acked-by: David Hildenbrand <david@redhat.com>
ddf19c
ddf19c
From: Janosch Frank <frankja@linux.ibm.com>
ddf19c
ddf19c
The POP states that for a list directed IPL the IPLB is stored into
ddf19c
memory by the machine loader and its address is stored at offset 0x14
ddf19c
of the lowcore.
ddf19c
ddf19c
ZIPL currently uses the address in offset 0x14 to access the IPLB and
ddf19c
acquire flags about secure boot. If the IPLB address points into
ddf19c
memory which has an unsupported mix of flags set, ZIPL will panic
ddf19c
instead of booting the OS.
ddf19c
ddf19c
As the lowcore can have quite a high entropy for a guest that did drop
ddf19c
out of protected mode (i.e. rebooted) we encountered the ZIPL panic
ddf19c
quite often.
ddf19c
ddf19c
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
ddf19c
Tested-by: Marc Hartmayer <mhartmay@linux.ibm.com>
ddf19c
Message-Id: <20200304114231.23493-19-frankja@linux.ibm.com>
ddf19c
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
ddf19c
Reviewed-by: David Hildenbrand <david@redhat.com>
ddf19c
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
ddf19c
(cherry picked from commit 9bfc04f9ef6802fff0fc77130ff345a541783363)
ddf19c
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
ddf19c
---
ddf19c
 pc-bios/s390-ccw/jump2ipl.c  |  1 +
ddf19c
 pc-bios/s390-ccw/main.c      |  8 +++++++-
ddf19c
 pc-bios/s390-ccw/netmain.c   |  1 +
ddf19c
 pc-bios/s390-ccw/s390-arch.h | 10 ++++++++--
ddf19c
 pc-bios/s390-ccw/s390-ccw.h  |  1 +
ddf19c
 5 files changed, 18 insertions(+), 3 deletions(-)
ddf19c
ddf19c
diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
ddf19c
index da13c43cc0..4eba2510b0 100644
ddf19c
--- a/pc-bios/s390-ccw/jump2ipl.c
ddf19c
+++ b/pc-bios/s390-ccw/jump2ipl.c
ddf19c
@@ -35,6 +35,7 @@ void jump_to_IPL_code(uint64_t address)
ddf19c
 {
ddf19c
     /* store the subsystem information _after_ the bootmap was loaded */
ddf19c
     write_subsystem_identification();
ddf19c
+    write_iplb_location();
ddf19c
 
ddf19c
     /* prevent unknown IPL types in the guest */
ddf19c
     if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
ddf19c
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
ddf19c
index a21b386280..4e65b411e1 100644
ddf19c
--- a/pc-bios/s390-ccw/main.c
ddf19c
+++ b/pc-bios/s390-ccw/main.c
ddf19c
@@ -9,6 +9,7 @@
ddf19c
  */
ddf19c
 
ddf19c
 #include "libc.h"
ddf19c
+#include "helper.h"
ddf19c
 #include "s390-arch.h"
ddf19c
 #include "s390-ccw.h"
ddf19c
 #include "cio.h"
ddf19c
@@ -22,7 +23,7 @@ QemuIplParameters qipl;
ddf19c
 IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
ddf19c
 static bool have_iplb;
ddf19c
 static uint16_t cutype;
ddf19c
-LowCore const *lowcore; /* Yes, this *is* a pointer to address 0 */
ddf19c
+LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
ddf19c
 
ddf19c
 #define LOADPARM_PROMPT "PROMPT  "
ddf19c
 #define LOADPARM_EMPTY  "        "
ddf19c
@@ -42,6 +43,11 @@ void write_subsystem_identification(void)
ddf19c
     *zeroes = 0;
ddf19c
 }
ddf19c
 
ddf19c
+void write_iplb_location(void)
ddf19c
+{
ddf19c
+    lowcore->ptr_iplb = ptr2u32(&iplb);
ddf19c
+}
ddf19c
+
ddf19c
 void panic(const char *string)
ddf19c
 {
ddf19c
     sclp_print(string);
ddf19c
diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
ddf19c
index f2dcc01e27..309ffa30d9 100644
ddf19c
--- a/pc-bios/s390-ccw/netmain.c
ddf19c
+++ b/pc-bios/s390-ccw/netmain.c
ddf19c
@@ -40,6 +40,7 @@
ddf19c
 #define DEFAULT_TFTP_RETRIES 20
ddf19c
 
ddf19c
 extern char _start[];
ddf19c
+void write_iplb_location(void) {}
ddf19c
 
ddf19c
 #define KERNEL_ADDR             ((void *)0L)
ddf19c
 #define KERNEL_MAX_SIZE         ((long)_start)
ddf19c
diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
ddf19c
index 504fc7c2f0..5f36361c02 100644
ddf19c
--- a/pc-bios/s390-ccw/s390-arch.h
ddf19c
+++ b/pc-bios/s390-ccw/s390-arch.h
ddf19c
@@ -36,7 +36,13 @@ typedef struct LowCore {
ddf19c
     /* prefix area: defined by architecture */
ddf19c
     PSWLegacy       ipl_psw;                  /* 0x000 */
ddf19c
     uint32_t        ccw1[2];                  /* 0x008 */
ddf19c
-    uint32_t        ccw2[2];                  /* 0x010 */
ddf19c
+    union {
ddf19c
+        uint32_t        ccw2[2];                  /* 0x010 */
ddf19c
+        struct {
ddf19c
+            uint32_t reserved10;
ddf19c
+            uint32_t ptr_iplb;
ddf19c
+        };
ddf19c
+    };
ddf19c
     uint8_t         pad1[0x80 - 0x18];        /* 0x018 */
ddf19c
     uint32_t        ext_params;               /* 0x080 */
ddf19c
     uint16_t        cpu_addr;                 /* 0x084 */
ddf19c
@@ -85,7 +91,7 @@ typedef struct LowCore {
ddf19c
     PSW             io_new_psw;               /* 0x1f0 */
ddf19c
 } __attribute__((packed, aligned(8192))) LowCore;
ddf19c
 
ddf19c
-extern LowCore const *lowcore;
ddf19c
+extern LowCore *lowcore;
ddf19c
 
ddf19c
 static inline void set_prefix(uint32_t address)
ddf19c
 {
ddf19c
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
ddf19c
index 11bce7d73c..21f27e7990 100644
ddf19c
--- a/pc-bios/s390-ccw/s390-ccw.h
ddf19c
+++ b/pc-bios/s390-ccw/s390-ccw.h
ddf19c
@@ -57,6 +57,7 @@ void consume_io_int(void);
ddf19c
 /* main.c */
ddf19c
 void panic(const char *string);
ddf19c
 void write_subsystem_identification(void);
ddf19c
+void write_iplb_location(void);
ddf19c
 extern char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
ddf19c
 unsigned int get_loadparm_index(void);
ddf19c
 
ddf19c
-- 
ddf19c
2.27.0
ddf19c