* Tue Nov 12 2024 Miroslav Rezanina <mrezanin@redhat.com> - 9.1.0-4.el10

- kvm-accel-kvm-check-for-KVM_CAP_READONLY_MEM-on-VM.patch [RHEL-58928]
- kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch [RHEL-58153]
- kvm-redhat-Remove-the-s390-netboot.img-from-the-spec-fil.patch [RHEL-58153]
- kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch [RHEL-58153]
- kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch [RHEL-58153]
- kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch [RHEL-58153]
- kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch [RHEL-58153]
- kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch [RHEL-58153]
- kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch [RHEL-58153]
- kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch [RHEL-58153]
- kvm-docs-system-Update-documentation-for-s390x-IPL.patch [RHEL-58153]
- kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch [RHEL-58153]
- kvm-vnc-fix-crash-when-no-console-attached.patch [RHEL-50529]
- kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch [RHEL-64308]
- kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch [RHEL-64308]
- kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch [RHEL-20574]
- kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch [RHEL-20574]
- kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-add-CPUID.24-features-for-AVX10.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-Add-feature-dependencies-for-AVX10.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-Introduce-GraniteRapids-v2-model.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch [RHEL-30315 RHEL-45110]
- Resolves: RHEL-58928
  (Boot SNP guests failed with qemu-kvm: kvm_set_user_memory_region)
- Resolves: RHEL-58153
  ([IBM 10.0 FEAT] KVM: Full boot order support - qemu part)
- Resolves: RHEL-50529
  (Qemu-kvm  crashed  if  no display device setting and switching display by remote-viewer)
- Resolves: RHEL-64308
  (High threshold value observed in vGPU live migration)
- Resolves: RHEL-20574
  (Fail migration properly when put cpu register fails)
- Resolves: RHEL-30315
  ([Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support)
- Resolves: RHEL-45110
  ([Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4)
This commit is contained in:
Miroslav Rezanina 2024-11-12 00:36:30 -05:00
parent 6f90188d18
commit 3143ae25cb
38 changed files with 7521 additions and 6 deletions

View File

@ -0,0 +1,56 @@
From 2b4558ec338adde1b9735128bb8d2f81db303a93 Mon Sep 17 00:00:00 2001
From: Avadhut Naik <avnaik@redhat.com>
Date: Wed, 23 Oct 2024 12:25:28 -0500
Subject: [PATCH 01/38] accel/kvm: check for KVM_CAP_READONLY_MEM on VM
RH-Author: avnaik1 <None>
RH-MergeRequest: 276: accel/kvm: check for KVM_CAP_READONLY_MEM on VM
RH-Jira: RHEL-58928
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [1/1] 1d392a9e47e68bb71dc44635c494d161585a885c (avnaik1/avnaik-qemu-kvm-fork)
JIRA: https://issues.redhat.com/browse/RHEL-58928
commit 64e0e63ea16aa0122dc0c41a0679da0ae4616208
Author: Tom Dohrmann <erbse.13@gmx.de>
Date: Tue Sep 3 06:29:53 2024 +0000
accel/kvm: check for KVM_CAP_READONLY_MEM on VM
KVM_CAP_READONLY_MEM used to be a global capability, but with the
introduction of AMD SEV-SNP confidential VMs, this extension is not
always available on all VM types [1,2].
Query the extension on the VM level instead of on the KVM level.
[1] https://patchwork.kernel.org/project/kvm/patch/20240809190319.1710470-2-seanjc@google.com/
[2] https://patchwork.kernel.org/project/kvm/patch/20240902144219.3716974-1-erbse.13@gmx.de/
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Tom Dohrmann <erbse.13@gmx.de>
Link: https://lore.kernel.org/r/20240903062953.3926498-1-erbse.13@gmx.de
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Avadhut Naik <avnaik@redhat.com>
---
accel/kvm/kvm-all.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 75d11a07b2..acc23092e7 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2603,7 +2603,7 @@ static int kvm_init(MachineState *ms)
}
kvm_readonly_mem_allowed =
- (kvm_check_extension(s, KVM_CAP_READONLY_MEM) > 0);
+ (kvm_vm_check_extension(s, KVM_CAP_READONLY_MEM) > 0);
kvm_resamplefds_allowed =
(kvm_check_extension(s, KVM_CAP_IRQFD_RESAMPLE) > 0);
--
2.39.3

View File

@ -0,0 +1,76 @@
From f1359f43bbc61f31c292ca1770688b6db6b959af Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:52 -0400
Subject: [PATCH 20/38] docs/system: Update documentation for s390x IPL
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [19/23] 8dfc0357ec42e9baac741670f6e7da3127de0e50 (thuth/qemu-kvm-cs9)
Update docs to show that s390x PC BIOS can support more than one boot device.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-19-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 0bd107138ff0b171e3cd314dbc200950bcab2b05)
---
docs/system/bootindex.rst | 7 ++++---
docs/system/s390x/bootdevices.rst | 9 ++++++---
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/docs/system/bootindex.rst b/docs/system/bootindex.rst
index 8b057f812f..988f7b3beb 100644
--- a/docs/system/bootindex.rst
+++ b/docs/system/bootindex.rst
@@ -49,10 +49,11 @@ Limitations
-----------
Some firmware has limitations on which devices can be considered for
-booting. For instance, the PC BIOS boot specification allows only one
-disk to be bootable. If boot from disk fails for some reason, the BIOS
+booting. For instance, the x86 PC BIOS boot specification allows only one
+disk to be bootable. If boot from disk fails for some reason, the x86 BIOS
won't retry booting from other disk. It can still try to boot from
-floppy or net, though.
+floppy or net, though. In the case of s390x BIOS, the BIOS will try up to
+8 total devices, any number of which may be disks.
Sometimes, firmware cannot map the device path QEMU wants firmware to
boot from to a boot method. It doesn't happen for devices the firmware
diff --git a/docs/system/s390x/bootdevices.rst b/docs/system/s390x/bootdevices.rst
index c97efb8fc0..1a1a764c1c 100644
--- a/docs/system/s390x/bootdevices.rst
+++ b/docs/system/s390x/bootdevices.rst
@@ -6,9 +6,7 @@ Booting with bootindex parameter
For classical mainframe guests (i.e. LPAR or z/VM installations), you always
have to explicitly specify the disk where you want to boot from (or "IPL" from,
-in s390x-speak -- IPL means "Initial Program Load"). In particular, there can
-also be only one boot device according to the architecture specification, thus
-specifying multiple boot devices is not possible (yet).
+in s390x-speak -- IPL means "Initial Program Load").
So for booting an s390x guest in QEMU, you should always mark the
device where you want to boot from with the ``bootindex`` property, for
@@ -17,6 +15,11 @@ example::
qemu-system-s390x -drive if=none,id=dr1,file=guest.qcow2 \
-device virtio-blk,drive=dr1,bootindex=1
+Multiple devices may have a bootindex. The lowest bootindex is assigned to the
+device to IPL first. If the IPL fails for the first, the device with the second
+lowest bootindex will be tried and so on until IPL is successful or there are no
+remaining boot devices to try.
+
For booting from a CD-ROM ISO image (which needs to include El-Torito boot
information in order to be bootable), it is recommended to specify a ``scsi-cd``
device, for example like this::
--
2.39.3

View File

@ -0,0 +1,66 @@
From c8e615cf130743ee95a61d7e21bb4b753eb082fb Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:40 -0400
Subject: [PATCH 08/38] docs/system/s390x/bootdevices: Update the documentation
about network booting
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [7/23] 52d357df45400b983e17cc6b1eeac691131bf5e5 (thuth/qemu-kvm-cs9)
Remove the information about the separate s390-netboot.img from
the documentation.
Co-authored by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Message-ID: <20241020012953.1380075-7-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit ab2691b6c7ff360875e0af86ff463278f17786f5)
---
docs/system/s390x/bootdevices.rst | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/docs/system/s390x/bootdevices.rst b/docs/system/s390x/bootdevices.rst
index 1a7a18b43b..c97efb8fc0 100644
--- a/docs/system/s390x/bootdevices.rst
+++ b/docs/system/s390x/bootdevices.rst
@@ -82,23 +82,17 @@ Note that ``0`` can be used to boot the default entry.
Booting from a network device
-----------------------------
-Beside the normal guest firmware (which is loaded from the file ``s390-ccw.img``
-in the data directory of QEMU, or via the ``-bios`` option), QEMU ships with
-a small TFTP network bootloader firmware for virtio-net-ccw devices, too. This
-firmware is loaded from a file called ``s390-netboot.img`` in the QEMU data
-directory. In case you want to load it from a different filename instead,
-you can specify it via the ``-global s390-ipl.netboot_fw=filename``
-command line option.
-
-The ``bootindex`` property is especially important for booting via the network.
-If you don't specify the ``bootindex`` property here, the network bootloader
-firmware code won't get loaded into the guest memory so that the network boot
-will fail. For a successful network boot, try something like this::
+The firmware that ships with QEMU includes a small TFTP network bootloader
+for virtio-net-ccw devices. The ``bootindex`` property is especially
+important for booting via the network. If you don't specify the ``bootindex``
+property here, the network bootloader won't be taken into consideration and
+the network boot will fail. For a successful network boot, try something
+like this::
qemu-system-s390x -netdev user,id=n1,tftp=...,bootfile=... \
-device virtio-net-ccw,netdev=n1,bootindex=1
-The network bootloader firmware also has basic support for pxelinux.cfg-style
+The network bootloader also has basic support for pxelinux.cfg-style
configuration files. See the `PXELINUX Configuration page
<https://wiki.syslinux.org/wiki/index.php?title=PXELINUX#Configuration>`__
for details how to set up the configuration file on your TFTP server.
--
2.39.3

View File

@ -0,0 +1,270 @@
From 416ee0a87ee4bfedf07bc37d328066375b36fdc1 Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:49 -0400
Subject: [PATCH 17/38] hw/s390x: Build an IPLB for each boot device
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [16/23] 40a579b400cebd1470bb632869ad4a5581e3c41f (thuth/qemu-kvm-cs9)
Build an IPLB for any device with a bootindex (up to a maximum of 8 devices).
The IPLB chain is placed immediately before the BIOS in memory. Because this
is not a fixed address, the location of the next IPLB and number of remaining
boot devices is stored in the QIPL global variable for possible later access by
the guest during IPL.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-16-jrossi@linux.ibm.com>
[thuth: Fix endianness problem when accessing the qipl structure]
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 0927875e704e93ace03bb7533c0877bf97e4bda9)
---
hw/s390x/ipl.c | 129 ++++++++++++++++++++++++++++--------
hw/s390x/ipl.h | 1 +
include/hw/s390x/ipl/qipl.h | 4 +-
3 files changed, 105 insertions(+), 29 deletions(-)
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index d83832d975..f4576f8822 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -56,6 +56,13 @@ static bool iplb_extended_needed(void *opaque)
return ipl->iplbext_migration;
}
+/* Place the IPLB chain immediately before the BIOS in memory */
+static uint64_t find_iplb_chain_addr(uint64_t bios_addr, uint16_t count)
+{
+ return (bios_addr & TARGET_PAGE_MASK)
+ - (count * sizeof(IplParameterBlock));
+}
+
static const VMStateDescription vmstate_iplb_extended = {
.name = "ipl/iplb_extended",
.version_id = 0,
@@ -398,6 +405,17 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st, int *devtype)
return ccw_dev;
}
+static uint64_t s390_ipl_map_iplb_chain(IplParameterBlock *iplb_chain)
+{
+ S390IPLState *ipl = get_ipl_device();
+ uint16_t count = be16_to_cpu(ipl->qipl.chain_len);
+ uint64_t len = sizeof(IplParameterBlock) * count;
+ uint64_t chain_addr = find_iplb_chain_addr(ipl->bios_start_addr, count);
+
+ cpu_physical_memory_write(chain_addr, iplb_chain, len);
+ return chain_addr;
+}
+
void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp)
{
int i;
@@ -428,54 +446,51 @@ void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp)
}
}
-static bool s390_gen_initial_iplb(S390IPLState *ipl)
+static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
{
- DeviceState *dev_st;
+ S390IPLState *ipl = get_ipl_device();
CcwDevice *ccw_dev = NULL;
SCSIDevice *sd;
int devtype;
uint8_t *lp;
- dev_st = get_boot_device(0);
- if (dev_st) {
- ccw_dev = s390_get_ccw_device(dev_st, &devtype);
- }
-
/*
* Currently allow IPL only from CCW devices.
*/
+ ccw_dev = s390_get_ccw_device(dev_st, &devtype);
if (ccw_dev) {
lp = ccw_dev->loadparm;
switch (devtype) {
case CCW_DEVTYPE_SCSI:
sd = SCSI_DEVICE(dev_st);
- ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
- ipl->iplb.blk0_len =
+ iplb->len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
+ iplb->blk0_len =
cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - S390_IPLB_HEADER_LEN);
- ipl->iplb.pbt = S390_IPL_TYPE_QEMU_SCSI;
- ipl->iplb.scsi.lun = cpu_to_be32(sd->lun);
- ipl->iplb.scsi.target = cpu_to_be16(sd->id);
- ipl->iplb.scsi.channel = cpu_to_be16(sd->channel);
- ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
- ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
+ 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.devno = cpu_to_be16(ccw_dev->sch->devno);
+ iplb->scsi.ssid = ccw_dev->sch->ssid & 3;
break;
case CCW_DEVTYPE_VFIO:
- ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
- ipl->iplb.pbt = S390_IPL_TYPE_CCW;
- ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
- ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
+ iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
+ iplb->pbt = S390_IPL_TYPE_CCW;
+ iplb->ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
+ 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:
- ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
- ipl->iplb.blk0_len =
+ iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
+ iplb->blk0_len =
cpu_to_be32(S390_IPLB_MIN_CCW_LEN - S390_IPLB_HEADER_LEN);
- ipl->iplb.pbt = S390_IPL_TYPE_CCW;
- ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
- ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
+ iplb->pbt = S390_IPL_TYPE_CCW;
+ iplb->ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
+ iplb->ccw.ssid = ccw_dev->sch->ssid & 3;
break;
}
@@ -484,8 +499,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
lp = S390_CCW_MACHINE(qdev_get_machine())->loadparm;
}
- s390_ipl_convert_loadparm((char *)lp, ipl->iplb.loadparm);
- ipl->iplb.flags |= DIAG308_FLAGS_LP_VALID;
+ s390_ipl_convert_loadparm((char *)lp, iplb->loadparm);
+ iplb->flags |= DIAG308_FLAGS_LP_VALID;
return true;
}
@@ -493,6 +508,62 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
return false;
}
+static bool s390_init_all_iplbs(S390IPLState *ipl)
+{
+ int iplb_num = 0;
+ IplParameterBlock iplb_chain[7];
+ DeviceState *dev_st = get_boot_device(0);
+ Object *machine = qdev_get_machine();
+
+ /*
+ * Parse the boot devices. Generate an IPLB for only the first boot device
+ * which will later be set with DIAG308.
+ */
+ if (!dev_st) {
+ ipl->qipl.chain_len = 0;
+ return false;
+ }
+
+ /* If no machine loadparm was defined fill it with spaces */
+ if (memcmp(S390_CCW_MACHINE(machine)->loadparm, NO_LOADPARM, 8) == 0) {
+ object_property_set_str(machine, "loadparm", " ", NULL);
+ }
+
+ iplb_num = 1;
+ s390_build_iplb(dev_st, &ipl->iplb);
+
+ /* Index any fallback boot devices */
+ while (get_boot_device(iplb_num)) {
+ iplb_num++;
+ }
+
+ if (iplb_num > MAX_BOOT_DEVS) {
+ warn_report("Excess boot devices defined! %d boot devices found, "
+ "but only the first %d will be considered.",
+ iplb_num, MAX_BOOT_DEVS);
+
+ iplb_num = MAX_BOOT_DEVS;
+ }
+
+ ipl->qipl.chain_len = cpu_to_be16(iplb_num - 1);
+
+ /*
+ * Build fallback IPLBs for any boot devices above index 0, up to a
+ * maximum amount as defined in ipl.h
+ */
+ if (iplb_num > 1) {
+ /* Start at 1 because the IPLB for boot index 0 is not chained */
+ for (int i = 1; i < iplb_num; i++) {
+ dev_st = get_boot_device(i);
+ s390_build_iplb(dev_st, &iplb_chain[i - 1]);
+ }
+
+ ipl->qipl.next_iplb = cpu_to_be64(s390_ipl_map_iplb_chain(iplb_chain));
+ }
+
+ return iplb_num;
+}
+
static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb,
int virtio_id)
{
@@ -620,7 +691,7 @@ void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type)
* this is the original boot device's SCSI
* so restore IPL parameter info from it
*/
- ipl->iplb_valid = s390_gen_initial_iplb(ipl);
+ ipl->iplb_valid = s390_build_iplb(get_boot_device(0), &ipl->iplb);
}
}
if (reset_type == S390_RESET_MODIFIED_CLEAR ||
@@ -714,7 +785,9 @@ void s390_ipl_prepare_cpu(S390CPU *cpu)
if (!ipl->kernel || ipl->iplb_valid) {
cpu->env.psw.addr = ipl->bios_start_addr;
if (!ipl->iplb_valid) {
- ipl->iplb_valid = s390_gen_initial_iplb(ipl);
+ ipl->iplb_valid = s390_init_all_iplbs(ipl);
+ } else {
+ ipl->qipl.chain_len = 0;
}
}
s390_ipl_set_boot_menu(ipl);
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index b670bad551..54eb48fd6e 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -20,6 +20,7 @@
#include "qom/object.h"
#define DIAG308_FLAGS_LP_VALID 0x80
+#define MAX_BOOT_DEVS 8 /* Max number of devices that may have a bootindex */
void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp);
void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp);
diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h
index b67d2ae061..1da4f75aa8 100644
--- a/include/hw/s390x/ipl/qipl.h
+++ b/include/hw/s390x/ipl/qipl.h
@@ -32,7 +32,9 @@ struct QemuIplParameters {
uint8_t reserved1[3];
uint64_t reserved2;
uint32_t boot_menu_timeout;
- uint8_t reserved3[12];
+ uint8_t reserved3[2];
+ uint16_t chain_len;
+ uint64_t next_iplb;
} QEMU_PACKED;
typedef struct QemuIplParameters QemuIplParameters;
--
2.39.3

View File

