Commit ba664cf2d3 for qemu.org

commit ba664cf2d3de0f2092d5126733a1b10bb86639a5
Author: Jared Rossi <jrossi@linux.ibm.com>
Date:   Mon Aug 31 15:49:18 2026 -0400

    s390x: Find scsi-pci boot device and build IPLB

    Add logic to identify a virtio-pci scsi controller and target lun with
    assigned bootindex, then build IPLB for it.

    Unfence PCI case for scsi devices in BIOS.

    Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
    Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>
    Tested-by: Eric Farman <farman@linux.ibm.com>
    Reviewed-by: Eric Farman <farman@linux.ibm.com>
    Link: https://lore.kernel.org/qemu-devel/20260831194919.3830270-8-jrossi@linux.ibm.com
    Signed-off-by: Eric Farman <farman@linux.ibm.com>

diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 4fa8124f92..1add11ad7b 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -402,6 +402,7 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st, int *devtype)
 }

 #define PCI_DEVTYPE_VIRTIO       0x05
+#define PCI_DEVTYPE_SCSI         0x06

 static S390PCIBusDevice *s390_get_pci_device(DeviceState *dev_st, int *devtype)
 {
@@ -417,6 +418,26 @@ static S390PCIBusDevice *s390_get_pci_device(DeviceState *dev_st, int *devtype)
             if (pbdev) {
                 tmp_dt = PCI_DEVTYPE_VIRTIO;
             }
+        } else {
+            SCSIDevice *sd = (SCSIDevice *)
+                object_dynamic_cast(OBJECT(dev_st), TYPE_SCSI_DEVICE);
+            if (sd) {
+                SCSIBus *sbus = scsi_bus_from_device(sd);
+                VirtIODevice *vdev = (VirtIODevice *)
+                    object_dynamic_cast(OBJECT(sbus->qbus.parent),
+                                                TYPE_VIRTIO_DEVICE);
+                if (vdev) {
+                    pci_dev = (PCIDevice *)
+                        object_dynamic_cast(OBJECT(qdev_get_parent_bus(DEVICE(vdev))->parent),
+                                            TYPE_PCI_DEVICE);
+                    if (pci_dev) {
+                        pbdev = s390_pci_find_dev_by_pci(s390_get_phb(), pci_dev);
+                        if (pbdev) {
+                            tmp_dt = PCI_DEVTYPE_SCSI;
+                        }
+                    }
+                }
+            }
         }
     }
     if (devtype) {
@@ -616,6 +637,22 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
             iplb->pbt = S390_IPL_TYPE_PCI;
             iplb->pci.fid = cpu_to_be32(pbdev->fid);
             break;
+        case PCI_DEVTYPE_SCSI:
+            sd = SCSI_DEVICE(dev_st);
+            scsi_lp = object_property_get_str(OBJECT(sd), "loadparm", NULL);
+            if (scsi_lp && strlen(scsi_lp) > 0) {
+                lp = scsi_lp;
+            }
+            iplb->len = cpu_to_be32(S390_IPLB_MIN_PCI_LEN);
+            iplb->blk0_len =
+                cpu_to_be32(S390_IPLB_MIN_PCI_LEN - S390_IPLB_HEADER_LEN);
+            iplb->pbt = S390_IPL_TYPE_QEMU_SCSI;
+            iplb->scsi.lun = cpu_to_be32(sd->lun);
+            iplb->scsi.target = cpu_to_be16(sd->id);
+            iplb->scsi.channel = cpu_to_be16(sd->channel);
+            iplb->scsi.bus = S390_IPL_TYPE_PCI;
+            iplb->scsi.fid = cpu_to_be32(pbdev->fid);
+            break;
         default:
             return false;
         }
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index a2a24b024f..d2a2ac3138 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -267,6 +267,9 @@ static bool find_boot_device(void)
             blk_schid.ssid = iplb->scsi.ssid & 0x3;
             found = find_subch(iplb->scsi.devno);
             break;
+        case S390_IPL_TYPE_PCI:
+            found = find_fid(iplb->scsi.fid);
+            break;
         default:
             puts("Unrecognized SCSI controller");
             break;