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

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