@ -0,0 +1,201 @@
From 36f64f38b39f2a2e0f0682f62f669d5e23074875 Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Thu, 20 Jun 2024 16:59:28 +0200
Subject: [PATCH 06/38] hw/s390x: Remove the possibility to load the
s390-netboot.img binary
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [5/23] ff245b81b45ddd3a78343d1a8cfdd725a8255d87 (thuth/qemu-kvm-cs9)
Since the netboot code has now been merged into the main s390-ccw.img
binary, we don't need the separate s390-netboot.img anymore. Remove
it and the code that was responsible for loading it.
Message-Id: <20240621082422.136217-6-thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 188e255bf8ed68fa64bcb63577cb100eeb326254)
---
hw/s390x/ipl.c | 55 --------------------------------------
hw/s390x/ipl.h | 12 +++------
hw/s390x/s390-virtio-ccw.c | 10 ++-----
pc-bios/meson.build | 1 -
4 files changed, 6 insertions(+), 72 deletions(-)
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 9362de0b6f..8a0a3e6961 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -288,7 +288,6 @@ static Property s390_ipl_properties[] = {
DEFINE_PROP_STRING("initrd", S390IPLState, initrd),
DEFINE_PROP_STRING("cmdline", S390IPLState, cmdline),
DEFINE_PROP_STRING("firmware", S390IPLState, firmware),
- DEFINE_PROP_STRING("netboot_fw", S390IPLState, netboot_fw),
DEFINE_PROP_BOOL("enforce_bios", S390IPLState, enforce_bios, false),
DEFINE_PROP_BOOL("iplbext_migration", S390IPLState, iplbext_migration,
true),
@@ -480,56 +479,6 @@ int s390_ipl_set_loadparm(uint8_t *loadparm)
return -1;
}
-static int load_netboot_image(Error **errp)
-{
- MachineState *ms = MACHINE(qdev_get_machine());
- S390IPLState *ipl = get_ipl_device();
- char *netboot_filename;
- MemoryRegion *sysmem = get_system_memory();
- MemoryRegion *mr = NULL;
- void *ram_ptr = NULL;
- int img_size = -1;
-
- mr = memory_region_find(sysmem, 0, 1).mr;
- if (!mr) {
- error_setg(errp, "Failed to find memory region at address 0");
- return -1;
- }
-
- ram_ptr = memory_region_get_ram_ptr(mr);
- if (!ram_ptr) {
- error_setg(errp, "No RAM found");
- goto unref_mr;
- }
-
- netboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, ipl->netboot_fw);
- if (netboot_filename == NULL) {
- error_setg(errp, "Could not find network bootloader '%s'",
- ipl->netboot_fw);
- goto unref_mr;
- }
-
- img_size = load_elf_ram(netboot_filename, NULL, NULL, NULL,
- &ipl->start_addr,
- NULL, NULL, NULL, 1, EM_S390, 0, 0, NULL,
- false);
-
- if (img_size < 0) {
- img_size = load_image_size(netboot_filename, ram_ptr, ms->ram_size);
- ipl->start_addr = KERN_IMAGE_START;
- }
-
- if (img_size < 0) {
- error_setg(errp, "Failed to load network bootloader");
- }
-
- g_free(netboot_filename);
-
-unref_mr:
- memory_region_unref(mr);
- return img_size;
-}
-
static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb,
int virtio_id)
{
@@ -754,10 +703,6 @@ void s390_ipl_prepare_cpu(S390CPU *cpu)
ipl->iplb_valid = s390_gen_initial_iplb(ipl);
}
}
- if (ipl->netboot) {
- load_netboot_image(&error_fatal);
- ipl->qipl.netboot_start_addr = cpu_to_be64(ipl->start_addr);
- }
s390_ipl_set_boot_menu(ipl);
s390_ipl_prepare_qipl(cpu);
}
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index 57cd125769..b2105b616a 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -134,11 +134,8 @@ void s390_ipl_clear_reset_request(void);
/*
* The QEMU IPL Parameters will be stored at absolute address
* 204 (0xcc) which means it is 32-bit word aligned but not
- * double-word aligned.
- * Placement of data fields in this area must account for
- * their alignment needs. E.g., netboot_start_address must
- * have an offset of 4 + n * 8 bytes within the struct in order
- * to keep it double-word aligned.
+ * double-word aligned. Placement of 64-bit data fields in this
+ * area must account for their alignment needs.
* The total size of the struct must never exceed 28 bytes.
* This definition must be kept in sync with the definition
* in pc-bios/s390-ccw/iplb.h.
@@ -146,9 +143,9 @@ void s390_ipl_clear_reset_request(void);
struct QemuIplParameters {
uint8_t qipl_flags;
uint8_t reserved1[3];
- uint64_t netboot_start_addr;
+ uint64_t reserved2;
uint32_t boot_menu_timeout;
- uint8_t reserved2[12];
+ uint8_t reserved3[12];
} QEMU_PACKED;
typedef struct QemuIplParameters QemuIplParameters;
@@ -178,7 +175,6 @@ struct S390IPLState {
char *initrd;
char *cmdline;
char *firmware;
- char *netboot_fw;
uint8_t cssid;
uint8_t ssid;
uint16_t devno;
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index b61392bac1..29a89a0c31 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -197,11 +197,10 @@ static void s390_memory_init(MemoryRegion *ram)
static void s390_init_ipl_dev(const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename, const char *firmware,
- const char *netboot_fw, bool enforce_bios)
+ bool enforce_bios)
{
Object *new = object_new(TYPE_S390_IPL);
DeviceState *dev = DEVICE(new);
- char *netboot_fw_prop;
if (kernel_filename) {
qdev_prop_set_string(dev, "kernel", kernel_filename);
@@ -212,11 +211,6 @@ static void s390_init_ipl_dev(const char *kernel_filename,
qdev_prop_set_string(dev, "cmdline", kernel_cmdline);
qdev_prop_set_string(dev, "firmware", firmware);
qdev_prop_set_bit(dev, "enforce_bios", enforce_bios);
- netboot_fw_prop = object_property_get_str(new, "netboot_fw", &error_abort);
- if (!strlen(netboot_fw_prop)) {
- qdev_prop_set_string(dev, "netboot_fw", netboot_fw);
- }
- g_free(netboot_fw_prop);
object_property_add_child(qdev_get_machine(), TYPE_S390_IPL,
new);
object_unref(new);
@@ -284,7 +278,7 @@ static void ccw_init(MachineState *machine)
s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline,
machine->initrd_filename,
machine->firmware ?: "s390-ccw.img",
- "s390-netboot.img", true);
+ true);
dev = qdev_new(TYPE_S390_PCI_HOST_BRIDGE);
object_property_add_child(qdev_get_machine(), TYPE_S390_PCI_HOST_BRIDGE,
diff --git a/pc-bios/meson.build b/pc-bios/meson.build
index 8602b45b9b..ea85c54c86 100644
--- a/pc-bios/meson.build
+++ b/pc-bios/meson.build
@@ -66,7 +66,6 @@ blobs = [
'kvmvapic.bin',
'pvh.bin',
's390-ccw.img',
- 's390-netboot.img',
'slof.bin',
'skiboot.lid',
'palcode-clipper',
--
2.39.3

View File

@ -0,0 +1,61 @@
From ce0d8bc163952ce177c37ea431cacf60889017f2 Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Fri, 21 Jun 2024 10:24:17 +0200
Subject: [PATCH 02/38] hw/s390x/ipl: Provide more memory to the s390-ccw.img
firmware
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/23] c33a2769b041e62285eb7840f8a7c05ac32aca7b (thuth/qemu-kvm-cs9)
We are going to link the SLOF libc into the s390-ccw.img, and this
libc needs more memory for providing space for malloc() and friends.
Thus bump the memory size that we reserve for the bios to 3 MiB
instead of only 2 MiB. While we're at it, add a proper check that
there is really enough memory assigned to the machine before blindly
using it.
Message-ID: <20240621082422.136217-3-thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit abaabb2e601adfe296a64471746a997eabcc607f)
---
hw/s390x/ipl.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index e934bf89d1..9362de0b6f 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -45,6 +45,7 @@
#define INITRD_PARM_START 0x010408UL
#define PARMFILE_START 0x001000UL
#define ZIPL_IMAGE_START 0x009000UL
+#define BIOS_MAX_SIZE 0x300000UL
#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64)
static bool iplb_extended_needed(void *opaque)
@@ -144,7 +145,14 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
* even if an external kernel has been defined.
*/
if (!ipl->kernel || ipl->enforce_bios) {
- uint64_t fwbase = (MIN(ms->ram_size, 0x80000000U) - 0x200000) & ~0xffffUL;
+ uint64_t fwbase;
+
+ if (ms->ram_size < BIOS_MAX_SIZE) {
+ error_setg(errp, "not enough RAM to load the BIOS file");
+ return;
+ }
+
+ fwbase = (MIN(ms->ram_size, 0x80000000U) - BIOS_MAX_SIZE) & ~0xffffUL;
bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, ipl->firmware);
if (bios_filename == NULL) {
--
2.39.3

View File

@ -0,0 +1,402 @@
From cd805347076eb3d977ad0779d98a019f5abfaa74 Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:47 -0400
Subject: [PATCH 15/38] include/hw/s390x: Add include files for common IPL
structs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [14/23] 54bcccfb27e230494b492eede1e074732b4efc17 (thuth/qemu-kvm-cs9)
Currently, structures defined in both hw/s390x/ipl.h and pc-bios/s390-ccw/iplb.h
must be kept in sync, which is prone to error. Instead, create a new directory
at include/hw/s390x/ipl/ to contain the definitions that must be shared.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-14-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit ba3658adc80a9370257a9c4e114829ec691311e3)
---
hw/s390x/ipl.h | 104 +-----------------------------
include/hw/s390x/ipl/qipl.h | 123 ++++++++++++++++++++++++++++++++++++
pc-bios/s390-ccw/Makefile | 2 +-
pc-bios/s390-ccw/iplb.h | 84 ++----------------------
4 files changed, 130 insertions(+), 183 deletions(-)
create mode 100644 include/hw/s390x/ipl/qipl.h
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index b2105b616a..fa394c339d 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -16,95 +16,11 @@
#include "cpu.h"
#include "exec/address-spaces.h"
#include "hw/qdev-core.h"
+#include "hw/s390x/ipl/qipl.h"
#include "qom/object.h"
-struct IPLBlockPVComp {
- uint64_t tweak_pref;
- uint64_t addr;
- uint64_t size;
-} QEMU_PACKED;
-typedef struct IPLBlockPVComp IPLBlockPVComp;
-
-struct IPLBlockPV {
- uint8_t reserved18[87]; /* 0x18 */
- uint8_t version; /* 0x6f */
- uint32_t reserved70; /* 0x70 */
- uint32_t num_comp; /* 0x74 */
- uint64_t pv_header_addr; /* 0x78 */
- uint64_t pv_header_len; /* 0x80 */
- struct IPLBlockPVComp components[0];
-} QEMU_PACKED;
-typedef struct IPLBlockPV IPLBlockPV;
-
-struct IplBlockCcw {
- uint8_t reserved0[85];
- uint8_t ssid;
- uint16_t devno;
- uint8_t vm_flags;
- uint8_t reserved3[3];
- uint32_t vm_parm_len;
- uint8_t nss_name[8];
- uint8_t vm_parm[64];
- uint8_t reserved4[8];
-} QEMU_PACKED;
-typedef struct IplBlockCcw IplBlockCcw;
-
-struct IplBlockFcp {
- uint8_t reserved1[305 - 1];
- uint8_t opt;
- uint8_t reserved2[3];
- uint16_t reserved3;
- uint16_t devno;
- uint8_t reserved4[4];
- uint64_t wwpn;
- uint64_t lun;
- uint32_t bootprog;
- uint8_t reserved5[12];
- uint64_t br_lba;
- uint32_t scp_data_len;
- uint8_t reserved6[260];
- uint8_t scp_data[0];
-} QEMU_PACKED;
-typedef struct IplBlockFcp IplBlockFcp;
-
-struct IplBlockQemuScsi {
- uint32_t lun;
- uint16_t target;
- uint16_t channel;
- uint8_t reserved0[77];
- uint8_t ssid;
- uint16_t devno;
-} QEMU_PACKED;
-typedef struct IplBlockQemuScsi IplBlockQemuScsi;
-
#define DIAG308_FLAGS_LP_VALID 0x80
-union IplParameterBlock {
- struct {
- uint32_t len;
- uint8_t reserved0[3];
- uint8_t version;
- uint32_t blk0_len;
- uint8_t pbt;
- uint8_t flags;
- uint16_t reserved01;
- uint8_t loadparm[8];
- union {
- IplBlockCcw ccw;
- IplBlockFcp fcp;
- IPLBlockPV pv;
- IplBlockQemuScsi scsi;
- };
- } QEMU_PACKED;
- struct {
- uint8_t reserved1[110];
- uint16_t devno;
- uint8_t reserved2[88];
- uint8_t reserved_ext[4096 - 200];
- } QEMU_PACKED;
-} QEMU_PACKED;
-typedef union IplParameterBlock IplParameterBlock;
-
int s390_ipl_set_loadparm(uint8_t *loadparm);
void s390_ipl_update_diag308(IplParameterBlock *iplb);
int s390_ipl_prepare_pv_header(Error **errp);
@@ -131,24 +47,6 @@ void s390_ipl_clear_reset_request(void);
#define QIPL_FLAG_BM_OPTS_CMD 0x80
#define QIPL_FLAG_BM_OPTS_ZIPL 0x40
-/*
- * The QEMU IPL Parameters will be stored at absolute address
- * 204 (0xcc) which means it is 32-bit word aligned but not
- * double-word aligned. Placement of 64-bit data fields in this
- * area must account for their alignment needs.
- * The total size of the struct must never exceed 28 bytes.
- * This definition must be kept in sync with the definition
- * in pc-bios/s390-ccw/iplb.h.
- */
-struct QemuIplParameters {
- uint8_t qipl_flags;
- uint8_t reserved1[3];
- uint64_t reserved2;
- uint32_t boot_menu_timeout;
- uint8_t reserved3[12];
-} QEMU_PACKED;
-typedef struct QemuIplParameters QemuIplParameters;
-
#define TYPE_S390_IPL "s390-ipl"
OBJECT_DECLARE_SIMPLE_TYPE(S390IPLState, S390_IPL)
diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h
new file mode 100644
index 0000000000..0ef04af027
--- /dev/null
+++ b/include/hw/s390x/ipl/qipl.h
@@ -0,0 +1,123 @@
+/*
+ * S/390 boot structures
+ *
+ * Copyright 2024 IBM Corp.
+ * Author(s): Jared Rossi <jrossi@linux.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#ifndef S390X_QIPL_H
+#define S390X_QIPL_H
+
+/* Boot Menu flags */
+#define QIPL_FLAG_BM_OPTS_CMD 0x80
+#define QIPL_FLAG_BM_OPTS_ZIPL 0x40
+
+#define QIPL_ADDRESS 0xcc
+#define LOADPARM_LEN 8
+
+/*
+ * The QEMU IPL Parameters will be stored at absolute address
+ * 204 (0xcc) which means it is 32-bit word aligned but not
+ * double-word aligned. Placement of 64-bit data fields in this
+ * area must account for their alignment needs.
+ * The total size of the struct must never exceed 28 bytes.
+ */
+struct QemuIplParameters {
+ uint8_t qipl_flags;
+ uint8_t reserved1[3];
+ uint64_t reserved2;
+ uint32_t boot_menu_timeout;
+ uint8_t reserved3[12];
+} QEMU_PACKED;
+typedef struct QemuIplParameters QemuIplParameters;
+
+struct IPLBlockPVComp {
+ uint64_t tweak_pref;
+ uint64_t addr;
+ uint64_t size;
+} QEMU_PACKED;
+typedef struct IPLBlockPVComp IPLBlockPVComp;
+
+struct IPLBlockPV {
+ uint8_t reserved18[87]; /* 0x18 */
+ uint8_t version; /* 0x6f */
+ uint32_t reserved70; /* 0x70 */
+ uint32_t num_comp; /* 0x74 */
+ uint64_t pv_header_addr; /* 0x78 */
+ uint64_t pv_header_len; /* 0x80 */
+ struct IPLBlockPVComp components[0];
+} QEMU_PACKED;
+typedef struct IPLBlockPV IPLBlockPV;
+
+struct IplBlockCcw {
+ uint8_t reserved0[85];
+ uint8_t ssid;
+ uint16_t devno;
+ uint8_t vm_flags;
+ uint8_t reserved3[3];
+ uint32_t vm_parm_len;
+ uint8_t nss_name[8];
+ uint8_t vm_parm[64];
+ uint8_t reserved4[8];
+} QEMU_PACKED;
+typedef struct IplBlockCcw IplBlockCcw;
+
+struct IplBlockFcp {
+ uint8_t reserved1[305 - 1];
+ uint8_t opt;
+ uint8_t reserved2[3];
+ uint16_t reserved3;
+ uint16_t devno;
+ uint8_t reserved4[4];
+ uint64_t wwpn;
+ uint64_t lun;
+ uint32_t bootprog;
+ uint8_t reserved5[12];
+ uint64_t br_lba;
+ uint32_t scp_data_len;
+ uint8_t reserved6[260];
+ uint8_t scp_data[0];
+} QEMU_PACKED;
+typedef struct IplBlockFcp IplBlockFcp;
+
+struct IplBlockQemuScsi {
+ uint32_t lun;
+ uint16_t target;
+ uint16_t channel;
+ uint8_t reserved0[77];
+ uint8_t ssid;
+ uint16_t devno;
+} QEMU_PACKED;
+typedef struct IplBlockQemuScsi IplBlockQemuScsi;
+
+union IplParameterBlock {
+ struct {
+ uint32_t len;
+ uint8_t reserved0[3];
+ uint8_t version;
+ uint32_t blk0_len;
+ uint8_t pbt;
+ uint8_t flags;
+ uint16_t reserved01;
+ uint8_t loadparm[LOADPARM_LEN];
+ union {
+ IplBlockCcw ccw;
+ IplBlockFcp fcp;
+ IPLBlockPV pv;
+ IplBlockQemuScsi scsi;
+ };
+ } QEMU_PACKED;
+ struct {
+ uint8_t reserved1[110];
+ uint16_t devno;
+ uint8_t reserved2[88];
+ uint8_t reserved_ext[4096 - 200];
+ } QEMU_PACKED;
+} QEMU_PACKED;
+typedef union IplParameterBlock IplParameterBlock;
+
+#endif
diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index 27cbb354af..db9e8f0892 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -3,7 +3,7 @@ all: build-all
@true
include config-host.mak
-CFLAGS = -O2 -g
+CFLAGS = -O2 -g -I $(SRC_PATH)/../../include/hw/s390x/ipl
MAKEFLAGS += -rR
GIT_SUBMODULES = roms/SLOF
diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h
index 3758698468..16643f5879 100644
--- a/pc-bios/s390-ccw/iplb.h
+++ b/pc-bios/s390-ccw/iplb.h
@@ -12,88 +12,14 @@
#ifndef IPLB_H
#define IPLB_H
-#define LOADPARM_LEN 8
+#ifndef QEMU_PACKED
+#define QEMU_PACKED __attribute__((packed))
+#endif
-struct IplBlockCcw {
- uint8_t reserved0[85];
- uint8_t ssid;
- uint16_t devno;
- uint8_t vm_flags;
- uint8_t reserved3[3];
- uint32_t vm_parm_len;
- uint8_t nss_name[8];
- uint8_t vm_parm[64];
- uint8_t reserved4[8];
-} __attribute__ ((packed));
-typedef struct IplBlockCcw IplBlockCcw;
-
-struct IplBlockFcp {
- uint8_t reserved1[305 - 1];
- uint8_t opt;
- uint8_t reserved2[3];
- uint16_t reserved3;
- uint16_t devno;
- uint8_t reserved4[4];
- uint64_t wwpn;
- uint64_t lun;
- uint32_t bootprog;
- uint8_t reserved5[12];
- uint64_t br_lba;
- uint32_t scp_data_len;
- uint8_t reserved6[260];
- uint8_t scp_data[];
-} __attribute__ ((packed));
-typedef struct IplBlockFcp IplBlockFcp;
-
-struct IplBlockQemuScsi {
- uint32_t lun;
- uint16_t target;
- uint16_t channel;
- uint8_t reserved0[77];
- uint8_t ssid;
- uint16_t devno;
-} __attribute__ ((packed));
-typedef struct IplBlockQemuScsi IplBlockQemuScsi;
-
-struct IplParameterBlock {
- uint32_t len;
- uint8_t reserved0[3];
- uint8_t version;
- uint32_t blk0_len;
- uint8_t pbt;
- uint8_t flags;
- uint16_t reserved01;
- uint8_t loadparm[LOADPARM_LEN];
- union {
- IplBlockCcw ccw;
- IplBlockFcp fcp;
- IplBlockQemuScsi scsi;
- };
-} __attribute__ ((packed));
-typedef struct IplParameterBlock IplParameterBlock;
-
-extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
-
-#define QIPL_ADDRESS 0xcc
-
-/* Boot Menu flags */
-#define QIPL_FLAG_BM_OPTS_CMD 0x80
-#define QIPL_FLAG_BM_OPTS_ZIPL 0x40
-
-/*
- * This definition must be kept in sync with the definition
- * in hw/s390x/ipl.h
- */
-struct QemuIplParameters {
- uint8_t qipl_flags;
- uint8_t reserved1[3];
- uint64_t reserved2;
- uint32_t boot_menu_timeout;
- uint8_t reserved3[12];
-} __attribute__ ((packed));
-typedef struct QemuIplParameters QemuIplParameters;
+#include <qipl.h>
extern QemuIplParameters qipl;
+extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
#define S390_IPL_TYPE_FCP 0x00
#define S390_IPL_TYPE_CCW 0x02
--
2.39.3

View File

@ -0,0 +1,287 @@
From 74964784ffb9a0ad307eddafddd6b47f596ca3c1 Mon Sep 17 00:00:00 2001
From: Julia Suvorova <jusual@redhat.com>
Date: Fri, 27 Sep 2024 12:47:40 +0200
Subject: [PATCH 28/38] kvm: Allow kvm_arch_get/put_registers to accept Error**
RH-Author: Julia Suvorova <None>
RH-MergeRequest: 287: kvm: Allow kvm_arch_get/put_registers to accept Error**
RH-Jira: RHEL-20574
RH-Acked-by: Juraj Marcin <None>
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Commit: [1/2] 7b1d8bf84339f908358f3fe3e392b1950aaa881d
This is necessary to provide discernible error messages to the caller.
Signed-off-by: Julia Suvorova <jusual@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/r/20240927104743.218468-2-jusual@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit a1676bb3047f28b292ecbce3a378ccc0b4721d47)
---
accel/kvm/kvm-all.c | 41 +++++++++++++++++++++++++++++---------
include/sysemu/kvm.h | 4 ++--
target/arm/kvm.c | 4 ++--
target/i386/kvm/kvm.c | 4 ++--
target/loongarch/kvm/kvm.c | 4 ++--
target/mips/kvm.c | 4 ++--
target/ppc/kvm.c | 4 ++--
target/riscv/kvm/kvm-cpu.c | 4 ++--
target/s390x/kvm/kvm.c | 4 ++--
9 files changed, 48 insertions(+), 25 deletions(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index acc23092e7..c7f1cc64b6 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2766,9 +2766,15 @@ void kvm_flush_coalesced_mmio_buffer(void)
static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
{
if (!cpu->vcpu_dirty && !kvm_state->guest_state_protected) {
- int ret = kvm_arch_get_registers(cpu);
+ Error *err = NULL;
+ int ret = kvm_arch_get_registers(cpu, &err);
if (ret) {
- error_report("Failed to get registers: %s", strerror(-ret));
+ if (err) {
+ error_reportf_err(err, "Failed to synchronize CPU state: ");
+ } else {
+ error_report("Failed to get registers: %s", strerror(-ret));
+ }
+
cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
vm_stop(RUN_STATE_INTERNAL_ERROR);
}
@@ -2786,9 +2792,15 @@ void kvm_cpu_synchronize_state(CPUState *cpu)
static void do_kvm_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg)
{
- int ret = kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE);
+ Error *err = NULL;
+ int ret = kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE, &err);
if (ret) {
- error_report("Failed to put registers after reset: %s", strerror(-ret));
+ if (err) {
+ error_reportf_err(err, "Restoring resisters after reset: ");
+ } else {
+ error_report("Failed to put registers after reset: %s",
+ strerror(-ret));
+ }
cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
vm_stop(RUN_STATE_INTERNAL_ERROR);
}
@@ -2803,9 +2815,15 @@ void kvm_cpu_synchronize_post_reset(CPUState *cpu)
static void do_kvm_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg)
{
- int ret = kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE);
+ Error *err = NULL;
+ int ret = kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE, &err);
if (ret) {
- error_report("Failed to put registers after init: %s", strerror(-ret));
+ if (err) {
+ error_reportf_err(err, "Putting registers after init: ");
+ } else {
+ error_report("Failed to put registers after init: %s",
+ strerror(-ret));
+ }
exit(1);
}
@@ -2995,10 +3013,15 @@ int kvm_cpu_exec(CPUState *cpu)
MemTxAttrs attrs;
if (cpu->vcpu_dirty) {
- ret = kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE);
+ Error *err = NULL;
+ ret = kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE, &err);
if (ret) {
- error_report("Failed to put registers after init: %s",
- strerror(-ret));
+ if (err) {
+ error_reportf_err(err, "Putting registers after init: ");
+ } else {
+ error_report("Failed to put registers after init: %s",
+ strerror(-ret));
+ }
ret = -1;
break;
}
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 9cf14ca3d5..d9ad723f78 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -359,7 +359,7 @@ int kvm_arch_handle_exit(CPUState *cpu, struct kvm_run *run);
int kvm_arch_process_async_events(CPUState *cpu);
-int kvm_arch_get_registers(CPUState *cpu);
+int kvm_arch_get_registers(CPUState *cpu, Error **errp);
/* state subset only touched by the VCPU itself during runtime */
#define KVM_PUT_RUNTIME_STATE 1
@@ -368,7 +368,7 @@ int kvm_arch_get_registers(CPUState *cpu);
/* full state set, modified during initialization or on vmload */
#define KVM_PUT_FULL_STATE 3
-int kvm_arch_put_registers(CPUState *cpu, int level);
+int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp);
int kvm_arch_get_default_type(MachineState *ms);
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 849e2e21b3..f1f1b5b375 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -2042,7 +2042,7 @@ static int kvm_arch_put_sve(CPUState *cs)
return 0;
}
-int kvm_arch_put_registers(CPUState *cs, int level)
+int kvm_arch_put_registers(CPUState *cs, int level, Error **errp)
{
uint64_t val;
uint32_t fpr;
@@ -2226,7 +2226,7 @@ static int kvm_arch_get_sve(CPUState *cs)
return 0;
}
-int kvm_arch_get_registers(CPUState *cs)
+int kvm_arch_get_registers(CPUState *cs, Error **errp)
{
uint64_t val;
unsigned int el;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 2b28c18693..423e6922d8 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -5121,7 +5121,7 @@ static int kvm_get_nested_state(X86CPU *cpu)
return ret;
}
-int kvm_arch_put_registers(CPUState *cpu, int level)
+int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp)
{
X86CPU *x86_cpu = X86_CPU(cpu);
int ret;
@@ -5209,7 +5209,7 @@ int kvm_arch_put_registers(CPUState *cpu, int level)
return 0;
}
-int kvm_arch_get_registers(CPUState *cs)
+int kvm_arch_get_registers(CPUState *cs, Error **errp)
{
X86CPU *cpu = X86_CPU(cs);
int ret;
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index e1be6a6959..9204d4295d 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -585,7 +585,7 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs)
return ret;
}
-int kvm_arch_get_registers(CPUState *cs)
+int kvm_arch_get_registers(CPUState *cs, Error **errp)
{
int ret;
@@ -613,7 +613,7 @@ int kvm_arch_get_registers(CPUState *cs)
return ret;
}
-int kvm_arch_put_registers(CPUState *cs, int level)
+int kvm_arch_put_registers(CPUState *cs, int level, Error **errp)
{
int ret;
diff --git a/target/mips/kvm.c b/target/mips/kvm.c
index a631ab544f..a98798c669 100644
--- a/target/mips/kvm.c
+++ b/target/mips/kvm.c
@@ -1172,7 +1172,7 @@ static int kvm_mips_get_cp0_registers(CPUState *cs)
return ret;
}
-int kvm_arch_put_registers(CPUState *cs, int level)
+int kvm_arch_put_registers(CPUState *cs, int level, Error **errp)
{
CPUMIPSState *env = cpu_env(cs);
struct kvm_regs regs;
@@ -1207,7 +1207,7 @@ int kvm_arch_put_registers(CPUState *cs, int level)
return ret;
}
-int kvm_arch_get_registers(CPUState *cs)
+int kvm_arch_get_registers(CPUState *cs, Error **errp)
{
CPUMIPSState *env = cpu_env(cs);
int ret = 0;
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 907dba60d1..3efc28f18b 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -900,7 +900,7 @@ int kvmppc_put_books_sregs(PowerPCCPU *cpu)
return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_SREGS, &sregs);
}
-int kvm_arch_put_registers(CPUState *cs, int level)
+int kvm_arch_put_registers(CPUState *cs, int level, Error **errp)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *env = &cpu->env;
@@ -1205,7 +1205,7 @@ static int kvmppc_get_books_sregs(PowerPCCPU *cpu)
return 0;
}
-int kvm_arch_get_registers(CPUState *cs)
+int kvm_arch_get_registers(CPUState *cs, Error **errp)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *env = &cpu->env;
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index f6e3156b8d..2bfb112be0 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -1192,7 +1192,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO
};
-int kvm_arch_get_registers(CPUState *cs)
+int kvm_arch_get_registers(CPUState *cs, Error **errp)
{
int ret = 0;
@@ -1237,7 +1237,7 @@ int kvm_riscv_sync_mpstate_to_kvm(RISCVCPU *cpu, int state)
return 0;
}
-int kvm_arch_put_registers(CPUState *cs, int level)
+int kvm_arch_put_registers(CPUState *cs, int level, Error **errp)
{
int ret = 0;
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index 94181d9281..8ffe0159d8 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -472,7 +472,7 @@ static int can_sync_regs(CPUState *cs, int regs)
#define KVM_SYNC_REQUIRED_REGS (KVM_SYNC_GPRS | KVM_SYNC_ACRS | \
KVM_SYNC_CRS | KVM_SYNC_PREFIX)
-int kvm_arch_put_registers(CPUState *cs, int level)
+int kvm_arch_put_registers(CPUState *cs, int level, Error **errp)
{
CPUS390XState *env = cpu_env(cs);
struct kvm_fpu fpu = {};
@@ -598,7 +598,7 @@ int kvm_arch_put_registers(CPUState *cs, int level)
return 0;
}
-int kvm_arch_get_registers(CPUState *cs)
+int kvm_arch_get_registers(CPUState *cs, Error **errp)
{
CPUS390XState *env = cpu_env(cs);
struct kvm_fpu fpu;
--
2.39.3

View File

@ -0,0 +1,60 @@
From 57746476c81359507743671addee330e303c1e02 Mon Sep 17 00:00:00 2001
From: Jens Remus <jremus@linux.ibm.com>
Date: Tue, 1 Oct 2024 17:36:16 +0200
Subject: [PATCH 22/38] pc-bios/s390-ccw: Clarify alignment is in bytes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [21/23] 17e89c1a3ca01b9de4683aebdbd06c5350422d27 (thuth/qemu-kvm-cs9)
The assembler directive .align [1] has architecture-dependent behavior,
which may be ambiguous for the reader. Some architectures perform the
alignment in bytes, others in power of two. s390 does in bytes.
Use the directive .balign [2] instead, to clarify that the alignment
request is in bytes. No functional change.
[1] https://sourceware.org/binutils/docs/as/Align.html
[2] https://sourceware.org/binutils/docs/as/Balign.html
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Message-ID: <20241001153618.17791-2-mhartmay@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit c58df213af7ec8924d219025a593b8f3ac475f16)
---
pc-bios/s390-ccw/start.S | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S
index 061b06591c..576fc12c06 100644
--- a/pc-bios/s390-ccw/start.S
+++ b/pc-bios/s390-ccw/start.S
@@ -112,7 +112,7 @@ io_new_code:
lctlg %c6,%c6,0(%r15)
br %r14
- .align 8
+ .balign 8
bss_start_literal:
.quad __bss_start
disabled_wait_psw:
@@ -125,7 +125,7 @@ io_new_mask:
.quad 0x0000000180000000
.bss
- .align 8
+ .balign 8
stack:
.space STACK_SIZE
.size stack,STACK_SIZE
--
2.39.3

View File

@ -0,0 +1,83 @@
From 62433cc6df65f10e99dab8b2ec9918b69c3c73ae Mon Sep 17 00:00:00 2001
From: Jens Remus <jremus@linux.ibm.com>
Date: Tue, 1 Oct 2024 17:36:17 +0200
Subject: [PATCH 23/38] pc-bios/s390-ccw: Don't generate TEXTRELs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [22/23] 57de00e48321faf13f673c6d52fd9d59d9be5c83 (thuth/qemu-kvm-cs9)
Commit 7cd50cbe4ca3 ("pc-bios/s390-ccw: Don't use __bss_start with the
"larl" instruction") introduced the address constant bss_start_literal
for __bss_start in the .text section, which introduced a relocation in
code (i.e. TEXTREL). The dedicated constant is required, as __bss_start
may not necessarily be aligned on a 2-byte boundary (see subject commit
for details).
Move the constant to the .data section to get rid of the relocation in
the .text section. Add the linker option -z text to prevent TEXTRELs to
get introduced in the future.
Note that the R_390_RELATIVE relocations are taken care of by function
glue() in include/hw/elf_ops.h.inc introduced by commit 5dce07e1cb67
("elf-loader: Provide the possibility to relocate s390 ELF files").
Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Message-ID: <20241001153618.17791-3-mhartmay@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 3259b4424a85d9cdfd1a33ed6030a6c51c1b9b8b)
---
pc-bios/s390-ccw/Makefile | 2 +-
pc-bios/s390-ccw/start.S | 7 +++++--
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index db9e8f0892..38254e22df 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -46,7 +46,7 @@ EXTRA_CFLAGS += -fwrapv -fno-strict-aliasing -fno-asynchronous-unwind-tables
EXTRA_CFLAGS += -msoft-float
EXTRA_CFLAGS += -std=gnu99
EXTRA_CFLAGS += $(LIBC_INC) $(LIBNET_INC)
-LDFLAGS += -Wl,-pie -nostdlib -z noexecstack
+LDFLAGS += -Wl,-pie -nostdlib -z noexecstack -z text
cc-test = $(CC) -Werror $1 -c -o /dev/null -xc /dev/null >/dev/null 2>/dev/null
cc-option = if $(call cc-test, $1); then \
diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S
index 576fc12c06..b70213e412 100644
--- a/pc-bios/s390-ccw/start.S
+++ b/pc-bios/s390-ccw/start.S
@@ -113,8 +113,6 @@ io_new_code:
br %r14
.balign 8
-bss_start_literal:
- .quad __bss_start
disabled_wait_psw:
.quad 0x0002000180000000,0x0000000000000000
enabled_wait_psw:
@@ -124,6 +122,11 @@ external_new_mask:
io_new_mask:
.quad 0x0000000180000000
+.data
+ .balign 8
+bss_start_literal:
+ .quad __bss_start
+
.bss
.balign 8
stack:
--
2.39.3

View File

