On 27/09/2024 02.51, jro...@linux.ibm.com wrote:
From: Jared Rossi <jro...@linux.ibm.com>

Because virtio-scsi type devices use a non-architected IPLB pbt code they cannot
be set and stored normally. Instead, the IPLB must be rebuilt during re-ipl.

As s390x does not natively support multiple boot devices, the devno field is
used to store the position in the boot order for the device.

Handling the rebuild as part of DIAG308 removes the need to check the devices
for invalid IPLBs later in the IPL.

Signed-off-by: Jared Rossi <jro...@linux.ibm.com>

---
...
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index ba66847b9c..86c995b580 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -448,7 +448,6 @@ void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t 
*ebcdic_lp)
static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
  {
-    S390IPLState *ipl = get_ipl_device();
      CcwDevice *ccw_dev = NULL;
      SCSIDevice *sd;
      int devtype;
@@ -481,9 +480,6 @@ static bool s390_build_iplb(DeviceState *dev_st, 
IplParameterBlock *iplb)
              iplb->ccw.ssid = ccw_dev->sch->ssid & 3;
              break;
          case CCW_DEVTYPE_VIRTIO_NET:
-            /* The S390IPLState netboot is true if ANY IPLB may use netboot */
-            ipl->netboot = true;
-            /* Fall through to CCW_DEVTYPE_VIRTIO case */
          case CCW_DEVTYPE_VIRTIO:
              iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
              iplb->blk0_len =
@@ -508,6 +504,16 @@ static bool s390_build_iplb(DeviceState *dev_st, 
IplParameterBlock *iplb)
      return false;
  }
+
+void s390_rebuild_iplb(uint16_t dev_index, IplParameterBlock *iplb) {

Please put the curly brace on a new line for function declarations.

+    S390IPLState *ipl = get_ipl_device();
+    uint16_t index;
+    index = ipl->rebuilt_iplb ? ipl->iplb_index : dev_index;
+
+    ipl->rebuilt_iplb = s390_build_iplb(get_boot_device(index), iplb);
+    ipl->iplb_index = index;
+}
...
@@ -661,35 +629,33 @@ IplParameterBlock *s390_ipl_get_iplb(void)
      return &ipl->iplb;
  }
-void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type)
+static void s390_ipl_prepare_qipl(S390CPU *cpu)
  {
      S390IPLState *ipl = get_ipl_device();
+    uint8_t *addr;
+    uint64_t len = 4096;
+
+    addr = cpu_physical_memory_map(cpu->env.psa, &len, true);
+    if (!addr || len < QIPL_ADDRESS + sizeof(QemuIplParameters)) {
+        error_report("Cannot set QEMU IPL parameters");
+        return;
+    }
+
+    memcpy(addr + QIPL_ADDRESS, &ipl->qipl, sizeof(QemuIplParameters));
+    cpu_physical_memory_unmap(addr, len, 1, len);
+}

Why did you move the s390_ipl_prepare_qipl() function around? It does not seem to get moved in the new code below, so the movement does not seem to be required?

+void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type)
+{
+    S390IPLState *ipl = get_ipl_device();
      if (reset_type == S390_RESET_EXTERNAL || reset_type == S390_RESET_REIPL) {
          /* use CPU 0 for full resets */
          ipl->reset_cpu_index = 0;
      } else {
          ipl->reset_cpu_index = cs->cpu_index;
      }
-    ipl->reset_type = reset_type;
- if (reset_type == S390_RESET_REIPL &&
-        ipl->iplb_valid &&
-        !ipl->netboot &&
-        ipl->iplb.pbt == S390_IPL_TYPE_CCW &&
-        is_virtio_scsi_device(&ipl->iplb)) {
-        CcwDevice *ccw_dev = s390_get_ccw_device(get_boot_device(0), NULL);
-
-        if (ccw_dev &&
-            cpu_to_be16(ccw_dev->sch->devno) == ipl->iplb.ccw.devno &&
-            (ccw_dev->sch->ssid & 3) == ipl->iplb.ccw.ssid) {
-            /*
-             * this is the original boot device's SCSI
-             * so restore IPL parameter info from it
-             */
-            ipl->iplb_valid = s390_build_iplb(get_boot_device(0), &ipl->iplb);
-        }
-    }
+    ipl->reset_type = reset_type;
      if (reset_type == S390_RESET_MODIFIED_CLEAR ||
          reset_type == S390_RESET_LOAD_NORMAL ||
          reset_type == S390_RESET_PV) {
@@ -725,20 +691,6 @@ void s390_ipl_clear_reset_request(void)
      ipl->reset_cpu_index = 0;
  }
-static void s390_ipl_prepare_qipl(S390CPU *cpu)
-{
-    S390IPLState *ipl = get_ipl_device();
-    uint8_t *addr;
-    uint64_t len = 4096;
-
-    addr = cpu_physical_memory_map(cpu->env.psa, &len, true);
-    if (!addr || len < QIPL_ADDRESS + sizeof(QemuIplParameters)) {
-        error_report("Cannot set QEMU IPL parameters");
-        return;
-    }
-    memcpy(addr + QIPL_ADDRESS, &ipl->qipl, sizeof(QemuIplParameters));
-    cpu_physical_memory_unmap(addr, len, 1, len);
-}


 Thomas



Reply via email to