Blame SOURCES/kvm-s390x-ipl-Try-to-detect-Linux-vs-non-Linux-for-initi.patch

b38b0f
From 8128e12a8cb09bdb6bcb1b5735a9726f689e27c3 Mon Sep 17 00:00:00 2001
b38b0f
From: Cornelia Huck <cohuck@redhat.com>
b38b0f
Date: Wed, 17 Apr 2019 13:57:18 +0100
b38b0f
Subject: [PATCH 01/24] s390x/ipl: Try to detect Linux vs non Linux for initial
b38b0f
 IPL PSW
b38b0f
b38b0f
RH-Author: Cornelia Huck <cohuck@redhat.com>
b38b0f
Message-id: <20190417135741.25297-2-cohuck@redhat.com>
b38b0f
Patchwork-id: 85783
b38b0f
O-Subject: [RHEL-8.1.0 qemu-kvm PATCH v2 01/24] s390x/ipl: Try to detect Linux vs non Linux for initial IPL PSW
b38b0f
Bugzilla: 1699070
b38b0f
RH-Acked-by: David Hildenbrand <david@redhat.com>
b38b0f
RH-Acked-by: Thomas Huth <thuth@redhat.com>
b38b0f
RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
b38b0f
b38b0f
From: Christian Borntraeger <borntraeger@de.ibm.com>
b38b0f
b38b0f
Right now the IPL device always starts from address 0x10000 (the usual
b38b0f
Linux entry point). To run other guests (e.g. test programs) it is
b38b0f
useful to use the IPL PSW from address 0. We can use the Linux magic
b38b0f
at 0x10008 to decide.
b38b0f
b38b0f
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
b38b0f
Message-Id: <20180612125933.262679-1-borntraeger@de.ibm.com>
b38b0f
Reviewed-by: David Hildenbrand <david@redhat.com>
b38b0f
Reviewed-by: Thomas Huth <thuth@redhat.com>
b38b0f
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
b38b0f
(cherry picked from commit acd7ef837d8987ad4ef2ab8f8e8c0f13ab413dd5)
b38b0f
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
b38b0f
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
b38b0f
---
b38b0f
 hw/s390x/ipl.c | 27 ++++++++++++++++++++++-----
b38b0f
 1 file changed, 22 insertions(+), 5 deletions(-)
b38b0f
b38b0f
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
b38b0f
index 150f6c0..617ac43 100644
b38b0f
--- a/hw/s390x/ipl.c
b38b0f
+++ b/hw/s390x/ipl.c
b38b0f
@@ -28,6 +28,7 @@
b38b0f
 #include "qemu/option.h"
b38b0f
 
b38b0f
 #define KERN_IMAGE_START                0x010000UL
b38b0f
+#define LINUX_MAGIC_ADDR                0x010008UL
b38b0f
 #define KERN_PARM_AREA                  0x010480UL
b38b0f
 #define INITRD_START                    0x800000UL
b38b0f
 #define INITRD_PARM_START               0x010408UL
b38b0f
@@ -104,7 +105,9 @@ static uint64_t bios_translate_addr(void *opaque, uint64_t srcaddr)
b38b0f
 static void s390_ipl_realize(DeviceState *dev, Error **errp)
b38b0f
 {
b38b0f
     S390IPLState *ipl = S390_IPL(dev);
b38b0f
-    uint64_t pentry = KERN_IMAGE_START;
b38b0f
+    uint32_t *ipl_psw;
b38b0f
+    uint64_t pentry;
b38b0f
+    char *magic;
b38b0f
     int kernel_size;
b38b0f
     Error *err = NULL;
b38b0f
 
b38b0f
@@ -156,10 +159,24 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
b38b0f
                                NULL, 1, EM_S390, 0, 0);
b38b0f
         if (kernel_size < 0) {
b38b0f
             kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);
b38b0f
-        }
b38b0f
-        if (kernel_size < 0) {
b38b0f
-            error_setg(&err, "could not load kernel '%s'", ipl->kernel);
b38b0f
-            goto error;
b38b0f
+            if (kernel_size < 0) {
b38b0f
+                error_setg(&err, "could not load kernel '%s'", ipl->kernel);
b38b0f
+                goto error;
b38b0f
+            }
b38b0f
+            /* if this is Linux use KERN_IMAGE_START */
b38b0f
+            magic = rom_ptr(LINUX_MAGIC_ADDR);
b38b0f
+            if (magic && !memcmp(magic, "S390EP", 6)) {
b38b0f
+                pentry = KERN_IMAGE_START;
b38b0f
+            } else {
b38b0f
+                /* if not Linux load the address of the (short) IPL PSW */
b38b0f
+                ipl_psw = rom_ptr(4);
b38b0f
+                if (ipl_psw) {
b38b0f
+                    pentry = be32_to_cpu(*ipl_psw) & 0x7fffffffUL;
b38b0f
+                } else {
b38b0f
+                    error_setg(&err, "Could not get IPL PSW");
b38b0f
+                    goto error;
b38b0f
+                }
b38b0f
+            }
b38b0f
         }
b38b0f
         /*
b38b0f
          * Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the
b38b0f
-- 
b38b0f
1.8.3.1
b38b0f