@ -0,0 +1,426 @@
From cfc51bd73616b36a98f7f65f0df3b637d3711811 Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:46 -0400
Subject: [PATCH 14/38] pc-bios/s390-ccw: Enable failed IPL to return after
error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [13/23] a78913dc1a9de94de76d484475b967997c457d57 (thuth/qemu-kvm-cs9)
Remove panic-on-error from IPL functions such that a return code is propagated
back to the main IPL calling function (rather than terminating immediately),
which facilitates possible error recovery in the future.
A select few panics remain, which indicate fatal non-devices errors that must
result in termination.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-13-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 0181e23713114fd4c33326c3372aaf48dcfb412a)
---
pc-bios/s390-ccw/bootmap.c | 53 ++++++++++++++++++--------
pc-bios/s390-ccw/cio.c | 3 +-
pc-bios/s390-ccw/jump2ipl.c | 5 ++-
pc-bios/s390-ccw/main.c | 32 +++++++++-------
pc-bios/s390-ccw/s390-ccw.h | 2 +-
pc-bios/s390-ccw/virtio-blkdev.c | 2 +-
pc-bios/s390-ccw/virtio.c | 65 +++++++++++++++++++++-----------
pc-bios/s390-ccw/virtio.h | 2 +-
8 files changed, 108 insertions(+), 56 deletions(-)
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index 95ef9104d0..56f2f75640 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -62,15 +62,34 @@ static void *s2_prev_blk = _s2;
static void *s2_cur_blk = _s2 + MAX_SECTOR_SIZE;
static void *s2_next_blk = _s2 + MAX_SECTOR_SIZE * 2;
-static inline void verify_boot_info(BootInfo *bip)
+static inline int verify_boot_info(BootInfo *bip)
{
- IPL_assert(magic_match(bip->magic, ZIPL_MAGIC), "No zIPL sig in BootInfo");
- IPL_assert(bip->version == BOOT_INFO_VERSION, "Wrong zIPL version");
- IPL_assert(bip->bp_type == BOOT_INFO_BP_TYPE_IPL, "DASD is not for IPL");
- IPL_assert(bip->dev_type == BOOT_INFO_DEV_TYPE_ECKD, "DASD is not ECKD");
- IPL_assert(bip->flags == BOOT_INFO_FLAGS_ARCH, "Not for this arch");
- IPL_assert(block_size_ok(bip->bp.ipl.bm_ptr.eckd.bptr.size),
- "Bad block size in zIPL section of the 1st record.");
+ if (!magic_match(bip->magic, ZIPL_MAGIC)) {
+ puts("No zIPL sig in BootInfo");
+ return -EINVAL;
+ }
+ if (bip->version != BOOT_INFO_VERSION) {
+ puts("Wrong zIPL version");
+ return -EINVAL;
+ }
+ if (bip->bp_type != BOOT_INFO_BP_TYPE_IPL) {
+ puts("DASD is not for IPL");
+ return -ENODEV;
+ }
+ if (bip->dev_type != BOOT_INFO_DEV_TYPE_ECKD) {
+ puts("DASD is not ECKD");
+ return -ENODEV;
+ }
+ if (bip->flags != BOOT_INFO_FLAGS_ARCH) {
+ puts("Not for this arch");
+ return -EINVAL;
+ }
+ if (!block_size_ok(bip->bp.ipl.bm_ptr.eckd.bptr.size)) {
+ puts("Bad block size in zIPL section of 1st record");
+ return -EINVAL;
+ }
+
+ return 0;
}
static void eckd_format_chs(ExtEckdBlockPtr *ptr, bool ldipl,
@@ -367,8 +386,8 @@ static int run_eckd_boot_script(block_number_t bmt_block_nr,
puts("Unknown script entry type");
return -EINVAL;
}
- write_reset_psw(bms->entry[i].address.load_address); /* no return */
- jump_to_IPL_code(0); /* no return */
+ write_reset_psw(bms->entry[i].address.load_address);
+ jump_to_IPL_code(0);
return -1;
}
@@ -1067,16 +1086,19 @@ void zipl_load(void)
if (vdev->is_cdrom) {
ipl_iso_el_torito();
- panic("\n! Cannot IPL this ISO image !\n");
+ puts("Failed to IPL this ISO image!");
+ return;
}
if (virtio_get_device_type() == VIRTIO_ID_NET) {
netmain();
- panic("\n! Cannot IPL from this network !\n");
+ puts("Failed to IPL from this network!");
+ return;
}
if (ipl_scsi()) {
- panic("\n! Cannot IPL this SCSI device !\n");
+ puts("Failed to IPL from this SCSI device!");
+ return;
}
switch (virtio_get_device_type()) {
@@ -1087,8 +1109,9 @@ void zipl_load(void)
zipl_load_vscsi();
break;
default:
- panic("\n! Unknown IPL device type !\n");
+ puts("Unknown IPL device type!");
+ return;
}
- puts("zIPL load failed.");
+ puts("zIPL load failed!");
}
diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c
index 7b09a38c96..5d543da73f 100644
--- a/pc-bios/s390-ccw/cio.c
+++ b/pc-bios/s390-ccw/cio.c
@@ -59,7 +59,8 @@ uint16_t cu_type(SubChannelId schid)
};
if (do_cio(schid, CU_TYPE_UNKNOWN, ptr2u32(&sense_id_ccw), CCW_FMT1)) {
- panic("Failed to run SenseID CCw\n");
+ puts("Failed to run SenseID CCW");
+ return CU_TYPE_UNKNOWN;
}
return sense_data.cu_type;
diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
index 80b7f6a1f3..8db1764ff3 100644
--- a/pc-bios/s390-ccw/jump2ipl.c
+++ b/pc-bios/s390-ccw/jump2ipl.c
@@ -33,7 +33,7 @@ static void jump_to_IPL_addr(void)
/* should not return */
}
-void jump_to_IPL_code(uint64_t address)
+int jump_to_IPL_code(uint64_t address)
{
/* store the subsystem information _after_ the bootmap was loaded */
write_subsystem_identification();
@@ -68,7 +68,8 @@ void jump_to_IPL_code(uint64_t address)
asm volatile("lghi %%r1,1\n\t"
"diag %%r1,%%r1,0x308\n\t"
: : : "1", "memory");
- panic("\n! IPL returns !\n");
+ puts("IPL code jump failed");
+ return -1;
}
void jump_to_low_kernel(void)
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index fc44da3161..34ef27d7a6 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -77,6 +77,9 @@ static int is_dev_possibly_bootable(int dev_no, int sch_no)
enable_subchannel(blk_schid);
cutype = cu_type(blk_schid);
+ if (cutype == CU_TYPE_UNKNOWN) {
+ return -EIO;
+ }
/*
* Note: we always have to run virtio_is_supported() here to make
@@ -194,10 +197,10 @@ static void boot_setup(void)
have_iplb = store_iplb(&iplb);
}
-static void find_boot_device(void)
+static bool find_boot_device(void)
{
VDev *vdev = virtio_get_device();
- bool found;
+ bool found = false;
switch (iplb.pbt) {
case S390_IPL_TYPE_CCW:
@@ -215,10 +218,10 @@ static void find_boot_device(void)
found = find_subch(iplb.scsi.devno);
break;
default:
- panic("List-directed IPL not supported yet!\n");
+ puts("Unsupported IPLB");
}
- IPL_assert(found, "Boot device not found\n");
+ return found;
}
static int virtio_setup(void)
@@ -244,11 +247,13 @@ static int virtio_setup(void)
ret = virtio_scsi_setup_device(blk_schid);
break;
default:
- panic("\n! No IPL device available !\n");
+ puts("\n! No IPL device available !\n");
+ return -1;
}
- if (!ret) {
- IPL_assert(virtio_ipl_disk_is_valid(), "No valid IPL device detected");
+ if (!ret && !virtio_ipl_disk_is_valid()) {
+ puts("No valid IPL device detected");
+ return -ENODEV;
}
return ret;
@@ -259,16 +264,16 @@ static void ipl_boot_device(void)
switch (cutype) {
case CU_TYPE_DASD_3990:
case CU_TYPE_DASD_2107:
- dasd_ipl(blk_schid, cutype); /* no return */
+ dasd_ipl(blk_schid, cutype);
break;
case CU_TYPE_VIRTIO:
- if (virtio_setup() == 0) {
- zipl_load(); /* Only returns in case of errors */
+ if (virtio_setup()) {
+ return; /* Only returns in case of errors */
}
+ zipl_load();
break;
default:
printf("Attempting to boot from unexpected device type 0x%X\n", cutype);
- panic("\nBoot failed.\n");
}
}
@@ -301,12 +306,11 @@ void main(void)
sclp_setup();
css_setup();
boot_setup();
- if (have_iplb) {
- find_boot_device();
+ if (have_iplb && find_boot_device()) {
ipl_boot_device();
} else {
probe_boot_device();
}
- panic("Failed to load OS from hard disk\n");
+ panic("Failed to IPL. Halting...");
}
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index 344ad15655..6cdce3e5e5 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -78,7 +78,7 @@ void zipl_load(void);
/* jump2ipl.c */
void write_reset_psw(uint64_t psw);
-void jump_to_IPL_code(uint64_t address);
+int jump_to_IPL_code(uint64_t address);
void jump_to_low_kernel(void);
/* menu.c */
diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c
index 1c585f034b..7b2d1e20f4 100644
--- a/pc-bios/s390-ccw/virtio-blkdev.c
+++ b/pc-bios/s390-ccw/virtio-blkdev.c
@@ -59,7 +59,7 @@ int virtio_read_many(unsigned long sector, void *load_addr, int sec_num)
case VIRTIO_ID_SCSI:
return virtio_scsi_read_many(vdev, sector, load_addr, sec_num);
}
- panic("\n! No readable IPL device !\n");
+
return -1;
}
diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index 8c6b0a8a92..8b5a370bb3 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -217,16 +217,19 @@ int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd)
return 0;
}
-void virtio_setup_ccw(VDev *vdev)
+int virtio_setup_ccw(VDev *vdev)
{
- int i, rc, cfg_size = 0;
+ int i, cfg_size = 0;
uint8_t status;
struct VirtioFeatureDesc {
uint32_t features;
uint8_t index;
} __attribute__((packed)) feats;
- IPL_assert(virtio_is_supported(vdev->schid), "PE");
+ if (!virtio_is_supported(vdev->schid)) {
+ puts("Virtio unsupported for this device ID");
+ return -ENODEV;
+ }
/* device ID has been established now */
vdev->config.blk.blk_size = 0; /* mark "illegal" - setup started... */
@@ -235,8 +238,10 @@ void virtio_setup_ccw(VDev *vdev)
run_ccw(vdev, CCW_CMD_VDEV_RESET, NULL, 0, false);
status = VIRTIO_CONFIG_S_ACKNOWLEDGE;
- rc = run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false);
- IPL_assert(rc == 0, "Could not write ACKNOWLEDGE status to host");
+ if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) {
+ puts("Could not write ACKNOWLEDGE status to host");
+ return -EIO;
+ }
switch (vdev->senseid.cu_model) {
case VIRTIO_ID_NET:
@@ -255,27 +260,37 @@ void virtio_setup_ccw(VDev *vdev)
cfg_size = sizeof(vdev->config.scsi);
break;
default:
- panic("Unsupported virtio device\n");
+ puts("Unsupported virtio device");
+ return -ENODEV;
}
status |= VIRTIO_CONFIG_S_DRIVER;
- rc = run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false);
- IPL_assert(rc == 0, "Could not write DRIVER status to host");
+ if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) {
+ puts("Could not write DRIVER status to host");
+ return -EIO;
+ }
/* Feature negotiation */
for (i = 0; i < ARRAY_SIZE(vdev->guest_features); i++) {
feats.features = 0;
feats.index = i;
- rc = run_ccw(vdev, CCW_CMD_READ_FEAT, &feats, sizeof(feats), false);
- IPL_assert(rc == 0, "Could not get features bits");
+ if (run_ccw(vdev, CCW_CMD_READ_FEAT, &feats, sizeof(feats), false)) {
+ puts("Could not get features bits");
+ return -EIO;
+ }
+
vdev->guest_features[i] &= bswap32(feats.features);
feats.features = bswap32(vdev->guest_features[i]);
- rc = run_ccw(vdev, CCW_CMD_WRITE_FEAT, &feats, sizeof(feats), false);
- IPL_assert(rc == 0, "Could not set features bits");
+ if (run_ccw(vdev, CCW_CMD_WRITE_FEAT, &feats, sizeof(feats), false)) {
+ puts("Could not set features bits");
+ return -EIO;
+ }
}
- rc = run_ccw(vdev, CCW_CMD_READ_CONF, &vdev->config, cfg_size, false);
- IPL_assert(rc == 0, "Could not get virtio device configuration");
+ if (run_ccw(vdev, CCW_CMD_READ_CONF, &vdev->config, cfg_size, false)) {
+ puts("Could not get virtio device configuration");
+ return -EIO;
+ }
for (i = 0; i < vdev->nr_vqs; i++) {
VqInfo info = {
@@ -289,19 +304,27 @@ void virtio_setup_ccw(VDev *vdev)
.num = 0,
};
- rc = run_ccw(vdev, CCW_CMD_READ_VQ_CONF, &config, sizeof(config), false);
- IPL_assert(rc == 0, "Could not get virtio device VQ configuration");
+ if (run_ccw(vdev, CCW_CMD_READ_VQ_CONF, &config, sizeof(config),
+ false)) {
+ puts("Could not get virtio device VQ config");
+ return -EIO;
+ }
info.num = config.num;
vring_init(&vdev->vrings[i], &info);
vdev->vrings[i].schid = vdev->schid;
- IPL_assert(
- run_ccw(vdev, CCW_CMD_SET_VQ, &info, sizeof(info), false) == 0,
- "Cannot set VQ info");
+ if (run_ccw(vdev, CCW_CMD_SET_VQ, &info, sizeof(info), false)) {
+ puts("Cannot set VQ info");
+ return -EIO;
+ }
}
status |= VIRTIO_CONFIG_S_DRIVER_OK;
- rc = run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false);
- IPL_assert(rc == 0, "Could not write DRIVER_OK status to host");
+ if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) {
+ puts("Could not write DRIVER_OK status to host");
+ return -EIO;
+ }
+
+ return 0;
}
bool virtio_is_supported(SubChannelId schid)
diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h
index 6f9a558ff5..9faf3986b1 100644
--- a/pc-bios/s390-ccw/virtio.h
+++ b/pc-bios/s390-ccw/virtio.h
@@ -274,7 +274,7 @@ void vring_send_buf(VRing *vr, void *p, int len, int flags);
int vr_poll(VRing *vr);
int vring_wait_reply(void);
int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd);
-void virtio_setup_ccw(VDev *vdev);
+int virtio_setup_ccw(VDev *vdev);
int virtio_net_init(void *mac_addr);
--
2.39.3

View File

@ -0,0 +1,63 @@
From 06818b9971babd2895158f9fb913d6262eea4cb7 Mon Sep 17 00:00:00 2001
From: Marc Hartmayer <mhartmay@linux.ibm.com>
Date: Tue, 1 Oct 2024 17:36:18 +0200
Subject: [PATCH 24/38] pc-bios/s390-ccw: Introduce `EXTRA_LDFLAGS`
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [23/23] 148b9e68cb80b5535c6bb732e5b5ce324ba3848e (thuth/qemu-kvm-cs9)
Some packaging tools want to override `LDFLAGS` when building QEMU, this will
result in a build error as most likely no `-nostdlib` flag is passed. Introduce
`EXTRA_LDFLAGS` so that the packager can override `LDFLAGS` without breaking the
build.
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Message-ID: <20241001153618.17791-4-mhartmay@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
[thuth: Drop the hunk to netbook.mak which is not necessary anymore]
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 694d79ffce996c0993cebccc07c2ab6fc281e7d0)
---
pc-bios/s390-ccw/Makefile | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index 38254e22df..dc69dd484f 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -4,6 +4,7 @@ all: build-all
include config-host.mak
CFLAGS = -O2 -g -I $(SRC_PATH)/../../include/hw/s390x/ipl
+LDFLAGS ?=
MAKEFLAGS += -rR
GIT_SUBMODULES = roms/SLOF
@@ -46,7 +47,7 @@ EXTRA_CFLAGS += -fwrapv -fno-strict-aliasing -fno-asynchronous-unwind-tables
EXTRA_CFLAGS += -msoft-float
EXTRA_CFLAGS += -std=gnu99
EXTRA_CFLAGS += $(LIBC_INC) $(LIBNET_INC)
-LDFLAGS += -Wl,-pie -nostdlib -z noexecstack -z text
+EXTRA_LDFLAGS += -Wl,-pie -nostdlib -z noexecstack -z text
cc-test = $(CC) -Werror $1 -c -o /dev/null -xc /dev/null >/dev/null 2>/dev/null
cc-option = if $(call cc-test, $1); then \
@@ -111,7 +112,7 @@ libnet.a: $(LIBNETOBJS)
build-all: s390-ccw.img
s390-ccw.elf: $(OBJECTS) libnet.a libc.a
- $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^,Linking)
+ $(call quiet-command,$(CC) $(EXTRA_LDFLAGS) $(LDFLAGS) -o $@ $^,Linking)
s390-ccw.img: s390-ccw.elf
$(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,Stripping $< into)
--
2.39.3

View File

@ -0,0 +1,263 @@
From 7686f2129e50540b6e9865fad8b4ab9c0343c432 Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:37 -0400
Subject: [PATCH 04/38] pc-bios/s390-ccw: Link the netboot code into the main
s390-ccw.img binary
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [3/23] 5c7283de7f4e2388e157ea408a44176fdaf5127a (thuth/qemu-kvm-cs9)
We originally built a separate binary for the netboot code since it
was considered as experimental and we could not be sure that the
necessary SLOF module had been checked out. Time passed, the code
proved its usefulness, and the build system nowadays makes sure that
the SLOF module is checked out if you have a s390x compiler available
for building the s390-ccw bios. So there is no real compelling reason
anymore to keep the netboot code in a separate binary. Linking the
code together with the main s390-ccw.img will make future enhancements
much easier, like supporting more than one boot device.
Co-authored by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Message-ID: <20241020012953.1380075-4-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 8e5739ce4b0b04d7121cb2b29521acde2a8f3a24)
---
pc-bios/s390-ccw/Makefile | 13 +++++++------
pc-bios/s390-ccw/bootmap.c | 2 +-
pc-bios/s390-ccw/cio.h | 2 ++
pc-bios/s390-ccw/iplb.h | 4 ++--
pc-bios/s390-ccw/main.c | 10 +++++++---
pc-bios/s390-ccw/netboot.mak | 14 --------------
pc-bios/s390-ccw/netmain.c | 15 ++-------------
pc-bios/s390-ccw/s390-ccw.h | 3 +++
pc-bios/s390-ccw/virtio.h | 1 -
9 files changed, 24 insertions(+), 40 deletions(-)
diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index 3f4232636e..cf6859823a 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -32,19 +32,20 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d
.PHONY : all clean build-all distclean
-OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \
- virtio.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o
+OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o netmain.o \
+ virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o
SLOF_DIR := $(SRC_PATH)/../../roms/SLOF
LIBC_INC := -nostdinc -I$(SLOF_DIR)/lib/libc/include
+LIBNET_INC := -I$(SLOF_DIR)/lib/libnet
EXTRA_CFLAGS += -Wall
EXTRA_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -fno-common -fPIE
EXTRA_CFLAGS += -fwrapv -fno-strict-aliasing -fno-asynchronous-unwind-tables
EXTRA_CFLAGS += -msoft-float
EXTRA_CFLAGS += -std=gnu99
-EXTRA_CFLAGS += $(LIBC_INC)
+EXTRA_CFLAGS += $(LIBC_INC) $(LIBNET_INC)
LDFLAGS += -Wl,-pie -nostdlib -z noexecstack
cc-test = $(CC) -Werror $1 -c -o /dev/null -xc /dev/null >/dev/null 2>/dev/null
@@ -62,9 +63,9 @@ config-cc.mak: Makefile
include $(SRC_PATH)/netboot.mak
-build-all: s390-ccw.img s390-netboot.img
+build-all: s390-ccw.img
-s390-ccw.elf: $(OBJECTS) libc.a
+s390-ccw.elf: $(OBJECTS) libnet.a libc.a
$(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^,Linking)
s390-ccw.img: s390-ccw.elf
@@ -72,7 +73,7 @@ s390-ccw.img: s390-ccw.elf
$(OBJECTS): Makefile
-ALL_OBJS = $(sort $(OBJECTS) $(NETOBJS) $(LIBCOBJS) $(LIBNETOBJS))
+ALL_OBJS = $(sort $(OBJECTS) $(LIBCOBJS) $(LIBNETOBJS))
-include $(ALL_OBJS:%.o=%.d)
clean:
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index 3cc79706be..414c3f1b47 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -929,7 +929,7 @@ void zipl_load(void)
}
if (virtio_get_device_type() == VIRTIO_ID_NET) {
- jump_to_IPL_code(vdev->netboot_start_addr);
+ netmain();
}
ipl_scsi();
diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h
index 8b18153deb..6a5e86ba01 100644
--- a/pc-bios/s390-ccw/cio.h
+++ b/pc-bios/s390-ccw/cio.h
@@ -361,6 +361,8 @@ typedef struct CcwSearchIdData {
uint8_t record;
} __attribute__((packed)) CcwSearchIdData;
+extern SubChannelId net_schid;
+
int enable_mss_facility(void);
void enable_subchannel(SubChannelId schid);
uint16_t cu_type(SubChannelId schid);
diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h
index cb6ac8a880..3758698468 100644
--- a/pc-bios/s390-ccw/iplb.h
+++ b/pc-bios/s390-ccw/iplb.h
@@ -87,9 +87,9 @@ extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
struct QemuIplParameters {
uint8_t qipl_flags;
uint8_t reserved1[3];
- uint64_t netboot_start_addr;
+ uint64_t reserved2;
uint32_t boot_menu_timeout;
- uint8_t reserved2[12];
+ uint8_t reserved3[12];
} __attribute__ ((packed));
typedef struct QemuIplParameters QemuIplParameters;
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 203df20965..fc44da3161 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -38,8 +38,13 @@ LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
*/
void write_subsystem_identification(void)
{
- lowcore->subchannel_id = blk_schid.sch_id;
- lowcore->subchannel_nr = blk_schid.sch_no;
+ if (cutype == CU_TYPE_VIRTIO && virtio_get_device_type() == VIRTIO_ID_NET) {
+ lowcore->subchannel_id = net_schid.sch_id;
+ lowcore->subchannel_nr = net_schid.sch_no;
+ } else {
+ lowcore->subchannel_id = blk_schid.sch_id;
+ lowcore->subchannel_nr = blk_schid.sch_no;
+ }
lowcore->io_int_parm = 0;
}
@@ -231,7 +236,6 @@ static int virtio_setup(void)
switch (vdev->senseid.cu_model) {
case VIRTIO_ID_NET:
puts("Network boot device detected");
- vdev->netboot_start_addr = qipl.netboot_start_addr;
return 0;
case VIRTIO_ID_BLOCK:
ret = virtio_blk_setup_device(blk_schid);
diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak
index d2b3d8ee74..0a24257ff4 100644
--- a/pc-bios/s390-ccw/netboot.mak
+++ b/pc-bios/s390-ccw/netboot.mak
@@ -1,18 +1,4 @@
-NETOBJS := start.o sclp.o cio.o virtio.o virtio-net.o jump2ipl.o netmain.o
-
-LIBNET_INC := -I$(SLOF_DIR)/lib/libnet
-
-NETLDFLAGS := $(LDFLAGS) -Wl,-Ttext=0x7800000
-
-$(NETOBJS): EXTRA_CFLAGS += $(LIBC_INC) $(LIBNET_INC)
-
-s390-netboot.elf: $(NETOBJS) libnet.a libc.a
- $(call quiet-command,$(CC) $(NETLDFLAGS) -o $@ $^,Linking)
-
-s390-netboot.img: s390-netboot.elf
- $(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,Stripping $< into)
-
# libc files:
LIBC_CFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \
diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
index 509119be15..bc6ad8695f 100644
--- a/pc-bios/s390-ccw/netmain.c
+++ b/pc-bios/s390-ccw/netmain.c
@@ -41,7 +41,6 @@
#define DEFAULT_TFTP_RETRIES 20
extern char _start[];
-void write_iplb_location(void) {}
#define KERNEL_ADDR ((void *)0L)
#define KERNEL_MAX_SIZE ((long)_start)
@@ -50,10 +49,9 @@ void write_iplb_location(void) {}
/* STSI 3.2.2 offset of first vmdb + offset of uuid inside vmdb */
#define STSI322_VMDB_UUID_OFFSET ((8 + 12) * 4)
-IplParameterBlock iplb __attribute__((aligned(PAGE_SIZE)));
static char cfgbuf[2048];
-static SubChannelId net_schid = { .one = 1 };
+SubChannelId net_schid = { .one = 1 };
static uint8_t mac[6];
static uint64_t dest_timer;
@@ -438,15 +436,6 @@ static int net_try_direct_tftp_load(filename_ip_t *fn_ip)
return rc;
}
-void write_subsystem_identification(void)
-{
- SubChannelId *schid = (SubChannelId *) 184;
- uint32_t *zeroes = (uint32_t *) 188;
-
- *schid = net_schid;
- *zeroes = 0;
-}
-
static bool find_net_dev(Schib *schib, int dev_no)
{
int i, r;
@@ -509,7 +498,7 @@ static void virtio_setup(void)
IPL_assert(found, "No virtio net device found");
}
-void main(void)
+void netmain(void)
{
filename_ip_t fn_ip;
int rc, fnlen;
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index 6f6d95d170..6abb34e563 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -55,6 +55,9 @@ void write_iplb_location(void);
unsigned int get_loadparm_index(void);
void main(void);
+/* netmain.c */
+void netmain(void);
+
/* sclp.c */
void sclp_print(const char *string);
void sclp_set_write_mask(uint32_t receive_mask, uint32_t send_mask);
diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h
index 85bd9d1695..6f9a558ff5 100644
--- a/pc-bios/s390-ccw/virtio.h
+++ b/pc-bios/s390-ccw/virtio.h
@@ -253,7 +253,6 @@ struct VDev {
uint8_t scsi_dev_heads;
bool scsi_device_selected;
ScsiDevice selected_scsi_device;
- uint64_t netboot_start_addr;
uint32_t max_transfer;
uint32_t guest_features[2];
};
--
2.39.3

View File

@ -0,0 +1,141 @@
From 56030483f01524ee7021218e07c8d0ce1b588c62 Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Fri, 21 Jun 2024 09:40:11 +0200
Subject: [PATCH 07/38] pc-bios/s390-ccw: Merge netboot.mak into the main
Makefile
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [6/23] 9ce64794a5c328673cdee6fa058088c3426efad8 (thuth/qemu-kvm-cs9)
Now that the netboot code has been merged into the main s390-ccw.img,
it also does not make sense to keep the build rules in a separate
file. Thus let's merge netboot.mak into the main Makefile.
Message-Id: <20240621082422.136217-7-thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit f1fdadda36f73c9a4a96f92deb3062528cd12acc)
---
pc-bios/s390-ccw/Makefile | 47 +++++++++++++++++++++++++++++++++++-
pc-bios/s390-ccw/netboot.mak | 45 ----------------------------------
2 files changed, 46 insertions(+), 46 deletions(-)
delete mode 100644 pc-bios/s390-ccw/netboot.mak
diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index cf6859823a..27cbb354af 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -61,7 +61,52 @@ config-cc.mak: Makefile
$(call cc-option,-march=z900,-march=z10)) 3> config-cc.mak
-include config-cc.mak
-include $(SRC_PATH)/netboot.mak
+# libc files:
+
+LIBC_CFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \
+ -MMD -MP -MT $@ -MF $(@:%.o=%.d)
+
+CTYPE_OBJS = isdigit.o isxdigit.o toupper.o
+%.o : $(SLOF_DIR)/lib/libc/ctype/%.c
+ $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling)
+
+STRING_OBJS = strcat.o strchr.o strrchr.o strcpy.o strlen.o strncpy.o \
+ strcmp.o strncmp.o strcasecmp.o strncasecmp.o strstr.o \
+ memset.o memcpy.o memmove.o memcmp.o
+%.o : $(SLOF_DIR)/lib/libc/string/%.c
+ $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling)
+
+STDLIB_OBJS = atoi.o atol.o strtoul.o strtol.o rand.o malloc.o free.o
+%.o : $(SLOF_DIR)/lib/libc/stdlib/%.c
+ $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling)
+
+STDIO_OBJS = sprintf.o snprintf.o vfprintf.o vsnprintf.o vsprintf.o fprintf.o \
+ printf.o putc.o puts.o putchar.o stdchnls.o fileno.o
+%.o : $(SLOF_DIR)/lib/libc/stdio/%.c
+ $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling)
+
+sbrk.o: $(SLOF_DIR)/slof/sbrk.c
+ $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling)
+
+LIBCOBJS := $(STRING_OBJS) $(CTYPE_OBJS) $(STDLIB_OBJS) $(STDIO_OBJS) sbrk.o
+
+libc.a: $(LIBCOBJS)
+ $(call quiet-command,$(AR) -rc $@ $^,Creating static library)
+
+# libnet files:
+
+LIBNETOBJS := args.o dhcp.o dns.o icmpv6.o ipv6.o tcp.o udp.o bootp.o \
+ dhcpv6.o ethernet.o ipv4.o ndp.o tftp.o pxelinux.o
+LIBNETCFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \
+ -DDHCPARCH=0x1F -MMD -MP -MT $@ -MF $(@:%.o=%.d)
+
+%.o : $(SLOF_DIR)/lib/libnet/%.c
+ $(call quiet-command,$(CC) $(LIBNETCFLAGS) -c -o $@ $<,Compiling)
+
+libnet.a: $(LIBNETOBJS)
+ $(call quiet-command,$(AR) -rc $@ $^,Creating static library)
+
+# Main targets:
build-all: s390-ccw.img
diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak
deleted file mode 100644
index 0a24257ff4..0000000000
--- a/pc-bios/s390-ccw/netboot.mak
+++ /dev/null
@@ -1,45 +0,0 @@
-
-# libc files:
-
-LIBC_CFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \
- -MMD -MP -MT $@ -MF $(@:%.o=%.d)
-
-CTYPE_OBJS = isdigit.o isxdigit.o toupper.o
-%.o : $(SLOF_DIR)/lib/libc/ctype/%.c
- $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling)
-
-STRING_OBJS = strcat.o strchr.o strrchr.o strcpy.o strlen.o strncpy.o \
- strcmp.o strncmp.o strcasecmp.o strncasecmp.o strstr.o \
- memset.o memcpy.o memmove.o memcmp.o
-%.o : $(SLOF_DIR)/lib/libc/string/%.c
- $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling)
-
-STDLIB_OBJS = atoi.o atol.o strtoul.o strtol.o rand.o malloc.o free.o
-%.o : $(SLOF_DIR)/lib/libc/stdlib/%.c
- $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling)
-
-STDIO_OBJS = sprintf.o snprintf.o vfprintf.o vsnprintf.o vsprintf.o fprintf.o \
- printf.o putc.o puts.o putchar.o stdchnls.o fileno.o
-%.o : $(SLOF_DIR)/lib/libc/stdio/%.c
- $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling)
-
-sbrk.o: $(SLOF_DIR)/slof/sbrk.c
- $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling)
-
-LIBCOBJS := $(STRING_OBJS) $(CTYPE_OBJS) $(STDLIB_OBJS) $(STDIO_OBJS) sbrk.o
-
-libc.a: $(LIBCOBJS)
- $(call quiet-command,$(AR) -rc $@ $^,Creating static library)
-
-# libnet files:
-
-LIBNETOBJS := args.o dhcp.o dns.o icmpv6.o ipv6.o tcp.o udp.o bootp.o \
- dhcpv6.o ethernet.o ipv4.o ndp.o tftp.o pxelinux.o
-LIBNETCFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \
- -DDHCPARCH=0x1F -MMD -MP -MT $@ -MF $(@:%.o=%.d)
-
-%.o : $(SLOF_DIR)/lib/libnet/%.c
- $(call quiet-command,$(CC) $(LIBNETCFLAGS) -c -o $@ $<,Compiling)
-
-libnet.a: $(LIBNETOBJS)
- $(call quiet-command,$(AR) -rc $@ $^,Creating static library)
--
2.39.3

