From 13ad956357a26421b69af6ddfc725c11c0dec0c7 Mon Sep 17 00:00:00 2001 From: MSVSphere Packaging Team Date: Thu, 21 Nov 2024 18:45:53 +0300 Subject: [PATCH] import qemu-kvm-9.1.0-4.el10 --- ...check-for-KVM_CAP_READONLY_MEM-on-VM.patch | 56 + ...m-Update-documentation-for-s390x-IPL.patch | 76 ++ ...x-bootdevices-Update-the-documentati.patch | 66 + ...x-Build-an-IPLB-for-each-boot-device.patch | 270 ++++ ...the-possibility-to-load-the-s390-net.patch | 201 +++ ...vide-more-memory-to-the-s390-ccw.img.patch | 61 + ...-Add-include-files-for-common-IPL-st.patch | 402 ++++++ ...ch_get-put_registers-to-accept-Error.patch | 287 ++++ ...90-ccw-Clarify-alignment-is-in-bytes.patch | 60 + ...ios-s390-ccw-Don-t-generate-TEXTRELs.patch | 83 ++ ...-Enable-failed-IPL-to-return-after-e.patch | 426 ++++++ ...ios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch | 63 + ...-Link-the-netboot-code-into-the-main.patch | 263 ++++ ...-Merge-netboot.mak-into-the-main-Mak.patch | 141 ++ ...ccw-Remove-panics-from-DASD-IPL-path.patch | 177 +++ ...ccw-Remove-panics-from-ECKD-IPL-path.patch | 475 +++++++ ...-ccw-Remove-panics-from-ISO-IPL-path.patch | 269 ++++ ...-Remove-panics-from-Netboot-IPL-path.patch | 130 ++ ...ccw-Remove-panics-from-SCSI-IPL-path.patch | 554 ++++++++ ...-Use-the-libc-from-SLOF-and-remove-s.patch | 1208 +++++++++++++++++ ...-s390x-Enable-multi-device-boot-loop.patch | 227 ++++ ...dual-loadparm-assignment-to-CCW-devi.patch | 362 +++++ ...LB-for-SCSI-device-directly-from-DIA.patch | 264 ++++ ...AVX512-state-when-AVX10-is-supported.patch | 56 + ...6-Add-feature-dependencies-for-AVX10.patch | 89 ++ ...386-Introduce-GraniteRapids-v2-model.patch | 59 + ...AVX10-feature-and-AVX10-version-prop.patch | 224 +++ ...i386-add-CPUID.24-features-for-AVX10.patch | 91 ++ ...i386-add-sha512-sm3-sm4-feature-bits.patch | 43 + ...set-correct-supported-XCR0-features-.patch | 50 + ...ot-rely-on-ExtSaveArea-for-accelerat.patch | 117 ++ ...Report-which-action-failed-in-kvm_ar.patch | 176 +++ ...rn-bool-from-x86_cpu_filter_features.patch | 83 ++ ...s390x-boot-order-tests-to-cdrom-test.patch | 74 + ...hange-trace-formats-from-hex-to-deci.patch | 70 + ...eport-only-stop-copy-size-in-vfio_st.patch | 66 + ...c-fix-crash-when-no-console-attached.patch | 62 + SPECS/qemu-kvm.spec | 146 +- 38 files changed, 7521 insertions(+), 6 deletions(-) create mode 100644 SOURCES/kvm-accel-kvm-check-for-KVM_CAP_READONLY_MEM-on-VM.patch create mode 100644 SOURCES/kvm-docs-system-Update-documentation-for-s390x-IPL.patch create mode 100644 SOURCES/kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch create mode 100644 SOURCES/kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch create mode 100644 SOURCES/kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch create mode 100644 SOURCES/kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch create mode 100644 SOURCES/kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch create mode 100644 SOURCES/kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch create mode 100644 SOURCES/kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch create mode 100644 SOURCES/kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch create mode 100644 SOURCES/kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch create mode 100644 SOURCES/kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch create mode 100644 SOURCES/kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch create mode 100644 SOURCES/kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch create mode 100644 SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch create mode 100644 SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch create mode 100644 SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch create mode 100644 SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch create mode 100644 SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch create mode 100644 SOURCES/kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch create mode 100644 SOURCES/kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch create mode 100644 SOURCES/kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch create mode 100644 SOURCES/kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch create mode 100644 SOURCES/kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch create mode 100644 SOURCES/kvm-target-i386-Add-feature-dependencies-for-AVX10.patch create mode 100644 SOURCES/kvm-target-i386-Introduce-GraniteRapids-v2-model.patch create mode 100644 SOURCES/kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch create mode 100644 SOURCES/kvm-target-i386-add-CPUID.24-features-for-AVX10.patch create mode 100644 SOURCES/kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch create mode 100644 SOURCES/kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch create mode 100644 SOURCES/kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch create mode 100644 SOURCES/kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch create mode 100644 SOURCES/kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch create mode 100644 SOURCES/kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch create mode 100644 SOURCES/kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch create mode 100644 SOURCES/kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch create mode 100644 SOURCES/kvm-vnc-fix-crash-when-no-console-attached.patch diff --git a/SOURCES/kvm-accel-kvm-check-for-KVM_CAP_READONLY_MEM-on-VM.patch b/SOURCES/kvm-accel-kvm-check-for-KVM_CAP_READONLY_MEM-on-VM.patch new file mode 100644 index 0000000..6724ead --- /dev/null +++ b/SOURCES/kvm-accel-kvm-check-for-KVM_CAP_READONLY_MEM-on-VM.patch @@ -0,0 +1,56 @@ +From 2b4558ec338adde1b9735128bb8d2f81db303a93 Mon Sep 17 00:00:00 2001 +From: Avadhut Naik +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 +RH-MergeRequest: 276: accel/kvm: check for KVM_CAP_READONLY_MEM on VM +RH-Jira: RHEL-58928 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Vitaly Kuznetsov +RH-Commit: [1/1] 1d392a9e47e68bb71dc44635c494d161585a885c (avnaik1/avnaik-qemu-kvm-fork) + +JIRA: https://issues.redhat.com/browse/RHEL-58928 + +commit 64e0e63ea16aa0122dc0c41a0679da0ae4616208 +Author: Tom Dohrmann +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 + Signed-off-by: Tom Dohrmann + Link: https://lore.kernel.org/r/20240903062953.3926498-1-erbse.13@gmx.de + Cc: qemu-stable@nongnu.org + Signed-off-by: Paolo Bonzini + +Signed-off-by: Avadhut Naik +--- + 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 + diff --git a/SOURCES/kvm-docs-system-Update-documentation-for-s390x-IPL.patch b/SOURCES/kvm-docs-system-Update-documentation-for-s390x-IPL.patch new file mode 100644 index 0000000..f0060a6 --- /dev/null +++ b/SOURCES/kvm-docs-system-Update-documentation-for-s390x-IPL.patch @@ -0,0 +1,76 @@ +From f1359f43bbc61f31c292ca1770688b6db6b959af Mon Sep 17 00:00:00 2001 +From: Jared Rossi +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-19-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(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 + diff --git a/SOURCES/kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch b/SOURCES/kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch new file mode 100644 index 0000000..808cd33 --- /dev/null +++ b/SOURCES/kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch @@ -0,0 +1,66 @@ +From c8e615cf130743ee95a61d7e21bb4b753eb082fb Mon Sep 17 00:00:00 2001 +From: Jared Rossi +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Signed-off-by: Jared Rossi +Message-ID: <20241020012953.1380075-7-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(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 + `__ + for details how to set up the configuration file on your TFTP server. +-- +2.39.3 + diff --git a/SOURCES/kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch b/SOURCES/kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch new file mode 100644 index 0000000..dafdddc --- /dev/null +++ b/SOURCES/kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch @@ -0,0 +1,270 @@ +From 416ee0a87ee4bfedf07bc37d328066375b36fdc1 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-16-jrossi@linux.ibm.com> +[thuth: Fix endianness problem when accessing the qipl structure] +Signed-off-by: Thomas Huth +(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 + diff --git a/SOURCES/kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch b/SOURCES/kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch new file mode 100644 index 0000000..6329706 --- /dev/null +++ b/SOURCES/kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch @@ -0,0 +1,201 @@ +From 36f64f38b39f2a2e0f0682f62f669d5e23074875 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +(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 + diff --git a/SOURCES/kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch b/SOURCES/kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch new file mode 100644 index 0000000..cea6973 --- /dev/null +++ b/SOURCES/kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch @@ -0,0 +1,61 @@ +From ce0d8bc163952ce177c37ea431cacf60889017f2 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +(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 + diff --git a/SOURCES/kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch b/SOURCES/kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch new file mode 100644 index 0000000..da7e469 --- /dev/null +++ b/SOURCES/kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch @@ -0,0 +1,402 @@ +From cd805347076eb3d977ad0779d98a019f5abfaa74 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-14-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(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 ++ * ++ * 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 + + 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 + diff --git a/SOURCES/kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch b/SOURCES/kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch new file mode 100644 index 0000000..f6eb21f --- /dev/null +++ b/SOURCES/kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch @@ -0,0 +1,287 @@ +From 74964784ffb9a0ad307eddafddd6b47f596ca3c1 Mon Sep 17 00:00:00 2001 +From: Julia Suvorova +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 +RH-MergeRequest: 287: kvm: Allow kvm_arch_get/put_registers to accept Error** +RH-Jira: RHEL-20574 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Peter Xu +RH-Commit: [1/2] 7b1d8bf84339f908358f3fe3e392b1950aaa881d + +This is necessary to provide discernible error messages to the caller. + +Signed-off-by: Julia Suvorova +Reviewed-by: Peter Xu +Link: https://lore.kernel.org/r/20240927104743.218468-2-jusual@redhat.com +Signed-off-by: Paolo Bonzini +(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 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch b/SOURCES/kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch new file mode 100644 index 0000000..357bfe7 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch @@ -0,0 +1,60 @@ +From 57746476c81359507743671addee330e303c1e02 Mon Sep 17 00:00:00 2001 +From: Jens Remus +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Marc Hartmayer +Message-ID: <20241001153618.17791-2-mhartmay@linux.ibm.com> +Reviewed-by: Thomas Huth +Signed-off-by: Thomas Huth +(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 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch b/SOURCES/kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch new file mode 100644 index 0000000..a113e2f --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch @@ -0,0 +1,83 @@ +From 62433cc6df65f10e99dab8b2ec9918b69c3c73ae Mon Sep 17 00:00:00 2001 +From: Jens Remus +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Signed-off-by: Jens Remus +Reviewed-by: Marc Hartmayer +Message-ID: <20241001153618.17791-3-mhartmay@linux.ibm.com> +Reviewed-by: Thomas Huth +Signed-off-by: Thomas Huth +(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 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch b/SOURCES/kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch new file mode 100644 index 0000000..d4d3246 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch @@ -0,0 +1,426 @@ +From cfc51bd73616b36a98f7f65f0df3b637d3711811 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-13-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(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 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch b/SOURCES/kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch new file mode 100644 index 0000000..b37a033 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch @@ -0,0 +1,63 @@ +From 06818b9971babd2895158f9fb913d6262eea4cb7 Mon Sep 17 00:00:00 2001 +From: Marc Hartmayer +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Message-ID: <20241001153618.17791-4-mhartmay@linux.ibm.com> +Reviewed-by: Thomas Huth +[thuth: Drop the hunk to netbook.mak which is not necessary anymore] +Signed-off-by: Thomas Huth +(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 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch b/SOURCES/kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch new file mode 100644 index 0000000..835a818 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch @@ -0,0 +1,263 @@ +From 7686f2129e50540b6e9865fad8b4ab9c0343c432 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Signed-off-by: Jared Rossi +Message-ID: <20241020012953.1380075-4-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(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 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch b/SOURCES/kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch new file mode 100644 index 0000000..c587fec --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch @@ -0,0 +1,141 @@ +From 56030483f01524ee7021218e07c8d0ce1b588c62 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +(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 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch new file mode 100644 index 0000000..774fb08 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch @@ -0,0 +1,177 @@ +From 8279e0d5e38b31b9fcd36ff38f0175163ac4ba28 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-11-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(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 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch new file mode 100644 index 0000000..4d55909 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch @@ -0,0 +1,475 @@ +From 0a8e0f11dd82d5988b1090e8e4b8326be0dcb30c Mon Sep 17 00:00:00 2001 +From: Jared Rossi +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-9-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(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 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch new file mode 100644 index 0000000..7004386 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch @@ -0,0 +1,269 @@ +From 6238d2aa6b1a1f421ac04b0d35281dd5e4c65b5c Mon Sep 17 00:00:00 2001 +From: Jared Rossi +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-8-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(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 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch new file mode 100644 index 0000000..d66f32c --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch @@ -0,0 +1,130 @@ +From d5e0f77bd63bc767856e1922b24556ef1b123b55 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-12-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(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 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch new file mode 100644 index 0000000..e02a98d --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch @@ -0,0 +1,554 @@ +From 6212bfb4f7a45b06b38bf5d11774de1d3df982aa Mon Sep 17 00:00:00 2001 +From: Jared Rossi +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-10-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(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 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch b/SOURCES/kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch new file mode 100644 index 0000000..9d14f0c --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch @@ -0,0 +1,1208 @@ +From 736819e0c108bdd8bcb75e28c24ff97c2411d85c Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:36 -0400 +Subject: [PATCH 03/38] pc-bios/s390-ccw: Use the libc from SLOF and remove + sclp prints +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [2/23] cfb15217ddbad8b3ae9606763ff1e1085807d381 (thuth/qemu-kvm-cs9) + +We are already using the libc from SLOF for the s390-netboot.img, and +this libc implementation is way more complete and accurate than the +simple implementation that we currently use for the s390-ccw.img binary. +Since we are now always assuming that the SLOF submodule is available +when building the s390-ccw bios (see commit bf6903f6944f), we can drop +the simple implementation and use the SLOF libc for the s390-ccw.img +binary, too. + +Additionally replace sclp_print calls with puts/printf now that it is +available. + +Co-authored by: Thomas Huth +Signed-off-by: Jared Rossi +Message-ID: <20241020012953.1380075-3-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 9f4278837dc770266c8a026696dd91a525dd2682) +--- + pc-bios/s390-ccw/Makefile | 15 +++-- + pc-bios/s390-ccw/bootmap.c | 47 ++++++------- + pc-bios/s390-ccw/bootmap.h | 4 +- + pc-bios/s390-ccw/cio.c | 78 ++++++++++------------ + pc-bios/s390-ccw/dasd-ipl.c | 5 +- + pc-bios/s390-ccw/jump2ipl.c | 5 +- + pc-bios/s390-ccw/libc.c | 88 ------------------------ + pc-bios/s390-ccw/libc.h | 89 ------------------------- + pc-bios/s390-ccw/main.c | 14 ++-- + pc-bios/s390-ccw/menu.c | 51 +++++++------- + pc-bios/s390-ccw/netboot.mak | 3 - + pc-bios/s390-ccw/netmain.c | 10 +-- + pc-bios/s390-ccw/s390-ccw.h | 30 +++------ + pc-bios/s390-ccw/sclp.c | 7 +- + pc-bios/s390-ccw/virtio-blkdev.c | 6 +- + pc-bios/s390-ccw/virtio-scsi.c | 17 ++--- + pc-bios/s390-ccw/virtio.c | 2 +- + tests/tcg/s390x/Makefile.softmmu-target | 2 +- + tests/tcg/s390x/console.c | 3 + + 19 files changed, 140 insertions(+), 336 deletions(-) + delete mode 100644 pc-bios/s390-ccw/libc.c + delete mode 100644 pc-bios/s390-ccw/libc.h + +diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile +index 6207911b53..3f4232636e 100644 +--- a/pc-bios/s390-ccw/Makefile ++++ b/pc-bios/s390-ccw/Makefile +@@ -33,13 +33,18 @@ 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 libc.o cio.o dasd-ipl.o ++ virtio.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 + + 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) + LDFLAGS += -Wl,-pie -nostdlib -z noexecstack + + cc-test = $(CC) -Werror $1 -c -o /dev/null -xc /dev/null >/dev/null 2>/dev/null +@@ -55,18 +60,18 @@ config-cc.mak: Makefile + $(call cc-option,-march=z900,-march=z10)) 3> config-cc.mak + -include config-cc.mak + ++include $(SRC_PATH)/netboot.mak ++ + build-all: s390-ccw.img s390-netboot.img + +-s390-ccw.elf: $(OBJECTS) +- $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $(OBJECTS),Linking) ++s390-ccw.elf: $(OBJECTS) libc.a ++ $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^,Linking) + + s390-ccw.img: s390-ccw.elf + $(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,Stripping $< into) + + $(OBJECTS): Makefile + +-include $(SRC_PATH)/netboot.mak +- + ALL_OBJS = $(sort $(OBJECTS) $(NETOBJS) $(LIBCOBJS) $(LIBNETOBJS)) + -include $(ALL_OBJS:%.o=%.d) + +diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c +index a2137449dc..3cc79706be 100644 +--- a/pc-bios/s390-ccw/bootmap.c ++++ b/pc-bios/s390-ccw/bootmap.c +@@ -8,7 +8,8 @@ + * directory. + */ + +-#include "libc.h" ++#include ++#include + #include "s390-ccw.h" + #include "s390-arch.h" + #include "bootmap.h" +@@ -21,7 +22,7 @@ + + #ifdef DEBUG_FALLBACK + #define dputs(txt) \ +- do { sclp_print("zipl: " txt); } while (0) ++ do { printf("zipl: " txt); } while (0) + #else + #define dputs(fmt, ...) \ + do { } while (0) +@@ -270,7 +271,7 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr) + prev_block_nr = cur_block_nr; + } + +- sclp_print("No zipl boot menu data found. Booting default entry."); ++ printf("No zipl boot menu data found. Booting default entry."); + return 0; + } + +@@ -338,22 +339,22 @@ static void ipl_eckd_cdl(void) + block_number_t bmt_block_nr, s1b_block_nr; + + /* we have just read the block #0 and recognized it as "IPL1" */ +- sclp_print("CDL\n"); ++ puts("CDL"); + + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); + read_block(1, ipl2, "Cannot read IPL2 record at block 1"); + + mbr = &ipl2->mbr; + if (!magic_match(mbr, ZIPL_MAGIC)) { +- sclp_print("No zIPL section in IPL2 record.\n"); ++ puts("No zIPL section in IPL2 record."); + return; + } + if (!block_size_ok(mbr->blockptr.xeckd.bptr.size)) { +- sclp_print("Bad block size in zIPL section of IPL2 record.\n"); ++ puts("Bad block size in zIPL section of IPL2 record."); + return; + } + if (mbr->dev_type != DEV_TYPE_ECKD) { +- sclp_print("Non-ECKD device type in zIPL section of IPL2 record.\n"); ++ puts("Non-ECKD device type in zIPL section of IPL2 record."); + return; + } + +@@ -366,11 +367,11 @@ static void ipl_eckd_cdl(void) + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); + read_block(2, vlbl, "Cannot read Volume Label at block 2"); + if (!magic_match(vlbl->key, VOL1_MAGIC)) { +- sclp_print("Invalid magic of volume label block.\n"); ++ puts("Invalid magic of volume label block."); + return; + } + if (!magic_match(vlbl->f.key, VOL1_MAGIC)) { +- sclp_print("Invalid magic of volser block.\n"); ++ puts("Invalid magic of volser block."); + return; + } + print_volser(vlbl->f.volser); +@@ -384,8 +385,8 @@ static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode) + LDL_VTOC *vlbl = (void *)sec; /* already read, 3rd block */ + char msg[4] = { '?', '.', '\n', '\0' }; + +- sclp_print((mode == ECKD_CMS) ? "CMS" : "LDL"); +- sclp_print(" version "); ++ printf((mode == ECKD_CMS) ? "CMS" : "LDL"); ++ printf(" version "); + switch (vlbl->LDL_version) { + case LDL1_VERSION: + msg[0] = '1'; +@@ -398,7 +399,7 @@ static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode) + msg[1] = '?'; + break; + } +- sclp_print(msg); ++ printf("%s", msg); + print_volser(vlbl->volser); + } + +@@ -419,7 +420,7 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) + if (!magic_match(ipl1->bip.magic, ZIPL_MAGIC)) { + return; /* not applicable layout */ + } +- sclp_print("unlabeled LDL.\n"); ++ puts("unlabeled LDL."); + } + verify_boot_info(&ipl1->bip); + +@@ -466,7 +467,7 @@ static void print_eckd_msg(void) + *p-- = ' '; + } + } +- sclp_print(msg); ++ printf("%s", msg); + } + + static void ipl_eckd(void) +@@ -488,11 +489,11 @@ 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) { +- sclp_print("List-Directed\n"); ++ 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 */ +- sclp_print("Retrying IPL "); ++ printf("Retrying IPL "); + print_eckd_msg(); + } + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); +@@ -634,7 +635,7 @@ static void ipl_scsi(void) + return; + } + +- sclp_print("Using SCSI scheme.\n"); ++ puts("Using SCSI scheme."); + debug_print_int("MBR Version", mbr->version_id); + IPL_check(mbr->version_id == 1, + "Unknown MBR layout version, assuming version 1"); +@@ -743,7 +744,7 @@ static inline uint32_t iso_get_file_size(uint32_t load_rba) + if (cur_record->file_flags & 0x2) { + /* Subdirectory */ + if (level == ISO9660_MAX_DIR_DEPTH - 1) { +- sclp_print("ISO-9660 directory depth limit exceeded\n"); ++ puts("ISO-9660 directory depth limit exceeded"); + } else { + level++; + sec_loc[level] = iso_733_to_u32(cur_record->ext_loc); +@@ -778,9 +779,9 @@ static void load_iso_bc_entry(IsoBcSection *load) + if (real_size) { + /* Round up blocks to load */ + blks_to_load = (real_size + ISO_SECTOR_SIZE - 1) / ISO_SECTOR_SIZE; +- sclp_print("ISO boot image size verified\n"); ++ puts("ISO boot image size verified"); + } else { +- sclp_print("ISO boot image size could not be verified\n"); ++ puts("ISO boot image size could not be verified"); + } + + read_iso_boot_image(bswap32(s.load_rba), +@@ -896,7 +897,7 @@ static void zipl_load_vblk(void) + } + + if (blksize != VIRTIO_DASD_DEFAULT_BLOCK_SIZE) { +- sclp_print("Using guessed DASD geometry.\n"); ++ puts("Using guessed DASD geometry."); + virtio_assume_eckd(); + } + ipl_eckd(); +@@ -909,7 +910,7 @@ static void zipl_load_vscsi(void) + ipl_iso_el_torito(); + } + +- sclp_print("Using guessed DASD geometry.\n"); ++ puts("Using guessed DASD geometry."); + virtio_assume_eckd(); + ipl_eckd(); + } +@@ -944,5 +945,5 @@ void zipl_load(void) + panic("\n! Unknown IPL device type !\n"); + } + +- sclp_print("zIPL load failed.\n"); ++ puts("zIPL load failed."); + } +diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h +index d4690a88c2..4a7d8a91f1 100644 +--- a/pc-bios/s390-ccw/bootmap.h ++++ b/pc-bios/s390-ccw/bootmap.h +@@ -336,9 +336,7 @@ static inline void print_volser(const void *volser) + + ebcdic_to_ascii((char *)volser, ascii, 6); + ascii[6] = '\0'; +- sclp_print("VOLSER=["); +- sclp_print(ascii); +- sclp_print("]\n"); ++ printf("VOLSER=[%s]\n", ascii); + } + + static inline bool unused_space(const void *p, size_t size) +diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c +index 83ca27ab41..7b09a38c96 100644 +--- a/pc-bios/s390-ccw/cio.c ++++ b/pc-bios/s390-ccw/cio.c +@@ -11,7 +11,8 @@ + * directory. + */ + +-#include "libc.h" ++#include ++#include + #include "s390-ccw.h" + #include "s390-arch.h" + #include "helper.h" +@@ -90,9 +91,9 @@ static void print_eckd_dasd_sense_data(SenseDataEckdDasd *sd) + char msgline[512]; + + if (sd->config_info & 0x8000) { +- sclp_print("Eckd Dasd Sense Data (fmt 24-bytes):\n"); ++ puts("Eckd Dasd Sense Data (fmt 24-bytes):"); + } else { +- sclp_print("Eckd Dasd Sense Data (fmt 32-bytes):\n"); ++ puts("Eckd Dasd Sense Data (fmt 32-bytes):"); + } + + strcat(msgline, " Sense Condition Flags :"); +@@ -158,22 +159,21 @@ static void print_eckd_dasd_sense_data(SenseDataEckdDasd *sd) + if (sd->status[1] & SNS_STAT2_IMPRECISE_END) { + strcat(msgline, " [Imprecise-End]"); + } +- strcat(msgline, "\n"); +- sclp_print(msgline); +- +- print_int(" Residual Count =", sd->res_count); +- print_int(" Phys Drive ID =", sd->phys_drive_id); +- print_int(" low cyl address =", sd->low_cyl_addr); +- print_int(" head addr & hi cyl =", sd->head_high_cyl_addr); +- print_int(" format/message =", sd->fmt_msg); +- print_int(" fmt-dependent[0-7] =", sd->fmt_dependent_info[0]); +- print_int(" fmt-dependent[8-15]=", sd->fmt_dependent_info[1]); +- print_int(" prog action code =", sd->program_action_code); +- print_int(" Configuration info =", sd->config_info); +- print_int(" mcode / hi-cyl =", sd->mcode_hicyl); +- print_int(" cyl & head addr [0]=", sd->cyl_head_addr[0]); +- print_int(" cyl & head addr [1]=", sd->cyl_head_addr[1]); +- print_int(" cyl & head addr [2]=", sd->cyl_head_addr[2]); ++ puts(msgline); ++ ++ printf(" Residual Count = 0x%X\n", sd->res_count); ++ printf(" Phys Drive ID = 0x%X\n", sd->phys_drive_id); ++ printf(" low cyl address = 0x%X\n", sd->low_cyl_addr); ++ printf(" head addr & hi cyl = 0x%X\n", sd->head_high_cyl_addr); ++ printf(" format/message = 0x%X\n", sd->fmt_msg); ++ printf(" fmt-dependent[0-7] = 0x%llX\n", sd->fmt_dependent_info[0]); ++ printf(" fmt-dependent[8-15]= 0x%llX\n", sd->fmt_dependent_info[1]); ++ printf(" prog action code = 0x%X\n", sd->program_action_code); ++ printf(" Configuration info = 0x%X\n", sd->config_info); ++ printf(" mcode / hi-cyl = 0x%X\n", sd->mcode_hicyl); ++ printf(" cyl & head addr [0]= 0x%X\n", sd->cyl_head_addr[0]); ++ printf(" cyl & head addr [1]= 0x%X\n", sd->cyl_head_addr[1]); ++ printf(" cyl & head addr [2]= 0x%X\n", sd->cyl_head_addr[2]); + } + + static void print_irb_err(Irb *irb) +@@ -182,7 +182,7 @@ static void print_irb_err(Irb *irb) + uint64_t prev_ccw = *(uint64_t *)u32toptr(irb->scsw.cpa - 8); + char msgline[256]; + +- sclp_print("Interrupt Response Block Data:\n"); ++ puts("Interrupt Response Block Data:"); + + strcat(msgline, " Function Ctrl :"); + if (irb->scsw.ctrl & SCSW_FCTL_START_FUNC) { +@@ -194,8 +194,7 @@ static void print_irb_err(Irb *irb) + if (irb->scsw.ctrl & SCSW_FCTL_CLEAR_FUNC) { + strcat(msgline, " [Clear]"); + } +- strcat(msgline, "\n"); +- sclp_print(msgline); ++ puts(msgline); + + msgline[0] = '\0'; + strcat(msgline, " Activity Ctrl :"); +@@ -220,8 +219,7 @@ static void print_irb_err(Irb *irb) + if (irb->scsw.ctrl & SCSW_ACTL_SUSPENDED) { + strcat(msgline, " [Suspended]"); + } +- strcat(msgline, "\n"); +- sclp_print(msgline); ++ puts(msgline); + + msgline[0] = '\0'; + strcat(msgline, " Status Ctrl :"); +@@ -240,9 +238,7 @@ static void print_irb_err(Irb *irb) + if (irb->scsw.ctrl & SCSW_SCTL_STATUS_PEND) { + strcat(msgline, " [Status-Pending]"); + } +- +- strcat(msgline, "\n"); +- sclp_print(msgline); ++ puts(msgline); + + msgline[0] = '\0'; + strcat(msgline, " Device Status :"); +@@ -270,8 +266,7 @@ static void print_irb_err(Irb *irb) + if (irb->scsw.dstat & SCSW_DSTAT_UEXCP) { + strcat(msgline, " [Unit-Exception]"); + } +- strcat(msgline, "\n"); +- sclp_print(msgline); ++ puts(msgline); + + msgline[0] = '\0'; + strcat(msgline, " Channel Status :"); +@@ -299,12 +294,11 @@ static void print_irb_err(Irb *irb) + if (irb->scsw.cstat & SCSW_CSTAT_CHAINCHK) { + strcat(msgline, " [Chaining-Check]"); + } +- strcat(msgline, "\n"); +- sclp_print(msgline); ++ puts(msgline); + +- print_int(" cpa=", irb->scsw.cpa); +- print_int(" prev_ccw=", prev_ccw); +- print_int(" this_ccw=", this_ccw); ++ printf(" cpa= 0x%X\n", irb->scsw.cpa); ++ printf(" prev_ccw= 0x%llX\n", prev_ccw); ++ printf(" this_ccw= 0x%llX\n", this_ccw); + } + + /* +@@ -341,7 +335,7 @@ static int __do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt, Irb *irb) + return -1; + } + if (rc) { +- print_int("ssch failed with cc=", rc); ++ printf("ssch failed with cc= 0x%x\n", rc); + return rc; + } + +@@ -350,7 +344,7 @@ static int __do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt, Irb *irb) + /* collect status */ + rc = tsch(schid, irb); + if (rc) { +- print_int("tsch failed with cc=", rc); ++ printf("tsch failed with cc= 0x%X\n", rc); + } + + return rc; +@@ -406,12 +400,12 @@ int do_cio(SubChannelId schid, uint16_t cutype, uint32_t ccw_addr, int fmt) + continue; + } + +- sclp_print("cio device error\n"); +- print_int(" ssid ", schid.ssid); +- print_int(" cssid ", schid.cssid); +- print_int(" sch_no", schid.sch_no); +- print_int(" ctrl-unit type", cutype); +- sclp_print("\n"); ++ printf("cio device error\n"); ++ printf(" ssid 0x%X\n", schid.ssid); ++ printf(" cssid 0x%X\n", schid.cssid); ++ printf(" sch_no 0x%X\n", schid.sch_no); ++ printf(" ctrl-unit type 0x%X\n", cutype); ++ printf("\n"); + print_irb_err(&irb); + if (cutype == CU_TYPE_DASD_3990 || cutype == CU_TYPE_DASD_2107 || + cutype == CU_TYPE_UNKNOWN) { +diff --git a/pc-bios/s390-ccw/dasd-ipl.c b/pc-bios/s390-ccw/dasd-ipl.c +index 254bb1a15e..ae751adec1 100644 +--- a/pc-bios/s390-ccw/dasd-ipl.c ++++ b/pc-bios/s390-ccw/dasd-ipl.c +@@ -8,7 +8,8 @@ + * directory. + */ + +-#include "libc.h" ++#include ++#include + #include "s390-ccw.h" + #include "s390-arch.h" + #include "dasd-ipl.h" +@@ -82,7 +83,7 @@ static int run_dynamic_ccw_program(SubChannelId schid, uint16_t cutype, + do { + has_next = dynamic_cp_fixup(cpa, &next_cpa); + +- print_int("executing ccw chain at ", cpa); ++ printf("executing ccw chain at 0x%X\n", cpa); + enable_prefixing(); + rc = do_cio(schid, cutype, cpa, CCW_FMT0); + disable_prefixing(); +diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c +index 78f5f46533..80b7f6a1f3 100644 +--- a/pc-bios/s390-ccw/jump2ipl.c ++++ b/pc-bios/s390-ccw/jump2ipl.c +@@ -6,7 +6,8 @@ + * directory. + */ + +-#include "libc.h" ++#include ++#include + #include "s390-ccw.h" + #include "s390-arch.h" + +@@ -57,7 +58,7 @@ void jump_to_IPL_code(uint64_t address) + debug_print_int("set IPL addr to", address ?: *reset_psw & PSW_MASK_SHORT_ADDR); + + /* Ensure the guest output starts fresh */ +- sclp_print("\n"); ++ printf("\n"); + + /* + * HACK ALERT. +diff --git a/pc-bios/s390-ccw/libc.c b/pc-bios/s390-ccw/libc.c +deleted file mode 100644 +index 3187923950..0000000000 +--- a/pc-bios/s390-ccw/libc.c ++++ /dev/null +@@ -1,88 +0,0 @@ +-/* +- * libc-style definitions and functions +- * +- * Copyright 2018 IBM Corp. +- * Author(s): Collin L. Walling +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- */ +- +-#include "libc.h" +-#include "s390-ccw.h" +- +-/** +- * atoui: +- * @str: the string to be converted. +- * +- * Given a string @str, convert it to an integer. Leading spaces are +- * ignored. Any other non-numerical value will terminate the conversion +- * and return 0. This function only handles numbers between 0 and +- * UINT64_MAX inclusive. +- * +- * Returns: an integer converted from the string @str, or the number 0 +- * if an error occurred. +- */ +-uint64_t atoui(const char *str) +-{ +- int val = 0; +- +- if (!str || !str[0]) { +- return 0; +- } +- +- while (*str == ' ') { +- str++; +- } +- +- while (*str) { +- if (!isdigit(*(unsigned char *)str)) { +- break; +- } +- val = val * 10 + *str - '0'; +- str++; +- } +- +- return val; +-} +- +-/** +- * uitoa: +- * @num: an integer (base 10) to be converted. +- * @str: a pointer to a string to store the conversion. +- * @len: the length of the passed string. +- * +- * Given an integer @num, convert it to a string. The string @str must be +- * allocated beforehand. The resulting string will be null terminated and +- * returned. This function only handles numbers between 0 and UINT64_MAX +- * inclusive. +- * +- * Returns: the string @str of the converted integer @num +- */ +-char *uitoa(uint64_t num, char *str, size_t len) +-{ +- long num_idx = 1; /* account for NUL */ +- uint64_t tmp = num; +- +- IPL_assert(str != NULL, "uitoa: no space allocated to store string"); +- +- /* Count indices of num */ +- while ((tmp /= 10) != 0) { +- num_idx++; +- } +- +- /* Check if we have enough space for num and NUL */ +- IPL_assert(len > num_idx, "uitoa: array too small for conversion"); +- +- str[num_idx--] = '\0'; +- +- /* Convert int to string */ +- while (num_idx >= 0) { +- str[num_idx--] = num % 10 + '0'; +- num /= 10; +- } +- +- return str; +-} +diff --git a/pc-bios/s390-ccw/libc.h b/pc-bios/s390-ccw/libc.h +deleted file mode 100644 +index bcdc45732d..0000000000 +--- a/pc-bios/s390-ccw/libc.h ++++ /dev/null +@@ -1,89 +0,0 @@ +-/* +- * libc-style definitions and functions +- * +- * Copyright (c) 2013 Alexander Graf +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- */ +- +-#ifndef S390_CCW_LIBC_H +-#define S390_CCW_LIBC_H +- +-typedef unsigned long size_t; +-typedef int bool; +-typedef unsigned char uint8_t; +-typedef unsigned short uint16_t; +-typedef unsigned int uint32_t; +-typedef unsigned long long uint64_t; +- +-static inline void *memset(void *s, int c, size_t n) +-{ +- size_t i; +- unsigned char *p = s; +- +- for (i = 0; i < n; i++) { +- p[i] = c; +- } +- +- return s; +-} +- +-static inline void *memcpy(void *s1, const void *s2, size_t n) +-{ +- uint8_t *dest = s1; +- const uint8_t *src = s2; +- size_t i; +- +- for (i = 0; i < n; i++) { +- dest[i] = src[i]; +- } +- +- return s1; +-} +- +-static inline int memcmp(const void *s1, const void *s2, size_t n) +-{ +- size_t i; +- const uint8_t *p1 = s1, *p2 = s2; +- +- for (i = 0; i < n; i++) { +- if (p1[i] != p2[i]) { +- return p1[i] > p2[i] ? 1 : -1; +- } +- } +- +- return 0; +-} +- +-static inline size_t strlen(const char *str) +-{ +- size_t i; +- for (i = 0; *str; i++) { +- str++; +- } +- return i; +-} +- +-static inline char *strcat(char *dest, const char *src) +-{ +- int i; +- char *dest_end = dest + strlen(dest); +- +- for (i = 0; i <= strlen(src); i++) { +- dest_end[i] = src[i]; +- } +- return dest; +-} +- +-static inline int isdigit(int c) +-{ +- return (c >= '0') && (c <= '9'); +-} +- +-uint64_t atoui(const char *str); +-char *uitoa(uint64_t num, char *str, size_t len); +- +-#endif +diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c +index 5506798098..203df20965 100644 +--- a/pc-bios/s390-ccw/main.c ++++ b/pc-bios/s390-ccw/main.c +@@ -8,7 +8,9 @@ + * directory. + */ + +-#include "libc.h" ++#include ++#include ++#include + #include "helper.h" + #include "s390-arch.h" + #include "s390-ccw.h" +@@ -50,7 +52,7 @@ void write_iplb_location(void) + + unsigned int get_loadparm_index(void) + { +- return atoui(loadparm_str); ++ return atoi(loadparm_str); + } + + static int is_dev_possibly_bootable(int dev_no, int sch_no) +@@ -176,7 +178,7 @@ static void boot_setup(void) + + sclp_get_loadparm_ascii(loadparm_str); + memcpy(lpmsg + 10, loadparm_str, 8); +- sclp_print(lpmsg); ++ puts(lpmsg); + + /* + * Clear out any potential S390EP magic (see jump_to_low_kernel()), +@@ -228,7 +230,7 @@ static int virtio_setup(void) + + switch (vdev->senseid.cu_model) { + case VIRTIO_ID_NET: +- sclp_print("Network boot device detected\n"); ++ puts("Network boot device detected"); + vdev->netboot_start_addr = qipl.netboot_start_addr; + return 0; + case VIRTIO_ID_BLOCK: +@@ -261,7 +263,7 @@ static void ipl_boot_device(void) + } + break; + default: +- print_int("Attempting to boot from unexpected device type", cutype); ++ printf("Attempting to boot from unexpected device type 0x%X\n", cutype); + panic("\nBoot failed.\n"); + } + } +@@ -287,7 +289,7 @@ static void probe_boot_device(void) + } + } + +- sclp_print("Could not find a suitable boot device (none specified)\n"); ++ puts("Could not find a suitable boot device (none specified)"); + } + + void main(void) +diff --git a/pc-bios/s390-ccw/menu.c b/pc-bios/s390-ccw/menu.c +index d601952d3e..84062e94af 100644 +--- a/pc-bios/s390-ccw/menu.c ++++ b/pc-bios/s390-ccw/menu.c +@@ -9,7 +9,10 @@ + * directory. + */ + +-#include "libc.h" ++#include ++#include ++#include ++#include + #include "s390-ccw.h" + #include "sclp.h" + #include "s390-time.h" +@@ -93,7 +96,7 @@ static int read_prompt(char *buf, size_t len) + case KEYCODE_BACKSP: + if (idx > 0) { + buf[--idx] = 0; +- sclp_print("\b \b"); ++ printf("\b \b"); + } + continue; + case KEYCODE_ENTER: +@@ -103,7 +106,7 @@ static int read_prompt(char *buf, size_t len) + /* Echo input and add to buffer */ + if (idx < len) { + buf[idx++] = inp[0]; +- sclp_print(inp); ++ printf("%s", inp); + } + } + } +@@ -140,22 +143,19 @@ static int get_index(void) + } + } + +- return atoui(buf); ++ return atoi(buf); + } + + static void boot_menu_prompt(bool retry) + { +- char tmp[11]; +- + if (retry) { +- sclp_print("\nError: undefined configuration" ++ printf("\nError: undefined configuration" + "\nPlease choose:\n"); + } else if (timeout > 0) { +- sclp_print("Please choose (default will boot in "); +- sclp_print(uitoa(timeout / 1000, tmp, sizeof(tmp))); +- sclp_print(" seconds):\n"); ++ printf("Please choose (default will boot in %d seconds):\n", ++ (int)(timeout / 1000)); + } else { +- sclp_print("Please choose:\n"); ++ puts("Please choose:"); + } + } + +@@ -163,7 +163,6 @@ static int get_boot_index(bool *valid_entries) + { + int boot_index; + bool retry = false; +- char tmp[5]; + + do { + boot_menu_prompt(retry); +@@ -172,8 +171,7 @@ static int get_boot_index(bool *valid_entries) + } while (boot_index < 0 || boot_index >= MAX_BOOT_ENTRIES || + !valid_entries[boot_index]); + +- sclp_print("\nBooting entry #"); +- sclp_print(uitoa(boot_index, tmp, sizeof(tmp))); ++ printf("\nBooting entry #%d", boot_index); + + return boot_index; + } +@@ -187,9 +185,9 @@ static int zipl_print_entry(const char *data, size_t len) + buf[len] = '\n'; + buf[len + 1] = '\0'; + +- sclp_print(buf); ++ printf("%s", buf); + +- return buf[0] == ' ' ? atoui(buf + 1) : atoui(buf); ++ return buf[0] == ' ' ? atoi(buf + 1) : atoi(buf); + } + + int menu_get_zipl_boot_index(const char *menu_data) +@@ -209,7 +207,7 @@ int menu_get_zipl_boot_index(const char *menu_data) + } + + /* Print banner */ +- sclp_print("s390-ccw zIPL Boot Menu\n\n"); ++ puts("s390-ccw zIPL Boot Menu\n"); + menu_data += strlen(menu_data) + 1; + + /* Print entries */ +@@ -221,37 +219,34 @@ int menu_get_zipl_boot_index(const char *menu_data) + valid_entries[entry] = true; + + if (entry == 0) { +- sclp_print("\n"); ++ printf("\n"); + } + } + +- sclp_print("\n"); ++ printf("\n"); + return get_boot_index(valid_entries); + } + + int menu_get_enum_boot_index(bool *valid_entries) + { +- char tmp[3]; + int i; + +- sclp_print("s390-ccw Enumerated Boot Menu.\n\n"); ++ puts("s390-ccw Enumerated Boot Menu.\n"); + + for (i = 0; i < MAX_BOOT_ENTRIES; i++) { + if (valid_entries[i]) { + if (i < 10) { +- sclp_print(" "); ++ printf(" "); + } +- sclp_print("["); +- sclp_print(uitoa(i, tmp, sizeof(tmp))); +- sclp_print("]"); ++ printf("[%d]", i); + if (i == 0) { +- sclp_print(" default\n"); ++ printf(" default\n"); + } +- sclp_print("\n"); ++ printf("\n"); + } + } + +- sclp_print("\n"); ++ printf("\n"); + return get_boot_index(valid_entries); + } + +diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak +index 046aa35587..d2b3d8ee74 100644 +--- a/pc-bios/s390-ccw/netboot.mak ++++ b/pc-bios/s390-ccw/netboot.mak +@@ -1,9 +1,6 @@ + +-SLOF_DIR := $(SRC_PATH)/../../roms/SLOF +- + NETOBJS := start.o sclp.o cio.o virtio.o virtio-net.o jump2ipl.o netmain.o + +-LIBC_INC := -nostdinc -I$(SLOF_DIR)/lib/libc/include + LIBNET_INC := -I$(SLOF_DIR)/lib/libnet + + NETLDFLAGS := $(LDFLAGS) -Wl,-Ttext=0x7800000 +diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c +index 5cd619b2d6..509119be15 100644 +--- a/pc-bios/s390-ccw/netmain.c ++++ b/pc-bios/s390-ccw/netmain.c +@@ -293,7 +293,7 @@ static int load_kernel_with_initrd(filename_ip_t *fn_ip, + printf("Loading pxelinux.cfg entry '%s'\n", entry->label); + + if (!entry->kernel) { +- printf("Kernel entry is missing!\n"); ++ puts("Kernel entry is missing!\n"); + return -1; + } + +@@ -515,13 +515,13 @@ void main(void) + int rc, fnlen; + + sclp_setup(); +- sclp_print("Network boot starting...\n"); ++ puts("Network boot starting..."); + + virtio_setup(); + + rc = net_init(&fn_ip); + if (rc) { +- panic("Network initialization failed. Halting.\n"); ++ panic("Network initialization failed. Halting."); + } + + fnlen = strlen(fn_ip.filename); +@@ -535,9 +535,9 @@ void main(void) + net_release(&fn_ip); + + if (rc > 0) { +- sclp_print("Network loading done, starting kernel...\n"); ++ puts("Network loading done, starting kernel..."); + jump_to_low_kernel(); + } + +- panic("Failed to load OS from network\n"); ++ panic("Failed to load OS from network."); + } +diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h +index c977a52b50..6f6d95d170 100644 +--- a/pc-bios/s390-ccw/s390-ccw.h ++++ b/pc-bios/s390-ccw/s390-ccw.h +@@ -13,6 +13,11 @@ + + /* #define DEBUG */ + ++#include ++#include ++#include ++#include ++ + typedef unsigned char u8; + typedef unsigned short u16; + typedef unsigned int u32; +@@ -26,9 +31,6 @@ typedef unsigned long long u64; + #define EBUSY 2 + #define ENODEV 3 + +-#ifndef NULL +-#define NULL 0 +-#endif + #ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) + #endif +@@ -87,7 +89,7 @@ bool menu_is_enabled_enum(void); + __attribute__ ((__noreturn__)) + static inline void panic(const char *string) + { +- sclp_print(string); ++ printf("ERROR: %s\n ", string); + disabled_wait(); + } + +@@ -109,20 +111,10 @@ static inline void fill_hex_val(char *out, void *ptr, unsigned size) + } + } + +-static inline void print_int(const char *desc, u64 addr) +-{ +- char out[] = ": 0xffffffffffffffff\n"; +- +- fill_hex_val(&out[4], &addr, sizeof(addr)); +- +- sclp_print(desc); +- sclp_print(out); +-} +- + static inline void debug_print_int(const char *desc, u64 addr) + { + #ifdef DEBUG +- print_int(desc, addr); ++ printf("%s 0x%X\n", desc, addr); + #endif + } + +@@ -147,18 +139,14 @@ static inline void debug_print_addr(const char *desc, void *p) + static inline void IPL_assert(bool term, const char *message) + { + if (!term) { +- sclp_print("\n! "); +- sclp_print(message); +- panic(" !\n"); /* no return */ ++ panic(message); /* no return */ + } + } + + static inline void IPL_check(bool term, const char *message) + { + if (!term) { +- sclp_print("\n! WARNING: "); +- sclp_print(message); +- sclp_print(" !\n"); ++ printf("WARNING: %s\n", message); + } + } + +diff --git a/pc-bios/s390-ccw/sclp.c b/pc-bios/s390-ccw/sclp.c +index 7251f9af4d..4a07de018d 100644 +--- a/pc-bios/s390-ccw/sclp.c ++++ b/pc-bios/s390-ccw/sclp.c +@@ -8,7 +8,7 @@ + * directory. + */ + +-#include "libc.h" ++#include + #include "s390-ccw.h" + #include "sclp.h" + +@@ -101,11 +101,6 @@ long write(int fd, const void *str, size_t len) + return len; + } + +-void sclp_print(const char *str) +-{ +- write(1, str, strlen(str)); +-} +- + void sclp_get_loadparm_ascii(char *loadparm) + { + +diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c +index a81207b52e..2666326801 100644 +--- a/pc-bios/s390-ccw/virtio-blkdev.c ++++ b/pc-bios/s390-ccw/virtio-blkdev.c +@@ -8,7 +8,7 @@ + * directory. + */ + +-#include "libc.h" ++#include + #include "s390-ccw.h" + #include "virtio.h" + #include "virtio-scsi.h" +@@ -76,7 +76,7 @@ unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list + return -1; + } + +- sclp_print("."); ++ printf("."); + status = virtio_read_many(sec, (void *)addr, sec_num); + if (status) { + panic("I/O Error"); +@@ -230,7 +230,7 @@ int virtio_blk_setup_device(SubChannelId schid) + vdev->schid = schid; + virtio_setup_ccw(vdev); + +- sclp_print("Using virtio-blk.\n"); ++ puts("Using virtio-blk."); + + return 0; + } +diff --git a/pc-bios/s390-ccw/virtio-scsi.c b/pc-bios/s390-ccw/virtio-scsi.c +index d1a84b937c..6b4a1caf8a 100644 +--- a/pc-bios/s390-ccw/virtio-scsi.c ++++ b/pc-bios/s390-ccw/virtio-scsi.c +@@ -9,7 +9,8 @@ + * directory. + */ + +-#include "libc.h" ++#include ++#include + #include "s390-ccw.h" + #include "virtio.h" + #include "scsi.h" +@@ -30,9 +31,9 @@ static inline void vs_assert(bool term, const char **msgs) + if (!term) { + int i = 0; + +- sclp_print("\n! "); ++ printf("\n! "); + while (msgs[i]) { +- sclp_print(msgs[i++]); ++ printf("%s", msgs[i++]); + } + panic(" !\n"); + } +@@ -236,11 +237,11 @@ static int virtio_scsi_locate_device(VDev *vdev) + if (resp.response == VIRTIO_SCSI_S_BAD_TARGET) { + continue; + } +- print_int("target", target); ++ printf("target 0x%X\n", target); + virtio_scsi_verify_response(&resp, "SCSI cannot report LUNs"); + } + if (r->lun_list_len == 0) { +- print_int("no LUNs for target", target); ++ printf("no LUNs for target 0x%X\n", target); + continue; + } + luns = r->lun_list_len / 8; +@@ -264,7 +265,7 @@ static int virtio_scsi_locate_device(VDev *vdev) + } + } + +- sclp_print("Warning: Could not locate a usable virtio-scsi device\n"); ++ puts("Warning: Could not locate a usable virtio-scsi device"); + return -ENODEV; + } + +@@ -379,7 +380,7 @@ static int virtio_scsi_setup(VDev *vdev) + } + + if (virtio_scsi_inquiry_response_is_cdrom(scsi_inquiry_std_response)) { +- sclp_print("SCSI CD-ROM detected.\n"); ++ puts("SCSI CD-ROM detected."); + vdev->is_cdrom = true; + vdev->scsi_block_size = VIRTIO_ISO_BLOCK_SIZE; + } +@@ -443,7 +444,7 @@ int virtio_scsi_setup_device(SubChannelId schid) + IPL_assert(vdev->config.scsi.cdb_size == VIRTIO_SCSI_CDB_SIZE, + "Config: CDB size mismatch"); + +- sclp_print("Using virtio-scsi.\n"); ++ puts("Using virtio-scsi."); + + return virtio_scsi_setup(vdev); + } +diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c +index 5edd058d88..8c6b0a8a92 100644 +--- a/pc-bios/s390-ccw/virtio.c ++++ b/pc-bios/s390-ccw/virtio.c +@@ -8,7 +8,7 @@ + * directory. + */ + +-#include "libc.h" ++#include + #include "s390-ccw.h" + #include "cio.h" + #include "virtio.h" +diff --git a/tests/tcg/s390x/Makefile.softmmu-target b/tests/tcg/s390x/Makefile.softmmu-target +index f60f94b090..90964a2ccb 100644 +--- a/tests/tcg/s390x/Makefile.softmmu-target ++++ b/tests/tcg/s390x/Makefile.softmmu-target +@@ -2,7 +2,7 @@ S390X_SRC=$(SRC_PATH)/tests/tcg/s390x + VPATH+=$(S390X_SRC) + QEMU_OPTS+=-action panic=exit-failure -nographic $(EXTFLAGS) -kernel + LINK_SCRIPT=$(S390X_SRC)/softmmu.ld +-CFLAGS+=-ggdb -O0 ++CFLAGS+=-ggdb -O0 -I$(SRC_PATH)/include/hw/s390x/ipl/ + LDFLAGS=-nostdlib -static + + %.o: %.S +diff --git a/tests/tcg/s390x/console.c b/tests/tcg/s390x/console.c +index d43ce3f44b..6c26f04949 100644 +--- a/tests/tcg/s390x/console.c ++++ b/tests/tcg/s390x/console.c +@@ -4,7 +4,10 @@ + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ ++ + #include "../../../pc-bios/s390-ccw/sclp.c" ++#include "../../../roms/SLOF/lib/libc/string/memset.c" ++#include "../../../roms/SLOF/lib/libc/string/memcpy.c" + + void __sys_outc(char c) + { +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch b/SOURCES/kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch new file mode 100644 index 0000000..edf9dd9 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch @@ -0,0 +1,227 @@ +From 9facd91b090c8b63cb06da93c2b2ea51f26a3310 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-18-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(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 ++#include + + 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 + diff --git a/SOURCES/kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch b/SOURCES/kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch new file mode 100644 index 0000000..b14ddcd --- /dev/null +++ b/SOURCES/kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch @@ -0,0 +1,362 @@ +From 2cbfea2082fdb4b6687b1ee7ad31826dcae6e5ca Mon Sep 17 00:00:00 2001 +From: Jared Rossi +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-15-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(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 + diff --git a/SOURCES/kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch b/SOURCES/kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch new file mode 100644 index 0000000..11fa6c5 --- /dev/null +++ b/SOURCES/kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch @@ -0,0 +1,264 @@ +From ad587091d8716dbc118776b8edb61db12f6da122 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Acked-by: Thomas Huth +Message-ID: <20241020012953.1380075-17-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(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 + diff --git a/SOURCES/kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch b/SOURCES/kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch new file mode 100644 index 0000000..81565b3 --- /dev/null +++ b/SOURCES/kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch @@ -0,0 +1,56 @@ +From a246db2fbd892b572fced12da843628f1aab8cd2 Mon Sep 17 00:00:00 2001 +From: Tao Su +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 +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 +RH-Acked-by: Miroslav Rezanina +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 + +Signed-off-by: Paolo Bonzini +Reviewed-by: Zhao Liu +Tested-by: Xuelian Guo +Signed-off-by: Tao Su +Link: https://lore.kernel.org/r/20241031085233.425388-8-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 0d7475be3b402c25d74c5a4573cbeb733c8f3559) +Signed-off-by: Paolo Bonzini +--- + 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 + diff --git a/SOURCES/kvm-target-i386-Add-feature-dependencies-for-AVX10.patch b/SOURCES/kvm-target-i386-Add-feature-dependencies-for-AVX10.patch new file mode 100644 index 0000000..f116f49 --- /dev/null +++ b/SOURCES/kvm-target-i386-Add-feature-dependencies-for-AVX10.patch @@ -0,0 +1,89 @@ +From c44f6f57898eb9f382545201033586a17bbde83c Mon Sep 17 00:00:00 2001 +From: Tao Su +Date: Thu, 31 Oct 2024 16:52:31 +0800 +Subject: [PATCH 35/38] target/i386: Add feature dependencies for AVX10 + +RH-Author: Paolo Bonzini +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 +RH-Acked-by: Miroslav Rezanina +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 +Signed-off-by: Tao Su +Link: https://lore.kernel.org/r/20241028024512.156724-5-tao1.su@linux.intel.com +Reviewed-by: Zhao Liu +Signed-off-by: Paolo Bonzini +Link: https://lore.kernel.org/r/20241031085233.425388-7-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 150ab84b2d0083e6af344cca70290614d4fe568d) +Signed-off-by: Paolo Bonzini +--- + 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 + diff --git a/SOURCES/kvm-target-i386-Introduce-GraniteRapids-v2-model.patch b/SOURCES/kvm-target-i386-Introduce-GraniteRapids-v2-model.patch new file mode 100644 index 0000000..d9a94af --- /dev/null +++ b/SOURCES/kvm-target-i386-Introduce-GraniteRapids-v2-model.patch @@ -0,0 +1,59 @@ +From 32437dacd0f0d5076af2d549317b92432ee52abd Mon Sep 17 00:00:00 2001 +From: Tao Su +Date: Thu, 31 Oct 2024 16:52:33 +0800 +Subject: [PATCH 37/38] target/i386: Introduce GraniteRapids-v2 model + +RH-Author: Paolo Bonzini +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 +RH-Acked-by: Miroslav Rezanina +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 +Signed-off-by: Tao Su +Link: https://lore.kernel.org/r/20241028024512.156724-7-tao1.su@linux.intel.com +Reviewed-by: Zhao Liu +Signed-off-by: Paolo Bonzini +Link: https://lore.kernel.org/r/20241031085233.425388-9-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 1a519388a882fbb352e49cbebb0ed8f62d05842d) +Signed-off-by: Paolo Bonzini +--- + 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 + diff --git a/SOURCES/kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch b/SOURCES/kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch new file mode 100644 index 0000000..e60ecf4 --- /dev/null +++ b/SOURCES/kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch @@ -0,0 +1,224 @@ +From 704bfed342ca7cfbef44b639aadfeada1841b091 Mon Sep 17 00:00:00 2001 +From: Tao Su +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 +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 +RH-Acked-by: Miroslav Rezanina +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 +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 +Tested-by: Xuelian Guo +Link: https://lore.kernel.org/r/20241031085233.425388-5-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit bccfb846fd52d6f20704ecfa4d01b60b43c6f640) +Signed-off-by: Paolo Bonzini +--- + 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 + diff --git a/SOURCES/kvm-target-i386-add-CPUID.24-features-for-AVX10.patch b/SOURCES/kvm-target-i386-add-CPUID.24-features-for-AVX10.patch new file mode 100644 index 0000000..36a0aff --- /dev/null +++ b/SOURCES/kvm-target-i386-add-CPUID.24-features-for-AVX10.patch @@ -0,0 +1,91 @@ +From cfb4964556facf1cb4500f0e3a754e4e20c13aed Mon Sep 17 00:00:00 2001 +From: Tao Su +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 +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 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [5/9] a8b6f9edc330b412fbd27eece2f4961f4f876e5b (bonzini/rhel-qemu-kvm) + +Introduce features for the supported vector bit lengths. + +Signed-off-by: Tao Su +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 +Reviewed-by: Zhao Liu +Tested-by: Xuelian Guo +Link: https://lore.kernel.org/r/20241031085233.425388-6-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 2d055b8fe11ee567c2ae8047311fd83697e494b6) +Signed-off-by: Paolo Bonzini +--- + 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 + diff --git a/SOURCES/kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch b/SOURCES/kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch new file mode 100644 index 0000000..7f6c82a --- /dev/null +++ b/SOURCES/kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch @@ -0,0 +1,43 @@ +From d457fd42e0752855d8370bac1cf3c07cd1fc46a3 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +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 +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 +RH-Acked-by: Miroslav Rezanina +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 +Signed-off-by: Paolo Bonzini +--- + 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 + diff --git a/SOURCES/kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch b/SOURCES/kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch new file mode 100644 index 0000000..c385b88 --- /dev/null +++ b/SOURCES/kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch @@ -0,0 +1,50 @@ +From 2424960a48dfa6bb499c4cb798b0e5c256deba10 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +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 +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 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/9] 0516319354addebf36f9d364fbae5cda7a98473b (bonzini/rhel-qemu-kvm) + +Signed-off-by: Paolo Bonzini +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20241031085233.425388-2-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 33098002a838a0450f243f5e17463aca700e923d) +Signed-off-by: Paolo Bonzini +--- + 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 + diff --git a/SOURCES/kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch b/SOURCES/kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch new file mode 100644 index 0000000..73353ea --- /dev/null +++ b/SOURCES/kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch @@ -0,0 +1,117 @@ +From 6df46774aa41872a706f1a535d5c547a8ef73556 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +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 +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 +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20241031085233.425388-3-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit b888c7807049cc044d10d70139cb945202fb7cd2) +Signed-off-by: Paolo Bonzini +--- + 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 + diff --git a/SOURCES/kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch b/SOURCES/kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch new file mode 100644 index 0000000..ceff6b7 --- /dev/null +++ b/SOURCES/kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch @@ -0,0 +1,176 @@ +From 6bae9faff44415edf51bb7f919fc816f8fe3cd12 Mon Sep 17 00:00:00 2001 +From: Julia Suvorova +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 +RH-MergeRequest: 287: kvm: Allow kvm_arch_get/put_registers to accept Error** +RH-Jira: RHEL-20574 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Peter Xu +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 +Reviewed-by: Peter Xu +Link: https://lore.kernel.org/r/20240927104743.218468-3-jusual@redhat.com +Signed-off-by: Paolo Bonzini +(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 + diff --git a/SOURCES/kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch b/SOURCES/kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch new file mode 100644 index 0000000..e3defc5 --- /dev/null +++ b/SOURCES/kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch @@ -0,0 +1,83 @@ +From c4792fc23bf28618601514e3af5f331b4292bdf7 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +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 +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 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [3/9] e5ae5d2050ad75411d8db6f9f9519bcaf88c4850 (bonzini/rhel-qemu-kvm) + +Prepare for filtering non-boolean features such as AVX10 version. + +Signed-off-by: Paolo Bonzini +Reviewed-by: Zhao Liu +Signed-off-by: Tao Su +Link: https://lore.kernel.org/r/20241031085233.425388-4-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 3507c6f04606593711408a6d26141bdbceff9377) +Signed-off-by: Paolo Bonzini +--- + 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 + diff --git a/SOURCES/kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch b/SOURCES/kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch new file mode 100644 index 0000000..9e993ab --- /dev/null +++ b/SOURCES/kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch @@ -0,0 +1,74 @@ +From 8b3125e03d0b20987e1b0a963c24d38cb382f99c Mon Sep 17 00:00:00 2001 +From: Jared Rossi +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 +RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] +RH-Jira: RHEL-58153 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-20-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(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 + diff --git a/SOURCES/kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch b/SOURCES/kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch new file mode 100644 index 0000000..d0a5cdf --- /dev/null +++ b/SOURCES/kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch @@ -0,0 +1,70 @@ +From 85752ed0d3bdf707a9c84a12b8b717d932b882a6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= +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 +RH-MergeRequest: 283: vfio/migration: Report only stop-copy size in vfio_state_pending_exact() +RH-Jira: RHEL-64308 +RH-Acked-by: Peter Xu +RH-Acked-by: Alex Williamson +RH-Commit: [2/2] c4f7485b3ad4f779a2f13b6f09c9bb5712a45401 (clegoate/qemu-kvm-c9s) + +JIRA: https://issues.redhat.com/browse/RHEL-64308 + +commit fa4e20defe239e42af0a1b5c030dec114f799f56 +Author: Avihai Horon +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 + Reviewed-by: Cédric Le Goater + +Signed-off-by: Cédric Le Goater +--- + 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 + diff --git a/SOURCES/kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch b/SOURCES/kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch new file mode 100644 index 0000000..bb62e86 --- /dev/null +++ b/SOURCES/kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch @@ -0,0 +1,66 @@ +From d32c2291e836f912a72aedaf2ace31d4e1679f95 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= +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 +RH-MergeRequest: 283: vfio/migration: Report only stop-copy size in vfio_state_pending_exact() +RH-Jira: RHEL-64308 +RH-Acked-by: Peter Xu +RH-Acked-by: Alex Williamson +RH-Commit: [1/2] 85956ae33c6aea99dba95500595e0ca7dc9dcdad (clegoate/qemu-kvm-c9s) + +JIRA: https://issues.redhat.com/browse/RHEL-64308 + +commit 3b5948f808e3b99aedfa0aff45cffbe8b7ec07ed +Author: Avihai Horon +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 + Reviewed-by: Cédric Le Goater + +Signed-off-by: Cédric Le Goater +--- + 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 + diff --git a/SOURCES/kvm-vnc-fix-crash-when-no-console-attached.patch b/SOURCES/kvm-vnc-fix-crash-when-no-console-attached.patch new file mode 100644 index 0000000..0e9d1cc --- /dev/null +++ b/SOURCES/kvm-vnc-fix-crash-when-no-console-attached.patch @@ -0,0 +1,62 @@ +From 9e58f195620d723a2a0b609aa1c59d4938551835 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +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 +RH-MergeRequest: 279: vnc: fix crash when no console attached +RH-Jira: RHEL-50529 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Miroslav Rezanina +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=, keysym=) 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=) at ../ui/vnc.c:2070 + #4 protocol_client_msg (vs=0x5555579045c0, data=, len=) 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 +Reviewed-by: Akihiko Odaki +Reviewed-by: Michael Tokarev +Signed-off-by: Michael Tokarev + +(cherry picked from commit 0e60fc80938d9ce84274a36ddfaaa640bdef2be8) +Signed-off-by: Marc-André Lureau +--- + 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 + diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec index 74cb542..4d68979 100644 --- a/SPECS/qemu-kvm.spec +++ b/SPECS/qemu-kvm.spec @@ -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 - 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 - 18:9.1.0-3.1 - Bump release for October 2024 mass rebuild: Resolves: RHEL-64018