Blame SOURCES/kvm-pc-bios-s390-ccw-bootmap-Improve-the-guessing-logic-.patch

1be5c7
From 8433b2ba40d0618c7086da87685e1c51b6da3b11 Mon Sep 17 00:00:00 2001
1be5c7
From: Thomas Huth <thuth@redhat.com>
1be5c7
Date: Fri, 8 Jul 2022 12:29:50 +0200
1be5c7
Subject: [PATCH 30/37] pc-bios/s390-ccw/bootmap: Improve the guessing logic in
1be5c7
 zipl_load_vblk()
1be5c7
1be5c7
RH-Author: Thomas Huth <thuth@redhat.com>
1be5c7
RH-MergeRequest: 198: pc-bios/s390-ccw: Fix boot from disks with 4k sectors that do not have the typical DASD geometry
1be5c7
RH-Commit: [2/9] db1d2e7929352bec0e1a5d4cf3fb385bbe02304b
1be5c7
RH-Bugzilla: 2098076
1be5c7
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
1be5c7
RH-Acked-by: David Hildenbrand <david@redhat.com>
1be5c7
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
1be5c7
1be5c7
Bugzilla: http://bugzilla.redhat.com/2098076
1be5c7
1be5c7
commit 422865f6672ee1482b98d18321b55c1ecfb06c82
1be5c7
Author: Thomas Huth <thuth@redhat.com>
1be5c7
Date:   Mon Jul 4 13:18:54 2022 +0200
1be5c7
1be5c7
    pc-bios/s390-ccw/bootmap: Improve the guessing logic in zipl_load_vblk()
1be5c7
1be5c7
    The logic of trying an final ISO or ECKD boot on virtio-block devices is
1be5c7
    very weird: Since the geometry hardly ever matches in virtio_disk_is_scsi(),
1be5c7
    virtio_blk_setup_device() always sets a "guessed" disk geometry via
1be5c7
    virtio_assume_scsi() (which is certainly also wrong in a lot of cases).
1be5c7
1be5c7
    zipl_load_vblk() then sees that there's been a "virtio_guessed_disk_nature"
1be5c7
    and tries to fix up the geometry again via virtio_assume_iso9660() before
1be5c7
    always trying to do ipl_iso_el_torito(). That's a very brain-twisting
1be5c7
    way of attempting to boot from ISO images, which won't work anymore after
1be5c7
    the following patches that will clean up the virtio_assume_scsi() mess
1be5c7
    (and thus get rid of the "virtio_guessed_disk_nature" here).
1be5c7
1be5c7
    Let's try a better approach instead: ISO files always have a magic
1be5c7
    string "CD001" at offset 0x8001 (see e.g. the ECMA-119 specification)
1be5c7
    which we can use to decide whether we should try to boot in ISO 9660
1be5c7
    mode (which we should also try if we see a sector size of 2048).
1be5c7
1be5c7
    And if we were not able to boot in ISO mode here, the final boot attempt
1be5c7
    before panicking is to boot in ECKD mode. Since this is our last boot
1be5c7
    attempt anyway, simply always assume the ECKD geometry here (if the sector
1be5c7
    size was not 4096 yet), so that we also do not depend on the guessed disk
1be5c7
    geometry from virtio_blk_setup_device() here anymore.
1be5c7
1be5c7
    Message-Id: <20220704111903.62400-4-thuth@redhat.com>
1be5c7
    Signed-off-by: Thomas Huth <thuth@redhat.com>
1be5c7
1be5c7
Signed-off-by: Thomas Huth <thuth@redhat.com>
1be5c7
---
1be5c7
 pc-bios/s390-ccw/bootmap.c | 27 +++++++++++++++++++++++----
1be5c7
 1 file changed, 23 insertions(+), 4 deletions(-)
1be5c7
1be5c7
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
1be5c7
index 56411ab3b6..994e59c0b0 100644
1be5c7
--- a/pc-bios/s390-ccw/bootmap.c
1be5c7
+++ b/pc-bios/s390-ccw/bootmap.c
1be5c7
@@ -780,18 +780,37 @@ static void ipl_iso_el_torito(void)
1be5c7
     }
1be5c7
 }
1be5c7
 
1be5c7
+/**
1be5c7
+ * Detect whether we're trying to boot from an .ISO image.
1be5c7
+ * These always have a signature string "CD001" at offset 0x8001.
1be5c7
+ */
1be5c7
+static bool has_iso_signature(void)
1be5c7
+{
1be5c7
+    int blksize = virtio_get_block_size();
1be5c7
+
1be5c7
+    if (!blksize || virtio_read(0x8000 / blksize, sec)) {
1be5c7
+        return false;
1be5c7
+    }
1be5c7
+
1be5c7
+    return !memcmp("CD001", &sec[1], 5);
1be5c7
+}
1be5c7
+
1be5c7
 /***********************************************************************
1be5c7
  * Bus specific IPL sequences
1be5c7
  */
1be5c7
 
1be5c7
 static void zipl_load_vblk(void)
1be5c7
 {
1be5c7
-    if (virtio_guessed_disk_nature()) {
1be5c7
-        virtio_assume_iso9660();
1be5c7
+    int blksize = virtio_get_block_size();
1be5c7
+
1be5c7
+    if (blksize == VIRTIO_ISO_BLOCK_SIZE || has_iso_signature()) {
1be5c7
+        if (blksize != VIRTIO_ISO_BLOCK_SIZE) {
1be5c7
+            virtio_assume_iso9660();
1be5c7
+        }
1be5c7
+        ipl_iso_el_torito();
1be5c7
     }
1be5c7
-    ipl_iso_el_torito();
1be5c7
 
1be5c7
-    if (virtio_guessed_disk_nature()) {
1be5c7
+    if (blksize != VIRTIO_DASD_DEFAULT_BLOCK_SIZE) {
1be5c7
         sclp_print("Using guessed DASD geometry.\n");
1be5c7
         virtio_assume_eckd();
1be5c7
     }
1be5c7
-- 
1be5c7
2.35.3
1be5c7