View File

@ -0,0 +1,177 @@
From 8279e0d5e38b31b9fcd36ff38f0175163ac4ba28 Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:44 -0400
Subject: [PATCH 12/38] pc-bios/s390-ccw: Remove panics from DASD IPL path
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [11/23] 10de76e1707b351835081f37ddf8ef1c2c00fe61 (thuth/qemu-kvm-cs9)
Remove panic-on-error from DASD IPL specific functions so that error recovery
may be possible in the future.
Functions that would previously panic now provide a return code.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-11-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 1d5c7f078e938e6844f404429dd70bc52b39dac6)
---
pc-bios/s390-ccw/dasd-ipl.c | 66 ++++++++++++++++++++-----------------
pc-bios/s390-ccw/dasd-ipl.h | 2 +-
2 files changed, 37 insertions(+), 31 deletions(-)
diff --git a/pc-bios/s390-ccw/dasd-ipl.c b/pc-bios/s390-ccw/dasd-ipl.c
index ae751adec1..babece95ea 100644
--- a/pc-bios/s390-ccw/dasd-ipl.c
+++ b/pc-bios/s390-ccw/dasd-ipl.c
@@ -111,38 +111,29 @@ static void make_readipl(void)
ccwIplRead->count = 0x18; /* Read 0x18 bytes of data */
}
-static void run_readipl(SubChannelId schid, uint16_t cutype)
+static int run_readipl(SubChannelId schid, uint16_t cutype)
{
- if (do_cio(schid, cutype, 0x00, CCW_FMT0)) {
- panic("dasd-ipl: Failed to run Read IPL channel program\n");
- }
+ return do_cio(schid, cutype, 0x00, CCW_FMT0);
}
/*
* The architecture states that IPL1 data should consist of a psw followed by
* format-0 READ and TIC CCWs. Let's sanity check.
*/
-static void check_ipl1(void)
+static bool check_ipl1(void)
{
Ccw0 *ccwread = (Ccw0 *)0x08;
Ccw0 *ccwtic = (Ccw0 *)0x10;
- if (ccwread->cmd_code != CCW_CMD_DASD_READ ||
- ccwtic->cmd_code != CCW_CMD_TIC) {
- panic("dasd-ipl: IPL1 data invalid. Is this disk really bootable?\n");
- }
+ return (ccwread->cmd_code == CCW_CMD_DASD_READ &&
+ ccwtic->cmd_code == CCW_CMD_TIC);
}
-static void check_ipl2(uint32_t ipl2_addr)
+static bool check_ipl2(uint32_t ipl2_addr)
{
Ccw0 *ccw = u32toptr(ipl2_addr);
- if (ipl2_addr == 0x00) {
- panic("IPL2 address invalid. Is this disk really bootable?\n");
- }
- if (ccw->cmd_code == 0x00) {
- panic("IPL2 ccw data invalid. Is this disk really bootable?\n");
- }
+ return (ipl2_addr != 0x00 && ccw->cmd_code != 0x00);
}
static uint32_t read_ipl2_addr(void)
@@ -188,52 +179,67 @@ static void ipl1_fixup(void)
ccwSearchTic->cda = ptr2u32(ccwSearchID);
}
-static void run_ipl1(SubChannelId schid, uint16_t cutype)
+static int run_ipl1(SubChannelId schid, uint16_t cutype)
{
uint32_t startAddr = 0x08;
- if (do_cio(schid, cutype, startAddr, CCW_FMT0)) {
- panic("dasd-ipl: Failed to run IPL1 channel program\n");
- }
+ return do_cio(schid, cutype, startAddr, CCW_FMT0);
}
-static void run_ipl2(SubChannelId schid, uint16_t cutype, uint32_t addr)
+static int run_ipl2(SubChannelId schid, uint16_t cutype, uint32_t addr)
{
- if (run_dynamic_ccw_program(schid, cutype, addr)) {
- panic("dasd-ipl: Failed to run IPL2 channel program\n");
- }
+ return run_dynamic_ccw_program(schid, cutype, addr);
}
/*
* Limitations in vfio-ccw support complicate the IPL process. Details can
* be found in docs/devel/s390-dasd-ipl.rst
*/
-void dasd_ipl(SubChannelId schid, uint16_t cutype)
+int dasd_ipl(SubChannelId schid, uint16_t cutype)
{
PSWLegacy *pswl = (PSWLegacy *) 0x00;
uint32_t ipl2_addr;
/* Construct Read IPL CCW and run it to read IPL1 from boot disk */
make_readipl();
- run_readipl(schid, cutype);
+ if (run_readipl(schid, cutype)) {
+ puts("Failed to run Read IPL channel program");
+ return -EIO;
+ }
+
ipl2_addr = read_ipl2_addr();
- check_ipl1();
+
+ if (!check_ipl1()) {
+ puts("IPL1 invalid for DASD-IPL");
+ return -EINVAL;
+ }
/*
* Fixup IPL1 channel program to account for vfio-ccw limitations, then run
* it to read IPL2 channel program from boot disk.
*/
ipl1_fixup();
- run_ipl1(schid, cutype);
- check_ipl2(ipl2_addr);
+ if (run_ipl1(schid, cutype)) {
+ puts("Failed to run IPL1 channel program");
+ return -EIO;
+ }
+
+ if (!check_ipl2(ipl2_addr)) {
+ puts("IPL2 invalid for DASD-IPL");
+ return -EINVAL;
+ }
/*
* Run IPL2 channel program to read operating system code from boot disk
*/
- run_ipl2(schid, cutype, ipl2_addr);
+ if (run_ipl2(schid, cutype, ipl2_addr)) {
+ puts("Failed to run IPL2 channel program");
+ return -EIO;
+ }
/* Transfer control to the guest operating system */
pswl->mask |= PSW_MASK_EAMODE; /* Force z-mode */
pswl->addr |= PSW_MASK_BAMODE; /* ... */
jump_to_low_kernel();
+ return -1;
}
diff --git a/pc-bios/s390-ccw/dasd-ipl.h b/pc-bios/s390-ccw/dasd-ipl.h
index c394828906..eb1898c84a 100644
--- a/pc-bios/s390-ccw/dasd-ipl.h
+++ b/pc-bios/s390-ccw/dasd-ipl.h
@@ -11,6 +11,6 @@
#ifndef DASD_IPL_H
#define DASD_IPL_H
-void dasd_ipl(SubChannelId schid, uint16_t cutype);
+int dasd_ipl(SubChannelId schid, uint16_t cutype);
#endif /* DASD_IPL_H */
--
2.39.3

View File

@ -0,0 +1,475 @@
From 0a8e0f11dd82d5988b1090e8e4b8326be0dcb30c Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:42 -0400
Subject: [PATCH 10/38] pc-bios/s390-ccw: Remove panics from ECKD IPL path
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [9/23] 628c2800ed02da8920e7e7c21d9f57e38a9a933d (thuth/qemu-kvm-cs9)
Remove panic-on-error from ECKD block device IPL specific functions so that
error recovery may be possible in the future.
Functions that would previously panic now provide a return code.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-9-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 806315279d5c629e1cc3a945bcfba3fe5482d84b)
---
pc-bios/s390-ccw/bootmap.c | 187 +++++++++++++++++++++++++------------
pc-bios/s390-ccw/bootmap.h | 1 +
2 files changed, 130 insertions(+), 58 deletions(-)
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index af73254acb..b9596e28c7 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -145,14 +145,17 @@ static block_number_t load_eckd_segments(block_number_t blk, bool ldipl,
bool more_data;
memset(_bprs, FREE_SPACE_FILLER, sizeof(_bprs));
- read_block(blk, bprs, "BPRS read failed");
+ if (virtio_read(blk, bprs)) {
+ puts("BPRS read failed");
+ return ERROR_BLOCK_NR;
+ }
do {
more_data = false;
for (j = 0;; j++) {
block_nr = gen_eckd_block_num(&bprs[j].xeckd, ldipl);
if (is_null_block_number(block_nr)) { /* end of chunk */
- break;
+ return NULL_BLOCK_NR;
}
/* we need the updated blockno for the next indirect entry
@@ -163,15 +166,20 @@ static block_number_t load_eckd_segments(block_number_t blk, bool ldipl,
}
/* List directed pointer does not store block size */
- IPL_assert(ldipl || block_size_ok(bprs[j].xeckd.bptr.size),
- "bad chunk block size");
+ if (!ldipl && !block_size_ok(bprs[j].xeckd.bptr.size)) {
+ puts("Bad chunk block size");
+ return ERROR_BLOCK_NR;
+ }
if (!eckd_valid_address(&bprs[j].xeckd, ldipl)) {
/*
* If an invalid address is found during LD-IPL then break and
- * retry as CCW
+ * retry as CCW-IPL, otherwise abort on error
*/
- IPL_assert(ldipl, "bad chunk ECKD addr");
+ if (!ldipl) {
+ puts("Bad chunk ECKD address");
+ return ERROR_BLOCK_NR;
+ }
break;
}
@@ -189,7 +197,10 @@ static block_number_t load_eckd_segments(block_number_t blk, bool ldipl,
* I.e. the next ptr must point to the unused memory area
*/
memset(_bprs, FREE_SPACE_FILLER, sizeof(_bprs));
- read_block(block_nr, bprs, "BPRS continuation read failed");
+ if (virtio_read(block_nr, bprs)) {
+ puts("BPRS continuation read failed");
+ return ERROR_BLOCK_NR;
+ }
more_data = true;
break;
}
@@ -198,7 +209,10 @@ static block_number_t load_eckd_segments(block_number_t blk, bool ldipl,
* to memory (address).
*/
rc = virtio_read_many(block_nr, (void *)(*address), count + 1);
- IPL_assert(rc == 0, "code chunk read failed");
+ if (rc != 0) {
+ puts("Code chunk read failed");
+ return ERROR_BLOCK_NR;
+ }
*address += (count + 1) * virtio_get_block_size();
}
@@ -232,7 +246,10 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr)
/* Get Stage1b data */
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
- read_block(s1b_block_nr, s1b, "Cannot read stage1b boot loader");
+ if (virtio_read(s1b_block_nr, s1b)) {
+ puts("Cannot read stage1b boot loader");
+ return -EIO;
+ }
memset(_s2, FREE_SPACE_FILLER, sizeof(_s2));
@@ -244,7 +261,10 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr)
break;
}
- read_block(cur_block_nr, s2_cur_blk, "Cannot read stage2 boot loader");
+ if (virtio_read(cur_block_nr, s2_cur_blk)) {
+ puts("Cannot read stage2 boot loader");
+ return -EIO;
+ }
if (find_zipl_boot_menu_banner(&banner_offset)) {
/*
@@ -252,8 +272,10 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr)
* possibility of menu data spanning multiple blocks.
*/
if (prev_block_nr) {
- read_block(prev_block_nr, s2_prev_blk,
- "Cannot read stage2 boot loader");
+ if (virtio_read(prev_block_nr, s2_prev_blk)) {
+ puts("Cannot read stage2 boot loader");
+ return -EIO;
+ }
}
if (i + 1 < STAGE2_BLK_CNT_MAX) {
@@ -261,8 +283,10 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr)
}
if (next_block_nr && !is_null_block_number(next_block_nr)) {
- read_block(next_block_nr, s2_next_blk,
- "Cannot read stage2 boot loader");
+ if (virtio_read(next_block_nr, s2_next_blk)) {
+ puts("Cannot read stage2 boot loader");
+ return -EIO;
+ }
}
return menu_get_zipl_boot_index(s2_cur_blk + banner_offset);
@@ -275,7 +299,7 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr)
return 0;
}
-static void run_eckd_boot_script(block_number_t bmt_block_nr,
+static int run_eckd_boot_script(block_number_t bmt_block_nr,
block_number_t s1b_block_nr)
{
int i;
@@ -292,17 +316,28 @@ static void run_eckd_boot_script(block_number_t bmt_block_nr,
}
debug_print_int("loadparm", loadparm);
- IPL_assert(loadparm < MAX_BOOT_ENTRIES, "loadparm value greater than"
- " maximum number of boot entries allowed");
+ if (loadparm >= MAX_BOOT_ENTRIES) {
+ puts("loadparm value greater than max number of boot entries allowed");
+ return -EINVAL;
+ }
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
- read_block(bmt_block_nr, sec, "Cannot read Boot Map Table");
+ if (virtio_read(bmt_block_nr, sec)) {
+ puts("Cannot read Boot Map Table");
+ return -EIO;
+ }
block_nr = gen_eckd_block_num(&bmt->entry[loadparm].xeckd, ldipl);
- IPL_assert(block_nr != -1, "Cannot find Boot Map Table Entry");
+ if (block_nr == NULL_BLOCK_NR) {
+ puts("Cannot find Boot Map Table Entry");
+ return -EIO;
+ }
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
- read_block(block_nr, sec, "Cannot read Boot Map Script");
+ if (virtio_read(block_nr, sec)) {
+ puts("Cannot read Boot Map Script");
+ return -EIO;
+ }
for (i = 0; bms->entry[i].type == BOOT_SCRIPT_LOAD ||
bms->entry[i].type == BOOT_SCRIPT_SIGNATURE; i++) {
@@ -317,21 +352,27 @@ static void run_eckd_boot_script(block_number_t bmt_block_nr,
do {
block_nr = load_eckd_segments(block_nr, ldipl, &address);
- } while (block_nr != -1);
+ if (block_nr == ERROR_BLOCK_NR) {
+ return ldipl ? 0 : -EIO;
+ }
+ } while (block_nr != NULL_BLOCK_NR);
}
if (ldipl && bms->entry[i].type != BOOT_SCRIPT_EXEC) {
/* Abort LD-IPL and retry as CCW-IPL */
- return;
+ return 0;
}
- IPL_assert(bms->entry[i].type == BOOT_SCRIPT_EXEC,
- "Unknown script entry type");
+ if (bms->entry[i].type != BOOT_SCRIPT_EXEC) {
+ puts("Unknown script entry type");
+ return -EINVAL;
+ }
write_reset_psw(bms->entry[i].address.load_address); /* no return */
jump_to_IPL_code(0); /* no return */
+ return -1;
}
-static void ipl_eckd_cdl(void)
+static int ipl_eckd_cdl(void)
{
XEckdMbr *mbr;
EckdCdlIpl2 *ipl2 = (void *)sec;
@@ -342,20 +383,23 @@ static void ipl_eckd_cdl(void)
puts("CDL");
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
- read_block(1, ipl2, "Cannot read IPL2 record at block 1");
+ if (virtio_read(1, ipl2)) {
+ puts("Cannot read IPL2 record at block 1");
+ return -EIO;
+ }
mbr = &ipl2->mbr;
if (!magic_match(mbr, ZIPL_MAGIC)) {
puts("No zIPL section in IPL2 record.");
- return;
+ return 0;
}
if (!block_size_ok(mbr->blockptr.xeckd.bptr.size)) {
puts("Bad block size in zIPL section of IPL2 record.");
- return;
+ return 0;
}
if (mbr->dev_type != DEV_TYPE_ECKD) {
puts("Non-ECKD device type in zIPL section of IPL2 record.");
- return;
+ return 0;
}
/* save pointer to Boot Map Table */
@@ -365,19 +409,21 @@ static void ipl_eckd_cdl(void)
s1b_block_nr = eckd_block_num(&ipl2->stage1.seek[0].chs);
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
- read_block(2, vlbl, "Cannot read Volume Label at block 2");
+ if (virtio_read(2, vlbl)) {
+ puts("Cannot read Volume Label at block 2");
+ return -EIO;
+ }
if (!magic_match(vlbl->key, VOL1_MAGIC)) {
puts("Invalid magic of volume label block.");
- return;
+ return 0;
}
if (!magic_match(vlbl->f.key, VOL1_MAGIC)) {
puts("Invalid magic of volser block.");
- return;
+ return 0;
}
print_volser(vlbl->f.volser);
- run_eckd_boot_script(bmt_block_nr, s1b_block_nr);
- /* no return */
+ return run_eckd_boot_script(bmt_block_nr, s1b_block_nr);
}
static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode)
@@ -403,7 +449,7 @@ static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode)
print_volser(vlbl->volser);
}
-static void ipl_eckd_ldl(ECKD_IPL_mode_t mode)
+static int ipl_eckd_ldl(ECKD_IPL_mode_t mode)
{
block_number_t bmt_block_nr, s1b_block_nr;
EckdLdlIpl1 *ipl1 = (void *)sec;
@@ -415,10 +461,13 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode)
/* DO NOT read BootMap pointer (only one, xECKD) at block #2 */
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
- read_block(0, sec, "Cannot read block 0 to grab boot info.");
+ if (virtio_read(0, sec)) {
+ puts("Cannot read block 0 to grab boot info.");
+ return -EIO;
+ }
if (mode == ECKD_LDL_UNLABELED) {
if (!magic_match(ipl1->bip.magic, ZIPL_MAGIC)) {
- return; /* not applicable layout */
+ return 0; /* not applicable layout */
}
puts("unlabeled LDL.");
}
@@ -430,8 +479,7 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode)
/* save pointer to Stage1b Data */
s1b_block_nr = eckd_block_num(&ipl1->stage1.seek[0].chs);
- run_eckd_boot_script(bmt_block_nr, s1b_block_nr);
- /* no return */
+ return run_eckd_boot_script(bmt_block_nr, s1b_block_nr);
}
static block_number_t eckd_find_bmt(ExtEckdBlockPtr *ptr)
@@ -441,7 +489,10 @@ static block_number_t eckd_find_bmt(ExtEckdBlockPtr *ptr)
BootRecord *br;
blockno = gen_eckd_block_num(ptr, 0);
- read_block(blockno, tmp_sec, "Cannot read boot record");
+ if (virtio_read(blockno, tmp_sec)) {
+ puts("Cannot read boot record");
+ return ERROR_BLOCK_NR;
+ }
br = (BootRecord *)tmp_sec;
if (!magic_match(br->magic, ZIPL_MAGIC)) {
/* If the boot record is invalid, return and try CCW-IPL instead */
@@ -470,7 +521,7 @@ static void print_eckd_msg(void)
printf("%s", msg);
}
-static void ipl_eckd(void)
+static int ipl_eckd(void)
{
IplVolumeLabel *vlbl = (void *)sec;
LDL_VTOC *vtoc = (void *)sec;
@@ -480,7 +531,10 @@ static void ipl_eckd(void)
/* Block 2 can contain either the CDL VOL1 label or the LDL VTOC */
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
- read_block(2, vlbl, "Cannot read block 2");
+ if (virtio_read(2, vlbl)) {
+ puts("Cannot read block 2");
+ return -EIO;
+ }
/*
* First check for a list-directed-format pointer which would
@@ -488,36 +542,53 @@ static void ipl_eckd(void)
*/
if (eckd_valid_address((ExtEckdBlockPtr *)&vlbl->f.br, 0)) {
ldipl_bmt = eckd_find_bmt((ExtEckdBlockPtr *)&vlbl->f.br);
- if (ldipl_bmt) {
+ switch (ldipl_bmt) {
+ case ERROR_BLOCK_NR:
+ return -EIO;
+ case NULL_BLOCK_NR:
+ break; /* Invalid BMT but the device may still boot with CCW-IPL */
+ default:
puts("List-Directed");
- /* LD-IPL does not use the S1B bock, just make it NULL */
- run_eckd_boot_script(ldipl_bmt, NULL_BLOCK_NR);
- /* Only return in error, retry as CCW-IPL */
+ /*
+ * LD-IPL does not use the S1B bock, just make it NULL_BLOCK_NR.
+ * In some failure cases retry IPL before aborting.
+ */
+ if (run_eckd_boot_script(ldipl_bmt, NULL_BLOCK_NR)) {
+ return -EIO;
+ }
+ /* Non-fatal error, retry as CCW-IPL */
printf("Retrying IPL ");
print_eckd_msg();
}
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
- read_block(2, vtoc, "Cannot read block 2");
+ if (virtio_read(2, vtoc)) {
+ puts("Cannot read block 2");
+ return -EIO;
+ }
}
/* Not list-directed */
if (magic_match(vtoc->magic, VOL1_MAGIC)) {
- ipl_eckd_cdl(); /* may return in error */
+ if (ipl_eckd_cdl()) {
+ return -1;
+ }
}
if (magic_match(vtoc->magic, CMS1_MAGIC)) {
- ipl_eckd_ldl(ECKD_CMS); /* no return */
+ return ipl_eckd_ldl(ECKD_CMS);
}
if (magic_match(vtoc->magic, LNX1_MAGIC)) {
- ipl_eckd_ldl(ECKD_LDL); /* no return */
+ return ipl_eckd_ldl(ECKD_LDL);
}
- ipl_eckd_ldl(ECKD_LDL_UNLABELED); /* it still may return */
+ if (ipl_eckd_ldl(ECKD_LDL_UNLABELED)) {
+ return -1;
+ }
/*
* Ok, it is not a LDL by any means.
* It still might be a CDL with zero record keys for IPL1 and IPL2
*/
- ipl_eckd_cdl();
+ return ipl_eckd_cdl();
}
/***********************************************************************
@@ -910,7 +981,7 @@ static bool has_iso_signature(void)
* Bus specific IPL sequences
*/
-static void zipl_load_vblk(void)
+static int zipl_load_vblk(void)
{
int blksize = virtio_get_block_size();
@@ -919,7 +990,7 @@ static void zipl_load_vblk(void)
virtio_assume_iso9660();
}
if (ipl_iso_el_torito()) {
- return;
+ return 0;
}
}
@@ -927,21 +998,21 @@ static void zipl_load_vblk(void)
puts("Using guessed DASD geometry.");
virtio_assume_eckd();
}
- ipl_eckd();
+ return ipl_eckd();
}
-static void zipl_load_vscsi(void)
+static int zipl_load_vscsi(void)
{
if (virtio_get_block_size() == VIRTIO_ISO_BLOCK_SIZE) {
/* Is it an ISO image in non-CD drive? */
if (ipl_iso_el_torito()) {
- return;
+ return 0;
}
}
puts("Using guessed DASD geometry.");
virtio_assume_eckd();
- ipl_eckd();
+ return ipl_eckd();
}
/***********************************************************************
diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h
index 3cb573b86b..95943441d3 100644
--- a/pc-bios/s390-ccw/bootmap.h
+++ b/pc-bios/s390-ccw/bootmap.h
@@ -16,6 +16,7 @@
typedef uint64_t block_number_t;
#define NULL_BLOCK_NR 0xffffffffffffffffULL
+#define ERROR_BLOCK_NR 0xfffffffffffffffeULL
#define FREE_SPACE_FILLER '\xAA'
--
2.39.3

View File

@ -0,0 +1,269 @@
From 6238d2aa6b1a1f421ac04b0d35281dd5e4c65b5c Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:41 -0400
Subject: [PATCH 09/38] pc-bios/s390-ccw: Remove panics from ISO IPL path
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [8/23] de54d00bb7f300a38e7babdf8c9b587c0ed81883 (thuth/qemu-kvm-cs9)
Remove panic-on-error from IPL ISO El Torito specific functions so that error
recovery may be possible in the future.
Functions that would previously panic now provide a return code.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-8-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit bef2b8dd1a36fc79cabcda48e667f2cba476924c)
---
pc-bios/s390-ccw/bootmap.c | 87 ++++++++++++++++++++++++-------------
pc-bios/s390-ccw/bootmap.h | 15 +++----
pc-bios/s390-ccw/s390-ccw.h | 1 +
3 files changed, 65 insertions(+), 38 deletions(-)
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index 414c3f1b47..af73254acb 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -678,8 +678,10 @@ static bool is_iso_bc_entry_compatible(IsoBcSection *s)
if (s->unused || !s->sector_count) {
return false;
}
- read_iso_sector(bswap32(s->load_rba), magic_sec,
- "Failed to read image sector 0");
+ if (virtio_read(bswap32(s->load_rba), magic_sec)) {
+ puts("Failed to read image sector 0");
+ return false;
+ }
/* Checking bytes 8 - 32 for S390 Linux magic */
return !memcmp(magic_sec + 8, linux_s390_magic, 24);
@@ -692,28 +694,35 @@ static uint32_t sec_offset[ISO9660_MAX_DIR_DEPTH];
/* Remained directory space in bytes */
static uint32_t dir_rem[ISO9660_MAX_DIR_DEPTH];
-static inline uint32_t iso_get_file_size(uint32_t load_rba)
+static inline long iso_get_file_size(uint32_t load_rba)
{
IsoVolDesc *vd = (IsoVolDesc *)sec;
IsoDirHdr *cur_record = &vd->vd.primary.rootdir;
uint8_t *temp = sec + ISO_SECTOR_SIZE;
int level = 0;
- read_iso_sector(ISO_PRIMARY_VD_SECTOR, sec,
- "Failed to read ISO primary descriptor");
+ if (virtio_read(ISO_PRIMARY_VD_SECTOR, sec)) {
+ puts("Failed to read ISO primary descriptor");
+ return -EIO;
+ }
+
sec_loc[0] = iso_733_to_u32(cur_record->ext_loc);
dir_rem[0] = 0;
sec_offset[0] = 0;
while (level >= 0) {
- IPL_assert(sec_offset[level] <= ISO_SECTOR_SIZE,
- "Directory tree structure violation");
+ if (sec_offset[level] > ISO_SECTOR_SIZE) {
+ puts("Directory tree structure violation");
+ return -EIO;
+ }
cur_record = (IsoDirHdr *)(temp + sec_offset[level]);
if (sec_offset[level] == 0) {
- read_iso_sector(sec_loc[level], temp,
- "Failed to read ISO directory");
+ if (virtio_read(sec_loc[level], temp)) {
+ puts("Failed to read ISO directory");
+ return -EIO;
+ }
if (dir_rem[level] == 0) {
/* Skip self and parent records */
dir_rem[level] = iso_733_to_u32(cur_record->data_len) -
@@ -758,8 +767,10 @@ static inline uint32_t iso_get_file_size(uint32_t load_rba)
if (dir_rem[level] == 0) {
/* Nothing remaining */
level--;
- read_iso_sector(sec_loc[level], temp,
- "Failed to read ISO directory");
+ if (virtio_read(sec_loc[level], temp)) {
+ puts("Failed to read ISO directory");
+ return -EIO;
+ }
}
}
@@ -774,19 +785,24 @@ static void load_iso_bc_entry(IsoBcSection *load)
* is padded and ISO_SECTOR_SIZE bytes aligned
*/
uint32_t blks_to_load = bswap16(s.sector_count) >> ET_SECTOR_SHIFT;
- uint32_t real_size = iso_get_file_size(bswap32(s.load_rba));
+ long real_size = iso_get_file_size(bswap32(s.load_rba));
- if (real_size) {
+ if (real_size > 0) {
/* Round up blocks to load */
blks_to_load = (real_size + ISO_SECTOR_SIZE - 1) / ISO_SECTOR_SIZE;
puts("ISO boot image size verified");
} else {
puts("ISO boot image size could not be verified");
+ if (real_size < 0) {
+ return;
+ }
}
- read_iso_boot_image(bswap32(s.load_rba),
+ if (read_iso_boot_image(bswap32(s.load_rba),
(void *)((uint64_t)bswap16(s.load_segment)),
- blks_to_load);
+ blks_to_load)) {
+ return;
+ }
jump_to_low_kernel();
}
@@ -809,17 +825,18 @@ static uint32_t find_iso_bc(void)
return bswap32(et->bc_offset);
}
}
- read_iso_sector(block_num++, sec,
- "Failed to read ISO volume descriptor");
+ if (virtio_read(block_num++, sec)) {
+ puts("Failed to read ISO volume descriptor");
+ return 0;
+ }
}
return 0;
}
-static IsoBcSection *find_iso_bc_entry(void)
+static IsoBcSection *find_iso_bc_entry(uint32_t offset)
{
IsoBcEntry *e = (IsoBcEntry *)sec;
- uint32_t offset = find_iso_bc();
int i;
unsigned int loadparm = get_loadparm_index();
@@ -827,11 +844,13 @@ static IsoBcSection *find_iso_bc_entry(void)
return NULL;
}
- read_iso_sector(offset, sec, "Failed to read El Torito boot catalog");
+ if (virtio_read(offset, sec)) {
+ puts("Failed to read El Torito boot catalog");
+ return NULL;
+ }
if (!is_iso_bc_valid(e)) {
/* The validation entry is mandatory */
- panic("No valid boot catalog found!\n");
return NULL;
}
@@ -851,19 +870,25 @@ static IsoBcSection *find_iso_bc_entry(void)
}
}
- panic("No suitable boot entry found on ISO-9660 media!\n");
-
return NULL;
}
-static void ipl_iso_el_torito(void)
+static int ipl_iso_el_torito(void)
{
- IsoBcSection *s = find_iso_bc_entry();
+ uint32_t offset = find_iso_bc();
+ if (!offset) {
+ return 0;
+ }
+
+ IsoBcSection *s = find_iso_bc_entry(offset);
if (s) {
- load_iso_bc_entry(s);
- /* no return */
+ load_iso_bc_entry(s); /* only return in error */
+ return -1;
}
+
+ puts("No suitable boot entry found on ISO-9660 media!");
+ return -EIO;
}
/**
@@ -893,7 +918,9 @@ static void zipl_load_vblk(void)
if (blksize != VIRTIO_ISO_BLOCK_SIZE) {
virtio_assume_iso9660();
}
- ipl_iso_el_torito();
+ if (ipl_iso_el_torito()) {
+ return;
+ }
}
if (blksize != VIRTIO_DASD_DEFAULT_BLOCK_SIZE) {
@@ -907,7 +934,9 @@ static void zipl_load_vscsi(void)
{
if (virtio_get_block_size() == VIRTIO_ISO_BLOCK_SIZE) {
/* Is it an ISO image in non-CD drive? */
- ipl_iso_el_torito();
+ if (ipl_iso_el_torito()) {
+ return;
+ }
}
puts("Using guessed DASD geometry.");
diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h
index 4a7d8a91f1..3cb573b86b 100644
--- a/pc-bios/s390-ccw/bootmap.h
+++ b/pc-bios/s390-ccw/bootmap.h
@@ -385,17 +385,14 @@ static inline uint32_t iso_733_to_u32(uint64_t x)
#define ISO_PRIMARY_VD_SECTOR 16
-static inline void read_iso_sector(uint32_t block_offset, void *buf,
- const char *errmsg)
-{
- IPL_assert(virtio_read_many(block_offset, buf, 1) == 0, errmsg);
-}
-
-static inline void read_iso_boot_image(uint32_t block_offset, void *load_addr,
+static inline int read_iso_boot_image(uint32_t block_offset, void *load_addr,
uint32_t blks_to_load)
{
- IPL_assert(virtio_read_many(block_offset, load_addr, blks_to_load) == 0,
- "Failed to read boot image!");
+ if (virtio_read_many(block_offset, load_addr, blks_to_load)) {
+ puts("Failed to read boot image!");
+ return -1;
+ }
+ return 0;
}
#define ISO9660_MAX_DIR_DEPTH 8
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index 6abb34e563..3e844abd71 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -30,6 +30,7 @@ typedef unsigned long long u64;
#define EIO 1
#define EBUSY 2
#define ENODEV 3
+#define EINVAL 4
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
--
2.39.3

View File

@ -0,0 +1,130 @@
From d5e0f77bd63bc767856e1922b24556ef1b123b55 Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:45 -0400
Subject: [PATCH 13/38] pc-bios/s390-ccw: Remove panics from Netboot IPL path
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [12/23] 26920462eca8a2e6d443c811efa69023fbe4f31f (thuth/qemu-kvm-cs9)
Remove panic-on-error from Netboot specific functions so that error recovery
may be possible in the future.
Functions that would previously panic now provide a return code.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-12-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit f1a2a6e41ef76e02ddc5ede3dd042ef96b4fb8d2)
---
pc-bios/s390-ccw/bootmap.c | 1 +
pc-bios/s390-ccw/netmain.c | 17 +++++++++++------
pc-bios/s390-ccw/s390-ccw.h | 2 +-
pc-bios/s390-ccw/virtio-net.c | 7 +++++--
4 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index 652807a16a..95ef9104d0 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -1072,6 +1072,7 @@ void zipl_load(void)
if (virtio_get_device_type() == VIRTIO_ID_NET) {
netmain();
+ panic("\n! Cannot IPL from this network !\n");
}
if (ipl_scsi()) {
diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
index bc6ad8695f..d1a6c9a91c 100644
--- a/pc-bios/s390-ccw/netmain.c
+++ b/pc-bios/s390-ccw/netmain.c
@@ -464,7 +464,7 @@ static bool find_net_dev(Schib *schib, int dev_no)
return false;
}
-static void virtio_setup(void)
+static bool virtio_setup(void)
{
Schib schib;
int ssid;
@@ -495,10 +495,10 @@ static void virtio_setup(void)
}
}
- IPL_assert(found, "No virtio net device found");
+ return found;
}
-void netmain(void)
+int netmain(void)
{
filename_ip_t fn_ip;
int rc, fnlen;
@@ -506,11 +506,15 @@ void netmain(void)
sclp_setup();
puts("Network boot starting...");
- virtio_setup();
+ if (!virtio_setup()) {
+ puts("No virtio net device found.");
+ return -1;
+ }
rc = net_init(&fn_ip);
if (rc) {
- panic("Network initialization failed. Halting.");
+ puts("Network initialization failed.");
+ return -1;
}
fnlen = strlen(fn_ip.filename);
@@ -528,5 +532,6 @@ void netmain(void)
jump_to_low_kernel();
}
- panic("Failed to load OS from network.");
+ puts("Failed to load OS from network.");
+ return -1;
}
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index 3e844abd71..344ad15655 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -57,7 +57,7 @@ unsigned int get_loadparm_index(void);
void main(void);
/* netmain.c */
-void netmain(void);
+int netmain(void);
/* sclp.c */
void sclp_print(const char *string);
diff --git a/pc-bios/s390-ccw/virtio-net.c b/pc-bios/s390-ccw/virtio-net.c
index 2fcb0a58c5..f9854a22c3 100644
--- a/pc-bios/s390-ccw/virtio-net.c
+++ b/pc-bios/s390-ccw/virtio-net.c
@@ -54,8 +54,11 @@ int virtio_net_init(void *mac_addr)
vdev->guest_features[0] = VIRTIO_NET_F_MAC_BIT;
virtio_setup_ccw(vdev);
- IPL_assert(vdev->guest_features[0] & VIRTIO_NET_F_MAC_BIT,
- "virtio-net device does not support the MAC address feature");
+ if (!(vdev->guest_features[0] & VIRTIO_NET_F_MAC_BIT)) {
+ puts("virtio-net device does not support the MAC address feature");
+ return -1;
+ }
+
memcpy(mac_addr, vdev->config.net.mac, ETH_ALEN);
for (i = 0; i < 64; i++) {
--
2.39.3

View File

@ -0,0 +1,554 @@
From 6212bfb4f7a45b06b38bf5d11774de1d3df982aa Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:43 -0400
Subject: [PATCH 11/38] pc-bios/s390-ccw: Remove panics from SCSI IPL path
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [10/23] 3d67ba81c0296f59f5ec2fab3361512e83b6d78d (thuth/qemu-kvm-cs9)
Remove panic-on-error from virtio-scsi IPL specific functions so that error
recovery may be possible in the future.
Functions that would previously panic now provide a return code.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-10-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit facd91ac1af75b657fc80189fe9cb026bb1abdbc)
---
pc-bios/s390-ccw/bootmap.c | 88 ++++++++++++++-----
pc-bios/s390-ccw/virtio-blkdev.c | 4 +-
pc-bios/s390-ccw/virtio-scsi.c | 143 +++++++++++++++++++++----------
3 files changed, 164 insertions(+), 71 deletions(-)
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index b9596e28c7..652807a16a 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -595,7 +595,7 @@ static int ipl_eckd(void)
* IPL a SCSI disk
*/
-static void zipl_load_segment(ComponentEntry *entry)
+static int zipl_load_segment(ComponentEntry *entry)
{
const int max_entries = (MAX_SECTOR_SIZE / sizeof(ScsiBlockPtr));
ScsiBlockPtr *bprs = (void *)sec;
@@ -615,7 +615,10 @@ static void zipl_load_segment(ComponentEntry *entry)
do {
memset(bprs, FREE_SPACE_FILLER, bprs_size);
fill_hex_val(blk_no, &blockno, sizeof(blockno));
- read_block(blockno, bprs, err_msg);
+ if (virtio_read(blockno, bprs)) {
+ puts(err_msg);
+ return -EIO;
+ }
for (i = 0;; i++) {
uint64_t *cur_desc = (void *)&bprs[i];
@@ -643,23 +646,37 @@ static void zipl_load_segment(ComponentEntry *entry)
}
address = virtio_load_direct(cur_desc[0], cur_desc[1], 0,
(void *)address);
- IPL_assert(address != -1, "zIPL load segment failed");
+ if (!address) {
+ puts("zIPL load segment failed");
+ return -EIO;
+ }
}
} while (blockno);
+
+ return 0;
}
/* Run a zipl program */
-static void zipl_run(ScsiBlockPtr *pte)
+static int zipl_run(ScsiBlockPtr *pte)
{
ComponentHeader *header;
ComponentEntry *entry;
uint8_t tmp_sec[MAX_SECTOR_SIZE];
- read_block(pte->blockno, tmp_sec, "Cannot read header");
+ if (virtio_read(pte->blockno, tmp_sec)) {
+ puts("Cannot read header");
+ return -EIO;
+ }
header = (ComponentHeader *)tmp_sec;
- IPL_assert(magic_match(tmp_sec, ZIPL_MAGIC), "No zIPL magic in header");
- IPL_assert(header->type == ZIPL_COMP_HEADER_IPL, "Bad header type");
+ if (!magic_match(tmp_sec, ZIPL_MAGIC)) {
+ puts("No zIPL magic in header");
+ return -EINVAL;
+ }
+ if (header->type != ZIPL_COMP_HEADER_IPL) {
+ puts("Bad header type");
+ return -EINVAL;
+ }
dputs("start loading images\n");
@@ -674,22 +691,30 @@ static void zipl_run(ScsiBlockPtr *pte)
continue;
}
- zipl_load_segment(entry);
+ if (zipl_load_segment(entry)) {
+ return -1;
+ }
entry++;
- IPL_assert((uint8_t *)(&entry[1]) <= (tmp_sec + MAX_SECTOR_SIZE),
- "Wrong entry value");
+ if ((uint8_t *)(&entry[1]) > (tmp_sec + MAX_SECTOR_SIZE)) {
+ puts("Wrong entry value");
+ return -EINVAL;
+ }
}
- IPL_assert(entry->component_type == ZIPL_COMP_ENTRY_EXEC, "No EXEC entry");
+ if (entry->component_type != ZIPL_COMP_ENTRY_EXEC) {
+ puts("No EXEC entry");
+ return -EINVAL;
+ }
/* should not return */
write_reset_psw(entry->compdat.load_psw);
jump_to_IPL_code(0);
+ return -1;
}
-static void ipl_scsi(void)
+static int ipl_scsi(void)
{
ScsiMbr *mbr = (void *)sec;
int program_table_entries = 0;
@@ -700,10 +725,13 @@ static void ipl_scsi(void)
/* Grab the MBR */
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
- read_block(0, mbr, "Cannot read block 0");
+ if (virtio_read(0, mbr)) {
+ puts("Cannot read block 0");
+ return -EIO;
+ }
if (!magic_match(mbr->magic, ZIPL_MAGIC)) {
- return;
+ return 0;
}
puts("Using SCSI scheme.");
@@ -711,11 +739,20 @@ static void ipl_scsi(void)
IPL_check(mbr->version_id == 1,
"Unknown MBR layout version, assuming version 1");
debug_print_int("program table", mbr->pt.blockno);
- IPL_assert(mbr->pt.blockno, "No Program Table");
+ if (!mbr->pt.blockno) {
+ puts("No Program Table");
+ return -EINVAL;
+ }
/* Parse the program table */
- read_block(mbr->pt.blockno, sec, "Error reading Program Table");
- IPL_assert(magic_match(sec, ZIPL_MAGIC), "No zIPL magic in PT");
+ if (virtio_read(mbr->pt.blockno, sec)) {
+ puts("Error reading Program Table");
+ return -EIO;
+ }
+ if (!magic_match(sec, ZIPL_MAGIC)) {
+ puts("No zIPL magic in Program Table");
+ return -EINVAL;
+ }
for (i = 0; i < MAX_BOOT_ENTRIES; i++) {
if (prog_table->entry[i].scsi.blockno) {
@@ -725,17 +762,22 @@ static void ipl_scsi(void)
}
debug_print_int("program table entries", program_table_entries);
- IPL_assert(program_table_entries != 0, "Empty Program Table");
+ if (program_table_entries == 0) {
+ puts("Empty Program Table");
+ return -EINVAL;
+ }
if (menu_is_enabled_enum()) {
loadparm = menu_get_enum_boot_index(valid_entries);
}
debug_print_int("loadparm", loadparm);
- IPL_assert(loadparm < MAX_BOOT_ENTRIES, "loadparm value greater than"
- " maximum number of boot entries allowed");
+ if (loadparm >= MAX_BOOT_ENTRIES) {
+ puts("loadparm value greater than max number of boot entries allowed");
+ return -EINVAL;
+ }
- zipl_run(&prog_table->entry[loadparm].scsi); /* no return */
+ return zipl_run(&prog_table->entry[loadparm].scsi);
}
/***********************************************************************
@@ -1032,7 +1074,9 @@ void zipl_load(void)
netmain();
}
- ipl_scsi();
+ if (ipl_scsi()) {
+ panic("\n! Cannot IPL this SCSI device !\n");
+ }
switch (virtio_get_device_type()) {
case VIRTIO_ID_BLOCK:
diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c
index 2666326801..1c585f034b 100644
--- a/pc-bios/s390-ccw/virtio-blkdev.c
+++ b/pc-bios/s390-ccw/virtio-blkdev.c
@@ -73,13 +73,13 @@ unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list
unsigned long addr = (unsigned long)load_addr;
if (sec_len != virtio_get_block_size()) {
- return -1;
+ return 0;
}
printf(".");
status = virtio_read_many(sec, (void *)addr, sec_num);
if (status) {
- panic("I/O Error");
+ return 0;
}
addr += sec_num * virtio_get_block_size();
diff --git a/pc-bios/s390-ccw/virtio-scsi.c b/pc-bios/s390-ccw/virtio-scsi.c
index 6b4a1caf8a..71db75ce7b 100644
--- a/pc-bios/s390-ccw/virtio-scsi.c
+++ b/pc-bios/s390-ccw/virtio-scsi.c
@@ -26,7 +26,7 @@ static uint8_t scsi_inquiry_std_response[256];
static ScsiInquiryEvpdPages scsi_inquiry_evpd_pages_response;
static ScsiInquiryEvpdBl scsi_inquiry_evpd_bl_response;
-static inline void vs_assert(bool term, const char **msgs)
+static inline bool vs_assert(bool term, const char **msgs)
{
if (!term) {
int i = 0;
@@ -35,11 +35,13 @@ static inline void vs_assert(bool term, const char **msgs)
while (msgs[i]) {
printf("%s", msgs[i++]);
}
- panic(" !\n");
+ puts(" !");
}
+
+ return term;
}
-static void virtio_scsi_verify_response(VirtioScsiCmdResp *resp,
+static bool virtio_scsi_verify_response(VirtioScsiCmdResp *resp,
const char *title)
{
const char *mr[] = {
@@ -56,8 +58,8 @@ static void virtio_scsi_verify_response(VirtioScsiCmdResp *resp,
0
};
- vs_assert(resp->response == VIRTIO_SCSI_S_OK, mr);
- vs_assert(resp->status == CDB_STATUS_GOOD, ms);
+ return vs_assert(resp->response == VIRTIO_SCSI_S_OK, mr) &&
+ vs_assert(resp->status == CDB_STATUS_GOOD, ms);
}
static void prepare_request(VDev *vdev, const void *cdb, int cdb_size,
@@ -78,24 +80,31 @@ static void prepare_request(VDev *vdev, const void *cdb, int cdb_size,
}
}
-static inline void vs_io_assert(bool term, const char *msg)
+static inline bool vs_io_assert(bool term, const char *msg)
{
- if (!term) {
- virtio_scsi_verify_response(&resp, msg);
+ if (!term && !virtio_scsi_verify_response(&resp, msg)) {
+ return false;
}
+
+ return true;
}
-static void vs_run(const char *title, VirtioCmd *cmd, VDev *vdev,
+static int vs_run(const char *title, VirtioCmd *cmd, VDev *vdev,
const void *cdb, int cdb_size,
void *data, uint32_t data_size)
{
prepare_request(vdev, cdb, cdb_size, data, data_size);
- vs_io_assert(virtio_run(vdev, VR_REQUEST, cmd) == 0, title);
+ if (!vs_io_assert(virtio_run(vdev, VR_REQUEST, cmd) == 0, title)) {
+ puts(title);
+ return -EIO;
+ }
+
+ return 0;
}
/* SCSI protocol implementation routines */
-static bool scsi_inquiry(VDev *vdev, uint8_t evpd, uint8_t page,
+static int scsi_inquiry(VDev *vdev, uint8_t evpd, uint8_t page,
void *data, uint32_t data_size)
{
ScsiCdbInquiry cdb = {
@@ -110,12 +119,13 @@ static bool scsi_inquiry(VDev *vdev, uint8_t evpd, uint8_t page,
{ data, data_size, VRING_DESC_F_WRITE },
};
- vs_run("inquiry", inquiry, vdev, &cdb, sizeof(cdb), data, data_size);
+ int ret = vs_run("inquiry", inquiry,
+ vdev, &cdb, sizeof(cdb), data, data_size);
- return virtio_scsi_response_ok(&resp);
+ return ret ? ret : virtio_scsi_response_ok(&resp);
}
-static bool scsi_test_unit_ready(VDev *vdev)
+static int scsi_test_unit_ready(VDev *vdev)
{
ScsiCdbTestUnitReady cdb = {
.command = 0x00,
@@ -131,7 +141,7 @@ static bool scsi_test_unit_ready(VDev *vdev)
return virtio_scsi_response_ok(&resp);
}
-static bool scsi_report_luns(VDev *vdev, void *data, uint32_t data_size)
+static int scsi_report_luns(VDev *vdev, void *data, uint32_t data_size)
{
ScsiCdbReportLuns cdb = {
.command = 0xa0,
@@ -144,13 +154,13 @@ static bool scsi_report_luns(VDev *vdev, void *data, uint32_t data_size)
{ data, data_size, VRING_DESC_F_WRITE },
};
- vs_run("report luns", report_luns,
+ int ret = vs_run("report luns", report_luns,
vdev, &cdb, sizeof(cdb), data, data_size);
- return virtio_scsi_response_ok(&resp);
+ return ret ? ret : virtio_scsi_response_ok(&resp);
}
-static bool scsi_read_10(VDev *vdev,
+static int scsi_read_10(VDev *vdev,
unsigned long sector, int sectors, void *data,
unsigned int data_size)
{
@@ -168,12 +178,13 @@ static bool scsi_read_10(VDev *vdev,
debug_print_int("read_10 sector", sector);
debug_print_int("read_10 sectors", sectors);
- vs_run("read(10)", read_10, vdev, &cdb, sizeof(cdb), data, data_size);
+ int ret = vs_run("read(10)", read_10,
+ vdev, &cdb, sizeof(cdb), data, data_size);
- return virtio_scsi_response_ok(&resp);
+ return ret ? ret : virtio_scsi_response_ok(&resp);
}
-static bool scsi_read_capacity(VDev *vdev,
+static int scsi_read_capacity(VDev *vdev,
void *data, uint32_t data_size)
{
ScsiCdbReadCapacity16 cdb = {
@@ -187,10 +198,10 @@ static bool scsi_read_capacity(VDev *vdev,
{ data, data_size, VRING_DESC_F_WRITE },
};
- vs_run("read capacity", read_capacity_16,
+ int ret = vs_run("read capacity", read_capacity_16,
vdev, &cdb, sizeof(cdb), data, data_size);
- return virtio_scsi_response_ok(&resp);
+ return ret ? ret : virtio_scsi_response_ok(&resp);
}
/* virtio-scsi routines */
@@ -207,7 +218,7 @@ static int virtio_scsi_locate_device(VDev *vdev)
static uint8_t data[16 + 8 * 63];
ScsiLunReport *r = (void *) data;
ScsiDevice *sdev = vdev->scsi_device;
- int i, luns;
+ int i, ret, luns;
/* QEMU has hardcoded channel #0 in many places.
* If this hardcoded value is ever changed, we'll need to add code for
@@ -233,13 +244,21 @@ static int virtio_scsi_locate_device(VDev *vdev)
sdev->channel = channel;
sdev->target = target;
sdev->lun = 0; /* LUN has to be 0 for REPORT LUNS */
- if (!scsi_report_luns(vdev, data, sizeof(data))) {
+ ret = scsi_report_luns(vdev, data, sizeof(data));
+ if (ret < 0) {
+ return ret;
+ }
+
+ else if (ret == 0) {
if (resp.response == VIRTIO_SCSI_S_BAD_TARGET) {
continue;
}
printf("target 0x%X\n", target);
- virtio_scsi_verify_response(&resp, "SCSI cannot report LUNs");
+ if (!virtio_scsi_verify_response(&resp, "SCSI cannot report LUNs")) {
+ return -EIO;
+ }
}
+
if (r->lun_list_len == 0) {
printf("no LUNs for target 0x%X\n", target);
continue;
@@ -283,7 +302,9 @@ int virtio_scsi_read_many(VDev *vdev,
data_size = sector_count * virtio_get_block_size() * f;
if (!scsi_read_10(vdev, sector * f, sector_count * f, load_addr,
data_size)) {
- virtio_scsi_verify_response(&resp, "virtio-scsi:read_many");
+ if (!virtio_scsi_verify_response(&resp, "virtio-scsi:read_many")) {
+ return -1;
+ }
}
load_addr += data_size;
sector += sector_count;
@@ -352,11 +373,16 @@ static int virtio_scsi_setup(VDev *vdev)
uint8_t code = resp.sense[0] & SCSI_SENSE_CODE_MASK;
uint8_t sense_key = resp.sense[2] & SCSI_SENSE_KEY_MASK;
- IPL_assert(resp.sense_len != 0, "virtio-scsi:setup: no SENSE data");
+ if (resp.sense_len == 0) {
+ puts("virtio-scsi: setup: no SENSE data");
+ return -EINVAL;
+ }
- IPL_assert(retry_test_unit_ready && code == 0x70 &&
- sense_key == SCSI_SENSE_KEY_UNIT_ATTENTION,
- "virtio-scsi:setup: cannot retry");
+ if (!retry_test_unit_ready || code != 0x70 ||
+ sense_key != SCSI_SENSE_KEY_UNIT_ATTENTION) {
+ puts("virtio-scsi:setup: cannot retry");
+ return -EIO;
+ }
/* retry on CHECK_CONDITION/UNIT_ATTENTION as it
* may not designate a real error, but it may be
@@ -367,16 +393,22 @@ static int virtio_scsi_setup(VDev *vdev)
continue;
}
- virtio_scsi_verify_response(&resp, "virtio-scsi:setup");
+ if (!virtio_scsi_verify_response(&resp, "virtio-scsi:setup")) {
+ return -1;
+ }
}
/* read and cache SCSI INQUIRY response */
- if (!scsi_inquiry(vdev,
+ ret = scsi_inquiry(vdev,
SCSI_INQUIRY_STANDARD,
SCSI_INQUIRY_STANDARD_NONE,
scsi_inquiry_std_response,
- sizeof(scsi_inquiry_std_response))) {
- virtio_scsi_verify_response(&resp, "virtio-scsi:setup:inquiry");
+ sizeof(scsi_inquiry_std_response));
+ if (ret < 1) {
+ if (ret != 0 || !virtio_scsi_verify_response(&resp,
+ "virtio-scsi:setup:inquiry")) {
+ return -1;
+ }
}
if (virtio_scsi_inquiry_response_is_cdrom(scsi_inquiry_std_response)) {
@@ -385,12 +417,16 @@ static int virtio_scsi_setup(VDev *vdev)
vdev->scsi_block_size = VIRTIO_ISO_BLOCK_SIZE;
}
- if (!scsi_inquiry(vdev,
+ ret = scsi_inquiry(vdev,
SCSI_INQUIRY_EVPD,
SCSI_INQUIRY_EVPD_SUPPORTED_PAGES,
evpd,
- sizeof(*evpd))) {
- virtio_scsi_verify_response(&resp, "virtio-scsi:setup:supported_pages");
+ sizeof(*evpd));
+ if (ret < 1) {
+ if (ret != 0 || !virtio_scsi_verify_response(&resp,
+ "virtio-scsi:setup:supported_pages")) {
+ return -1;
+ }
}
debug_print_int("EVPD length", evpd->page_length);
@@ -402,12 +438,16 @@ static int virtio_scsi_setup(VDev *vdev)
continue;
}
- if (!scsi_inquiry(vdev,
+ ret = scsi_inquiry(vdev,
SCSI_INQUIRY_EVPD,
SCSI_INQUIRY_EVPD_BLOCK_LIMITS,
evpd_bl,
- sizeof(*evpd_bl))) {
- virtio_scsi_verify_response(&resp, "virtio-scsi:setup:blocklimits");
+ sizeof(*evpd_bl));
+ if (ret < 1) {
+ if (ret != 0 || !virtio_scsi_verify_response(&resp,
+ "virtio-scsi:setup:blocklimits")) {
+ return -1;
+ }
}
debug_print_int("max transfer", evpd_bl->max_transfer);
@@ -423,8 +463,12 @@ static int virtio_scsi_setup(VDev *vdev)
vdev->max_transfer = MIN_NON_ZERO(VIRTIO_SCSI_MAX_SECTORS,
vdev->max_transfer);
- if (!scsi_read_capacity(vdev, data, data_size)) {
- virtio_scsi_verify_response(&resp, "virtio-scsi:setup:read_capacity");
+ ret = scsi_read_capacity(vdev, data, data_size);
+ if (ret < 1) {
+ if (ret != 0 || !virtio_scsi_verify_response(&resp,
+ "virtio-scsi:setup:read_capacity")) {
+ return -1;
+ }
}
scsi_parse_capacity_report(data, &vdev->scsi_last_block,
(uint32_t *) &vdev->scsi_block_size);
@@ -439,10 +483,15 @@ int virtio_scsi_setup_device(SubChannelId schid)
vdev->schid = schid;
virtio_setup_ccw(vdev);
- IPL_assert(vdev->config.scsi.sense_size == VIRTIO_SCSI_SENSE_SIZE,
- "Config: sense size mismatch");
- IPL_assert(vdev->config.scsi.cdb_size == VIRTIO_SCSI_CDB_SIZE,
- "Config: CDB size mismatch");
+ if (vdev->config.scsi.sense_size != VIRTIO_SCSI_SENSE_SIZE) {
+ puts("Config: sense size mismatch");
+ return -EINVAL;
+ }
+
+ if (vdev->config.scsi.cdb_size != VIRTIO_SCSI_CDB_SIZE) {
+ puts("Config: CDB size mismatch");
+ return -EINVAL;
+ }
puts("Using virtio-scsi.");
--
2.39.3

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,227 @@
From 9facd91b090c8b63cb06da93c2b2ea51f26a3310 Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:51 -0400
Subject: [PATCH 19/38] pc-bios/s390x: Enable multi-device boot loop
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [18/23] 809cf0c60e4323a1260194e482f6b077f54af90a (thuth/qemu-kvm-cs9)
Allow attempts to boot from multiple IPL devices. If the first device fails to
IPL, select the pre-built IPLB for the next device in the boot order and attempt
to IPL from it. Continue this process until IPL is successful or there are no
devices left to try.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-18-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit f697bed22f58eff9b2893ac2fe3d511847398400)
---
pc-bios/s390-ccw/iplb.h | 24 ++++++++++++++++++++
pc-bios/s390-ccw/jump2ipl.c | 7 +++---
pc-bios/s390-ccw/main.c | 45 +++++++++++++++++++++++--------------
pc-bios/s390-ccw/netmain.c | 2 +-
4 files changed, 57 insertions(+), 21 deletions(-)
diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h
index 16643f5879..08f259ff31 100644
--- a/pc-bios/s390-ccw/iplb.h
+++ b/pc-bios/s390-ccw/iplb.h
@@ -17,9 +17,11 @@
#endif
#include <qipl.h>
+#include <string.h>
extern QemuIplParameters qipl;
extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
+extern bool have_iplb;
#define S390_IPL_TYPE_FCP 0x00
#define S390_IPL_TYPE_CCW 0x02
@@ -49,4 +51,26 @@ static inline bool set_iplb(IplParameterBlock *iplb)
return manage_iplb(iplb, false);
}
+/*
+ * The IPL started on the device, but failed in some way. If the IPLB chain
+ * still has more devices left to try, use the next device in order.
+ */
+static inline bool load_next_iplb(void)
+{
+ IplParameterBlock *next_iplb;
+
+ if (qipl.chain_len < 1) {
+ return false;
+ }
+
+ qipl.index++;
+ next_iplb = (IplParameterBlock *) qipl.next_iplb;
+ memcpy(&iplb, next_iplb, sizeof(IplParameterBlock));
+
+ qipl.chain_len--;
+ qipl.next_iplb = qipl.next_iplb + sizeof(IplParameterBlock);
+
+ return true;
+}
+
#endif /* IPLB_H */
diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
index 99d18947d1..86321d0f46 100644
--- a/pc-bios/s390-ccw/jump2ipl.c
+++ b/pc-bios/s390-ccw/jump2ipl.c
@@ -45,9 +45,10 @@ int jump_to_IPL_code(uint64_t address)
*/
if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
iplb.devno = qipl.index;
- if (!set_iplb(&iplb)) {
- panic("Failed to set IPLB");
- }
+ }
+
+ if (have_iplb && !set_iplb(&iplb)) {
+ panic("Failed to set IPLB");
}
/*
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index ab4709e16e..a4d1c05aac 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -23,7 +23,7 @@ static SubChannelId blk_schid = { .one = 1 };
static char loadparm_str[LOADPARM_LEN + 1];
QemuIplParameters qipl;
IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
-static bool have_iplb;
+bool have_iplb;
static uint16_t cutype;
LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
@@ -55,6 +55,12 @@ void write_iplb_location(void)
}
}
+static void copy_qipl(void)
+{
+ QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
+ memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
+}
+
unsigned int get_loadparm_index(void)
{
return atoi(loadparm_str);
@@ -152,6 +158,7 @@ static void menu_setup(void)
/* If loadparm was set to any other value, then do not enable menu */
if (memcmp(loadparm_str, LOADPARM_EMPTY, LOADPARM_LEN) != 0) {
+ menu_set_parms(qipl.qipl_flags & ~BOOT_MENU_FLAG_MASK, 0);
return;
}
@@ -183,7 +190,6 @@ static void css_setup(void)
static void boot_setup(void)
{
char lpmsg[] = "LOADPARM=[________]\n";
- have_iplb = store_iplb(&iplb);
if (memcmp(iplb.loadparm, NO_LOADPARM, LOADPARM_LEN) != 0) {
ebcdic_to_ascii((char *) iplb.loadparm, loadparm_str, LOADPARM_LEN);
@@ -191,6 +197,10 @@ static void boot_setup(void)
sclp_get_loadparm_ascii(loadparm_str);
}
+ if (have_iplb) {
+ menu_setup();
+ }
+
memcpy(lpmsg + 10, loadparm_str, 8);
puts(lpmsg);
@@ -208,6 +218,7 @@ static bool find_boot_device(void)
switch (iplb.pbt) {
case S390_IPL_TYPE_CCW:
+ vdev->scsi_device_selected = false;
debug_print_int("device no. ", iplb.ccw.devno);
blk_schid.ssid = iplb.ccw.ssid & 0x3;
debug_print_int("ssid ", blk_schid.ssid);
@@ -231,15 +242,8 @@ static bool find_boot_device(void)
static int virtio_setup(void)
{
VDev *vdev = virtio_get_device();
- QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
int ret;
- memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
-
- if (have_iplb) {
- menu_setup();
- }
-
switch (vdev->senseid.cu_model) {
case VIRTIO_ID_NET:
puts("Network boot device detected");
@@ -271,10 +275,9 @@ static void ipl_boot_device(void)
dasd_ipl(blk_schid, cutype);
break;
case CU_TYPE_VIRTIO:
- if (virtio_setup()) {
- return; /* Only returns in case of errors */
+ if (virtio_setup() == 0) {
+ zipl_load();
}
- zipl_load();
break;
default:
printf("Attempting to boot from unexpected device type 0x%X\n", cutype);
@@ -307,14 +310,22 @@ static void probe_boot_device(void)
void main(void)
{
+ copy_qipl();
sclp_setup();
css_setup();
- boot_setup();
- if (have_iplb && find_boot_device()) {
- ipl_boot_device();
- } else {
+ have_iplb = store_iplb(&iplb);
+ if (!have_iplb) {
probe_boot_device();
}
- panic("Failed to IPL. Halting...");
+ while (have_iplb) {
+ boot_setup();
+ if (have_iplb && find_boot_device()) {
+ ipl_boot_device();
+ }
+ have_iplb = load_next_iplb();
+ }
+
+ panic("No suitable device for IPL. Halting...");
+
}
diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
index d1a6c9a91c..e46e470db4 100644
--- a/pc-bios/s390-ccw/netmain.c
+++ b/pc-bios/s390-ccw/netmain.c
@@ -478,7 +478,7 @@ static bool virtio_setup(void)
*/
enable_mss_facility();
- if (store_iplb(&iplb)) {
+ if (have_iplb || store_iplb(&iplb)) {
IPL_assert(iplb.pbt == S390_IPL_TYPE_CCW, "IPL_TYPE_CCW expected");
dev_no = iplb.ccw.devno;
debug_print_int("device no. ", dev_no);
--
2.39.3

View File

@ -0,0 +1,362 @@
From 2cbfea2082fdb4b6687b1ee7ad31826dcae6e5ca Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:48 -0400
Subject: [PATCH 16/38] s390x: Add individual loadparm assignment to CCW device
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [15/23] fe8aa289e564c45e589c9ecb131af60d4d914919 (thuth/qemu-kvm-cs9)
Add a loadparm property to the VirtioCcwDevice object so that different
loadparms can be defined on a per-device basis for CCW boot devices.
The machine/global loadparm is still supported. If both a global and per-device
loadparm are defined, the per-device value will override the global value for
that device, but any other devices that do not specify a per-device loadparm
will still use the global loadparm.
It is invalid to assign a loadparm to a non-boot device.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-15-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit bb185de42339025db9bbd5aa11f3f644c2a077f8)
---
hw/s390x/ccw-device.c | 46 +++++++++++++++++++++++++
hw/s390x/ccw-device.h | 2 ++
hw/s390x/ipl.c | 68 ++++++++++++++++++++++---------------
hw/s390x/ipl.h | 3 +-
hw/s390x/s390-virtio-ccw.c | 18 +---------
hw/s390x/sclp.c | 9 ++---
include/hw/s390x/ipl/qipl.h | 1 +
pc-bios/s390-ccw/main.c | 10 ++++--
8 files changed, 102 insertions(+), 55 deletions(-)
diff --git a/hw/s390x/ccw-device.c b/hw/s390x/ccw-device.c
index a7d682e5af..4e54f34b1c 100644
--- a/hw/s390x/ccw-device.c
+++ b/hw/s390x/ccw-device.c
@@ -13,6 +13,10 @@
#include "ccw-device.h"
#include "hw/qdev-properties.h"
#include "qemu/module.h"
+#include "ipl.h"
+#include "qapi/visitor.h"
+#include "qemu/ctype.h"
+#include "qapi/error.h"
static void ccw_device_refill_ids(CcwDevice *dev)
{
@@ -37,10 +41,52 @@ static bool ccw_device_realize(CcwDevice *dev, Error **errp)
return true;
}
+static void ccw_device_get_loadparm(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ CcwDevice *dev = CCW_DEVICE(obj);
+ char *str = g_strndup((char *) dev->loadparm, sizeof(dev->loadparm));
+
+ visit_type_str(v, name, &str, errp);
+ g_free(str);
+}
+
+static void ccw_device_set_loadparm(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ CcwDevice *dev = CCW_DEVICE(obj);
+ char *val;
+ int index;
+
+ index = object_property_get_int(obj, "bootindex", NULL);
+
+ if (index < 0) {
+ error_setg(errp, "LOADPARM is only valid for boot devices!");
+ }
+
+ if (!visit_type_str(v, name, &val, errp)) {
+ return;
+ }
+
+ s390_ipl_fmt_loadparm(dev->loadparm, val, errp);
+}
+
+static const PropertyInfo ccw_loadparm = {
+ .name = "ccw_loadparm",
+ .description = "Up to 8 chars in set of [A-Za-z0-9. ] to pass"
+ " to the guest loader/kernel",
+ .get = ccw_device_get_loadparm,
+ .set = ccw_device_set_loadparm,
+};
+
static Property ccw_device_properties[] = {
DEFINE_PROP_CSS_DEV_ID("devno", CcwDevice, devno),
DEFINE_PROP_CSS_DEV_ID_RO("dev_id", CcwDevice, dev_id),
DEFINE_PROP_CSS_DEV_ID_RO("subch_id", CcwDevice, subch_id),
+ DEFINE_PROP("loadparm", CcwDevice, loadparm, ccw_loadparm,
+ typeof(uint8_t[8])),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/s390x/ccw-device.h b/hw/s390x/ccw-device.h
index 5feeb0ee7a..1e1737c0f3 100644
--- a/hw/s390x/ccw-device.h
+++ b/hw/s390x/ccw-device.h
@@ -26,6 +26,8 @@ struct CcwDevice {
CssDevId dev_id;
/* The actual busid of the virtual subchannel. */
CssDevId subch_id;
+ /* If set, use this loadparm value when device is boot target */
+ uint8_t loadparm[8];
};
typedef struct CcwDevice CcwDevice;
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 8a0a3e6961..d83832d975 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -34,6 +34,7 @@
#include "qemu/config-file.h"
#include "qemu/cutils.h"
#include "qemu/option.h"
+#include "qemu/ctype.h"
#include "standard-headers/linux/virtio_ids.h"
#define KERN_IMAGE_START 0x010000UL
@@ -397,12 +398,43 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st, int *devtype)
return ccw_dev;
}
+void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp)
+{
+ int i;
+
+ /* Initialize the loadparm with spaces */
+ memset(loadparm, ' ', LOADPARM_LEN);
+ for (i = 0; i < LOADPARM_LEN && str[i]; i++) {
+ uint8_t c = qemu_toupper(str[i]); /* mimic HMC */
+
+ if (qemu_isalnum(c) || c == '.' || c == ' ') {
+ loadparm[i] = c;
+ } else {
+ error_setg(errp, "LOADPARM: invalid character '%c' (ASCII 0x%02x)",
+ c, c);
+ return;
+ }
+ }
+}
+
+void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp)
+{
+ int i;
+
+ /* Initialize the loadparm with EBCDIC spaces (0x40) */
+ memset(ebcdic_lp, '@', LOADPARM_LEN);
+ for (i = 0; i < LOADPARM_LEN && ascii_lp[i]; i++) {
+ ebcdic_lp[i] = ascii2ebcdic[(uint8_t) ascii_lp[i]];
+ }
+}
+
static bool s390_gen_initial_iplb(S390IPLState *ipl)
{
DeviceState *dev_st;
CcwDevice *ccw_dev = NULL;
SCSIDevice *sd;
int devtype;
+ uint8_t *lp;
dev_st = get_boot_device(0);
if (dev_st) {
@@ -413,6 +445,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
* Currently allow IPL only from CCW devices.
*/
if (ccw_dev) {
+ lp = ccw_dev->loadparm;
+
switch (devtype) {
case CCW_DEVTYPE_SCSI:
sd = SCSI_DEVICE(dev_st);
@@ -445,40 +479,20 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
break;
}
- if (!s390_ipl_set_loadparm(ipl->iplb.loadparm)) {
- ipl->iplb.flags |= DIAG308_FLAGS_LP_VALID;
+ /* If the device loadparm is empty use the global machine loadparm */
+ if (memcmp(lp, NO_LOADPARM, 8) == 0) {
+ lp = S390_CCW_MACHINE(qdev_get_machine())->loadparm;
}
+ s390_ipl_convert_loadparm((char *)lp, ipl->iplb.loadparm);
+ ipl->iplb.flags |= DIAG308_FLAGS_LP_VALID;
+
return true;
}
return false;
}
-int s390_ipl_set_loadparm(uint8_t *loadparm)
-{
- MachineState *machine = MACHINE(qdev_get_machine());
- char *lp = object_property_get_str(OBJECT(machine), "loadparm", NULL);
-
- if (lp) {
- int i;
-
- /* lp is an uppercase string without leading/embedded spaces */
- for (i = 0; i < 8 && lp[i]; i++) {
- loadparm[i] = ascii2ebcdic[(uint8_t) lp[i]];
- }
-
- if (i < 8) {
- memset(loadparm + i, 0x40, 8 - i); /* fill with EBCDIC spaces */
- }
-
- g_free(lp);
- return 0;
- }
-
- return -1;
-}
-
static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb,
int virtio_id)
{
@@ -534,7 +548,7 @@ static void update_machine_ipl_properties(IplParameterBlock *iplb)
ascii_loadparm[i] = 0;
object_property_set_str(machine, "loadparm", ascii_loadparm, &err);
} else {
- object_property_set_str(machine, "loadparm", "", &err);
+ object_property_set_str(machine, "loadparm", " ", &err);
}
if (err) {
warn_report_err(err);
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index fa394c339d..b670bad551 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -21,7 +21,8 @@
#define DIAG308_FLAGS_LP_VALID 0x80
-int s390_ipl_set_loadparm(uint8_t *loadparm);
+void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp);
+void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp);
void s390_ipl_update_diag308(IplParameterBlock *iplb);
int s390_ipl_prepare_pv_header(Error **errp);
int s390_ipl_pv_unpack(void);
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 29a89a0c31..0347dc69ca 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -724,28 +724,12 @@ static void machine_set_loadparm(Object *obj, Visitor *v,
{
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
char *val;
- int i;
if (!visit_type_str(v, name, &val, errp)) {
return;
}
- for (i = 0; i < sizeof(ms->loadparm) && val[i]; i++) {
- uint8_t c = qemu_toupper(val[i]); /* mimic HMC */
-
- if (('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || (c == '.') ||
- (c == ' ')) {
- ms->loadparm[i] = c;
- } else {
- error_setg(errp, "LOADPARM: invalid character '%c' (ASCII 0x%02x)",
- c, c);
- return;
- }
- }
-
- for (; i < sizeof(ms->loadparm); i++) {
- ms->loadparm[i] = ' '; /* pad right with spaces */
- }
+ s390_ipl_fmt_loadparm(ms->loadparm, val, errp);
}
static void ccw_machine_class_init(ObjectClass *oc, void *data)
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index e725dcd5fd..8757626b5c 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -110,7 +110,6 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
MachineState *machine = MACHINE(qdev_get_machine());
int cpu_count;
int rnsize, rnmax;
- IplParameterBlock *ipib = s390_ipl_get_iplb();
int required_len = SCCB_REQ_LEN(ReadInfo, machine->possible_cpus->len);
int offset_cpu = s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) ?
offsetof(ReadInfo, entries) :
@@ -171,12 +170,8 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
read_info->rnmax2 = cpu_to_be64(rnmax);
}
- if (ipib && ipib->flags & DIAG308_FLAGS_LP_VALID) {
- memcpy(&read_info->loadparm, &ipib->loadparm,
- sizeof(read_info->loadparm));
- } else {
- s390_ipl_set_loadparm(read_info->loadparm);
- }
+ s390_ipl_convert_loadparm((char *)S390_CCW_MACHINE(machine)->loadparm,
+ read_info->loadparm);
sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION);
}
diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h
index 0ef04af027..b67d2ae061 100644
--- a/include/hw/s390x/ipl/qipl.h
+++ b/include/hw/s390x/ipl/qipl.h
@@ -18,6 +18,7 @@
#define QIPL_ADDRESS 0xcc
#define LOADPARM_LEN 8
+#define NO_LOADPARM "\0\0\0\0\0\0\0\0"
/*
* The QEMU IPL Parameters will be stored at absolute address
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 34ef27d7a6..ab4709e16e 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -183,8 +183,14 @@ static void css_setup(void)
static void boot_setup(void)
{
char lpmsg[] = "LOADPARM=[________]\n";
+ have_iplb = store_iplb(&iplb);
+
+ if (memcmp(iplb.loadparm, NO_LOADPARM, LOADPARM_LEN) != 0) {
+ ebcdic_to_ascii((char *) iplb.loadparm, loadparm_str, LOADPARM_LEN);
+ } else {
+ sclp_get_loadparm_ascii(loadparm_str);
+ }
- sclp_get_loadparm_ascii(loadparm_str);
memcpy(lpmsg + 10, loadparm_str, 8);
puts(lpmsg);
@@ -193,8 +199,6 @@ static void boot_setup(void)
* so we don't taint our decision-making process during a reboot.
*/
memset((char *)S390EP, 0, 6);
-
- have_iplb = store_iplb(&iplb);
}
static bool find_boot_device(void)
--
2.39.3

View File

@ -0,0 +1,264 @@
From ad587091d8716dbc118776b8edb61db12f6da122 Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:50 -0400
Subject: [PATCH 18/38] s390x: Rebuild IPLB for SCSI device directly from
DIAG308
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [17/23] 8267b7ecd71f2af5409e2e41890b6e5bb56fabd2 (thuth/qemu-kvm-cs9)
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 <jrossi@linux.ibm.com>
Acked-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-17-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 455e3bc3f74ee76964efec2e0c646db15095d0d2)
---
hw/s390x/ipl.c | 74 ++++++-------------------------------
hw/s390x/ipl.h | 11 ++++--
include/hw/s390x/ipl/qipl.h | 3 +-
pc-bios/s390-ccw/jump2ipl.c | 11 ++++--
target/s390x/diag.c | 9 ++++-
5 files changed, 38 insertions(+), 70 deletions(-)
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index f4576f8822..5fbd43c346 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)
+{
+ 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;
+}
+
static bool s390_init_all_iplbs(S390IPLState *ipl)
{
int iplb_num = 0;
@@ -564,44 +570,6 @@ static bool s390_init_all_iplbs(S390IPLState *ipl)
return iplb_num;
}
-static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb,
- int virtio_id)
-{
- uint8_t cssid;
- uint8_t ssid;
- uint16_t devno;
- uint16_t schid;
- SubchDev *sch = NULL;
-
- if (iplb->pbt != S390_IPL_TYPE_CCW) {
- return false;
- }
-
- devno = be16_to_cpu(iplb->ccw.devno);
- ssid = iplb->ccw.ssid & 3;
-
- for (schid = 0; schid < MAX_SCHID; schid++) {
- for (cssid = 0; cssid < MAX_CSSID; cssid++) {
- sch = css_find_subch(1, cssid, ssid, schid);
-
- if (sch && sch->devno == devno) {
- return sch->id.cu_model == virtio_id;
- }
- }
- }
- return false;
-}
-
-static bool is_virtio_net_device(IplParameterBlock *iplb)
-{
- return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_NET);
-}
-
-static bool is_virtio_scsi_device(IplParameterBlock *iplb)
-{
- return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_SCSI);
-}
-
static void update_machine_ipl_properties(IplParameterBlock *iplb)
{
Object *machine = qdev_get_machine();
@@ -641,7 +609,7 @@ void s390_ipl_update_diag308(IplParameterBlock *iplb)
ipl->iplb = *iplb;
ipl->iplb_valid = true;
}
- ipl->netboot = is_virtio_net_device(iplb);
+
update_machine_ipl_properties(iplb);
}
@@ -668,32 +636,14 @@ IplParameterBlock *s390_ipl_get_iplb(void)
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) {
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index 54eb48fd6e..d7d0b7bfd2 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -24,6 +24,7 @@
void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp);
void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp);
+void s390_rebuild_iplb(uint16_t index, IplParameterBlock *iplb);
void s390_ipl_update_diag308(IplParameterBlock *iplb);
int s390_ipl_prepare_pv_header(Error **errp);
int s390_ipl_pv_unpack(void);
@@ -65,7 +66,8 @@ struct S390IPLState {
bool enforce_bios;
bool iplb_valid;
bool iplb_valid_pv;
- bool netboot;
+ bool rebuilt_iplb;
+ uint16_t iplb_index;
/* reset related properties don't have to be migrated or reset */
enum s390_reset reset_type;
int reset_cpu_index;
@@ -172,11 +174,14 @@ static inline bool iplb_valid_pv(IplParameterBlock *iplb)
static inline bool iplb_valid(IplParameterBlock *iplb)
{
+ uint32_t len = be32_to_cpu(iplb->len);
+
switch (iplb->pbt) {
case S390_IPL_TYPE_FCP:
- return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN;
+ return len >= S390_IPLB_MIN_FCP_LEN;
case S390_IPL_TYPE_CCW:
- return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN;
+ return len >= S390_IPLB_MIN_CCW_LEN;
+ case S390_IPL_TYPE_QEMU_SCSI:
default:
return false;
}
diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h
index 1da4f75aa8..6824391111 100644
--- a/include/hw/s390x/ipl/qipl.h
+++ b/include/hw/s390x/ipl/qipl.h
@@ -29,7 +29,8 @@
*/
struct QemuIplParameters {
uint8_t qipl_flags;
- uint8_t reserved1[3];
+ uint8_t index;
+ uint8_t reserved1[2];
uint64_t reserved2;
uint32_t boot_menu_timeout;
uint8_t reserved3[2];
diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
index 8db1764ff3..99d18947d1 100644
--- a/pc-bios/s390-ccw/jump2ipl.c
+++ b/pc-bios/s390-ccw/jump2ipl.c
@@ -39,10 +39,15 @@ int jump_to_IPL_code(uint64_t address)
write_subsystem_identification();
write_iplb_location();
- /* prevent unknown IPL types in the guest */
+ /*
+ * The IPLB for QEMU SCSI type devices must be rebuilt during re-ipl. The
+ * iplb.devno is set to the boot position of the target SCSI device.
+ */
if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
- iplb.pbt = S390_IPL_TYPE_CCW;
- set_iplb(&iplb);
+ iplb.devno = qipl.index;
+ if (!set_iplb(&iplb)) {
+ panic("Failed to set IPLB");
+ }
}
/*
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
index 27ffd48576..a1fd54ddac 100644
--- a/target/s390x/diag.c
+++ b/target/s390x/diag.c
@@ -133,7 +133,14 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
valid = subcode == DIAG308_PV_SET ? iplb_valid_pv(iplb) : iplb_valid(iplb);
if (!valid) {
- env->regs[r1 + 1] = DIAG_308_RC_INVALID;
+ if (subcode == DIAG308_SET && iplb->pbt == S390_IPL_TYPE_QEMU_SCSI) {
+ s390_rebuild_iplb(iplb->devno, iplb);
+ s390_ipl_update_diag308(iplb);
+ env->regs[r1 + 1] = DIAG_308_RC_OK;
+ } else {
+ env->regs[r1 + 1] = DIAG_308_RC_INVALID;
+ }
+
goto out;
}
--
2.39.3

View File

@ -0,0 +1,56 @@
From a246db2fbd892b572fced12da843628f1aab8cd2 Mon Sep 17 00:00:00 2001
From: Tao Su <tao1.su@linux.intel.com>
Date: Thu, 31 Oct 2024 16:52:32 +0800
Subject: [PATCH 36/38] target/i386: Add AVX512 state when AVX10 is supported
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets
RH-Jira: RHEL-30315 RHEL-45110
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [7/9] 6f791fae9a3255140795b709435b25159226becf (bonzini/rhel-qemu-kvm)
AVX10 state enumeration in CPUID leaf D and enabling in XCR0 register
are identical to AVX512 state regardless of the supported vector lengths.
Given that some E-cores will support AVX10 but not support AVX512, add
AVX512 state components to guest when AVX10 is enabled.
Based on a patch by Tao Su <tao1.su@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Tested-by: Xuelian Guo <xuelian.guo@intel.com>
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Link: https://lore.kernel.org/r/20241031085233.425388-8-tao1.su@linux.intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 0d7475be3b402c25d74c5a4573cbeb733c8f3559)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index a740429fdd..ddec461dd4 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7140,7 +7140,15 @@ static bool cpuid_has_xsave_feature(CPUX86State *env, const ExtSaveArea *esa)
return false;
}
- return (env->features[esa->feature] & esa->bits);
+ if (env->features[esa->feature] & esa->bits) {
+ return true;
+ }
+ if (esa->feature == FEAT_7_0_EBX && esa->bits == CPUID_7_0_EBX_AVX512F
+ && (env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_AVX10)) {
+ return true;
+ }
+
+ return false;
}
static void x86_cpu_reset_hold(Object *obj, ResetType type)
--
2.39.3

View File

@ -0,0 +1,89 @@
From c44f6f57898eb9f382545201033586a17bbde83c Mon Sep 17 00:00:00 2001
From: Tao Su <tao1.su@linux.intel.com>
Date: Thu, 31 Oct 2024 16:52:31 +0800
Subject: [PATCH 35/38] target/i386: Add feature dependencies for AVX10
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets
RH-Jira: RHEL-30315 RHEL-45110
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [6/9] 38b1a79032d7acdb264a6403fd4d8239d89b68c4 (bonzini/rhel-qemu-kvm)
Since the highest supported vector length for a processor implies that
all lesser vector lengths are also supported, add the dependencies of
the supported vector lengths. If all vector lengths aren't supported,
clear AVX10 enable bit as well.
Note that the order of AVX10 related dependencies should be kept as:
CPUID_24_0_EBX_AVX10_128 -> CPUID_24_0_EBX_AVX10_256,
CPUID_24_0_EBX_AVX10_256 -> CPUID_24_0_EBX_AVX10_512,
CPUID_24_0_EBX_AVX10_VL_MASK -> CPUID_7_1_EDX_AVX10,
CPUID_7_1_EDX_AVX10 -> CPUID_24_0_EBX,
so that prevent user from setting weird CPUID combinations, e.g. 256-bits
and 512-bits are supported but 128-bits is not, no vector lengths are
supported but AVX10 enable bit is still set.
Since AVX10_128 will be reserved as 1, adding these dependencies has the
bonus that when user sets -cpu host,-avx10-128, CPUID_7_1_EDX_AVX10 and
CPUID_24_0_EBX will be disabled automatically.
Tested-by: Xuelian Guo <xuelian.guo@intel.com>
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Link: https://lore.kernel.org/r/20241028024512.156724-5-tao1.su@linux.intel.com
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Link: https://lore.kernel.org/r/20241031085233.425388-7-tao1.su@linux.intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 150ab84b2d0083e6af344cca70290614d4fe568d)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.c | 16 ++++++++++++++++
target/i386/cpu.h | 4 ++++
2 files changed, 20 insertions(+)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 958cbff54d..a740429fdd 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1766,6 +1766,22 @@ static FeatureDep feature_dependencies[] = {
.from = { FEAT_7_0_EBX, CPUID_7_0_EBX_SGX },
.to = { FEAT_SGX_12_1_EAX, ~0ull },
},
+ {
+ .from = { FEAT_24_0_EBX, CPUID_24_0_EBX_AVX10_128 },
+ .to = { FEAT_24_0_EBX, CPUID_24_0_EBX_AVX10_256 },
+ },
+ {
+ .from = { FEAT_24_0_EBX, CPUID_24_0_EBX_AVX10_256 },
+ .to = { FEAT_24_0_EBX, CPUID_24_0_EBX_AVX10_512 },
+ },
+ {
+ .from = { FEAT_24_0_EBX, CPUID_24_0_EBX_AVX10_VL_MASK },
+ .to = { FEAT_7_1_EDX, CPUID_7_1_EDX_AVX10 },
+ },
+ {
+ .from = { FEAT_7_1_EDX, CPUID_7_1_EDX_AVX10 },
+ .to = { FEAT_24_0_EBX, ~0ull },
+ },
};
typedef struct X86RegisterInfo32 {
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index c60290b8d5..4da9ed5930 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -997,6 +997,10 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w);
#define CPUID_24_0_EBX_AVX10_256 (1U << 17)
/* AVX10 512-bit vector support is present */
#define CPUID_24_0_EBX_AVX10_512 (1U << 18)
+/* AVX10 vector length support mask */
+#define CPUID_24_0_EBX_AVX10_VL_MASK (CPUID_24_0_EBX_AVX10_128 | \
+ CPUID_24_0_EBX_AVX10_256 | \
+ CPUID_24_0_EBX_AVX10_512)
/* RAS Features */
#define CPUID_8000_0007_EBX_OVERFLOW_RECOV (1U << 0)
--
2.39.3

View File

@ -0,0 +1,59 @@
From 32437dacd0f0d5076af2d549317b92432ee52abd Mon Sep 17 00:00:00 2001
From: Tao Su <tao1.su@linux.intel.com>
Date: Thu, 31 Oct 2024 16:52:33 +0800
Subject: [PATCH 37/38] target/i386: Introduce GraniteRapids-v2 model
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets
RH-Jira: RHEL-30315 RHEL-45110
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [8/9] c53ba67dd616c9f376db0ab4f1478dd50f5dd874 (bonzini/rhel-qemu-kvm)
Update GraniteRapids CPU model to add AVX10 and the missing features(ss,
tsc-adjust, cldemote, movdiri, movdir64b).
Tested-by: Xuelian Guo <xuelian.guo@intel.com>
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Link: https://lore.kernel.org/r/20241028024512.156724-7-tao1.su@linux.intel.com
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Link: https://lore.kernel.org/r/20241031085233.425388-9-tao1.su@linux.intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 1a519388a882fbb352e49cbebb0ed8f62d05842d)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ddec461dd4..e7367cfe82 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4385,6 +4385,23 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.model_id = "Intel Xeon Processor (GraniteRapids)",
.versions = (X86CPUVersionDefinition[]) {
{ .version = 1 },
+ {
+ .version = 2,
+ .props = (PropValue[]) {
+ { "ss", "on" },
+ { "tsc-adjust", "on" },
+ { "cldemote", "on" },
+ { "movdiri", "on" },
+ { "movdir64b", "on" },
+ { "avx10", "on" },
+ { "avx10-128", "on" },
+ { "avx10-256", "on" },
+ { "avx10-512", "on" },
+ { "avx10-version", "1" },
+ { "stepping", "1" },
+ { /* end of list */ }
+ }
+ },
{ /* end of list */ },
},
},
--
2.39.3

View File

@ -0,0 +1,224 @@
From 704bfed342ca7cfbef44b639aadfeada1841b091 Mon Sep 17 00:00:00 2001
From: Tao Su <tao1.su@linux.intel.com>
Date: Thu, 31 Oct 2024 16:52:29 +0800
Subject: [PATCH 33/38] target/i386: add AVX10 feature and AVX10 version
property
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets
RH-Jira: RHEL-30315 RHEL-45110
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [4/9] 8101218e0a5789770fcef7ca277f7b39df48f176 (bonzini/rhel-qemu-kvm)
When AVX10 enable bit is set, the 0x24 leaf will be present as "AVX10
Converged Vector ISA leaf" containing fields for the version number and
the supported vector bit lengths.
Introduce avx10-version property so that avx10 version can be controlled
by user and cpu model. Per spec, avx10 version can never be 0, the default
value of avx10-version is set to 0 to determine whether it is specified by
user. The default can come from the device model or, for the max model,
from KVM's reported value.
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Link: https://lore.kernel.org/r/20241028024512.156724-3-tao1.su@linux.intel.com
Link: https://lore.kernel.org/r/20241028024512.156724-4-tao1.su@linux.intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Xuelian Guo <xuelian.guo@intel.com>
Link: https://lore.kernel.org/r/20241031085233.425388-5-tao1.su@linux.intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit bccfb846fd52d6f20704ecfa4d01b60b43c6f640)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.c | 64 ++++++++++++++++++++++++++++++++++++++-----
target/i386/cpu.h | 4 +++
target/i386/kvm/kvm.c | 3 +-
3 files changed, 63 insertions(+), 8 deletions(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 353f50a1b9..a2e1a18537 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -47,6 +47,9 @@
#include "cpu-internal.h"
static void x86_cpu_realizefn(DeviceState *dev, Error **errp);
+static void x86_cpu_get_supported_cpuid(uint32_t func, uint32_t index,
+ uint32_t *eax, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx);
/* Helpers for building CPUID[2] descriptors: */
@@ -1133,7 +1136,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
"avx-vnni-int8", "avx-ne-convert", NULL, NULL,
"amx-complex", NULL, "avx-vnni-int16", NULL,
NULL, NULL, "prefetchiti", NULL,
- NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, "avx10",
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
@@ -1961,6 +1964,7 @@ typedef struct X86CPUDefinition {
int family;
int model;
int stepping;
+ uint8_t avx10_version;
FeatureWordArray features;
const char *model_id;
const CPUCaches *const cache_info;
@@ -6326,6 +6330,9 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model)
*/
object_property_set_str(OBJECT(cpu), "vendor", def->vendor, &error_abort);
+ object_property_set_uint(OBJECT(cpu), "avx10-version", def->avx10_version,
+ &error_abort);
+
x86_cpu_apply_version_props(cpu, model);
/*
@@ -6854,6 +6861,16 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
}
break;
}
+ case 0x24: {
+ *eax = 0;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ if ((env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_AVX10) && count == 0) {
+ *ebx = env->features[FEAT_24_0_EBX] | env->avx10_version;
+ }
+ break;
+ }
case 0x40000000:
/*
* CPUID code in kvm_arch_init_vcpu() ignores stuff
@@ -7434,6 +7451,12 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
~env->user_features[w] &
~feature_word_info[w].no_autoenable_flags;
}
+
+ if ((env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_AVX10) && !env->avx10_version) {
+ uint32_t eax, ebx, ecx, edx;
+ x86_cpu_get_supported_cpuid(0x24, 0, &eax, &ebx, &ecx, &edx);
+ env->avx10_version = ebx & 0xff;
+ }
}
for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) {
@@ -7497,6 +7520,11 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x1F);
}
+ /* Advanced Vector Extensions 10 (AVX10) requires CPUID[0x24] */
+ if (env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_AVX10) {
+ x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x24);
+ }
+
/* SVM requires CPUID[0x8000000A] */
if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A);
@@ -7547,6 +7575,10 @@ static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose)
CPUX86State *env = &cpu->env;
FeatureWord w;
const char *prefix = NULL;
+ bool have_filtered_features;
+
+ uint32_t eax_0, ebx_0, ecx_0, edx_0;
+ uint32_t eax_1, ebx_1, ecx_1, edx_1;
if (verbose) {
prefix = accel_uses_host_cpuid()
@@ -7568,13 +7600,10 @@ static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose)
*/
if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) &&
kvm_enabled()) {
- uint32_t eax_0, ebx_0, ecx_0, edx_0_unused;
- uint32_t eax_1, ebx_1, ecx_1_unused, edx_1_unused;
-
x86_cpu_get_supported_cpuid(0x14, 0,
- &eax_0, &ebx_0, &ecx_0, &edx_0_unused);
+ &eax_0, &ebx_0, &ecx_0, &edx_0);
x86_cpu_get_supported_cpuid(0x14, 1,
- &eax_1, &ebx_1, &ecx_1_unused, &edx_1_unused);
+ &eax_1, &ebx_1, &ecx_1, &edx_1);
if (!eax_0 ||
((ebx_0 & INTEL_PT_MINIMAL_EBX) != INTEL_PT_MINIMAL_EBX) ||
@@ -7595,7 +7624,27 @@ static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose)
}
}
- return x86_cpu_have_filtered_features(cpu);
+ have_filtered_features = x86_cpu_have_filtered_features(cpu);
+
+ if (env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_AVX10) {
+ x86_cpu_get_supported_cpuid(0x24, 0,
+ &eax_0, &ebx_0, &ecx_0, &edx_0);
+ uint8_t version = ebx_0 & 0xff;
+
+ if (version < env->avx10_version) {
+ if (prefix) {
+ warn_report("%s: avx10.%d. Adjust to avx10.%d",
+ prefix, env->avx10_version, version);
+ }
+ env->avx10_version = version;
+ have_filtered_features = true;
+ }
+ } else if (env->avx10_version && prefix) {
+ warn_report("%s: avx10.%d.", prefix, env->avx10_version);
+ have_filtered_features = true;
+ }
+
+ return have_filtered_features;
}
static void x86_cpu_hyperv_realize(X86CPU *cpu)
@@ -8376,6 +8425,7 @@ static Property x86_cpu_properties[] = {
DEFINE_PROP_UINT32("min-level", X86CPU, env.cpuid_min_level, 0),
DEFINE_PROP_UINT32("min-xlevel", X86CPU, env.cpuid_min_xlevel, 0),
DEFINE_PROP_UINT32("min-xlevel2", X86CPU, env.cpuid_min_xlevel2, 0),
+ DEFINE_PROP_UINT8("avx10-version", X86CPU, env.avx10_version, 0),
DEFINE_PROP_UINT64("ucode-rev", X86CPU, ucode_rev, 0),
DEFINE_PROP_BOOL("full-cpuid-auto-level", X86CPU, full_cpuid_auto_level, true),
DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor),
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 14edd57a37..591113349d 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -972,6 +972,8 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w);
#define CPUID_7_1_EDX_AMX_COMPLEX (1U << 8)
/* PREFETCHIT0/1 Instructions */
#define CPUID_7_1_EDX_PREFETCHITI (1U << 14)
+/* Support for Advanced Vector Extensions 10 */
+#define CPUID_7_1_EDX_AVX10 (1U << 19)
/* Flexible return and event delivery (FRED) */
#define CPUID_7_1_EAX_FRED (1U << 17)
/* Load into IA32_KERNEL_GS_BASE (LKGS) */
@@ -1914,6 +1916,8 @@ typedef struct CPUArchState {
uint32_t cpuid_vendor3;
uint32_t cpuid_version;
FeatureWordArray features;
+ /* AVX10 version */
+ uint8_t avx10_version;
/* Features that were explicitly enabled/disabled */
FeatureWordArray user_features;
uint32_t cpuid_model[12];
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 814f93da19..d0329a4ed7 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -1891,7 +1891,8 @@ static uint32_t kvm_x86_build_cpuid(CPUX86State *env,
case 0x7:
case 0x14:
case 0x1d:
- case 0x1e: {
+ case 0x1e:
+ case 0x24: {
uint32_t times;
c->function = i;
--
2.39.3

View File

@ -0,0 +1,91 @@
From cfb4964556facf1cb4500f0e3a754e4e20c13aed Mon Sep 17 00:00:00 2001
From: Tao Su <tao1.su@linux.intel.com>
Date: Thu, 31 Oct 2024 16:52:30 +0800
Subject: [PATCH 34/38] target/i386: add CPUID.24 features for AVX10
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets
RH-Jira: RHEL-30315 RHEL-45110
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [5/9] a8b6f9edc330b412fbd27eece2f4961f4f876e5b (bonzini/rhel-qemu-kvm)
Introduce features for the supported vector bit lengths.
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Link: https://lore.kernel.org/r/20241028024512.156724-3-tao1.su@linux.intel.com
Link: https://lore.kernel.org/r/20241028024512.156724-4-tao1.su@linux.intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Tested-by: Xuelian Guo <xuelian.guo@intel.com>
Link: https://lore.kernel.org/r/20241031085233.425388-6-tao1.su@linux.intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 2d055b8fe11ee567c2ae8047311fd83697e494b6)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.c | 15 +++++++++++++++
target/i386/cpu.h | 8 ++++++++
2 files changed, 23 insertions(+)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index a2e1a18537..958cbff54d 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -902,6 +902,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
#define TCG_SGX_12_0_EAX_FEATURES 0
#define TCG_SGX_12_0_EBX_FEATURES 0
#define TCG_SGX_12_1_EAX_FEATURES 0
+#define TCG_24_0_EBX_FEATURES 0
#if defined CONFIG_USER_ONLY
#define CPUID_8000_0008_EBX_KERNEL_FEATURES (CPUID_8000_0008_EBX_IBPB | \
@@ -1167,6 +1168,20 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
},
.tcg_features = TCG_7_2_EDX_FEATURES,
},
+ [FEAT_24_0_EBX] = {
+ .type = CPUID_FEATURE_WORD,
+ .feat_names = {
+ [16] = "avx10-128",
+ [17] = "avx10-256",
+ [18] = "avx10-512",
+ },
+ .cpuid = {
+ .eax = 0x24,
+ .needs_ecx = true, .ecx = 0,
+ .reg = R_EBX,
+ },
+ .tcg_features = TCG_24_0_EBX_FEATURES,
+ },
[FEAT_8000_0007_EDX] = {
.type = CPUID_FEATURE_WORD,
.feat_names = {
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 591113349d..c60290b8d5 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -666,6 +666,7 @@ typedef enum FeatureWord {
FEAT_XSAVE_XSS_HI, /* CPUID[EAX=0xd,ECX=1].EDX */
FEAT_7_1_EDX, /* CPUID[EAX=7,ECX=1].EDX */
FEAT_7_2_EDX, /* CPUID[EAX=7,ECX=2].EDX */
+ FEAT_24_0_EBX, /* CPUID[EAX=0x24,ECX=0].EBX */
FEATURE_WORDS,
} FeatureWord;
@@ -990,6 +991,13 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w);
/* Packets which contain IP payload have LIP values */
#define CPUID_14_0_ECX_LIP (1U << 31)
+/* AVX10 128-bit vector support is present */
+#define CPUID_24_0_EBX_AVX10_128 (1U << 16)
+/* AVX10 256-bit vector support is present */
+#define CPUID_24_0_EBX_AVX10_256 (1U << 17)
+/* AVX10 512-bit vector support is present */
+#define CPUID_24_0_EBX_AVX10_512 (1U << 18)
+
/* RAS Features */
#define CPUID_8000_0007_EBX_OVERFLOW_RECOV (1U << 0)
#define CPUID_8000_0007_EBX_SUCCOR (1U << 1)
--
2.39.3

View File

@ -0,0 +1,43 @@
From d457fd42e0752855d8370bac1cf3c07cd1fc46a3 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 3 Jul 2024 13:42:49 +0200
Subject: [PATCH 38/38] target/i386: add sha512, sm3, sm4 feature bits
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets
RH-Jira: RHEL-30315 RHEL-45110
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [9/9] 80a6ce9fe3b7225f74a2822ce263d539148cda56 (bonzini/rhel-qemu-kvm)
Status: queued for QEMU 10.0
SHA512, SM3, SM4 (CPUID[EAX=7,ECX=1).EAX bits 0 to 2) is supported by
Clearwater Forest processor, add it to QEMU as it does not need any
specific enablement.
See https://lore.kernel.org/kvm/20241105054825.870939-1-tao1.su@linux.intel.com/
for reference.
Reviewed-by: Tao Su <tao1.su@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index e7367cfe82..ff063a9a50 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1114,7 +1114,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
[FEAT_7_1_EAX] = {
.type = CPUID_FEATURE_WORD,
.feat_names = {
- NULL, NULL, NULL, NULL,
+ "sha512", "sm3", "sm4", NULL,
"avx-vnni", "avx512-bf16", NULL, "cmpccxadd",
NULL, NULL, "fzrm", "fsrs",
"fsrc", NULL, NULL, NULL,
--
2.39.3

View File

@ -0,0 +1,50 @@
From 2424960a48dfa6bb499c4cb798b0e5c256deba10 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Thu, 31 Oct 2024 16:52:26 +0800
Subject: [PATCH 30/38] target/i386: cpu: set correct supported XCR0 features
for TCG
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets
RH-Jira: RHEL-30315 RHEL-45110
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/9] 0516319354addebf36f9d364fbae5cda7a98473b (bonzini/rhel-qemu-kvm)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Link: https://lore.kernel.org/r/20241031085233.425388-2-tao1.su@linux.intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 33098002a838a0450f243f5e17463aca700e923d)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 34e0ce5e62..dbdab0f821 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1297,7 +1297,9 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
.needs_ecx = true, .ecx = 0,
.reg = R_EAX,
},
- .tcg_features = ~0U,
+ .tcg_features = XSTATE_FP_MASK | XSTATE_SSE_MASK |
+ XSTATE_YMM_MASK | XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK |
+ XSTATE_PKRU_MASK,
.migratable_flags = XSTATE_FP_MASK | XSTATE_SSE_MASK |
XSTATE_YMM_MASK | XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK |
XSTATE_OPMASK_MASK | XSTATE_ZMM_Hi256_MASK | XSTATE_Hi16_ZMM_MASK |
@@ -1310,7 +1312,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
.needs_ecx = true, .ecx = 0,
.reg = R_EDX,
},
- .tcg_features = ~0U,
+ .tcg_features = 0U,
},
/*Below are MSR exposed features*/
[FEAT_ARCH_CAPABILITIES] = {
--
2.39.3

View File

@ -0,0 +1,117 @@
From 6df46774aa41872a706f1a535d5c547a8ef73556 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Thu, 31 Oct 2024 16:52:27 +0800
Subject: [PATCH 31/38] target/i386: do not rely on ExtSaveArea for
accelerator-supported XCR0 bits
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets
RH-Jira: RHEL-30315 RHEL-45110
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/9] 70d54c2101fd1d30a891a414a8c50566c2ddef67 (bonzini/rhel-qemu-kvm)
Right now, QEMU is using the "feature" and "bits" fields of ExtSaveArea
to query the accelerator for the support status of extended save areas.
This is a problem for AVX10, which attaches two feature bits (AVX512F
and AVX10) to the same extended save states.
To keep the AVX10 hacks to the minimum, limit usage of esa->features
and esa->bits. Instead, just query the accelerator for the 0xD leaf.
Do it in common code and clear esa->size if an extended save state is
unsupported.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Link: https://lore.kernel.org/r/20241031085233.425388-3-tao1.su@linux.intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit b888c7807049cc044d10d70139cb945202fb7cd2)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.c | 33 +++++++++++++++++++++++++++++++--
target/i386/kvm/kvm-cpu.c | 4 ----
2 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index dbdab0f821..d23f15e99a 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7086,6 +7086,15 @@ static void x86_cpu_set_sgxlepubkeyhash(CPUX86State *env)
#endif
}
+static bool cpuid_has_xsave_feature(CPUX86State *env, const ExtSaveArea *esa)
+{
+ if (!esa->size) {
+ return false;
+ }
+
+ return (env->features[esa->feature] & esa->bits);
+}
+
static void x86_cpu_reset_hold(Object *obj, ResetType type)
{
CPUState *cs = CPU(obj);
@@ -7194,7 +7203,7 @@ static void x86_cpu_reset_hold(Object *obj, ResetType type)
if (!((1 << i) & CPUID_XSTATE_XCR0_MASK)) {
continue;
}
- if (env->features[esa->feature] & esa->bits) {
+ if (cpuid_has_xsave_feature(env, esa)) {
xcr0 |= 1ull << i;
}
}
@@ -7332,7 +7341,7 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu)
mask = 0;
for (i = 0; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
const ExtSaveArea *esa = &x86_ext_save_areas[i];
- if (env->features[esa->feature] & esa->bits) {
+ if (cpuid_has_xsave_feature(env, esa)) {
mask |= (1ULL << i);
}
}
@@ -8003,6 +8012,26 @@ static void x86_cpu_register_feature_bit_props(X86CPUClass *xcc,
static void x86_cpu_post_initfn(Object *obj)
{
+ static bool first = true;
+ uint64_t supported_xcr0;
+ int i;
+
+ if (first) {
+ first = false;
+
+ supported_xcr0 =
+ ((uint64_t) x86_cpu_get_supported_feature_word(NULL, FEAT_XSAVE_XCR0_HI) << 32) |
+ x86_cpu_get_supported_feature_word(NULL, FEAT_XSAVE_XCR0_LO);
+
+ for (i = XSTATE_SSE_BIT + 1; i < XSAVE_STATE_AREA_COUNT; i++) {
+ ExtSaveArea *esa = &x86_ext_save_areas[i];
+
+ if (!(supported_xcr0 & (1 << i))) {
+ esa->size = 0;
+ }
+ }
+ }
+
accel_cpu_instance_init(CPU(obj));
}
diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c
index 684e731cbc..961b87e98e 100644
--- a/target/i386/kvm/kvm-cpu.c
+++ b/target/i386/kvm/kvm-cpu.c
@@ -143,10 +143,6 @@ static void kvm_cpu_xsave_init(void)
if (!esa->size) {
continue;
}
- if ((x86_cpu_get_supported_feature_word(NULL, esa->feature) & esa->bits)
- != esa->bits) {
- continue;
- }
host_cpuid(0xd, i, &eax, &ebx, &ecx, &edx);
if (eax != 0) {
assert(esa->size == eax);
--
2.39.3

View File

@ -0,0 +1,176 @@
From 6bae9faff44415edf51bb7f919fc816f8fe3cd12 Mon Sep 17 00:00:00 2001
From: Julia Suvorova <jusual@redhat.com>
Date: Fri, 27 Sep 2024 12:47:41 +0200
Subject: [PATCH 29/38] target/i386/kvm: Report which action failed in
kvm_arch_put/get_registers
RH-Author: Julia Suvorova <None>
RH-MergeRequest: 287: kvm: Allow kvm_arch_get/put_registers to accept Error**
RH-Jira: RHEL-20574
RH-Acked-by: Juraj Marcin <None>
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Commit: [2/2] 1e430500be009393846a19451472b3d1031c1283
To help debug and triage future failure reports (akin to [1,2]) that
may occur during kvm_arch_put/get_registers, the error path of each
action is accompanied by unique error message.
[1] https://issues.redhat.com/browse/RHEL-7558
[2] https://issues.redhat.com/browse/RHEL-21761
Signed-off-by: Julia Suvorova <jusual@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/r/20240927104743.218468-3-jusual@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit fc058618d1596d29e89016750a1aaf64c9fe8832)
---
target/i386/kvm/kvm.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 423e6922d8..814f93da19 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -5136,6 +5136,7 @@ int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp)
if (level >= KVM_PUT_RESET_STATE) {
ret = kvm_put_msr_feature_control(x86_cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to set feature control MSR");
return ret;
}
}
@@ -5143,12 +5144,14 @@ int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp)
/* must be before kvm_put_nested_state so that EFER.SVME is set */
ret = has_sregs2 ? kvm_put_sregs2(x86_cpu) : kvm_put_sregs(x86_cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to set special registers");
return ret;
}
if (level >= KVM_PUT_RESET_STATE) {
ret = kvm_put_nested_state(x86_cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to set nested state");
return ret;
}
}
@@ -5166,6 +5169,7 @@ int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp)
if (xen_mode == XEN_EMULATE && level == KVM_PUT_FULL_STATE) {
ret = kvm_put_xen_state(cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to set Xen state");
return ret;
}
}
@@ -5173,37 +5177,45 @@ int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp)
ret = kvm_getput_regs(x86_cpu, 1);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to set general purpose registers");
return ret;
}
ret = kvm_put_xsave(x86_cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to set XSAVE");
return ret;
}
ret = kvm_put_xcrs(x86_cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to set XCRs");
return ret;
}
ret = kvm_put_msrs(x86_cpu, level);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to set MSRs");
return ret;
}
ret = kvm_put_vcpu_events(x86_cpu, level);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to set vCPU events");
return ret;
}
if (level >= KVM_PUT_RESET_STATE) {
ret = kvm_put_mp_state(x86_cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to set MP state");
return ret;
}
}
ret = kvm_put_tscdeadline_msr(x86_cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to set TSC deadline MSR");
return ret;
}
ret = kvm_put_debugregs(x86_cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to set debug registers");
return ret;
}
return 0;
@@ -5218,6 +5230,7 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp)
ret = kvm_get_vcpu_events(cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to get vCPU events");
goto out;
}
/*
@@ -5226,44 +5239,54 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp)
*/
ret = kvm_get_mp_state(cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to get MP state");
goto out;
}
ret = kvm_getput_regs(cpu, 0);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to get general purpose registers");
goto out;
}
ret = kvm_get_xsave(cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to get XSAVE");
goto out;
}
ret = kvm_get_xcrs(cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to get XCRs");
goto out;
}
ret = has_sregs2 ? kvm_get_sregs2(cpu) : kvm_get_sregs(cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to get special registers");
goto out;
}
ret = kvm_get_msrs(cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to get MSRs");
goto out;
}
ret = kvm_get_apic(cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to get APIC");
goto out;
}
ret = kvm_get_debugregs(cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to get debug registers");
goto out;
}
ret = kvm_get_nested_state(cpu);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to get nested state");
goto out;
}
#ifdef CONFIG_XEN_EMU
if (xen_mode == XEN_EMULATE) {
ret = kvm_get_xen_state(cs);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to get Xen state");
goto out;
}
}
--
2.39.3

View File

@ -0,0 +1,83 @@
From c4792fc23bf28618601514e3af5f331b4292bdf7 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Thu, 31 Oct 2024 16:52:28 +0800
Subject: [PATCH 32/38] target/i386: return bool from x86_cpu_filter_features
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets
RH-Jira: RHEL-30315 RHEL-45110
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [3/9] e5ae5d2050ad75411d8db6f9f9519bcaf88c4850 (bonzini/rhel-qemu-kvm)
Prepare for filtering non-boolean features such as AVX10 version.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Link: https://lore.kernel.org/r/20241031085233.425388-4-tao1.su@linux.intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 3507c6f04606593711408a6d26141bdbceff9377)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index d23f15e99a..353f50a1b9 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5835,7 +5835,7 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features,
}
}
-static void x86_cpu_filter_features(X86CPU *cpu, bool verbose);
+static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose);
/* Build a list with the name of all features on a feature word array */
static void x86_cpu_list_feature_names(FeatureWordArray features,
@@ -7540,9 +7540,9 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
* Finishes initialization of CPUID data, filters CPU feature
* words based on host availability of each feature.
*
- * Returns: 0 if all flags are supported by the host, non-zero otherwise.
+ * Returns: true if any flag is not supported by the host, false otherwise.
*/
-static void x86_cpu_filter_features(X86CPU *cpu, bool verbose)
+static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose)
{
CPUX86State *env = &cpu->env;
FeatureWord w;
@@ -7594,6 +7594,8 @@ static void x86_cpu_filter_features(X86CPU *cpu, bool verbose)
mark_unavailable_features(cpu, FEAT_7_0_EBX, CPUID_7_0_EBX_INTEL_PT, prefix);
}
}
+
+ return x86_cpu_have_filtered_features(cpu);
}
static void x86_cpu_hyperv_realize(X86CPU *cpu)
@@ -7691,14 +7693,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
}
}
- x86_cpu_filter_features(cpu, cpu->check_cpuid || cpu->enforce_cpuid);
-
- if (cpu->enforce_cpuid && x86_cpu_have_filtered_features(cpu)) {
- error_setg(&local_err,
- accel_uses_host_cpuid() ?
+ if (x86_cpu_filter_features(cpu, cpu->check_cpuid || cpu->enforce_cpuid)) {
+ if (cpu->enforce_cpuid) {
+ error_setg(&local_err,
+ accel_uses_host_cpuid() ?
"Host doesn't support requested features" :
"TCG doesn't support requested features");
- goto out;
+ goto out;
+ }
}
/* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
--
2.39.3

View File

@ -0,0 +1,74 @@
From 8b3125e03d0b20987e1b0a963c24d38cb382f99c Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:53 -0400
Subject: [PATCH 21/38] tests/qtest: Add s390x boot order tests to cdrom-test.c
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [20/23] 1e79fbbd76e5bbf933fadda82dabf95fb60ead8c (thuth/qemu-kvm-cs9)
Add two new qtests to verify that a valid IPL device can successfully boot after
failed IPL attempts from one or more invalid devices.
cdrom-test/as-fallback-device: Defines the primary boot target as a device that
is invalid for IPL and a second boot target that is valid for IPL. Ensures that
the valid device will be selected after the initial failed IPL.
cdrom-test/as-last-option: Defines the maximum number of boot devices (8)
where only the final entry in the boot order is valid. Ensures that a valid
device will be selected even after multiple failed IPL attempts from both
virtio-blk and virtio-scsi device types.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-20-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit f5aa2d9d4c6480fa73b89c935050afe57e5d8bd9)
---
tests/qtest/cdrom-test.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/tests/qtest/cdrom-test.c b/tests/qtest/cdrom-test.c
index 5d89e62515..ecba648144 100644
--- a/tests/qtest/cdrom-test.c
+++ b/tests/qtest/cdrom-test.c
@@ -206,6 +206,30 @@ static void add_s390x_tests(void)
"-drive driver=null-co,read-zeroes=on,if=none,id=d1 "
"-device virtio-blk,drive=d2,bootindex=1 "
"-drive if=none,id=d2,media=cdrom,file=", test_cdboot);
+ qtest_add_data_func("cdrom/boot/as-fallback-device",
+ "-device virtio-serial -device virtio-scsi "
+ "-device virtio-blk,drive=d1,bootindex=1 "
+ "-drive driver=null-co,read-zeroes=on,if=none,id=d1 "
+ "-device virtio-blk,drive=d2,bootindex=2 "
+ "-drive if=none,id=d2,media=cdrom,file=", test_cdboot);
+ qtest_add_data_func("cdrom/boot/as-last-option",
+ "-device virtio-serial -device virtio-scsi "
+ "-device virtio-blk,drive=d1,bootindex=1 "
+ "-drive driver=null-co,read-zeroes=on,if=none,id=d1 "
+ "-device virtio-blk,drive=d2,bootindex=2 "
+ "-drive driver=null-co,read-zeroes=on,if=none,id=d2 "
+ "-device virtio-blk,drive=d3,bootindex=3 "
+ "-drive driver=null-co,read-zeroes=on,if=none,id=d3 "
+ "-device scsi-hd,drive=d4,bootindex=4 "
+ "-drive driver=null-co,read-zeroes=on,if=none,id=d4 "
+ "-device scsi-hd,drive=d5,bootindex=5 "
+ "-drive driver=null-co,read-zeroes=on,if=none,id=d5 "
+ "-device virtio-blk,drive=d6,bootindex=6 "
+ "-drive driver=null-co,read-zeroes=on,if=none,id=d6 "
+ "-device scsi-hd,drive=d7,bootindex=7 "
+ "-drive driver=null-co,read-zeroes=on,if=none,id=d7 "
+ "-device scsi-cd,drive=d8,bootindex=8 "
+ "-drive if=none,id=d8,media=cdrom,file=", test_cdboot);
if (qtest_has_device("x-terminal3270")) {
qtest_add_data_func("cdrom/boot/without-bootindex",
"-device virtio-scsi -device virtio-serial "
--
2.39.3

View File

@ -0,0 +1,70 @@
From 85752ed0d3bdf707a9c84a12b8b717d932b882a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
Date: Wed, 6 Nov 2024 17:31:16 +0100
Subject: [PATCH 27/38] vfio/migration: Change trace formats from hex to
decimal
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Cédric Le Goater <clg@redhat.com>
RH-MergeRequest: 283: vfio/migration: Report only stop-copy size in vfio_state_pending_exact()
RH-Jira: RHEL-64308
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Alex Williamson <None>
RH-Commit: [2/2] c4f7485b3ad4f779a2f13b6f09c9bb5712a45401 (clegoate/qemu-kvm-c9s)
JIRA: https://issues.redhat.com/browse/RHEL-64308
commit fa4e20defe239e42af0a1b5c030dec114f799f56
Author: Avihai Horon <avihaih@nvidia.com>
Date: Sun Oct 20 16:01:08 2024 +0300
vfio/migration: Change trace formats from hex to decimal
Data sizes in VFIO migration trace events are printed in hex format
while in migration core trace events they are printed in decimal format.
This inconsistency makes it less readable when using both trace event
types. Hence, change the data sizes print format to decimal in VFIO
migration trace events.
Signed-off-by: Avihai Horon <avihaih@nvidia.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
---
hw/vfio/trace-events | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index 98bd4dccea..3756ff660e 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -151,7 +151,7 @@ vfio_display_edid_write_error(void) ""
vfio_load_cleanup(const char *name) " (%s)"
vfio_load_device_config_state(const char *name) " (%s)"
vfio_load_state(const char *name, uint64_t data) " (%s) data 0x%"PRIx64
-vfio_load_state_device_data(const char *name, uint64_t data_size, int ret) " (%s) size 0x%"PRIx64" ret %d"
+vfio_load_state_device_data(const char *name, uint64_t data_size, int ret) " (%s) size %"PRIu64" ret %d"
vfio_migration_realize(const char *name) " (%s)"
vfio_migration_set_device_state(const char *name, const char *state) " (%s) state %s"
vfio_migration_set_state(const char *name, const char *new_state, const char *recover_state) " (%s) new state %s, recover state %s"
@@ -160,10 +160,10 @@ vfio_save_block(const char *name, int data_size) " (%s) data_size %d"
vfio_save_cleanup(const char *name) " (%s)"
vfio_save_complete_precopy(const char *name, int ret) " (%s) ret %d"
vfio_save_device_config_state(const char *name) " (%s)"
-vfio_save_iterate(const char *name, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy initial size 0x%"PRIx64" precopy dirty size 0x%"PRIx64
-vfio_save_setup(const char *name, uint64_t data_buffer_size) " (%s) data buffer size 0x%"PRIx64
-vfio_state_pending_estimate(const char *name, uint64_t precopy, uint64_t postcopy, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy 0x%"PRIx64" postcopy 0x%"PRIx64" precopy initial size 0x%"PRIx64" precopy dirty size 0x%"PRIx64
-vfio_state_pending_exact(const char *name, uint64_t precopy, uint64_t postcopy, uint64_t stopcopy_size, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy 0x%"PRIx64" postcopy 0x%"PRIx64" stopcopy size 0x%"PRIx64" precopy initial size 0x%"PRIx64" precopy dirty size 0x%"PRIx64
+vfio_save_iterate(const char *name, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy initial size %"PRIu64" precopy dirty size %"PRIu64
+vfio_save_setup(const char *name, uint64_t data_buffer_size) " (%s) data buffer size %"PRIu64
+vfio_state_pending_estimate(const char *name, uint64_t precopy, uint64_t postcopy, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy %"PRIu64" postcopy %"PRIu64" precopy initial size %"PRIu64" precopy dirty size %"PRIu64
+vfio_state_pending_exact(const char *name, uint64_t precopy, uint64_t postcopy, uint64_t stopcopy_size, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy %"PRIu64" postcopy %"PRIu64" stopcopy size %"PRIu64" precopy initial size %"PRIu64" precopy dirty size %"PRIu64
vfio_vmstate_change(const char *name, int running, const char *reason, const char *dev_state) " (%s) running %d reason %s device state %s"
vfio_vmstate_change_prepare(const char *name, int running, const char *reason, const char *dev_state) " (%s) running %d reason %s device state %s"
--
2.39.3

View File

@ -0,0 +1,66 @@
From d32c2291e836f912a72aedaf2ace31d4e1679f95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
Date: Wed, 6 Nov 2024 17:31:16 +0100
Subject: [PATCH 26/38] vfio/migration: Report only stop-copy size in
vfio_state_pending_exact()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Cédric Le Goater <clg@redhat.com>
RH-MergeRequest: 283: vfio/migration: Report only stop-copy size in vfio_state_pending_exact()
RH-Jira: RHEL-64308
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Alex Williamson <None>
RH-Commit: [1/2] 85956ae33c6aea99dba95500595e0ca7dc9dcdad (clegoate/qemu-kvm-c9s)
JIRA: https://issues.redhat.com/browse/RHEL-64308
commit 3b5948f808e3b99aedfa0aff45cffbe8b7ec07ed
Author: Avihai Horon <avihaih@nvidia.com>
Date: Sun Oct 20 16:01:06 2024 +0300
vfio/migration: Report only stop-copy size in vfio_state_pending_exact()
vfio_state_pending_exact() is used to update migration core how much
device data is left for the device migration. Currently, the sum of
pre-copy and stop-copy sizes of the VFIO device are reported.
The pre-copy size is obtained via the VFIO_MIG_GET_PRECOPY_INFO ioctl,
which returns the amount of device data available to be transferred
while the device is in the PRE_COPY states.
The stop-copy size is obtained via the VFIO_DEVICE_FEATURE_MIG_DATA_SIZE
ioctl, which returns the total amount of device data left to be
transferred in order to complete the device migration.
According to the above, current implementation is wrong -- it reports
extra overlapping data because pre-copy size is already contained in
stop-copy size. Fix it by reporting only stop-copy size.
Fixes: eda7362af959 ("vfio/migration: Add VFIO migration pre-copy support")
Signed-off-by: Avihai Horon <avihaih@nvidia.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
---
hw/vfio/migration.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 262d42a46e..dd717e8d6c 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -576,9 +576,6 @@ static void vfio_state_pending_exact(void *opaque, uint64_t *must_precopy,
if (vfio_device_state_is_precopy(vbasedev)) {
vfio_query_precopy_size(migration);
-
- *must_precopy +=
- migration->precopy_init_size + migration->precopy_dirty_size;
}
trace_vfio_state_pending_exact(vbasedev->name, *must_precopy, *can_postcopy,
--
2.39.3

View File

@ -0,0 +1,62 @@
From 9e58f195620d723a2a0b609aa1c59d4938551835 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
Date: Tue, 20 Aug 2024 17:11:12 +0400
Subject: [PATCH 25/38] vnc: fix crash when no console attached
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
RH-MergeRequest: 279: vnc: fix crash when no console attached
RH-Jira: RHEL-50529
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] 0ea2135d95786752fe50c00271be997144adb4bc (marcandre.lureau-rh/qemu-kvm-centos)
JIRA: https://issues.redhat.com/browse/RHEL-50529
Since commit e99441a3793b5 ("ui/curses: Do not use console_select()")
qemu_text_console_put_keysym() no longer checks for NULL console
argument, which leads to a later crash:
Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
0x00005555559ee186 in qemu_text_console_handle_keysym (s=0x0, keysym=31) at ../ui/console-vc.c:332
332 } else if (s->echo && (keysym == '\r' || keysym == '\n')) {
(gdb) bt
#0 0x00005555559ee186 in qemu_text_console_handle_keysym (s=0x0, keysym=31) at ../ui/console-vc.c:332
#1 0x00005555559e18e5 in qemu_text_console_put_keysym (s=<optimized out>, keysym=<optimized out>) at ../ui/console.c:303
#2 0x00005555559f2e88 in do_key_event (vs=vs@entry=0x5555579045c0, down=down@entry=1, keycode=keycode@entry=60, sym=sym@entry=65471) at ../ui/vnc.c:2034
#3 0x00005555559f845c in ext_key_event (vs=0x5555579045c0, down=1, sym=65471, keycode=<optimized out>) at ../ui/vnc.c:2070
#4 protocol_client_msg (vs=0x5555579045c0, data=<optimized out>, len=<optimized out>) at ../ui/vnc.c:2514
#5 0x00005555559f515c in vnc_client_read (vs=0x5555579045c0) at ../ui/vnc.c:1607
Fixes: e99441a3793b5 ("ui/curses: Do not use console_select()")
Fixes: https://issues.redhat.com/browse/RHEL-50529
Cc: qemu-stable@nongnu.org
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 0e60fc80938d9ce84274a36ddfaaa640bdef2be8)
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
ui/vnc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/vnc.c b/ui/vnc.c
index dae5d51210..5057ec8680 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1935,7 +1935,7 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
}
qkbd_state_key_event(vs->vd->kbd, qcode, down);
- if (!qemu_console_is_graphic(vs->vd->dcl.con)) {
+ if (QEMU_IS_TEXT_CONSOLE(vs->vd->dcl.con)) {
QemuTextConsole *con = QEMU_TEXT_CONSOLE(vs->vd->dcl.con);
bool numlock = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK);
bool control = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL);
--
2.39.3

View File

@ -143,7 +143,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \
Summary: QEMU is a machine emulator and virtualizer
Name: qemu-kvm
Version: 9.1.0
Release: 3%{?rcrel}%{?dist}%{?cc_suffix}.1
Release: 4%{?rcrel}%{?dist}%{?cc_suffix}
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
# Epoch 15 used for RHEL 8
# Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5)
@ -237,6 +237,89 @@ Patch33: kvm-RH-Author-Shaoqin-Huang-shahuang-redhat.com.patch
Patch34: kvm-qemu-guest-agent-Update-the-logfile-path-of-qga-fsfr.patch
# For RHEL-58936 - [RHEL-10.0] QEMU core dump on applying merge property to memory backend
Patch35: kvm-hostmem-Apply-merge-property-after-the-memory-region.patch
# For RHEL-58928 - Boot SNP guests failed with qemu-kvm: kvm_set_user_memory_region
Patch36: kvm-accel-kvm-check-for-KVM_CAP_READONLY_MEM-on-VM.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch37: kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch38: kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch39: kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch41: kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch42: kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch43: kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch44: kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch45: kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch46: kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch47: kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch48: kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch49: kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch50: kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch51: kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch52: kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch53: kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch54: kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch55: kvm-docs-system-Update-documentation-for-s390x-IPL.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch56: kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch57: kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch58: kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch
# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part
Patch59: kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch
# For RHEL-50529 - Qemu-kvm crashed if no display device setting and switching display by remote-viewer
Patch60: kvm-vnc-fix-crash-when-no-console-attached.patch
# For RHEL-64308 - High threshold value observed in vGPU live migration
Patch61: kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch
# For RHEL-64308 - High threshold value observed in vGPU live migration
Patch62: kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch
# For RHEL-20574 - Fail migration properly when put cpu register fails
Patch63: kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch
# For RHEL-20574 - Fail migration properly when put cpu register fails
Patch64: kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch
# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support
# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4
Patch65: kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch
# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support
# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4
Patch66: kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch
# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support
# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4
Patch67: kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch
# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support
# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4
Patch68: kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch
# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support
# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4
Patch69: kvm-target-i386-add-CPUID.24-features-for-AVX10.patch
# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support
# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4
Patch70: kvm-target-i386-Add-feature-dependencies-for-AVX10.patch
# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support
# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4
Patch71: kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch
# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support
# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4
Patch72: kvm-target-i386-Introduce-GraniteRapids-v2-model.patch
# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support
# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4
Patch73: kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch
%if %{have_clang}
BuildRequires: clang
@ -865,7 +948,7 @@ cp -a qemu-system-%{kvm_target} qemu-kvm
%ifarch s390x
# Copy the built new images into place for "make check":
cp pc-bios/s390-ccw/s390-ccw.img pc-bios/s390-ccw/s390-netboot.img pc-bios/
cp pc-bios/s390-ccw/s390-ccw.img pc-bios/
%endif
popd
@ -1004,7 +1087,6 @@ rm -rf %{buildroot}%{_datadir}/%{name}/skiboot.lid
rm -rf %{buildroot}%{_datadir}/%{name}/qboot.rom
rm -rf %{buildroot}%{_datadir}/%{name}/s390-ccw.img
rm -rf %{buildroot}%{_datadir}/%{name}/s390-netboot.img
rm -rf %{buildroot}%{_datadir}/%{name}/hppa-firmware.img
rm -rf %{buildroot}%{_datadir}/%{name}/hppa-firmware64.img
rm -rf %{buildroot}%{_datadir}/%{name}/canyonlands.dtb
@ -1028,9 +1110,8 @@ rm -rf %{buildroot}%{_libexecdir}/virtfs-proxy-helper
rm -rf %{buildroot}%{_mandir}/man1/virtfs-proxy-helper*
%ifarch s390x
# Use the s390-*.img that we've just built, not the pre-built ones
# Use the s390-ccw.img that we've just built, not the pre-built one
install -m 0644 %{qemu_kvm_build}/pc-bios/s390-ccw/s390-ccw.img %{buildroot}%{_datadir}/%{name}/
install -m 0644 %{qemu_kvm_build}/pc-bios/s390-ccw/s390-netboot.img %{buildroot}%{_datadir}/%{name}/
%else
rm -rf %{buildroot}%{_libdir}/%{name}/hw-s390x-virtio-gpu-ccw.so
%endif
@ -1220,7 +1301,6 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
%endif
%ifarch s390x
%{_datadir}/%{name}/s390-ccw.img
%{_datadir}/%{name}/s390-netboot.img
%endif
%{_datadir}/icons/*
%{_datadir}/%{name}/linuxboot_dma.bin
@ -1304,6 +1384,60 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
%endif
%changelog
* Tue Nov 12 2024 Miroslav Rezanina <mrezanin@redhat.com> - 9.1.0-4.el10
- kvm-accel-kvm-check-for-KVM_CAP_READONLY_MEM-on-VM.patch [RHEL-58928]
- kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch [RHEL-58153]
- kvm-redhat-Remove-the-s390-netboot.img-from-the-spec-fil.patch [RHEL-58153]
- kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch [RHEL-58153]
- kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch [RHEL-58153]
- kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch [RHEL-58153]
- kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch [RHEL-58153]
- kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch [RHEL-58153]
- kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch [RHEL-58153]
- kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch [RHEL-58153]
- kvm-docs-system-Update-documentation-for-s390x-IPL.patch [RHEL-58153]
- kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch [RHEL-58153]
- kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch [RHEL-58153]
- kvm-vnc-fix-crash-when-no-console-attached.patch [RHEL-50529]
- kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch [RHEL-64308]
- kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch [RHEL-64308]
- kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch [RHEL-20574]
- kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch [RHEL-20574]
- kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-add-CPUID.24-features-for-AVX10.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-Add-feature-dependencies-for-AVX10.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-Introduce-GraniteRapids-v2-model.patch [RHEL-30315 RHEL-45110]
- kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch [RHEL-30315 RHEL-45110]
- Resolves: RHEL-58928
(Boot SNP guests failed with qemu-kvm: kvm_set_user_memory_region)
- Resolves: RHEL-58153
([IBM 10.0 FEAT] KVM: Full boot order support - qemu part)
- Resolves: RHEL-50529
(Qemu-kvm crashed if no display device setting and switching display by remote-viewer)
- Resolves: RHEL-64308
(High threshold value observed in vGPU live migration)
- Resolves: RHEL-20574
(Fail migration properly when put cpu register fails)
- Resolves: RHEL-30315
([Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support)
- Resolves: RHEL-45110
([Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4)
* Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com> - 18:9.1.0-3.1
- Bump release for October 2024 mass rebuild:
Resolves: RHEL-64018