Update to 9.1.0-8

i10-beta changed/i10-beta/qemu-kvm-9.1.0-8.el10
Dmitry Samoylik 4 weeks ago
parent 03b08ac07f
commit bcedab4925

2
.gitignore vendored

@ -1 +1 @@
SOURCES/qemu-9.0.0.tar.xz
SOURCES/qemu-9.1.0.tar.xz

@ -1 +1 @@
6699bb03d6da21159b89668bca01c6c958b95d07 SOURCES/qemu-9.0.0.tar.xz
d5bcdca53341c29470ef323191a3388fdb0571ed SOURCES/qemu-9.1.0.tar.xz

@ -1,4 +1,4 @@
From 91262ecfbd218a95dab8491e4226674f79debf5a Mon Sep 17 00:00:00 2001
From 7e57931a524e1e805ba8d68e75828e98c591e975 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 26 May 2021 10:56:02 +0200
Subject: Initial redhat build
@ -13,25 +13,33 @@ several issues are fixed in QEMU tree:
We disable make check due to issues with some of the tests.
We are rebasing from qemu-kvm-9.0.0-8.el10.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase notes (9.1.0 rc0):
- Remove --disable-block-migration and --disable-pvrdma configure options (upstream)
- Removed --disable-avx512f configure option
- Removed qemu-vsmr-helper (changed upstream)
---
.distro/Makefile | 101 ++
.distro/Makefile.common | 42 +
.distro/README.tests | 39 +
.distro/modules-load.conf | 4 +
.distro/qemu-guest-agent.service | 1 -
.distro/qemu-kvm.spec.template | 1250 +++++++++++++++++++++++
.distro/qemu-kvm.spec.template | 1332 +++++++++++++++++++++++
.distro/rpminspect.yaml | 6 +-
.distro/scripts/extract_build_cmd.py | 12 +
.distro/scripts/frh.py | 4 +-
.distro/scripts/process-patches.sh | 4 +
.distro/scripts/process-patches.sh | 6 +-
.gitignore | 1 +
README.systemtap | 43 +
scripts/qemu-guest-agent/fsfreeze-hook | 2 +-
scripts/systemtap/conf.d/qemu_kvm.conf | 4 +
scripts/systemtap/script.d/qemu_kvm.stp | 1 +
ui/vnc-auth-sasl.c | 2 +-
16 files changed, 1510 insertions(+), 6 deletions(-)
16 files changed, 1593 insertions(+), 7 deletions(-)
create mode 100644 .distro/Makefile
create mode 100644 .distro/Makefile.common
create mode 100644 .distro/README.tests

@ -1,4 +1,4 @@
From 8e767ade83e18995692d3554b6b71c9e15b51d89 Mon Sep 17 00:00:00 2001
From 003f37e17fb03b8977effd968426a0aeb5855028 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 7 Dec 2022 03:05:48 -0500
Subject: Enable/disable devices for RHEL
@ -6,18 +6,45 @@ Subject: Enable/disable devices for RHEL
This commit adds all changes related to changes in supported devices.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase notes (9.1.0 rc0):
- Return value added for kvm_s390_apply_cpu_model
- Added new USB_HID and USB_HUB options
Rebase notes (9.1.0 rc1):
- Fixing valid_cpu_types preprocessing
Rebase notes (9.1.0 rc4):
- Moved x86 cpu deprecation from x86 machine type patch
- Removed unnecessary chunk in cirrus_vga.c
- Not needed hack removal of cpu-v7m.c from build
Rebase notes (9.1.0):
- Remove ppc64 device configuration
- Remove unnecessary chunks
- Removed CONFIG_VHOST_USER_SCMI and CONFIG_VHOST_USER_SND from some archs
Merged commits (9.1.0 rc0):
- f24c7a1fee Disable FDC devices
- fe8c6cb1ce Disable vga-cirrus device
- fccd117a12 Enable vhost-user-snd-pci device
- c0b40cc648 target/cpu-models/x86: Remove the existing deprecated CPU models on c10s
- ce42b3da0e x86/cpu: deprecate cpu models that do not support x86-64-v3
- 01ffa96c3b target/s390x/cpu_models: Disable everything up to the z12 CPU model
- cd57d17e3c target/s390x: Revert the old s390x CPU model disablement code
- 42af7b3ad5 Enable vhost-user-scmi devices
Merged commits (9.1.0 rc4):
- aa374ce5ea x86/cpu: update deprecation string to match lowest undeprecated model
---
.distro/qemu-kvm.spec.template | 18 +--
.../aarch64-softmmu/aarch64-rh-devices.mak | 42 +++++++
.../ppc64-softmmu/ppc64-rh-devices.mak | 37 ++++++
.distro/qemu-kvm.spec.template | 20 +--
.../aarch64-softmmu/aarch64-rh-devices.mak | 46 +++++++
configs/devices/rh-virtio.mak | 10 ++
.../s390x-softmmu/s390x-rh-devices.mak | 19 +++
.../x86_64-softmmu/x86_64-rh-devices.mak | 112 ++++++++++++++++++
hw/arm/virt.c | 2 +
hw/block/fdc.c | 10 ++
hw/cpu/meson.build | 3 +-
.../x86_64-softmmu/x86_64-rh-devices.mak | 114 ++++++++++++++++++
hw/arm/virt.c | 4 +
hw/cxl/meson.build | 3 +-
hw/display/cirrus_vga.c | 4 +
hw/ide/piix.c | 5 +-
hw/input/pckbd.c | 2 +
hw/net/e1000.c | 2 +
@ -30,22 +57,21 @@ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
target/arm/tcg/cpu32.c | 2 +
target/arm/tcg/cpu64.c | 8 ++
target/arm/tcg/meson.build | 2 +-
target/s390x/cpu_models_sysemu.c | 3 +
target/s390x/kvm/kvm.c | 8 ++
target/i386/cpu.c | 19 +++
target/s390x/cpu_models.c | 2 +-
tests/qtest/arm-cpu-features.c | 4 +
26 files changed, 309 insertions(+), 16 deletions(-)
22 files changed, 275 insertions(+), 16 deletions(-)
create mode 100644 configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
create mode 100644 configs/devices/ppc64-softmmu/ppc64-rh-devices.mak
create mode 100644 configs/devices/rh-virtio.mak
create mode 100644 configs/devices/s390x-softmmu/s390x-rh-devices.mak
create mode 100644 configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
diff --git a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
new file mode 100644
index 0000000000..b0191d3c69
index 0000000000..58075e2812
--- /dev/null
+++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
@@ -0,0 +1,42 @@
@@ -0,0 +1,46 @@
+include ../rh-virtio.mak
+
+CONFIG_ARM_GIC_KVM=y
@ -68,6 +94,8 @@ index 0000000000..b0191d3c69
+CONFIG_USB_XHCI_PCI=y
+CONFIG_USB_STORAGE_CORE=y
+CONFIG_USB_STORAGE_CLASSIC=y
+CONFIG_USB_HUB=y
+CONFIG_USB_HID=y
+CONFIG_VFIO=y
+CONFIG_VFIO_PCI=y
+CONFIG_VIRTIO_MMIO=y
@ -88,49 +116,8 @@ index 0000000000..b0191d3c69
+CONFIG_VHOST_USER_VSOCK=y
+CONFIG_VHOST_USER_FS=y
+CONFIG_IOMMUFD=y
diff --git a/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak b/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak
new file mode 100644
index 0000000000..dbb7d30829
--- /dev/null
+++ b/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak
@@ -0,0 +1,37 @@
+include ../rh-virtio.mak
+
+CONFIG_DIMM=y
+CONFIG_MEM_DEVICE=y
+CONFIG_NVDIMM=y
+CONFIG_PCI=y
+CONFIG_PCI_DEVICES=y
+CONFIG_PCI_TESTDEV=y
+CONFIG_PCI_EXPRESS=y
+CONFIG_PSERIES=y
+CONFIG_SCSI=y
+CONFIG_SPAPR_VSCSI=y
+CONFIG_TEST_DEVICES=y
+CONFIG_USB=y
+CONFIG_USB_OHCI=y
+CONFIG_USB_OHCI_PCI=y
+CONFIG_USB_SMARTCARD=y
+CONFIG_USB_STORAGE_CORE=y
+CONFIG_USB_STORAGE_CLASSIC=y
+CONFIG_USB_XHCI=y
+CONFIG_USB_XHCI_NEC=y
+CONFIG_USB_XHCI_PCI=y
+CONFIG_VFIO=y
+CONFIG_VFIO_PCI=y
+CONFIG_VGA=y
+CONFIG_VGA_PCI=y
+CONFIG_VHOST_USER=y
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_VGA=y
+CONFIG_WDT_IB6300ESB=y
+CONFIG_XICS=y
+CONFIG_XIVE=y
+CONFIG_TPM=y
+CONFIG_TPM_SPAPR=y
+CONFIG_TPM_EMULATOR=y
+CONFIG_VHOST_VSOCK=y
+CONFIG_VHOST_USER_VSOCK=y
+CONFIG_VHOST_USER_SND=y
+CONFIG_VHOST_USER_SCMI=y
diff --git a/configs/devices/rh-virtio.mak b/configs/devices/rh-virtio.mak
new file mode 100644
index 0000000000..94ede1b5f6
@ -174,10 +161,10 @@ index 0000000000..24cf6dbd03
+CONFIG_IOMMUFD=y
diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
new file mode 100644
index 0000000000..d60ff1bcfc
index 0000000000..45a8a15291
--- /dev/null
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
@@ -0,0 +1,112 @@
@@ -0,0 +1,114 @@
+include ../rh-virtio.mak
+
+CONFIG_ACPI=y
@ -199,9 +186,9 @@ index 0000000000..d60ff1bcfc
+CONFIG_E1000E_PCI_EXPRESS=y
+CONFIG_E1000_PCI=y
+CONFIG_EDU=y
+CONFIG_FDC=y
+CONFIG_FDC_SYSBUS=y
+CONFIG_FDC_ISA=y
+#CONFIG_FDC=y
+#CONFIG_FDC_SYSBUS=y
+#CONFIG_FDC_ISA=y
+CONFIG_FW_CFG_DMA=y
+CONFIG_HDA=y
+CONFIG_HYPERV=y
@ -264,10 +251,11 @@ index 0000000000..d60ff1bcfc
+CONFIG_USB_XHCI=y
+CONFIG_USB_XHCI_NEC=y
+CONFIG_USB_XHCI_PCI=y
+CONFIG_USB_HUB=y
+CONFIG_USB_HID=y
+CONFIG_VFIO=y
+CONFIG_VFIO_PCI=y
+CONFIG_VGA=y
+CONFIG_VGA_CIRRUS=y
+CONFIG_VGA_PCI=y
+CONFIG_VHOST_USER=y
+CONFIG_VHOST_USER_BLK=y
@ -290,11 +278,12 @@ index 0000000000..d60ff1bcfc
+CONFIG_VHOST_USER_VSOCK=y
+CONFIG_VHOST_USER_FS=y
+CONFIG_IOMMUFD=y
+CONFIG_VHOST_USER_SND=y
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index a9a913aead..6c6d155002 100644
index 687fe0bb8b..eea7d2d038 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2954,6 +2954,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
@@ -3032,6 +3032,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
MachineClass *mc = MACHINE_CLASS(oc);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
static const char * const valid_cpu_types[] = {
@ -302,53 +291,18 @@ index a9a913aead..6c6d155002 100644
#ifdef CONFIG_TCG
ARM_CPU_TYPE_NAME("cortex-a7"),
ARM_CPU_TYPE_NAME("cortex-a15"),
@@ -2971,6 +2972,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
@@ -3047,8 +3048,11 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
ARM_CPU_TYPE_NAME("neoverse-n2"),
#endif /* TARGET_AARCH64 */
#endif /* CONFIG_TCG */
+#endif /* disabled for RHEL */
#ifdef TARGET_AARCH64
+#if 0 /* Disabled for Red Hat Enterprise Linux */
ARM_CPU_TYPE_NAME("cortex-a53"),
+#endif /* disabled for RHEL */
ARM_CPU_TYPE_NAME("cortex-a57"),
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
ARM_CPU_TYPE_NAME("host"),
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 6dd94e98bc..a05757fc9a 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -49,6 +49,8 @@
#include "qom/object.h"
#include "fdc-internal.h"
+#include "hw/boards.h"
+
/********************************************************/
/* debug Floppy devices */
@@ -2346,6 +2348,14 @@ void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl, Error **errp)
FDrive *drive;
static int command_tables_inited = 0;
+ /* Restricted for Red Hat Enterprise Linux: */
+ MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
+ if (!strstr(mc->name, "-rhel7.")) {
+ error_setg(errp, "Device %s is not supported with machine type %s",
+ object_get_typename(OBJECT(dev)), mc->name);
+ return;
+ }
+
if (fdctrl->fallback == FLOPPY_DRIVE_TYPE_AUTO) {
error_setg(errp, "Cannot choose a fallback FDrive type of 'auto'");
return;
diff --git a/hw/cpu/meson.build b/hw/cpu/meson.build
index 38cdcfbe57..e588ecfd42 100644
--- a/hw/cpu/meson.build
+++ b/hw/cpu/meson.build
@@ -1,4 +1,5 @@
-system_ss.add(files('core.c', 'cluster.c'))
+#system_ss.add(files('core.c', 'cluster.c'))
+system_ss.add(files('core.c'))
system_ss.add(when: 'CONFIG_ARM11MPCORE', if_true: files('arm11mpcore.c'))
system_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview_mpcore.c'))
diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build
index 3e375f61a9..613adb3ebb 100644
--- a/hw/cxl/meson.build
@ -363,28 +317,6 @@ index 3e375f61a9..613adb3ebb 100644
),
if_false: files(
'cxl-host-stubs.c',
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index 150883a971..497365bd80 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -36,6 +36,7 @@
#include "qemu/module.h"
#include "qemu/units.h"
#include "qemu/log.h"
+#include "qemu/error-report.h"
#include "sysemu/reset.h"
#include "qapi/error.h"
#include "trace.h"
@@ -2946,6 +2947,9 @@ static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp)
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
int16_t device_id = pc->device_id;
+ warn_report("'cirrus-vga' is deprecated, "
+ "please use a different VGA card instead");
+
/*
* Follow real hardware, cirrus card emulated has 4 MB video memory.
* Also accept 8 MB/16 MB for backward compatibility.
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 80efc633d3..9cb82b8eea 100644
--- a/hw/ide/piix.c
@ -422,7 +354,7 @@ index 74f10b640f..2e85ecf476 100644
static const TypeInfo i8042_info = {
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 43f3a4a701..267f182883 100644
index 5012b96464..b435e54228 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1746,6 +1746,7 @@ static const E1000Info e1000_devices[] = {
@ -442,7 +374,7 @@ index 43f3a4a701..267f182883 100644
static void e1000_register_types(void)
diff --git a/hw/usb/meson.build b/hw/usb/meson.build
index aac3bb35f2..5411ff35df 100644
index d7de1003e3..1cdc0a1ba0 100644
--- a/hw/usb/meson.build
+++ b/hw/usb/meson.build
@@ -55,7 +55,7 @@ system_ss.add(when: 'CONFIG_USB_SMARTCARD', if_true: files('dev-smartcard-reader
@ -455,7 +387,7 @@ index aac3bb35f2..5411ff35df 100644
endif
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index d7f18c96e6..aaabbb8b0b 100644
index 621fc65454..c38bdd6fa4 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -20,7 +20,8 @@ if have_vhost
@ -499,10 +431,10 @@ index 3cc8cc738b..6f21fea1f5 100644
QAPI_LIST_PREPEND(*cpu_list, info);
}
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index ab8d007a86..e5dce20f19 100644
index 19191c2391..465f423d25 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2546,6 +2546,10 @@ static void cpu_register_class_init(ObjectClass *oc, void *data)
@@ -2726,6 +2726,10 @@ static void cpu_register_class_init(ObjectClass *oc, void *data)
acc->info = data;
cc->gdb_core_xml_file = "arm-core.xml";
@ -514,10 +446,10 @@ index ab8d007a86..e5dce20f19 100644
void arm_cpu_register(const ARMCPUInfo *info)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index bc0c84873f..e9472c8bb8 100644
index 9a3fd59562..1261eae94d 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -37,6 +37,8 @@
@@ -35,6 +35,8 @@
#define KVM_HAVE_MCE_INJECTION 1
#endif
@ -526,7 +458,7 @@ index bc0c84873f..e9472c8bb8 100644
#define EXCP_UDEF 1 /* undefined instruction */
#define EXCP_SWI 2 /* software interrupt */
#define EXCP_PREFETCH_ABORT 3
@@ -1092,6 +1094,7 @@ typedef struct ARMCPUInfo {
@@ -1110,6 +1112,7 @@ typedef struct ARMCPUInfo {
const char *name;
void (*initfn)(Object *obj);
void (*class_init)(ObjectClass *oc, void *data);
@ -535,10 +467,10 @@ index bc0c84873f..e9472c8bb8 100644
/**
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 985b1efe16..46a4e80171 100644
index 262a1d6c0b..800514d3fc 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -648,6 +648,7 @@ static void aarch64_a57_initfn(Object *obj)
@@ -653,6 +653,7 @@ static void aarch64_a57_initfn(Object *obj)
define_cortex_a72_a57_a53_cp_reginfo(cpu);
}
@ -546,7 +478,7 @@ index 985b1efe16..46a4e80171 100644
static void aarch64_a53_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
@@ -704,6 +705,7 @@ static void aarch64_a53_initfn(Object *obj)
@@ -710,6 +711,7 @@ static void aarch64_a53_initfn(Object *obj)
cpu->gic_pribits = 5;
define_cortex_a72_a57_a53_cp_reginfo(cpu);
}
@ -554,7 +486,7 @@ index 985b1efe16..46a4e80171 100644
static void aarch64_host_initfn(Object *obj)
{
@@ -742,8 +744,11 @@ static void aarch64_max_initfn(Object *obj)
@@ -748,8 +750,11 @@ static void aarch64_max_initfn(Object *obj)
}
static const ARMCPUInfo aarch64_cpus[] = {
@ -567,7 +499,7 @@ index 985b1efe16..46a4e80171 100644
{ .name = "max", .initfn = aarch64_max_initfn },
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
{ .name = "host", .initfn = aarch64_host_initfn },
@@ -814,8 +819,13 @@ static void aarch64_cpu_instance_init(Object *obj)
@@ -820,8 +825,13 @@ static void aarch64_cpu_instance_init(Object *obj)
static void cpu_register_class_init(ObjectClass *oc, void *data)
{
ARMCPUClass *acc = ARM_CPU_CLASS(oc);
@ -582,10 +514,10 @@ index 985b1efe16..46a4e80171 100644
void aarch64_cpu_register(const ARMCPUInfo *info)
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
index de8f2be941..8896295ae3 100644
index 20c2737f17..7e66fb6f14 100644
--- a/target/arm/tcg/cpu32.c
+++ b/target/arm/tcg/cpu32.c
@@ -92,6 +92,7 @@ void aa32_max_features(ARMCPU *cpu)
@@ -120,6 +120,7 @@ void aa32_max_features(ARMCPU *cpu)
cpu->isar.id_dfr1 = t;
}
@ -593,13 +525,13 @@ index de8f2be941..8896295ae3 100644
/* CPU models. These are not needed for the AArch64 linux-user build. */
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
@@ -1037,3 +1038,4 @@ static void arm_tcg_cpu_register_types(void)
@@ -1066,3 +1067,4 @@ static void arm_tcg_cpu_register_types(void)
type_init(arm_tcg_cpu_register_types)
#endif /* !CONFIG_USER_ONLY || !TARGET_AARCH64 */
+#endif /* disabled for RHEL */
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 9f7a9f3d2c..7ec6851c9c 100644
index fe232eb306..2678047488 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -29,6 +29,7 @@
@ -610,7 +542,7 @@ index 9f7a9f3d2c..7ec6851c9c 100644
static uint64_t make_ccsidr64(unsigned assoc, unsigned linesize,
unsigned cachesize)
{
@@ -134,6 +135,7 @@ static void aarch64_a35_initfn(Object *obj)
@@ -135,6 +136,7 @@ static void aarch64_a35_initfn(Object *obj)
/* These values are the same with A53/A57/A72. */
define_cortex_a72_a57_a53_cp_reginfo(cpu);
}
@ -618,7 +550,7 @@ index 9f7a9f3d2c..7ec6851c9c 100644
static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
@@ -223,6 +225,7 @@ static void cpu_max_get_l0gptsz(Object *obj, Visitor *v, const char *name,
@@ -224,6 +226,7 @@ static void cpu_max_get_l0gptsz(Object *obj, Visitor *v, const char *name,
static Property arm_cpu_lpa2_property =
DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true);
@ -626,7 +558,7 @@ index 9f7a9f3d2c..7ec6851c9c 100644
static void aarch64_a55_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
@@ -1065,6 +1068,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
@@ -1074,6 +1077,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
aarch64_add_pauth_properties(obj);
aarch64_add_sve_properties(obj);
}
@ -634,7 +566,7 @@ index 9f7a9f3d2c..7ec6851c9c 100644
/*
* -cpu max: a CPU with as many features enabled as our emulation supports.
@@ -1271,6 +1275,7 @@ void aarch64_max_tcg_initfn(Object *obj)
@@ -1295,6 +1299,7 @@ void aarch64_max_tcg_initfn(Object *obj)
qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
}
@ -642,7 +574,7 @@ index 9f7a9f3d2c..7ec6851c9c 100644
static const ARMCPUInfo aarch64_cpus[] = {
{ .name = "cortex-a35", .initfn = aarch64_a35_initfn },
{ .name = "cortex-a55", .initfn = aarch64_a55_initfn },
@@ -1282,14 +1287,17 @@ static const ARMCPUInfo aarch64_cpus[] = {
@@ -1306,14 +1311,17 @@ static const ARMCPUInfo aarch64_cpus[] = {
{ .name = "neoverse-v1", .initfn = aarch64_neoverse_v1_initfn },
{ .name = "neoverse-n2", .initfn = aarch64_neoverse_n2_initfn },
};
@ -661,51 +593,161 @@ index 9f7a9f3d2c..7ec6851c9c 100644
type_init(aarch64_cpu_register_types)
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
index 3b1a9f0fc5..6c95d99181 100644
index 508932a249..1293647501 100644
--- a/target/arm/tcg/meson.build
+++ b/target/arm/tcg/meson.build
@@ -56,5 +56,5 @@ arm_system_ss.add(files(
@@ -58,5 +58,5 @@ arm_system_ss.add(files(
'psci.c',
))
-arm_system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('cpu-v7m.c'))
+#arm_system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('cpu-v7m.c'))
arm_user_ss.add(when: 'TARGET_AARCH64', if_false: files('cpu-v7m.c'))
diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c
index 2d99218069..0728bfcc20 100644
--- a/target/s390x/cpu_models_sysemu.c
+++ b/target/s390x/cpu_models_sysemu.c
@@ -34,6 +34,9 @@ static void check_unavailable_features(const S390CPUModel *max_model,
(max_model->def->gen == model->def->gen &&
max_model->def->ec_ga < model->def->ec_ga)) {
list_add_feat("type", unavailable);
+ } else if (model->def->gen < 11 && kvm_enabled()) {
+ /* Older CPU models are not supported on Red Hat Enterprise Linux */
+ list_add_feat("type", unavailable);
}
/* detect missing features if any to properly report them */
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index 4ce809c5d4..55fb4855b1 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -2565,6 +2565,14 @@ void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp)
error_setg(errp, "KVM doesn't support CPU models");
return;
}
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 85ef7452c0..34e0ce5e62 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2411,9 +2411,13 @@ static const CPUCaches epyc_genoa_cache_info = {
* PT in VMX operation
*/
+#define RHEL_CPU_DEPRECATION \
+ "use at least 'Haswell' / 'EPYC', or 'host' / 'max'"
+
+ /* Older CPU models are not supported on Red Hat Enterprise Linux */
+ if (model->def->gen < 11) {
+ error_setg(errp, "KVM: Unsupported CPU type specified: %s",
+ MACHINE(qdev_get_machine())->cpu_type);
+ return;
+ }
+
prop.cpuid = s390_cpuid_from_cpu_model(model);
prop.ibc = s390_ibc_from_cpu_model(model);
/* configure cpu features indicated via STFL(e) */
static const X86CPUDefinition builtin_x86_defs[] = {
{
.name = "qemu64",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 0xd,
.vendor = CPUID_VENDOR_AMD,
.family = 15,
@@ -2432,6 +2436,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x8000000A,
.model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
},
+#if 0 // Deprecated CPU models are removed in RHEL-10
{
.name = "phenom",
.level = 5,
@@ -2796,8 +2801,10 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
},
+#endif // Removal of deprecated CPU models in RHEL-10
{
.name = "Nehalem",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 11,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2875,6 +2882,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Westmere",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 11,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2956,6 +2964,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "SandyBridge",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -3042,6 +3051,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "IvyBridge",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -4469,6 +4479,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Denverton",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 21,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -4579,6 +4590,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Snowridge",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 27,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -4760,8 +4772,10 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Intel Xeon Phi Processor (Knights Mill)",
},
+#if 0 // Deprecated CPU models are removed in RHEL-10
{
.name = "Opteron_G1",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 15,
@@ -4782,6 +4796,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Opteron_G2",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 15,
@@ -4804,6 +4819,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Opteron_G3",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 16,
@@ -4827,8 +4843,10 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
},
+#endif
{
.name = "Opteron_G4",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 0xd,
.vendor = CPUID_VENDOR_AMD,
.family = 21,
@@ -4861,6 +4879,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Opteron_G5",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 0xd,
.vendor = CPUID_VENDOR_AMD,
.family = 21,
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index a27f4b6f79..798c18f940 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -72,7 +72,6 @@ static S390CPUDef s390_cpu_defs[] = {
CPUDEF_INIT(0x2096, 9, 2, 40, 0x00000000U, "z9BC", "IBM System z9 BC GA1"),
CPUDEF_INIT(0x2094, 9, 3, 40, 0x00000000U, "z9EC.3", "IBM System z9 EC GA3"),
CPUDEF_INIT(0x2096, 9, 3, 40, 0x00000000U, "z9BC.2", "IBM System z9 BC GA2"),
-#endif
CPUDEF_INIT(0x2097, 10, 1, 43, 0x00000000U, "z10EC", "IBM System z10 EC GA1"),
CPUDEF_INIT(0x2097, 10, 2, 43, 0x00000000U, "z10EC.2", "IBM System z10 EC GA2"),
CPUDEF_INIT(0x2098, 10, 2, 43, 0x00000000U, "z10BC", "IBM System z10 BC GA1"),
@@ -81,6 +80,7 @@ static S390CPUDef s390_cpu_defs[] = {
CPUDEF_INIT(0x2817, 11, 1, 44, 0x08000000U, "z196", "IBM zEnterprise 196 GA1"),
CPUDEF_INIT(0x2817, 11, 2, 44, 0x08000000U, "z196.2", "IBM zEnterprise 196 GA2"),
CPUDEF_INIT(0x2818, 11, 2, 44, 0x08000000U, "z114", "IBM zEnterprise 114 GA1"),
+#endif
CPUDEF_INIT(0x2827, 12, 1, 44, 0x08000000U, "zEC12", "IBM zEnterprise EC12 GA1"),
CPUDEF_INIT(0x2827, 12, 2, 44, 0x08000000U, "zEC12.2", "IBM zEnterprise EC12 GA2"),
CPUDEF_INIT(0x2828, 12, 2, 44, 0x08000000U, "zBC12", "IBM zEnterprise BC12 GA1"),
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
index 9d6e6190d5..f822526acb 100644
index cfd6f77353..3016e6233c 100644
--- a/tests/qtest/arm-cpu-features.c
+++ b/tests/qtest/arm-cpu-features.c
@@ -452,8 +452,10 @@ static void test_query_cpu_model_expansion(const void *data)

@ -1,4 +1,4 @@
From 802da738d5231ef56d25f4ffcfa6e7d97698ee72 Mon Sep 17 00:00:00 2001
From 18ae40658bedd6dceab0ffe0bce77ba48e6f0fae Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Fri, 11 Jan 2019 09:54:45 +0100
Subject: Machine type related general changes
@ -8,10 +8,18 @@ split to allow easier review. It contains changes not related to any
architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase notes (9.1.0 rc0):
- Upstream removed uuid_encoced argument on smbios_set_defaults
Merged commits (9.1.0 rc0):
- 043ad5ce97 Add upstream compatibility bits (partial)
- bfbdab5824 rhel 9.4.0 machine type compat for virtio-gpu migration
---
hw/acpi/piix4.c | 2 +-
hw/arm/virt.c | 2 +-
hw/core/machine.c | 269 +++++++++++++++++++++++++++++++++++
hw/arm/virt.c | 3 +-
hw/core/machine.c | 281 +++++++++++++++++++++++++++++++++++
hw/i386/fw_cfg.c | 3 +-
hw/net/rtl8139.c | 4 +-
hw/smbios/smbios.c | 46 +++++-
@ -19,10 +27,10 @@ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
hw/usb/hcd-xhci-pci.c | 59 ++++++--
hw/usb/hcd-xhci-pci.h | 1 +
hw/virtio/virtio-mem.c | 3 +-
include/hw/boards.h | 40 ++++++
include/hw/boards.h | 43 ++++++
include/hw/firmware/smbios.h | 4 +-
include/hw/i386/pc.h | 3 +
13 files changed, 414 insertions(+), 24 deletions(-)
13 files changed, 430 insertions(+), 24 deletions(-)
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index debe1adb84..e8ddcd716e 100644
@ -38,23 +46,24 @@ index debe1adb84..e8ddcd716e 100644
.fields = (const VMStateField[]) {
VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState),
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 6c6d155002..36e9b4b4e9 100644
index eea7d2d038..b2aa3f1355 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1651,7 +1651,7 @@ static void virt_build_smbios(VirtMachineState *vms)
@@ -1699,7 +1699,8 @@ static void virt_build_smbios(VirtMachineState *vms)
}
smbios_set_defaults("QEMU", product,
vmc->smbios_old_sys_ver ? "1.0" : mc->name,
- true);
+ true, NULL, NULL);
- vmc->smbios_old_sys_ver ? "1.0" : mc->name);
+ vmc->smbios_old_sys_ver ? "1.0" : mc->name,
+ NULL, NULL);
/* build the array of physical mem area from base_memmap */
mem_array.address = vms->memmap[VIRT_MEM].base;
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 37ede0e7d4..695cb89a46 100644
index 27dcda0248..f7fed78e4b 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -296,6 +296,275 @@ GlobalProperty hw_compat_2_1[] = {
@@ -305,6 +305,287 @@ GlobalProperty hw_compat_2_1[] = {
};
const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
@ -64,6 +73,18 @@ index 37ede0e7d4..695cb89a46 100644
+const char *rhel_old_machine_deprecation =
+ "machine types for previous major releases are deprecated";
+
+GlobalProperty hw_compat_rhel_9_5[] = {
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { "migration", "zero-page-detection", "legacy"},
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { TYPE_VIRTIO_IOMMU_PCI, "granule", "4k" },
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" },
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { "virtio-gpu-device", "x-scanout-vmstate-version", "1" },
+};
+const size_t hw_compat_rhel_9_5_len = G_N_ELEMENTS(hw_compat_rhel_9_5);
+
+GlobalProperty hw_compat_rhel_9_4[] = {
+ /* hw_compat_rhel_9_4 from hw_compat_8_0 */
+ { TYPE_VIRTIO_NET, "host_uso", "off"},
@ -331,24 +352,24 @@ index 37ede0e7d4..695cb89a46 100644
static char *machine_get_kernel(Object *obj, Error **errp)
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index d802d2787f..c7aa39a13e 100644
index 0e4494627c..33ef280420 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -64,7 +64,8 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
@@ -73,7 +73,8 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
if (pcmc->smbios_defaults) {
/* These values are guest ABI, do not change */
smbios_set_defaults("QEMU", mc->desc, mc->name,
- pcmc->smbios_uuid_encoded);
+ pcmc->smbios_uuid_encoded,
- smbios_set_defaults("QEMU", mc->desc, mc->name);
+ smbios_set_defaults("QEMU", mc->desc, mc->name,
+ pcmc->smbios_stream_product, pcmc->smbios_stream_version);
}
/* tell smbios about cpuid version and features */
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 897c86ec41..2d0db43f49 100644
index 03a204ef8a..f2fe057535 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -3169,7 +3169,7 @@ static int rtl8139_pre_save(void *opaque)
@@ -3173,7 +3173,7 @@ static int rtl8139_pre_save(void *opaque)
static const VMStateDescription vmstate_rtl8139 = {
.name = "rtl8139",
@ -357,7 +378,7 @@ index 897c86ec41..2d0db43f49 100644
.minimum_version_id = 3,
.post_load = rtl8139_post_load,
.pre_save = rtl8139_pre_save,
@@ -3250,7 +3250,9 @@ static const VMStateDescription vmstate_rtl8139 = {
@@ -3254,7 +3254,9 @@ static const VMStateDescription vmstate_rtl8139 = {
VMSTATE_UINT32(tally_counters.TxMCol, RTL8139State),
VMSTATE_UINT64(tally_counters.RxOkPhy, RTL8139State),
VMSTATE_UINT64(tally_counters.RxOkBrd, RTL8139State),
@ -368,10 +389,10 @@ index 897c86ec41..2d0db43f49 100644
VMSTATE_UINT16(tally_counters.TxUndrn, RTL8139State),
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index eed5787b15..68608a3403 100644
index a394514264..88642ccce0 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -39,6 +39,10 @@ size_t usr_blobs_len;
@@ -38,6 +38,10 @@ size_t usr_blobs_len;
static unsigned usr_table_max;
static unsigned usr_table_cnt;
@ -382,7 +403,7 @@ index eed5787b15..68608a3403 100644
uint8_t *smbios_tables;
size_t smbios_tables_len;
unsigned smbios_table_max;
@@ -629,7 +633,7 @@ static void smbios_build_type_1_table(void)
@@ -626,7 +630,7 @@ static void smbios_build_type_1_table(void)
static void smbios_build_type_2_table(void)
{
@ -391,17 +412,16 @@ index eed5787b15..68608a3403 100644
SMBIOS_TABLE_SET_STR(2, manufacturer_str, type2.manufacturer);
SMBIOS_TABLE_SET_STR(2, product_str, type2.product);
@@ -1018,16 +1022,52 @@ void smbios_set_default_processor_family(uint16_t processor_family)
@@ -1014,15 +1018,51 @@ void smbios_set_default_processor_family(uint16_t processor_family)
}
void smbios_set_defaults(const char *manufacturer, const char *product,
const char *version,
- bool uuid_encoded)
+ bool uuid_encoded,
- const char *version)
+ const char *version,
+ const char *stream_product,
+ const char *stream_version)
{
smbios_have_defaults = true;
smbios_uuid_encoded = uuid_encoded;
+ /*
+ * If @stream_product & @stream_version are non-NULL, then
@ -460,7 +480,7 @@ index 28fdabc321..bad13ec224 100644
vmstate_pit_channel, PITChannelState),
VMSTATE_INT64(channels[0].next_transition_time,
diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c
index 4423983308..43b4b71fdf 100644
index 264d7ebb77..2b9a3e06d4 100644
--- a/hw/usb/hcd-xhci-pci.c
+++ b/hw/usb/hcd-xhci-pci.c
@@ -104,6 +104,33 @@ static int xhci_pci_vmstate_post_load(void *opaque, int version_id)
@ -524,7 +544,7 @@ index 4423983308..43b4b71fdf 100644
}
pci_register_bar(dev, 0,
PCI_BASE_ADDRESS_SPACE_MEMORY |
@@ -154,6 +170,14 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
@@ -153,6 +169,14 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
assert(ret > 0);
}
@ -539,7 +559,7 @@ index 4423983308..43b4b71fdf 100644
if (s->msix != ON_OFF_AUTO_OFF) {
/* TODO check for errors, and should fail when msix=on */
msix_init(dev, s->xhci.numintrs,
@@ -198,11 +222,18 @@ static void xhci_instance_init(Object *obj)
@@ -197,11 +221,18 @@ static void xhci_instance_init(Object *obj)
qdev_alias_all_properties(DEVICE(&s->xhci), obj);
}
@ -571,7 +591,7 @@ index 08f70ce97c..1be7527c1b 100644
#endif
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index ffd119ebac..0e2be2219c 100644
index ef64bf1b4a..ba11aa4646 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -1694,8 +1694,9 @@ static Property virtio_mem_properties[] = {
@ -586,13 +606,16 @@ index ffd119ebac..0e2be2219c 100644
};
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 8b8f6d5c00..0466f9d0f3 100644
index 48ff6d8b93..ccfc3e10eb 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -512,4 +512,44 @@ extern const size_t hw_compat_2_2_len;
@@ -822,4 +822,47 @@ extern const size_t hw_compat_2_2_len;
extern GlobalProperty hw_compat_2_1[];
extern const size_t hw_compat_2_1_len;
+extern GlobalProperty hw_compat_rhel_9_5[];
+extern const size_t hw_compat_rhel_9_5_len;
+
+extern GlobalProperty hw_compat_rhel_9_4[];
+extern const size_t hw_compat_rhel_9_4_len;
+
@ -635,27 +658,27 @@ index 8b8f6d5c00..0466f9d0f3 100644
+extern const char *rhel_old_machine_deprecation;
#endif
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 8d3fb2fb3b..d9d6d7a169 100644
index f066ab7262..e805d25fbe 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -332,7 +332,9 @@ void smbios_entry_add(QemuOpts *opts, Error **errp);
@@ -331,7 +331,9 @@ void smbios_add_usr_blob_size(size_t size);
void smbios_entry_add(QemuOpts *opts, Error **errp);
void smbios_set_cpuid(uint32_t version, uint32_t features);
void smbios_set_defaults(const char *manufacturer, const char *product,
const char *version,
- bool uuid_encoded);
+ bool uuid_encoded,
- const char *version);
+ const char *version,
+ const char *stream_product,
+ const char *stream_version);
void smbios_set_default_processor_family(uint16_t processor_family);
uint8_t *smbios_get_table_legacy(size_t *length, Error **errp);
void smbios_get_tables(MachineState *ms,
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 27a68071d7..ebd8f973f2 100644
index 4e55d7ef6e..8776a3c937 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -112,6 +112,9 @@ struct PCMachineClass {
@@ -103,6 +103,9 @@ struct PCMachineClass {
bool smbios_defaults;
bool smbios_legacy_mode;
bool smbios_uuid_encoded;
SmbiosEntryPointType default_smbios_ep_type;
+ /* New fields needed for Windows HardwareID-6 matching */
+ const char *smbios_stream_product;

@ -1,430 +0,0 @@
From 3afc6e4cb6725d01b8f89207701bca199c9ecc9f Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Fri, 19 Oct 2018 12:53:31 +0200
Subject: Add aarch64 machine types
Adding changes to add RHEL machine types for aarch64 architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hw/arm/virt.c | 299 +++++++++++++++++++++++++++++++++++++++++-
include/hw/arm/virt.h | 8 ++
2 files changed, 306 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 36e9b4b4e9..22bc345137 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -101,6 +101,7 @@ static void arm_virt_compat_set(MachineClass *mc)
arm_virt_compat_len);
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
void *data) \
@@ -128,7 +129,63 @@ static void arm_virt_compat_set(MachineClass *mc)
DEFINE_VIRT_MACHINE_LATEST(major, minor, true)
#define DEFINE_VIRT_MACHINE(major, minor) \
DEFINE_VIRT_MACHINE_LATEST(major, minor, false)
+#endif /* disabled for RHEL */
+
+/*
+ * This variable is for changes to properties that are RHEL specific,
+ * different to the current upstream and to be applied to the latest
+ * machine type. They may be overriden by older machine compats.
+ *
+ * virtio-net-pci variant romfiles are not needed because edk2 does
+ * fully support the pxe boot. Besides virtio romfiles are not shipped
+ * on rhel/aarch64.
+ */
+GlobalProperty arm_rhel_compat[] = {
+ {"virtio-net-pci", "romfile", "" },
+ {"virtio-net-pci-transitional", "romfile", "" },
+ {"virtio-net-pci-non-transitional", "romfile", "" },
+};
+const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat);
+/*
+ * This cannot be called from the rhel_virt_class_init() because
+ * TYPE_RHEL_MACHINE is abstract and mc->compat_props g_ptr_array_new()
+ * only is called on virt-rhelm.n.s non abstract class init.
+ */
+static void arm_rhel_compat_set(MachineClass *mc)
+{
+ compat_props_add(mc->compat_props, arm_rhel_compat,
+ arm_rhel_compat_len);
+}
+
+#define DEFINE_RHEL_MACHINE_LATEST(m, n, s, latest) \
+ static void rhel##m##n##s##_virt_class_init(ObjectClass *oc, \
+ void *data) \
+ { \
+ MachineClass *mc = MACHINE_CLASS(oc); \
+ arm_rhel_compat_set(mc); \
+ rhel##m##n##s##_virt_options(mc); \
+ mc->desc = "RHEL " # m "." # n "." # s " ARM Virtual Machine"; \
+ if (latest) { \
+ mc->alias = "virt"; \
+ mc->is_default = 1; \
+ } \
+ } \
+ static const TypeInfo rhel##m##n##s##_machvirt_info = { \
+ .name = MACHINE_TYPE_NAME("virt-rhel" # m "." # n "." # s), \
+ .parent = TYPE_RHEL_MACHINE, \
+ .class_init = rhel##m##n##s##_virt_class_init, \
+ }; \
+ static void rhel##m##n##s##_machvirt_init(void) \
+ { \
+ type_register_static(&rhel##m##n##s##_machvirt_info); \
+ } \
+ type_init(rhel##m##n##s##_machvirt_init);
+
+#define DEFINE_RHEL_MACHINE_AS_LATEST(major, minor, subminor) \
+ DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, true)
+#define DEFINE_RHEL_MACHINE(major, minor, subminor) \
+ DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, false)
/* Number of external interrupt lines to configure the GIC with */
#define NUM_IRQS 256
@@ -2355,6 +2412,7 @@ static void machvirt_init(MachineState *machine)
qemu_add_machine_init_done_notifier(&vms->machine_done);
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_secure(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2382,6 +2440,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp)
vms->virt = value;
}
+#endif /* disabled for RHEL */
static bool virt_get_highmem(Object *obj, Error **errp)
{
@@ -2397,6 +2456,7 @@ static void virt_set_highmem(Object *obj, bool value, Error **errp)
vms->highmem = value;
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_compact_highmem(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2410,6 +2470,7 @@ static void virt_set_compact_highmem(Object *obj, bool value, Error **errp)
vms->highmem_compact = value;
}
+#endif /* disabled for RHEL */
static bool virt_get_highmem_redists(Object *obj, Error **errp)
{
@@ -2453,7 +2514,6 @@ static void virt_set_highmem_mmio(Object *obj, bool value, Error **errp)
vms->highmem_mmio = value;
}
-
static bool virt_get_its(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2468,6 +2528,7 @@ static void virt_set_its(Object *obj, bool value, Error **errp)
vms->its = value;
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_dtb_randomness(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2481,6 +2542,7 @@ static void virt_set_dtb_randomness(Object *obj, bool value, Error **errp)
vms->dtb_randomness = value;
}
+#endif /* disabled for RHEL */
static char *virt_get_oem_id(Object *obj, Error **errp)
{
@@ -2564,6 +2626,7 @@ static void virt_set_ras(Object *obj, bool value, Error **errp)
vms->ras = value;
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_mte(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2577,6 +2640,7 @@ static void virt_set_mte(Object *obj, bool value, Error **errp)
vms->mte = value;
}
+#endif /* disabled for RHEL */
static char *virt_get_gic_version(Object *obj, Error **errp)
{
@@ -2949,6 +3013,7 @@ static int virt_kvm_type(MachineState *ms, const char *type_str)
return fixed_ipa ? 0 : requested_pa_size;
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void virt_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@@ -3463,3 +3528,235 @@ static void virt_machine_2_6_options(MachineClass *mc)
vmc->no_pmu = true;
}
DEFINE_VIRT_MACHINE(2, 6)
+#endif /* disabled for RHEL */
+
+static void rhel_machine_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
+ arm_virt_compat_set(mc);
+
+ mc->family = "virt-rhel-Z";
+ mc->init = machvirt_init;
+ /* Maximum supported VCPU count for all virt-rhel* machines */
+ mc->max_cpus = 384;
+#ifdef CONFIG_TPM
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
+#endif
+ mc->block_default_type = IF_VIRTIO;
+ mc->no_cdrom = 1;
+ mc->pci_allow_0_address = true;
+ /* We know we will never create a pre-ARMv7 CPU which needs 1K pages */
+ mc->minimum_page_bits = 12;
+ mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
+ mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57");
+ mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
+ mc->kvm_type = virt_kvm_type;
+ assert(!mc->get_hotplug_handler);
+ mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
+ hc->pre_plug = virt_machine_device_pre_plug_cb;
+ hc->plug = virt_machine_device_plug_cb;
+ hc->unplug_request = virt_machine_device_unplug_request_cb;
+ hc->unplug = virt_machine_device_unplug_cb;
+ mc->nvdimm_supported = true;
+ mc->smp_props.clusters_supported = true;
+ mc->auto_enable_numa_with_memhp = true;
+ mc->auto_enable_numa_with_memdev = true;
+ /* platform instead of architectural choice */
+ mc->cpu_cluster_has_numa_boundary = true;
+ mc->default_ram_id = "mach-virt.ram";
+ mc->default_nic = "virtio-net-pci";
+
+ object_class_property_add(oc, "acpi", "OnOffAuto",
+ virt_get_acpi, virt_set_acpi,
+ NULL, NULL);
+ object_class_property_set_description(oc, "acpi",
+ "Enable ACPI");
+
+ object_class_property_add_bool(oc, "highmem", virt_get_highmem,
+ virt_set_highmem);
+ object_class_property_set_description(oc, "highmem",
+ "Set on/off to enable/disable using "
+ "physical address space above 32 bits");
+
+ object_class_property_add_bool(oc, "highmem-redists",
+ virt_get_highmem_redists,
+ virt_set_highmem_redists);
+ object_class_property_set_description(oc, "highmem-redists",
+ "Set on/off to enable/disable high "
+ "memory region for GICv3 or GICv4 "
+ "redistributor");
+
+ object_class_property_add_bool(oc, "highmem-ecam",
+ virt_get_highmem_ecam,
+ virt_set_highmem_ecam);
+ object_class_property_set_description(oc, "highmem-ecam",
+ "Set on/off to enable/disable high "
+ "memory region for PCI ECAM");
+
+ object_class_property_add_bool(oc, "highmem-mmio",
+ virt_get_highmem_mmio,
+ virt_set_highmem_mmio);
+ object_class_property_set_description(oc, "highmem-mmio",
+ "Set on/off to enable/disable high "
+ "memory region for PCI MMIO");
+
+ object_class_property_add_str(oc, "gic-version", virt_get_gic_version,
+ virt_set_gic_version);
+ object_class_property_set_description(oc, "gic-version",
+ "Set GIC version. "
+ "Valid values are 2, 3, host and max");
+
+ object_class_property_add_str(oc, "iommu", virt_get_iommu, virt_set_iommu);
+ object_class_property_set_description(oc, "iommu",
+ "Set the IOMMU type. "
+ "Valid values are none and smmuv3");
+
+ object_class_property_add_bool(oc, "default-bus-bypass-iommu",
+ virt_get_default_bus_bypass_iommu,
+ virt_set_default_bus_bypass_iommu);
+ object_class_property_set_description(oc, "default-bus-bypass-iommu",
+ "Set on/off to enable/disable "
+ "bypass_iommu for default root bus");
+
+ object_class_property_add_bool(oc, "ras", virt_get_ras,
+ virt_set_ras);
+ object_class_property_set_description(oc, "ras",
+ "Set on/off to enable/disable reporting host memory errors "
+ "to a KVM guest using ACPI and guest external abort exceptions");
+
+ object_class_property_add_bool(oc, "its", virt_get_its,
+ virt_set_its);
+ object_class_property_set_description(oc, "its",
+ "Set on/off to enable/disable "
+ "ITS instantiation");
+
+ object_class_property_add_str(oc, "x-oem-id",
+ virt_get_oem_id,
+ virt_set_oem_id);
+ object_class_property_set_description(oc, "x-oem-id",
+ "Override the default value of field OEMID "
+ "in ACPI table header."
+ "The string may be up to 6 bytes in size");
+
+
+ object_class_property_add_str(oc, "x-oem-table-id",
+ virt_get_oem_table_id,
+ virt_set_oem_table_id);
+ object_class_property_set_description(oc, "x-oem-table-id",
+ "Override the default value of field OEM Table ID "
+ "in ACPI table header."
+ "The string may be up to 8 bytes in size");
+}
+
+static void rhel_virt_instance_init(Object *obj)
+{
+ VirtMachineState *vms = VIRT_MACHINE(obj);
+ VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
+
+ /* EL3 is disabled by default and non-configurable for RHEL */
+ vms->secure = false;
+
+ /* EL2 is disabled by default and non-configurable for RHEL */
+ vms->virt = false;
+
+ /* High memory is enabled by default */
+ vms->highmem = true;
+ vms->highmem_compact = !vmc->no_highmem_compact;
+ vms->gic_version = VIRT_GIC_VERSION_NOSEL;
+
+ vms->highmem_ecam = !vmc->no_highmem_ecam;
+ vms->highmem_mmio = true;
+ vms->highmem_redists = true;
+
+ if (vmc->no_its) {
+ vms->its = false;
+ } else {
+ /* Default allows ITS instantiation */
+ vms->its = true;
+
+ if (vmc->no_tcg_its) {
+ vms->tcg_its = false;
+ } else {
+ vms->tcg_its = true;
+ }
+ }
+
+ /* Default disallows iommu instantiation */
+ vms->iommu = VIRT_IOMMU_NONE;
+
+ /* The default root bus is attached to iommu by default */
+ vms->default_bus_bypass_iommu = false;
+
+ /* Default disallows RAS instantiation and is non-configurable for RHEL */
+ vms->ras = false;
+
+ /* MTE is disabled by default and non-configurable for RHEL */
+ vms->mte = false;
+
+ /* Supply kaslr-seed and rng-seed by default, non-configurable for RHEL */
+ vms->dtb_randomness = true;
+
+ vms->irqmap = a15irqmap;
+
+ virt_flash_create(vms);
+
+ vms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
+ vms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
+}
+
+static const TypeInfo rhel_machine_info = {
+ .name = TYPE_RHEL_MACHINE,
+ .parent = TYPE_MACHINE,
+ .abstract = true,
+ .instance_size = sizeof(VirtMachineState),
+ .class_size = sizeof(VirtMachineClass),
+ .class_init = rhel_machine_class_init,
+ .instance_init = rhel_virt_instance_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ },
+};
+
+static void rhel_machine_init(void)
+{
+ type_register_static(&rhel_machine_info);
+}
+type_init(rhel_machine_init);
+
+static void rhel940_virt_options(MachineClass *mc)
+{
+}
+DEFINE_RHEL_MACHINE_AS_LATEST(9, 4, 0)
+
+static void rhel920_virt_options(MachineClass *mc)
+{
+ rhel940_virt_options(mc);
+
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len);
+
+ /* RHEL 9.4 is the first supported release */
+ mc->deprecation_reason =
+ "machine types for versions prior to 9.4 are deprecated";
+}
+DEFINE_RHEL_MACHINE(9, 2, 0)
+
+static void rhel900_virt_options(MachineClass *mc)
+{
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
+
+ rhel920_virt_options(mc);
+
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len);
+
+ /* Disable FEAT_LPA2 since old kernels (<= v5.12) don't boot with that feature */
+ vmc->no_tcg_lpa2 = true;
+ /* Compact layout for high memory regions was introduced with 9.2.0 */
+ vmc->no_highmem_compact = true;
+}
+DEFINE_RHEL_MACHINE(9, 0, 0)
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index bb486d36b1..237fc77bda 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -179,9 +179,17 @@ struct VirtMachineState {
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
+#if 0 /* disabled for Red Hat Enterprise Linux */
#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass, VIRT_MACHINE)
+#else
+#define TYPE_RHEL_MACHINE MACHINE_TYPE_NAME("virt-rhel")
+typedef struct VirtMachineClass VirtMachineClass;
+typedef struct VirtMachineState VirtMachineState;
+DECLARE_OBJ_CHECKERS(VirtMachineState, VirtMachineClass, VIRT_MACHINE, TYPE_RHEL_MACHINE)
+#endif
+
void virt_acpi_setup(VirtMachineState *vms);
bool virt_is_acpi_enabled(VirtMachineState *vms);
--
2.39.3

@ -0,0 +1,36 @@
From 16946c2c7be0ae23dc1f267323cfc7630a1c9e87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 13:32:32 +0100
Subject: meson: temporarily disable -Wunused-function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Deleting the upstream versioned machine types will leave some functions
unused until RHEL machine types are added once again. Temporarily
disable the -Wunused-function warning to preserve bisectability with
fine grained patch splits.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Rebase notes (9.1.0 rc0)
- New patch
---
meson.build | 1 +
1 file changed, 1 insertion(+)
diff --git a/meson.build b/meson.build
index fbda17c987..161d496d55 100644
--- a/meson.build
+++ b/meson.build
@@ -651,6 +651,7 @@ warn_flags = [
'-Wno-string-plus-int',
'-Wno-tautological-type-limit-compare',
'-Wno-typedef-redefinition',
+ '-Wno-unused-function',
]
if host_os != 'darwin'
--
2.39.3

@ -1,273 +0,0 @@
From fa1d70b9a9cfe020e7ebe7798ebb70314658ccf7 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Fri, 19 Oct 2018 13:47:32 +0200
Subject: Add s390x machine types
Adding changes to add RHEL machine types for s390x architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hw/s390x/s390-virtio-ccw.c | 159 +++++++++++++++++++++++++++++++
target/s390x/cpu_models.c | 11 +++
target/s390x/cpu_models.h | 2 +
target/s390x/cpu_models_sysemu.c | 2 +
4 files changed, 174 insertions(+)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index b1dcb3857f..ff753a29e0 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -859,6 +859,7 @@ bool css_migration_enabled(void)
} \
type_init(ccw_machine_register_##suffix)
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void ccw_machine_9_0_instance_options(MachineState *machine)
{
}
@@ -1272,6 +1273,164 @@ static void ccw_machine_2_4_class_options(MachineClass *mc)
compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_CCW_MACHINE(2_4, "2.4", false);
+#endif
+
+
+static void ccw_machine_rhel940_instance_options(MachineState *machine)
+{
+}
+
+static void ccw_machine_rhel940_class_options(MachineClass *mc)
+{
+}
+DEFINE_CCW_MACHINE(rhel940, "rhel9.4.0", true);
+
+static void ccw_machine_rhel920_instance_options(MachineState *machine)
+{
+ ccw_machine_rhel940_instance_options(machine);
+}
+
+static void ccw_machine_rhel920_class_options(MachineClass *mc)
+{
+ ccw_machine_rhel940_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len);
+ mc->smp_props.drawers_supported = false; /* from ccw_machine_8_1 */
+ mc->smp_props.books_supported = false; /* from ccw_machine_8_1 */
+}
+DEFINE_CCW_MACHINE(rhel920, "rhel9.2.0", false);
+
+static void ccw_machine_rhel900_instance_options(MachineState *machine)
+{
+ static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_2 };
+
+ ccw_machine_rhel920_instance_options(machine);
+
+ s390_set_qemu_cpu_model(0x3906, 14, 2, qemu_cpu_feat);
+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAIE);
+}
+
+static void ccw_machine_rhel900_class_options(MachineClass *mc)
+{
+ S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
+ static GlobalProperty compat[] = {
+ { TYPE_S390_PCI_DEVICE, "interpret", "off", },
+ { TYPE_S390_PCI_DEVICE, "forwarding-assist", "off", },
+ };
+
+ ccw_machine_rhel920_class_options(mc);
+
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len);
+ s390mc->max_threads = S390_MAX_CPUS;
+}
+DEFINE_CCW_MACHINE(rhel900, "rhel9.0.0", false);
+
+static void ccw_machine_rhel860_instance_options(MachineState *machine)
+{
+ /* Note: The -rhel8.6.0 and -rhel9.0.0 machines are technically identical */
+ ccw_machine_rhel900_instance_options(machine);
+}
+
+static void ccw_machine_rhel860_class_options(MachineClass *mc)
+{
+ static GlobalProperty compat[] = {
+ { TYPE_S390_PCI_DEVICE, "interpret", "on", },
+ { TYPE_S390_PCI_DEVICE, "forwarding-assist", "on", },
+ };
+
+ ccw_machine_rhel900_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_6, hw_compat_rhel_8_6_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
+
+ /* All RHEL machines for prior major releases are deprecated */
+ mc->deprecation_reason = rhel_old_machine_deprecation;
+}
+DEFINE_CCW_MACHINE(rhel860, "rhel8.6.0", false);
+
+static void ccw_machine_rhel850_instance_options(MachineState *machine)
+{
+ static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_0 };
+
+ ccw_machine_rhel860_instance_options(machine);
+
+ s390_set_qemu_cpu_model(0x2964, 13, 2, qemu_cpu_feat);
+
+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_NNPA);
+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2);
+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_BEAR_ENH);
+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_RDP);
+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAI);
+}
+
+static void ccw_machine_rhel850_class_options(MachineClass *mc)
+{
+ static GlobalProperty compat[] = {
+ { TYPE_S390_PCI_DEVICE, "interpret", "off", },
+ { TYPE_S390_PCI_DEVICE, "forwarding-assist", "off", },
+ };
+
+ ccw_machine_rhel860_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_5, hw_compat_rhel_8_5_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
+ mc->smp_props.prefer_sockets = true;
+}
+DEFINE_CCW_MACHINE(rhel850, "rhel8.5.0", false);
+
+static void ccw_machine_rhel840_instance_options(MachineState *machine)
+{
+ ccw_machine_rhel850_instance_options(machine);
+}
+
+static void ccw_machine_rhel840_class_options(MachineClass *mc)
+{
+ ccw_machine_rhel850_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_4, hw_compat_rhel_8_4_len);
+}
+DEFINE_CCW_MACHINE(rhel840, "rhel8.4.0", false);
+
+static void ccw_machine_rhel820_instance_options(MachineState *machine)
+{
+ ccw_machine_rhel840_instance_options(machine);
+}
+
+static void ccw_machine_rhel820_class_options(MachineClass *mc)
+{
+ ccw_machine_rhel840_class_options(mc);
+ mc->fixup_ram_size = s390_fixup_ram_size;
+ /* we did not publish a rhel8.3.0 machine */
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_3, hw_compat_rhel_8_3_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_2, hw_compat_rhel_8_2_len);
+}
+DEFINE_CCW_MACHINE(rhel820, "rhel8.2.0", false);
+
+static void ccw_machine_rhel760_instance_options(MachineState *machine)
+{
+ static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V3_1 };
+
+ ccw_machine_rhel820_instance_options(machine);
+
+ s390_set_qemu_cpu_model(0x2827, 12, 2, qemu_cpu_feat);
+
+ /* The multiple-epoch facility was not available with rhel7.6.0 on z14GA1 */
+ s390_cpudef_featoff(14, 1, S390_FEAT_MULTIPLE_EPOCH);
+ s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_QSIE);
+ s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_QTOUE);
+ s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_STOE);
+ s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_STOUE);
+}
+
+static void ccw_machine_rhel760_class_options(MachineClass *mc)
+{
+ ccw_machine_rhel820_class_options(mc);
+ /* We never published the s390x version of RHEL-AV 8.0 and 8.1, so add this here */
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_1, hw_compat_rhel_8_1_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_0, hw_compat_rhel_8_0_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_7_6, hw_compat_rhel_7_6_len);
+}
+DEFINE_CCW_MACHINE(rhel760, "rhel7.6.0", false);
static void ccw_machine_register_types(void)
{
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 8ed3bb6a27..370b3b3065 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -46,6 +46,9 @@
* of a following release have been a superset of the previous release. With
* generation 15 one base feature and one optional feature have been deprecated.
*/
+
+#define RHEL_CPU_DEPRECATION "use at least 'z14', or 'host' / 'qemu' / 'max'"
+
static S390CPUDef s390_cpu_defs[] = {
CPUDEF_INIT(0x2064, 7, 1, 38, 0x00000000U, "z900", "IBM zSeries 900 GA1"),
CPUDEF_INIT(0x2064, 7, 2, 38, 0x00000000U, "z900.2", "IBM zSeries 900 GA2"),
@@ -866,22 +869,30 @@ static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data)
static void s390_base_cpu_model_class_init(ObjectClass *oc, void *data)
{
S390CPUClass *xcc = S390_CPU_CLASS(oc);
+ CPUClass *cc = CPU_CLASS(oc);
/* all base models are migration safe */
xcc->cpu_def = (const S390CPUDef *) data;
xcc->is_migration_safe = true;
xcc->is_static = true;
xcc->desc = xcc->cpu_def->desc;
+ if (xcc->cpu_def->gen < 14) {
+ cc->deprecation_note = RHEL_CPU_DEPRECATION;
+ }
}
static void s390_cpu_model_class_init(ObjectClass *oc, void *data)
{
S390CPUClass *xcc = S390_CPU_CLASS(oc);
+ CPUClass *cc = CPU_CLASS(oc);
/* model that can change between QEMU versions */
xcc->cpu_def = (const S390CPUDef *) data;
xcc->is_migration_safe = true;
xcc->desc = xcc->cpu_def->desc;
+ if (xcc->cpu_def->gen < 14) {
+ cc->deprecation_note = RHEL_CPU_DEPRECATION;
+ }
}
static void s390_qemu_cpu_model_class_init(ObjectClass *oc, void *data)
diff --git a/target/s390x/cpu_models.h b/target/s390x/cpu_models.h
index d7b8912989..1a806a97c4 100644
--- a/target/s390x/cpu_models.h
+++ b/target/s390x/cpu_models.h
@@ -38,6 +38,8 @@ typedef struct S390CPUDef {
S390FeatBitmap full_feat;
/* used to init full_feat from generated data */
S390FeatInit full_init;
+ /* if deprecated, provides a suggestion */
+ const char *deprecation_note;
} S390CPUDef;
/* CPU model based on a CPU definition */
diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c
index 0728bfcc20..ca2e5d91e2 100644
--- a/target/s390x/cpu_models_sysemu.c
+++ b/target/s390x/cpu_models_sysemu.c
@@ -59,6 +59,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
CpuDefinitionInfo *info;
char *name = g_strdup(object_class_get_name(klass));
S390CPUClass *scc = S390_CPU_CLASS(klass);
+ CPUClass *cc = CPU_CLASS(klass);
/* strip off the -s390x-cpu */
g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0;
@@ -68,6 +69,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
info->migration_safe = scc->is_migration_safe;
info->q_static = scc->is_static;
info->q_typename = g_strdup(object_class_get_name(klass));
+ info->deprecated = !!cc->deprecation_note;
/* check for unavailable features */
if (cpu_list_data->model) {
Object *obj;
--
2.39.3

@ -0,0 +1,101 @@
From 2f0ba1a1ed66a8ae32e7a92f3d3b744d8b59b879 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 10 Jul 2024 02:25:51 -0400
Subject: Remove upstream machine types for aarch64, s390x and x86_64
architectures
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We will replace upstream machine types on supported architectures with RHEL
machine types.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
Rebase notes (9.1.0 rc0):
- Split off commits adding RHEL machine types
---
hw/arm/virt.c | 2 ++
hw/i386/pc_piix.c | 2 ++
hw/i386/pc_q35.c | 2 ++
hw/s390x/s390-virtio-ccw.c | 2 ++
4 files changed, 8 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index b2aa3f1355..5396e7cb24 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3306,6 +3306,7 @@ static void machvirt_machine_init(void)
}
type_init(machvirt_machine_init);
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void virt_machine_9_1_options(MachineClass *mc)
{
}
@@ -3552,3 +3553,4 @@ static void virt_machine_2_6_options(MachineClass *mc)
vmc->no_pmu = true;
}
DEFINE_VIRT_MACHINE(2, 6)
+#endif /* disabled for RHEL */
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 347afa4c37..67107b174a 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -448,6 +448,7 @@ static void pc_i440fx_init(MachineState *machine)
#define DEFINE_I440FX_MACHINE(major, minor) \
DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, major, minor);
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void pc_i440fx_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
@@ -775,6 +776,7 @@ static void pc_i440fx_machine_2_4_options(MachineClass *m)
}
DEFINE_I440FX_MACHINE(2, 4);
+#endif /* Disabled for Red Hat Enterprise Linux */
#ifdef CONFIG_ISAPC
static void isapc_machine_options(MachineClass *m)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index f2d8edfa84..5fb283f2df 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -356,6 +356,7 @@ static void pc_q35_machine_options(MachineClass *m)
pc_q35_compat_defaults, pc_q35_compat_defaults_len);
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void pc_q35_machine_9_1_options(MachineClass *m)
{
pc_q35_machine_options(m);
@@ -668,3 +669,4 @@ static void pc_q35_machine_2_4_options(MachineClass *m)
}
DEFINE_Q35_MACHINE(2, 4);
+#endif /* Disabled for Red Hat Enterprise Linux */
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index c483ff8064..86bfc9d2eb 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -871,6 +871,7 @@ static const TypeInfo ccw_machine_info = {
DEFINE_CCW_MACHINE_IMPL(false, major, minor)
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void ccw_machine_9_1_instance_options(MachineState *machine)
{
}
@@ -1305,6 +1306,7 @@ static void ccw_machine_2_4_class_options(MachineClass *mc)
DEFINE_CCW_MACHINE(2, 4);
#endif
+#endif /* disabled for RHEL */
static void ccw_machine_register_types(void)
{
--
2.39.3

@ -0,0 +1,197 @@
From ccb1eaa95ce9c92a196fe034c033502f582a324b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 15:27:03 +0100
Subject: Adapt versioned machine type macros for RHEL
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The versioned machine type macros are changed thus:
* All symbol names get 'rhel' inserted eg 'virt_rhel_macine_9_4_0_<blah>'
* All machine type names get 'rhel' inserted eg 'virt-rhel9.4.0-machine'
* Lifecycle is changed to deprecate after 1 major RHEL release,
force non-registration (effectively deletion) after 2 major releases
* Custom message to explain RHEL deprecation/deletion policy
* Remove upstream logic that temporarily disabled deletion since
the upstream constraints in this area don't apply to RHEL
* For automatic deprecation/deletion, RHEL_VERSION is defined
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
.distro/Makefile | 2 +-
.distro/Makefile.common | 1 +
.distro/qemu-kvm.spec.template | 1 +
.distro/scripts/process-patches.sh | 3 ++
include/hw/boards.h | 60 ++++++++++--------------------
meson.build | 1 +
meson_options.txt | 2 +
scripts/meson-buildoptions.sh | 2 +
8 files changed, 30 insertions(+), 42 deletions(-)
diff --git a/include/hw/boards.h b/include/hw/boards.h
index ccfc3e10eb..7f7eb4ec40 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -548,16 +548,16 @@ struct MachineState {
* "{prefix}-{major}.{minor}.{micro}-{tag}"
*/
#define _MACHINE_VER_TYPE_NAME2(prefix, major, minor) \
- prefix "-" #major "." #minor TYPE_MACHINE_SUFFIX
+ prefix "-rhel" #major "." #minor TYPE_MACHINE_SUFFIX
#define _MACHINE_VER_TYPE_NAME3(prefix, major, minor, micro) \
- prefix "-" #major "." #minor "." #micro TYPE_MACHINE_SUFFIX
+ prefix "-rhel" #major "." #minor "." #micro TYPE_MACHINE_SUFFIX
#define _MACHINE_VER_TYPE_NAME4(prefix, major, minor, _unused_, tag) \
- prefix "-" #major "." #minor "-" #tag TYPE_MACHINE_SUFFIX
+ prefix "-rhel" #major "." #minor "-" #tag TYPE_MACHINE_SUFFIX
#define _MACHINE_VER_TYPE_NAME5(prefix, major, minor, micro, _unused_, tag) \
- prefix "-" #major "." #minor "." #micro "-" #tag TYPE_MACHINE_SUFFIX
+ prefix "-rhel" #major "." #minor "." #micro "-" #tag TYPE_MACHINE_SUFFIX
#define MACHINE_VER_TYPE_NAME(prefix, ...) \
_MACHINE_VER_PICK(__VA_ARGS__, \
@@ -585,16 +585,16 @@ struct MachineState {
* {prefix}_machine_{major}_{minor}_{micro}_{tag}_{sym}
*/
#define _MACHINE_VER_SYM2(sym, prefix, major, minor) \
- prefix ## _machine_ ## major ## _ ## minor ## _ ## sym
+ prefix ## _rhel_machine_ ## major ## _ ## minor ## _ ## sym
#define _MACHINE_VER_SYM3(sym, prefix, major, minor, micro) \
- prefix ## _machine_ ## major ## _ ## minor ## _ ## micro ## _ ## sym
+ prefix ## _rhel_machine_ ## major ## _ ## minor ## _ ## micro ## _ ## sym
#define _MACHINE_VER_SYM4(sym, prefix, major, minor, _unused_, tag) \
- prefix ## _machine_ ## major ## _ ## minor ## _ ## tag ## _ ## sym
+ prefix ## _rhel_machine_ ## major ## _ ## minor ## _ ## tag ## _ ## sym
#define _MACHINE_VER_SYM5(sym, prefix, major, minor, micro, _unused_, tag) \
- prefix ## _machine_ ## major ## _ ## minor ## _ ## micro ## _ ## tag ## _ ## sym
+ prefix ## _rhel_machine_ ## major ## _ ## minor ## _ ## micro ## _ ## tag ## _ ## sym
#define MACHINE_VER_SYM(sym, prefix, ...) \
_MACHINE_VER_PICK(__VA_ARGS__, \
@@ -605,26 +605,22 @@ struct MachineState {
/*
- * How many years/major releases for each phase
- * of the life cycle. Assumes use of versioning
- * scheme where major is bumped each year
+ * How many RHEL major releases for each phase
+ * of the life cycle.
*/
-#define MACHINE_VER_DELETION_MAJOR 6
-#define MACHINE_VER_DEPRECATION_MAJOR 3
+#define MACHINE_VER_DELETION_MAJOR 2
+#define MACHINE_VER_DEPRECATION_MAJOR 1
/*
* Expands to a static string containing a deprecation
* message for a versioned machine type
*/
#define MACHINE_VER_DEPRECATION_MSG \
- "machines more than " stringify(MACHINE_VER_DEPRECATION_MAJOR) \
- " years old are subject to deletion after " \
- stringify(MACHINE_VER_DELETION_MAJOR) " years"
+ "machines from the previous RHEL major release are " \
+ "subject to deletion in the next RHEL major release"
#define _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor) \
- (((QEMU_VERSION_MAJOR - major) > cutoff) || \
- (((QEMU_VERSION_MAJOR - major) == cutoff) && \
- (QEMU_VERSION_MINOR - minor) >= 0))
+ ((RHEL_VERSION - major) >= cutoff)
#define _MACHINE_VER_IS_EXPIRED2(cutoff, major, minor) \
_MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor)
@@ -686,32 +682,14 @@ struct MachineState {
* This must be unconditionally used in the register
* method for all machine types which support versioning.
*
- * Inijtially it will effectively be a no-op, but after a
- * suitable period of time has passed, it will cause
- * execution of the method to return, avoiding registration
- * of the machine
- *
- * The new deprecation and deletion policy for versioned
- * machine types was introduced in QEMU 9.1.0.
- *
- * Under the new policy a number of old machine types (any
- * prior to 2.12) would be liable for immediate deletion
- * which would be a violation of our historical deprecation
- * and removal policy
- *
- * Thus deletions are temporarily gated on existance of
- * the env variable "QEMU_DELETE_MACHINES" / QEMU version
- * number >= 10.1.0. This gate can be deleted in the 10.1.0
- * dev cycle
+ * It will automatically avoid registration of machines
+ * that should have been deleted at the start of this
+ * RHEL release
*/
#define MACHINE_VER_DELETION(...) \
do { \
if (MACHINE_VER_SHOULD_DELETE(__VA_ARGS__)) { \
- if (getenv("QEMU_DELETE_MACHINES") || \
- QEMU_VERSION_MAJOR > 10 || (QEMU_VERSION_MAJOR == 10 && \
- QEMU_VERSION_MINOR >= 1)) { \
- return; \
- } \
+ return; \
} \
} while (0)
diff --git a/meson.build b/meson.build
index 161d496d55..2de5ab024f 100644
--- a/meson.build
+++ b/meson.build
@@ -2440,6 +2440,7 @@ config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
+config_host_data.set('RHEL_VERSION', get_option('rhel_version').split('.')[0])
config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
diff --git a/meson_options.txt b/meson_options.txt
index 0269fa0f16..aa2ba0baef 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -2,6 +2,8 @@
# on the configure script command line. If you add more, list them in
# scripts/meson-buildoptions.py's SKIP_OPTIONS constant too.
+option('rhel_version', type: 'string', value: '0.0',
+ description: 'RHEL major/minor version')
option('qemu_suffix', type : 'string', value: 'qemu',
description: 'Suffix for QEMU data/modules/config directories (can be empty)')
option('docdir', type : 'string', value : 'share/doc',
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index c97079a38c..5f0cbfc725 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -71,6 +71,7 @@ meson_options_help() {
printf "%s\n" ' "manufacturer" name for qemu-ga registry entries'
printf "%s\n" ' [QEMU]'
printf "%s\n" ' --qemu-ga-version=VALUE version number for qemu-ga installer'
+ printf "%s\n" ' --rhel-version=VALUE RHEL major/minor version [0.0]'
printf "%s\n" ' --smbd=VALUE Path to smbd for slirp networking'
printf "%s\n" ' --sysconfdir=VALUE Sysconf data directory [etc]'
printf "%s\n" ' --tls-priority=VALUE Default TLS protocol/cipher priority string'
@@ -450,6 +451,7 @@ _meson_option_parse() {
--disable-relocatable) printf "%s" -Drelocatable=false ;;
--enable-replication) printf "%s" -Dreplication=enabled ;;
--disable-replication) printf "%s" -Dreplication=disabled ;;
+ --rhel-version=*) quote_sh "-Drhel_version=$2" ;;
--enable-rng-none) printf "%s" -Drng_none=true ;;
--disable-rng-none) printf "%s" -Drng_none=false ;;
--enable-rutabaga-gfx) printf "%s" -Drutabaga_gfx=enabled ;;
--
2.39.3

@ -0,0 +1,37 @@
From 551632921a8330cff09e7d92429aa45cf51c75e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 18:45:58 +0100
Subject: Increase deletion schedule to 4 releases
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Until RHEL 10 pc machine type is introduced, we have to keep
7.6.0 machine types as a special exception to our normal rule of
deleting machine types after 2 releases due to being a default
machine type.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Rebase notes (9.1.0 rc0)
- New patch
---
include/hw/boards.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 7f7eb4ec40..fd5a957cad 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -608,7 +608,7 @@ struct MachineState {
* How many RHEL major releases for each phase
* of the life cycle.
*/
-#define MACHINE_VER_DELETION_MAJOR 2
+#define MACHINE_VER_DELETION_MAJOR 4
#define MACHINE_VER_DEPRECATION_MAJOR 1
/*
--
2.39.3

@ -0,0 +1,301 @@
From 6cb1d3cf4ac08fe8c435e98500224a022d019e55 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 13:25:47 +0100
Subject: Add downstream aarch64 versioned 'virt' machine types
Adding changes to add RHEL machine types for aarch64 architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase notes (9.1.0 rc0):
- Merge copy+pasted base machine definition back with upstream
base machine definition to reduce RHEL delta, as is done with
other targets
- Convert to new DEFINE_VIRT_MACHINE macros
Rebase notes (9.1.0 rc1):
- do not remove cpu validation (review comment)
Rebase notes (9.1.0 rc2):
- use ifdef instead of removal for disabling unwanted upstream code
Merged patches (9.1.0 rc0):
- 043ad5ce97 Add upstream compatibility bits (partial)
---
hw/arm/virt.c | 101 ++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 81 insertions(+), 20 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 5396e7cb24..903c0f2e9f 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -90,6 +90,22 @@ static GlobalProperty arm_virt_compat[] = {
};
static const size_t arm_virt_compat_len = G_N_ELEMENTS(arm_virt_compat);
+/*
+ * This variable is for changes to properties that are RHEL specific,
+ * different to the current upstream and to be applied to the latest
+ * machine type. They may be overriden by older machine compats.
+ *
+ * virtio-net-pci variant romfiles are not needed because edk2 does
+ * fully support the pxe boot. Besides virtio romfiles are not shipped
+ * on rhel/aarch64.
+ */
+GlobalProperty arm_rhel_compat[] = {
+ {"virtio-net-pci", "romfile", "" },
+ {"virtio-net-pci-transitional", "romfile", "" },
+ {"virtio-net-pci-non-transitional", "romfile", "" },
+};
+const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat);
+
/*
* This cannot be called from the virt_machine_class_init() because
* TYPE_VIRT_MACHINE is abstract and mc->compat_props g_ptr_array_new()
@@ -99,6 +115,8 @@ static void arm_virt_compat_set(MachineClass *mc)
{
compat_props_add(mc->compat_props, arm_virt_compat,
arm_virt_compat_len);
+ compat_props_add(mc->compat_props, arm_rhel_compat,
+ arm_rhel_compat_len);
}
#define DEFINE_VIRT_MACHINE_IMPL(latest, ...) \
@@ -109,10 +127,11 @@ static void arm_virt_compat_set(MachineClass *mc)
MachineClass *mc = MACHINE_CLASS(oc); \
arm_virt_compat_set(mc); \
MACHINE_VER_SYM(options, virt, __VA_ARGS__)(mc); \
- mc->desc = "QEMU " MACHINE_VER_STR(__VA_ARGS__) " ARM Virtual Machine"; \
+ mc->desc = "RHEL " MACHINE_VER_STR(__VA_ARGS__) " ARM Virtual Machine"; \
MACHINE_VER_DEPRECATION(__VA_ARGS__); \
if (latest) { \
mc->alias = "virt"; \
+ mc->is_default = 1; \
} \
} \
static const TypeInfo MACHINE_VER_SYM(info, virt, __VA_ARGS__) = \
@@ -128,10 +147,10 @@ static void arm_virt_compat_set(MachineClass *mc)
} \
type_init(MACHINE_VER_SYM(register, virt, __VA_ARGS__));
-#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor) \
- DEFINE_VIRT_MACHINE_IMPL(true, major, minor)
-#define DEFINE_VIRT_MACHINE(major, minor) \
- DEFINE_VIRT_MACHINE_IMPL(false, major, minor)
+#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor, micro) \
+ DEFINE_VIRT_MACHINE_IMPL(true, major, minor, micro)
+#define DEFINE_VIRT_MACHINE(major, minor, micro) \
+ DEFINE_VIRT_MACHINE_IMPL(false, major, minor, micro)
/* Number of external interrupt lines to configure the GIC with */
@@ -2434,6 +2453,7 @@ static void machvirt_init(MachineState *machine)
qemu_add_machine_init_done_notifier(&vms->machine_done);
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_secure(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2461,6 +2481,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp)
vms->virt = value;
}
+#endif /* disabled for RHEL */
static bool virt_get_highmem(Object *obj, Error **errp)
{
@@ -2476,6 +2497,7 @@ static void virt_set_highmem(Object *obj, bool value, Error **errp)
vms->highmem = value;
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_compact_highmem(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2489,6 +2511,7 @@ static void virt_set_compact_highmem(Object *obj, bool value, Error **errp)
vms->highmem_compact = value;
}
+#endif /* disabled for RHEL */
static bool virt_get_highmem_redists(Object *obj, Error **errp)
{
@@ -2547,6 +2570,7 @@ static void virt_set_its(Object *obj, bool value, Error **errp)
vms->its = value;
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_dtb_randomness(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2560,6 +2584,7 @@ static void virt_set_dtb_randomness(Object *obj, bool value, Error **errp)
vms->dtb_randomness = value;
}
+#endif /* disabled for RHEL */
static char *virt_get_oem_id(Object *obj, Error **errp)
{
@@ -2643,6 +2668,7 @@ static void virt_set_ras(Object *obj, bool value, Error **errp)
vms->ras = value;
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_mte(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2656,6 +2682,7 @@ static void virt_set_mte(Object *obj, bool value, Error **errp)
vms->mte = value;
}
+#endif /* disabled for RHEL */
static char *virt_get_gic_version(Object *obj, Error **errp)
{
@@ -3063,16 +3090,10 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
NULL
};
+ mc->family = "virt-rhel-Z";
mc->init = machvirt_init;
- /* Start with max_cpus set to 512, which is the maximum supported by KVM.
- * The value may be reduced later when we have more information about the
- * configuration of the particular instance.
- */
- mc->max_cpus = 512;
- machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_CALXEDA_XGMAC);
- machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE);
- machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
- machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_PLATFORM);
+ /* Maximum supported VCPU count for all virt-rhel* machines */
+ mc->max_cpus = 384;
#ifdef CONFIG_TPM
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
#endif
@@ -3083,11 +3104,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->minimum_page_bits = 12;
mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
-#ifdef CONFIG_TCG
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
-#else
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("max");
-#endif
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57");
mc->valid_cpu_types = valid_cpu_types;
mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
mc->kvm_type = virt_kvm_type;
@@ -3111,6 +3128,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
NULL, NULL);
object_class_property_set_description(oc, "acpi",
"Enable ACPI");
+#if 0 /* disabled for RHEL */
object_class_property_add_bool(oc, "secure", virt_get_secure,
virt_set_secure);
object_class_property_set_description(oc, "secure",
@@ -3123,6 +3141,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
"Set on/off to enable/disable emulating a "
"guest CPU which implements the ARM "
"Virtualization Extensions");
+#endif /* disabled for RHEL */
object_class_property_add_bool(oc, "highmem", virt_get_highmem,
virt_set_highmem);
@@ -3130,12 +3149,14 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
"Set on/off to enable/disable using "
"physical address space above 32 bits");
+#if 0 /* disabled for RHEL */
object_class_property_add_bool(oc, "compact-highmem",
virt_get_compact_highmem,
virt_set_compact_highmem);
object_class_property_set_description(oc, "compact-highmem",
"Set on/off to enable/disable compact "
"layout for high memory regions");
+#endif /* disabled for RHEL */
object_class_property_add_bool(oc, "highmem-redists",
virt_get_highmem_redists,
@@ -3163,7 +3184,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
virt_set_gic_version);
object_class_property_set_description(oc, "gic-version",
"Set GIC version. "
- "Valid values are 2, 3, 4, host and max");
+ "Valid values are 2, 3, host and max");
object_class_property_add_str(oc, "iommu", virt_get_iommu, virt_set_iommu);
object_class_property_set_description(oc, "iommu",
@@ -3183,11 +3204,13 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
"Set on/off to enable/disable reporting host memory errors "
"to a KVM guest using ACPI and guest external abort exceptions");
+#if 0 /* disabled for RHEL */
object_class_property_add_bool(oc, "mte", virt_get_mte, virt_set_mte);
object_class_property_set_description(oc, "mte",
"Set on/off to enable/disable emulating a "
"guest CPU which implements the ARM "
"Memory Tagging Extension");
+#endif /* disabled for RHEL */
object_class_property_add_bool(oc, "its", virt_get_its,
virt_set_its);
@@ -3195,6 +3218,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
"Set on/off to enable/disable "
"ITS instantiation");
+#if 0 /* disabled for RHEL */
object_class_property_add_bool(oc, "dtb-randomness",
virt_get_dtb_randomness,
virt_set_dtb_randomness);
@@ -3207,6 +3231,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
virt_set_dtb_randomness);
object_class_property_set_description(oc, "dtb-kaslr-seed",
"Deprecated synonym of dtb-randomness");
+#endif /* disabled for RHEL */
object_class_property_add_str(oc, "x-oem-id",
virt_get_oem_id,
@@ -3554,3 +3579,39 @@ static void virt_machine_2_6_options(MachineClass *mc)
}
DEFINE_VIRT_MACHINE(2, 6)
#endif /* disabled for RHEL */
+
+static void virt_rhel_machine_9_4_0_options(MachineClass *mc)
+{
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
+}
+DEFINE_VIRT_MACHINE_AS_LATEST(9, 4, 0)
+
+static void virt_rhel_machine_9_2_0_options(MachineClass *mc)
+{
+ virt_rhel_machine_9_4_0_options(mc);
+
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len);
+
+ /* RHEL 9.4 is the first supported release */
+ mc->deprecation_reason =
+ "machine types for versions prior to 9.4 are deprecated";
+}
+DEFINE_VIRT_MACHINE(9, 2, 0)
+
+static void virt_rhel_machine_9_0_0_options(MachineClass *mc)
+{
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
+
+ virt_rhel_machine_9_2_0_options(mc);
+
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len);
+
+ /* Disable FEAT_LPA2 since old kernels (<= v5.12) don't boot with that feature */
+ vmc->no_tcg_lpa2 = true;
+ /* Compact layout for high memory regions was introduced with 9.2.0 */
+ vmc->no_highmem_compact = true;
+}
+DEFINE_VIRT_MACHINE(9, 0, 0)
--
2.39.3

@ -0,0 +1,208 @@
From 24d6b22e10c87e9a4bf4df834738f42caa1d5014 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 13:44:36 +0100
Subject: Add downstream s390x versioned 's390-ccw-virtio' machine types
Adding changes to add RHEL machine types for s390x architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
--
Rebase notes(9.1.0 rc0):
- Convert to new DEFINE_CCW_MACHINE macros
Merged patches (9.1.0 rc0):
- 043ad5ce97 Add upstream compatibility bits (partial)
- 04596b496e s390x: remove deprecated rhel machine types
---
hw/s390x/s390-virtio-ccw.c | 65 +++++++++++++++++++++++++++++---
target/s390x/cpu_models.c | 11 ++++++
target/s390x/cpu_models.h | 2 +
target/s390x/cpu_models_sysemu.c | 2 +
4 files changed, 75 insertions(+), 5 deletions(-)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 86bfc9d2eb..451017c50e 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -617,6 +617,7 @@ static void s390_nmi(NMIState *n, int cpu_index, Error **errp)
s390_cpu_restart(S390_CPU(cs));
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static ram_addr_t s390_fixup_ram_size(ram_addr_t sz)
{
/* same logic as in sclp.c */
@@ -636,6 +637,7 @@ static ram_addr_t s390_fixup_ram_size(ram_addr_t sz)
}
return newsz;
}
+#endif /* disabled for RHEL */
static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp)
{
@@ -837,7 +839,7 @@ static const TypeInfo ccw_machine_info = {
{ \
MachineClass *mc = MACHINE_CLASS(oc); \
MACHINE_VER_SYM(class_options, ccw, __VA_ARGS__)(mc); \
- mc->desc = "Virtual s390x machine (version " MACHINE_VER_STR(__VA_ARGS__) ")"; \
+ mc->desc = "Virtual s390x machine (version rhel" MACHINE_VER_STR(__VA_ARGS__) ")"; \
MACHINE_VER_DEPRECATION(__VA_ARGS__); \
if (latest) { \
mc->alias = "s390-ccw-virtio"; \
@@ -864,11 +866,11 @@ static const TypeInfo ccw_machine_info = {
} \
type_init(MACHINE_VER_SYM(register, ccw, __VA_ARGS__))
-#define DEFINE_CCW_MACHINE_AS_LATEST(major, minor) \
- DEFINE_CCW_MACHINE_IMPL(true, major, minor)
+#define DEFINE_CCW_MACHINE_AS_LATEST(major, minor, micro) \
+ DEFINE_CCW_MACHINE_IMPL(true, major, minor, micro)
-#define DEFINE_CCW_MACHINE(major, minor) \
- DEFINE_CCW_MACHINE_IMPL(false, major, minor)
+#define DEFINE_CCW_MACHINE(major, minor, micro) \
+ DEFINE_CCW_MACHINE_IMPL(false, major, minor, micro)
#if 0 /* Disabled for Red Hat Enterprise Linux */
@@ -1308,6 +1310,59 @@ DEFINE_CCW_MACHINE(2, 4);
#endif
#endif /* disabled for RHEL */
+static void ccw_rhel_machine_9_4_0_instance_options(MachineState *machine)
+{
+}
+
+static void ccw_rhel_machine_9_4_0_class_options(MachineClass *mc)
+{
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
+}
+DEFINE_CCW_MACHINE_AS_LATEST(9, 4, 0);
+
+static void ccw_rhel_machine_9_2_0_instance_options(MachineState *machine)
+{
+ ccw_rhel_machine_9_4_0_instance_options(machine);
+}
+
+static void ccw_rhel_machine_9_2_0_class_options(MachineClass *mc)
+{
+ ccw_rhel_machine_9_4_0_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len);
+ mc->smp_props.drawers_supported = false; /* from ccw_machine_8_1 */
+ mc->smp_props.books_supported = false; /* from ccw_machine_8_1 */
+}
+DEFINE_CCW_MACHINE(9, 2, 0);
+
+static void ccw_rhel_machine_9_0_0_instance_options(MachineState *machine)
+{
+ static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_2 };
+
+ ccw_rhel_machine_9_2_0_instance_options(machine);
+
+ s390_set_qemu_cpu_model(0x3906, 14, 2, qemu_cpu_feat);
+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAIE);
+}
+
+static void ccw_rhel_machine_9_0_0_class_options(MachineClass *mc)
+{
+ S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
+ static GlobalProperty compat[] = {
+ { TYPE_S390_PCI_DEVICE, "interpret", "off", },
+ { TYPE_S390_PCI_DEVICE, "forwarding-assist", "off", },
+ };
+
+ ccw_rhel_machine_9_2_0_class_options(mc);
+
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len);
+ s390mc->max_threads = S390_MAX_CPUS;
+}
+DEFINE_CCW_MACHINE(9, 0, 0);
+
static void ccw_machine_register_types(void)
{
type_register_static(&ccw_machine_info);
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 798c18f940..8afa9af1a5 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -47,6 +47,9 @@
* of a following release have been a superset of the previous release. With
* generation 15 one base feature and one optional feature have been deprecated.
*/
+
+#define RHEL_CPU_DEPRECATION "use at least 'z14', or 'host' / 'qemu' / 'max'"
+
static S390CPUDef s390_cpu_defs[] = {
/*
* Linux requires at least z10 nowadays, and IBM only supports recent CPUs
@@ -871,22 +874,30 @@ static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data)
static void s390_base_cpu_model_class_init(ObjectClass *oc, void *data)
{
S390CPUClass *xcc = S390_CPU_CLASS(oc);
+ CPUClass *cc = CPU_CLASS(oc);
/* all base models are migration safe */
xcc->cpu_def = (const S390CPUDef *) data;
xcc->is_migration_safe = true;
xcc->is_static = true;
xcc->desc = xcc->cpu_def->desc;
+ if (xcc->cpu_def->gen < 14) {
+ cc->deprecation_note = RHEL_CPU_DEPRECATION;
+ }
}
static void s390_cpu_model_class_init(ObjectClass *oc, void *data)
{
S390CPUClass *xcc = S390_CPU_CLASS(oc);
+ CPUClass *cc = CPU_CLASS(oc);
/* model that can change between QEMU versions */
xcc->cpu_def = (const S390CPUDef *) data;
xcc->is_migration_safe = true;
xcc->desc = xcc->cpu_def->desc;
+ if (xcc->cpu_def->gen < 14) {
+ cc->deprecation_note = RHEL_CPU_DEPRECATION;
+ }
}
static void s390_qemu_cpu_model_class_init(ObjectClass *oc, void *data)
diff --git a/target/s390x/cpu_models.h b/target/s390x/cpu_models.h
index 71d4bc2dd4..d6c7c2cb50 100644
--- a/target/s390x/cpu_models.h
+++ b/target/s390x/cpu_models.h
@@ -38,6 +38,8 @@ typedef struct S390CPUDef {
S390FeatBitmap full_feat;
/* used to init full_feat from generated data */
S390FeatInit full_init;
+ /* if deprecated, provides a suggestion */
+ const char *deprecation_note;
} S390CPUDef;
/* CPU model based on a CPU definition */
diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c
index f6df691b66..b8de04de99 100644
--- a/target/s390x/cpu_models_sysemu.c
+++ b/target/s390x/cpu_models_sysemu.c
@@ -56,6 +56,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
CpuDefinitionInfo *info;
char *name = g_strdup(object_class_get_name(klass));
S390CPUClass *scc = S390_CPU_CLASS(klass);
+ CPUClass *cc = CPU_CLASS(klass);
/* strip off the -s390x-cpu */
g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0;
@@ -65,6 +66,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
info->migration_safe = scc->is_migration_safe;
info->q_static = scc->is_static;
info->q_typename = g_strdup(object_class_get_name(klass));
+ info->deprecated = !!cc->deprecation_note;
/* check for unavailable features */
if (cpu_list_data->model) {
Object *obj;
--
2.39.3

@ -1,44 +1,54 @@
From ec10588d2f5d748005e0dca42b299ae15868a900 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Fri, 19 Oct 2018 13:10:31 +0200
Subject: Add x86_64 machine types
From c8510c21f0fde361d6cbce81bfb2f4acb6941b58 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 13:44:41 +0100
Subject: Add downstream x86_64 versioned 'pc' & 'q35' machine types
Adding changes to add RHEL machine types for x86_64 architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase notes (9.1.0 rc0):
- Merged pc_q35_machine_rhel_options back into
pc_q35_machine_options to reduce delta to upstream
- Convert to new DEFINE_(I440FX|Q35)_MACHINE macros
Rebase notes (9.1.0 rc4):
- Moved x86 cpu deprecation note to device disable patch
Merged patches (9.1.0 rc0):
- 043ad5ce97 Add upstream compatibility bits (partial)
---
hw/i386/fw_cfg.c | 2 +-
hw/i386/pc.c | 159 ++++++++++++++++++++-
hw/i386/pc_piix.c | 109 ++++++++++++++
hw/i386/pc_q35.c | 285 +++++++++++++++++++++++++++++++++++++
hw/i386/pc.c | 159 ++++++++++++++++++++++++++++-
hw/i386/pc_piix.c | 102 ++++++++++++++++++-
hw/i386/pc_q35.c | 204 +++++++++++++++++++++++++++++++++++--
include/hw/boards.h | 2 +
include/hw/i386/pc.h | 33 +++++
target/i386/cpu.c | 21 +++
include/hw/i386/pc.h | 33 ++++++
target/i386/kvm/kvm-cpu.c | 1 +
target/i386/kvm/kvm.c | 4 +
tests/qtest/pvpanic-test.c | 5 +-
10 files changed, 617 insertions(+), 4 deletions(-)
9 files changed, 499 insertions(+), 13 deletions(-)
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index c7aa39a13e..283c3f4c16 100644
index 33ef280420..a322709ffa 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -63,7 +63,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
@@ -73,7 +73,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
if (pcmc->smbios_defaults) {
/* These values are guest ABI, do not change */
- smbios_set_defaults("QEMU", mc->desc, mc->name,
+ smbios_set_defaults("Red Hat", "KVM", mc->desc,
pcmc->smbios_uuid_encoded,
pcmc->smbios_stream_product, pcmc->smbios_stream_version);
}
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 5c21b0c4db..4a154c1a9a 100644
index 7779c88a91..a49d346d2e 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -326,6 +326,161 @@ GlobalProperty pc_compat_2_0[] = {
};
const size_t pc_compat_2_0_len = G_N_ELEMENTS(pc_compat_2_0);
@@ -276,6 +276,161 @@ const size_t pc_compat_2_4_len = G_N_ELEMENTS(pc_compat_2_4);
*/
#define PC_FW_DATA (0x20000 + 0x8000)
+/* This macro is for changes to properties that are RHEL specific,
+ * different to the current upstream and to be applied to the latest
@ -198,15 +208,15 @@ index 5c21b0c4db..4a154c1a9a 100644
GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled)
{
GSIState *s;
@@ -1813,6 +1968,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
pcmc->resizable_acpi_blob = true;
@@ -1767,6 +1922,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
pcmc->kvmclock_create_always = true;
x86mc->apic_xrupt_override = true;
assert(!mc->get_hotplug_handler);
+ mc->async_pf_vmexit_disable = false;
mc->get_hotplug_handler = pc_get_hotplug_handler;
mc->hotplug_allowed = pc_hotplug_allowed;
mc->cpu_index_to_instance_props = x86_cpu_index_to_props;
@@ -1823,7 +1979,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
mc->auto_enable_numa_with_memhp = true;
@@ -1774,7 +1930,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
mc->has_hotpluggable_cpus = true;
mc->default_boot_order = "cad";
mc->block_default_type = IF_IDE;
@ -217,7 +227,7 @@ index 5c21b0c4db..4a154c1a9a 100644
mc->wakeup = pc_machine_wakeup;
hc->pre_plug = pc_machine_device_pre_plug_cb;
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 18ba076609..a647262d63 100644
index 67107b174a..5535e1ffbf 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -52,6 +52,7 @@
@ -228,19 +238,21 @@ index 18ba076609..a647262d63 100644
#ifdef CONFIG_XEN
#include <xen/hvm/hvm_info_table.h>
#include "hw/xen/xen_pt.h"
@@ -422,6 +423,7 @@ static void pc_set_south_bridge(Object *obj, int value, Error **errp)
* hw_compat_*, pc_compat_*, or * pc_*_machine_options().
*/
@@ -445,8 +446,8 @@ static void pc_i440fx_init(MachineState *machine)
pc_init1(machine, TYPE_I440FX_PCI_DEVICE);
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void pc_compat_2_3_fn(MachineState *machine)
{
X86MachineState *x86ms = X86_MACHINE(machine);
@@ -951,3 +953,110 @@ static void xenfv_3_1_machine_options(MachineClass *m)
-#define DEFINE_I440FX_MACHINE(major, minor) \
- DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, major, minor);
+#define DEFINE_I440FX_MACHINE(major, minor, micro) \
+ DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, major, minor, micro);
#if 0 /* Disabled for Red Hat Enterprise Linux */
static void pc_i440fx_machine_options(MachineClass *m)
@@ -826,3 +827,100 @@ static void xenfv_machine_3_1_options(MachineClass *m)
DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init,
xenfv_3_1_machine_options);
xenfv_machine_3_1_options);
#endif
+#endif /* Disabled for Red Hat Enterprise Linux */
+
+/* Red Hat Enterprise Linux machine types */
+
@ -251,7 +263,6 @@ index 18ba076609..a647262d63 100644
+ m->family = "pc_piix_Y";
+ m->default_machine_opts = "firmware=bios-256k.bin,hpet=off";
+ pcmc->pci_root_uid = 0;
+ pcmc->resizable_acpi_blob = true;
+ m->default_nic = "e1000";
+ m->default_display = "std";
+ m->no_parallel = 1;
@ -264,12 +275,7 @@ index 18ba076609..a647262d63 100644
+ m->smp_props.prefer_sockets = true;
+}
+
+static void pc_init_rhel760(MachineState *machine)
+{
+ pc_init1(machine, TYPE_I440FX_PCI_DEVICE);
+}
+
+static void pc_machine_rhel760_options(MachineClass *m)
+static void pc_i440fx_rhel_machine_7_6_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ ObjectClass *oc = OBJECT_CLASS(m);
@ -278,9 +284,6 @@ index 18ba076609..a647262d63 100644
+ m->async_pf_vmexit_disable = true;
+ m->smbus_no_migration_support = true;
+
+ /* All RHEL machines for prior major releases are deprecated */
+ m->deprecation_reason = rhel_old_machine_deprecation;
+
+ pcmc->pvh_enabled = false;
+ pcmc->default_cpu_version = CPU_VERSION_LEGACY;
+ pcmc->kvmclock_create_always = false;
@ -302,7 +305,8 @@ index 18ba076609..a647262d63 100644
+ object_class_property_set_description(oc, "x-south-bridge",
+ "Use a different south bridge than PIIX3");
+
+
+ compat_props_add(m->compat_props, hw_compat_rhel_9_5,
+ hw_compat_rhel_9_5_len);
+ compat_props_add(m->compat_props, hw_compat_rhel_9_4,
+ hw_compat_rhel_9_4_len);
+ compat_props_add(m->compat_props, hw_compat_rhel_9_3,
@ -345,78 +349,63 @@ index 18ba076609..a647262d63 100644
+ compat_props_add(m->compat_props, pc_rhel_7_6_compat, pc_rhel_7_6_compat_len);
+}
+
+DEFINE_PC_MACHINE(rhel760, "pc-i440fx-rhel7.6.0", pc_init_rhel760,
+ pc_machine_rhel760_options);
+DEFINE_I440FX_MACHINE(7, 6, 0);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index c7bc8a2041..e872dc7e46 100644
index 5fb283f2df..2ca9ff3747 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -341,6 +341,7 @@ static void pc_q35_init(MachineState *machine)
DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn)
@@ -338,20 +338,19 @@ static void pc_q35_machine_options(MachineClass *m)
pcmc->pci_root_uid = 0;
pcmc->default_cpu_version = 1;
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void pc_q35_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
@@ -693,3 +694,287 @@ static void pc_q35_2_4_machine_options(MachineClass *m)
DEFINE_Q35_MACHINE(v2_4, "pc-q35-2.4", NULL,
pc_q35_2_4_machine_options);
+#endif /* Disabled for Red Hat Enterprise Linux */
+
+/* Red Hat Enterprise Linux machine types */
+
+/* Options for the latest rhel q35 machine type */
+static void pc_q35_machine_rhel_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pcmc->pci_root_uid = 0;
+ m->default_nic = "e1000e";
- m->family = "pc_q35";
- m->desc = "Standard PC (Q35 + ICH9, 2009)";
+ m->family = "pc_q35_Z";
+ m->units_per_default_bus = 1;
m->units_per_default_bus = 1;
- m->default_machine_opts = "firmware=bios-256k.bin";
+ m->default_machine_opts = "firmware=bios-256k.bin,hpet=off";
+ m->default_display = "std";
+ m->no_floppy = 1;
m->default_display = "std";
m->default_nic = "e1000e";
- m->default_kernel_irqchip_split = false;
m->no_floppy = 1;
- m->max_cpus = 4096;
- m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL);
+ m->max_cpus = 710;
+ m->no_parallel = 1;
+ pcmc->default_cpu_version = 1;
+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_AMD_IOMMU_DEVICE);
+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE);
+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
machine_class_allow_dynamic_sysbus_dev(m, TYPE_AMD_IOMMU_DEVICE);
machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE);
machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
- machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
+ m->alias = "q35";
+ m->max_cpus = 710;
+ compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len);
+ compat_props_add(m->compat_props,
+ pc_q35_compat_defaults, pc_q35_compat_defaults_len);
+}
compat_props_add(m->compat_props,
pc_q35_compat_defaults, pc_q35_compat_defaults_len);
}
@@ -670,3 +669,194 @@ static void pc_q35_machine_2_4_options(MachineClass *m)
DEFINE_Q35_MACHINE(2, 4);
#endif /* Disabled for Red Hat Enterprise Linux */
+
+static void pc_q35_init_rhel940(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+/* Red Hat Enterprise Linux machine types */
+
+static void pc_q35_machine_rhel940_options(MachineClass *m)
+static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel_options(m);
+ pc_q35_machine_options(m);
+ m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)";
+ pcmc->smbios_stream_product = "RHEL";
+ pcmc->smbios_stream_version = "9.4.0";
+}
+
+DEFINE_PC_MACHINE(q35_rhel940, "pc-q35-rhel9.4.0", pc_q35_init_rhel940,
+ pc_q35_machine_rhel940_options);
+
+
+static void pc_q35_init_rhel920(MachineState *machine)
+{
+ pc_q35_init(machine);
+ compat_props_add(m->compat_props, hw_compat_rhel_9_5,
+ hw_compat_rhel_9_5_len);
+}
+
+static void pc_q35_machine_rhel920_options(MachineClass *m)
+DEFINE_Q35_MACHINE_BUGFIX(9, 4, 0);
+
+static void pc_q35_rhel_machine_9_2_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel940_options(m);
+ pc_q35_rhel_machine_9_4_0_options(m);
+ m->desc = "RHEL-9.2.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL;
+ pcmc->smbios_stream_product = "RHEL";
@ -439,18 +428,12 @@ index c7bc8a2041..e872dc7e46 100644
+ pc_rhel_9_2_compat_len);
+}
+
+DEFINE_PC_MACHINE(q35_rhel920, "pc-q35-rhel9.2.0", pc_q35_init_rhel920,
+ pc_q35_machine_rhel920_options);
+DEFINE_Q35_MACHINE_BUGFIX(9, 2, 0);
+
+static void pc_q35_init_rhel900(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+
+static void pc_q35_machine_rhel900_options(MachineClass *m)
+static void pc_q35_rhel_machine_9_0_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel920_options(m);
+ pc_q35_rhel_machine_9_2_0_options(m);
+ m->desc = "RHEL-9.0.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL;
+ pcmc->smbios_stream_product = "RHEL";
@ -464,43 +447,27 @@ index c7bc8a2041..e872dc7e46 100644
+ pc_rhel_9_0_compat_len);
+}
+
+DEFINE_PC_MACHINE(q35_rhel900, "pc-q35-rhel9.0.0", pc_q35_init_rhel900,
+ pc_q35_machine_rhel900_options);
+DEFINE_Q35_MACHINE_BUGFIX(9, 0, 0);
+
+static void pc_q35_init_rhel860(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+
+static void pc_q35_machine_rhel860_options(MachineClass *m)
+static void pc_q35_rhel_machine_8_6_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel900_options(m);
+ pc_q35_rhel_machine_9_0_0_options(m);
+ m->desc = "RHEL-8.6.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL;
+
+ /* All RHEL machines for prior major releases are deprecated */
+ m->deprecation_reason = rhel_old_machine_deprecation;
+
+ pcmc->smbios_stream_product = "RHEL-AV";
+ pcmc->smbios_stream_version = "8.6.0";
+ compat_props_add(m->compat_props, hw_compat_rhel_8_6,
+ hw_compat_rhel_8_6_len);
+}
+
+DEFINE_PC_MACHINE(q35_rhel860, "pc-q35-rhel8.6.0", pc_q35_init_rhel860,
+ pc_q35_machine_rhel860_options);
+
+DEFINE_Q35_MACHINE_BUGFIX(8, 6, 0);
+
+static void pc_q35_init_rhel850(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+
+static void pc_q35_machine_rhel850_options(MachineClass *m)
+static void pc_q35_rhel_machine_8_5_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel860_options(m);
+ pc_q35_rhel_machine_8_6_0_options(m);
+ m->desc = "RHEL-8.5.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL;
+ pcmc->smbios_stream_product = "RHEL-AV";
@ -512,19 +479,12 @@ index c7bc8a2041..e872dc7e46 100644
+ m->smp_props.prefer_sockets = true;
+}
+
+DEFINE_PC_MACHINE(q35_rhel850, "pc-q35-rhel8.5.0", pc_q35_init_rhel850,
+ pc_q35_machine_rhel850_options);
+DEFINE_Q35_MACHINE_BUGFIX(8, 5, 0);
+
+
+static void pc_q35_init_rhel840(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+
+static void pc_q35_machine_rhel840_options(MachineClass *m)
+static void pc_q35_rhel_machine_8_4_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel850_options(m);
+ pc_q35_rhel_machine_8_5_0_options(m);
+ m->desc = "RHEL-8.4.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL;
+ pcmc->smbios_stream_product = "RHEL-AV";
@ -535,19 +495,12 @@ index c7bc8a2041..e872dc7e46 100644
+ pc_rhel_8_4_compat_len);
+}
+
+DEFINE_PC_MACHINE(q35_rhel840, "pc-q35-rhel8.4.0", pc_q35_init_rhel840,
+ pc_q35_machine_rhel840_options);
+DEFINE_Q35_MACHINE_BUGFIX(8, 4, 0);
+
+
+static void pc_q35_init_rhel830(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+
+static void pc_q35_machine_rhel830_options(MachineClass *m)
+static void pc_q35_rhel_machine_8_3_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel840_options(m);
+ pc_q35_rhel_machine_8_4_0_options(m);
+ m->desc = "RHEL-8.3.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL;
+ pcmc->smbios_stream_product = "RHEL-AV";
@ -562,18 +515,12 @@ index c7bc8a2041..e872dc7e46 100644
+ pcmc->pci_root_uid = 1;
+}
+
+DEFINE_PC_MACHINE(q35_rhel830, "pc-q35-rhel8.3.0", pc_q35_init_rhel830,
+ pc_q35_machine_rhel830_options);
+
+static void pc_q35_init_rhel820(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+DEFINE_Q35_MACHINE_BUGFIX(8, 3, 0);
+
+static void pc_q35_machine_rhel820_options(MachineClass *m)
+static void pc_q35_rhel_machine_8_2_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel830_options(m);
+ pc_q35_rhel_machine_8_3_0_options(m);
+ m->desc = "RHEL-8.2.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL;
+ m->numa_mem_supported = true;
@ -586,18 +533,12 @@ index c7bc8a2041..e872dc7e46 100644
+ pc_rhel_8_2_compat_len);
+}
+
+DEFINE_PC_MACHINE(q35_rhel820, "pc-q35-rhel8.2.0", pc_q35_init_rhel820,
+ pc_q35_machine_rhel820_options);
+DEFINE_Q35_MACHINE_BUGFIX(8, 2, 0);
+
+static void pc_q35_init_rhel810(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+
+static void pc_q35_machine_rhel810_options(MachineClass *m)
+static void pc_q35_rhel_machine_8_1_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel820_options(m);
+ pc_q35_rhel_machine_8_2_0_options(m);
+ m->desc = "RHEL-8.1.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL;
+ pcmc->smbios_stream_product = NULL;
@ -606,18 +547,12 @@ index c7bc8a2041..e872dc7e46 100644
+ compat_props_add(m->compat_props, pc_rhel_8_1_compat, pc_rhel_8_1_compat_len);
+}
+
+DEFINE_PC_MACHINE(q35_rhel810, "pc-q35-rhel8.1.0", pc_q35_init_rhel810,
+ pc_q35_machine_rhel810_options);
+DEFINE_Q35_MACHINE_BUGFIX(8, 1, 0);
+
+static void pc_q35_init_rhel800(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+
+static void pc_q35_machine_rhel800_options(MachineClass *m)
+static void pc_q35_rhel_machine_8_0_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel810_options(m);
+ pc_q35_rhel_machine_8_1_0_options(m);
+ m->desc = "RHEL-8.0.0 PC (Q35 + ICH9, 2009)";
+ m->smbus_no_migration_support = true;
+ m->alias = NULL;
@ -627,17 +562,11 @@ index c7bc8a2041..e872dc7e46 100644
+ compat_props_add(m->compat_props, pc_rhel_8_0_compat, pc_rhel_8_0_compat_len);
+}
+
+DEFINE_PC_MACHINE(q35_rhel800, "pc-q35-rhel8.0.0", pc_q35_init_rhel800,
+ pc_q35_machine_rhel800_options);
+
+static void pc_q35_init_rhel760(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+DEFINE_Q35_MACHINE_BUGFIX(8, 0, 0);
+
+static void pc_q35_machine_rhel760_options(MachineClass *m)
+static void pc_q35_rhel_machine_7_6_0_options(MachineClass *m)
+{
+ pc_q35_machine_rhel800_options(m);
+ pc_q35_rhel_machine_8_0_0_options(m);
+ m->alias = NULL;
+ m->desc = "RHEL-7.6.0 PC (Q35 + ICH9, 2009)";
+ m->async_pf_vmexit_disable = true;
@ -645,13 +574,13 @@ index c7bc8a2041..e872dc7e46 100644
+ compat_props_add(m->compat_props, pc_rhel_7_6_compat, pc_rhel_7_6_compat_len);
+}
+
+DEFINE_PC_MACHINE(q35_rhel760, "pc-q35-rhel7.6.0", pc_q35_init_rhel760,
+ pc_q35_machine_rhel760_options);
+DEFINE_Q35_MACHINE_BUGFIX(7, 6, 0);
+
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 0466f9d0f3..46b8725c41 100644
index fd5a957cad..3dea5cee73 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -283,6 +283,8 @@ struct MachineClass {
@@ -289,6 +289,8 @@ struct MachineClass {
strList *allowed_dynamic_sysbus_devices;
bool auto_enable_numa_with_memhp;
bool auto_enable_numa_with_memdev;
@ -661,12 +590,12 @@ index 0466f9d0f3..46b8725c41 100644
bool smbus_no_migration_support;
bool nvdimm_supported;
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index ebd8f973f2..a984c951ad 100644
index 8776a3c937..8e9597f40f 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -291,6 +291,39 @@ extern const size_t pc_compat_2_1_len;
extern GlobalProperty pc_compat_2_0[];
extern const size_t pc_compat_2_0_len;
@@ -302,6 +302,39 @@ extern const size_t pc_compat_2_4_len;
extern GlobalProperty pc_compat_2_3[];
extern const size_t pc_compat_2_3_len;
+extern GlobalProperty pc_rhel_compat[];
+extern const size_t pc_rhel_compat_len;
@ -704,165 +633,11 @@ index ebd8f973f2..a984c951ad 100644
#define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \
static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *data) \
{ \
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 33760a2ee1..be7b0663cd 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2190,9 +2190,13 @@ static const CPUCaches epyc_genoa_cache_info = {
* PT in VMX operation
*/
+#define RHEL_CPU_DEPRECATION \
+ "use at least 'Nehalem' / 'Opteron_G4', or 'host' / 'max'"
+
static const X86CPUDefinition builtin_x86_defs[] = {
{
.name = "qemu64",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 0xd,
.vendor = CPUID_VENDOR_AMD,
.family = 15,
@@ -2213,6 +2217,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "phenom",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 16,
@@ -2245,6 +2250,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "core2duo",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 10,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2287,6 +2293,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "kvm64",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 15,
@@ -2328,6 +2335,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "qemu32",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 4,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2342,6 +2350,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "kvm32",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_INTEL,
.family = 15,
@@ -2372,6 +2381,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "coreduo",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 10,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2405,6 +2415,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "486",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 1,
.vendor = CPUID_VENDOR_INTEL,
.family = 4,
@@ -2417,6 +2428,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "pentium",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 1,
.vendor = CPUID_VENDOR_INTEL,
.family = 5,
@@ -2429,6 +2441,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "pentium2",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 2,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2441,6 +2454,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "pentium3",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 3,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2453,6 +2467,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "athlon",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 2,
.vendor = CPUID_VENDOR_AMD,
.family = 6,
@@ -2468,6 +2483,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "n270",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 10,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2493,6 +2509,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Conroe",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 10,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2533,6 +2550,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Penryn",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 10,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -4394,6 +4412,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Opteron_G1",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 15,
@@ -4414,6 +4433,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Opteron_G2",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 15,
@@ -4436,6 +4456,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Opteron_G3",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 16,
diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c
index 9c791b7b05..b91af5051f 100644
index 6bf8dcfc60..684e731cbc 100644
--- a/target/i386/kvm/kvm-cpu.c
+++ b/target/i386/kvm/kvm-cpu.c
@@ -138,6 +138,7 @@ static PropValue kvm_default_props[] = {
@@ -178,6 +178,7 @@ static PropValue kvm_default_props[] = {
{ "acpi", "off" },
{ "monitor", "off" },
{ "svm", "off" },
@ -871,10 +646,10 @@ index 9c791b7b05..b91af5051f 100644
};
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index e68cbe9293..739f33db47 100644
index 2fa88ef1e3..2b28c18693 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -3715,6 +3715,7 @@ static int kvm_get_msrs(X86CPU *cpu)
@@ -4244,6 +4244,7 @@ static int kvm_get_msrs(X86CPU *cpu)
struct kvm_msr_entry *msrs = cpu->kvm_msr_buf->entries;
int ret, i;
uint64_t mtrr_top_bits;
@ -882,7 +657,7 @@ index e68cbe9293..739f33db47 100644
kvm_msr_buf_reset(cpu);
@@ -4069,6 +4070,9 @@ static int kvm_get_msrs(X86CPU *cpu)
@@ -4636,6 +4637,9 @@ static int kvm_get_msrs(X86CPU *cpu)
break;
case MSR_KVM_ASYNC_PF_EN:
env->async_pf_en_msr = msrs[i].data;
@ -893,10 +668,10 @@ index e68cbe9293..739f33db47 100644
case MSR_KVM_ASYNC_PF_INT:
env->async_pf_int_msr = msrs[i].data;
diff --git a/tests/qtest/pvpanic-test.c b/tests/qtest/pvpanic-test.c
index 78f1cf8186..ac954c9b06 100644
index d49d2ba931..c18f63e255 100644
--- a/tests/qtest/pvpanic-test.c
+++ b/tests/qtest/pvpanic-test.c
@@ -17,7 +17,7 @@ static void test_panic_nopause(void)
@@ -18,7 +18,7 @@ static void test_panic_nopause(void)
QDict *response, *data;
QTestState *qts;
@ -904,8 +679,8 @@ index 78f1cf8186..ac954c9b06 100644
+ qts = qtest_init("-M q35 -device pvpanic -action panic=none");
val = qtest_inb(qts, 0x505);
g_assert_cmpuint(val, ==, 3);
@@ -40,7 +40,8 @@ static void test_panic(void)
g_assert_cmpuint(val, ==, PVPANIC_EVENTS);
@@ -41,7 +41,8 @@ static void test_panic(void)
QDict *response, *data;
QTestState *qts;
@ -914,7 +689,7 @@ index 78f1cf8186..ac954c9b06 100644
+ qts = qtest_init("-M q35 -device pvpanic -action panic=pause");
val = qtest_inb(qts, 0x505);
g_assert_cmpuint(val, ==, 3);
g_assert_cmpuint(val, ==, PVPANIC_EVENTS);
--
2.39.3

@ -0,0 +1,32 @@
From bd6f1170d3a011c475ec4a8315512c7c190de3e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 13:47:04 +0100
Subject: Revert "meson: temporarily disable -Wunused-function"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reverts commit c682111eaa73d9b985187b8be330338f50b78a7a.
No longer needed after introduction of downstream machines.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
meson.build | 1 -
1 file changed, 1 deletion(-)
diff --git a/meson.build b/meson.build
index 2de5ab024f..b3529aa0e1 100644
--- a/meson.build
+++ b/meson.build
@@ -651,7 +651,6 @@ warn_flags = [
'-Wno-string-plus-int',
'-Wno-tautological-type-limit-compare',
'-Wno-typedef-redefinition',
- '-Wno-unused-function',
]
if host_os != 'darwin'
--
2.39.3

@ -1,145 +0,0 @@
From 043ad5ce9789dbbfe1a888de58f6039ea7ae47a4 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 20 Mar 2024 05:34:32 -0400
Subject: Add upstream compatibility bits
Adding new compats structure for changes introduced during rebase to QEMU 9.0.0.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase notes (9.0.0 rc2):
- Add aw-bits setting for aarch compat record (overwritten for 9.4 and older)
---
hw/arm/virt.c | 6 ++++--
hw/core/machine.c | 10 ++++++++++
hw/i386/pc_piix.c | 3 ++-
hw/i386/pc_q35.c | 3 +++
hw/s390x/s390-virtio-ccw.c | 1 +
include/hw/boards.h | 3 +++
6 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 22bc345137..3f0496cdb9 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -85,6 +85,7 @@
#include "hw/char/pl011.h"
#include "qemu/guest-random.h"
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static GlobalProperty arm_virt_compat[] = {
{ TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" },
};
@@ -101,7 +102,6 @@ static void arm_virt_compat_set(MachineClass *mc)
arm_virt_compat_len);
}
-#if 0 /* Disabled for Red Hat Enterprise Linux */
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
void *data) \
@@ -144,6 +144,8 @@ GlobalProperty arm_rhel_compat[] = {
{"virtio-net-pci", "romfile", "" },
{"virtio-net-pci-transitional", "romfile", "" },
{"virtio-net-pci-non-transitional", "romfile", "" },
+ /* arm_rhel_compat from arm_virt_compat, added for 9.0.0 rebase */
+ { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" },
};
const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat);
@@ -3534,7 +3536,6 @@ static void rhel_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
- arm_virt_compat_set(mc);
mc->family = "virt-rhel-Z";
mc->init = machvirt_init;
@@ -3728,6 +3729,7 @@ type_init(rhel_machine_init);
static void rhel940_virt_options(MachineClass *mc)
{
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
}
DEFINE_RHEL_MACHINE_AS_LATEST(9, 4, 0)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 695cb89a46..0f256d9633 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -302,6 +302,16 @@ const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
const char *rhel_old_machine_deprecation =
"machine types for previous major releases are deprecated";
+GlobalProperty hw_compat_rhel_9_5[] = {
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { "migration", "zero-page-detection", "legacy"},
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { TYPE_VIRTIO_IOMMU_PCI, "granule", "4k" },
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" },
+};
+const size_t hw_compat_rhel_9_5_len = G_N_ELEMENTS(hw_compat_rhel_9_5);
+
GlobalProperty hw_compat_rhel_9_4[] = {
/* hw_compat_rhel_9_4 from hw_compat_8_0 */
{ TYPE_VIRTIO_NET, "host_uso", "off"},
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index a647262d63..6b260682eb 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -1015,7 +1015,8 @@ static void pc_machine_rhel760_options(MachineClass *m)
object_class_property_set_description(oc, "x-south-bridge",
"Use a different south bridge than PIIX3");
-
+ compat_props_add(m->compat_props, hw_compat_rhel_9_5,
+ hw_compat_rhel_9_5_len);
compat_props_add(m->compat_props, hw_compat_rhel_9_4,
hw_compat_rhel_9_4_len);
compat_props_add(m->compat_props, hw_compat_rhel_9_3,
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index e872dc7e46..2b54944c0f 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -733,6 +733,9 @@ static void pc_q35_machine_rhel940_options(MachineClass *m)
m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)";
pcmc->smbios_stream_product = "RHEL";
pcmc->smbios_stream_version = "9.4.0";
+
+ compat_props_add(m->compat_props, hw_compat_rhel_9_5,
+ hw_compat_rhel_9_5_len);
}
DEFINE_PC_MACHINE(q35_rhel940, "pc-q35-rhel9.4.0", pc_q35_init_rhel940,
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index ff753a29e0..9ad54682c6 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -1282,6 +1282,7 @@ static void ccw_machine_rhel940_instance_options(MachineState *machine)
static void ccw_machine_rhel940_class_options(MachineClass *mc)
{
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
}
DEFINE_CCW_MACHINE(rhel940, "rhel9.4.0", true);
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 46b8725c41..cca62f906b 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -514,6 +514,9 @@ extern const size_t hw_compat_2_2_len;
extern GlobalProperty hw_compat_2_1[];
extern const size_t hw_compat_2_1_len;
+extern GlobalProperty hw_compat_rhel_9_5[];
+extern const size_t hw_compat_rhel_9_5_len;
+
extern GlobalProperty hw_compat_rhel_9_4[];
extern const size_t hw_compat_rhel_9_4_len;
--
2.39.3

@ -1,4 +1,4 @@
From 241ad69d849fce983685fc754fc0572c5b737cbe Mon Sep 17 00:00:00 2001
From 3c4bab07566d32859e227ca1083b0dc64111e3f7 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 2 Sep 2020 09:39:41 +0200
Subject: Enable make check
@ -7,11 +7,18 @@ Fixing tests after device disabling and machine types changes and enabling
make check run during build.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase notes (9.1.0 rc0):
- Disable fdc-testa
Rebase notes (9.1.0 rc0):
- Use q35 machine type for new pvpanic test
---
.distro/qemu-kvm.spec.template | 4 ++--
tests/avocado/replay_kernel.py | 2 +-
tests/avocado/reverse_debugging.py | 2 +-
tests/avocado/tcg_plugins.py | 6 ++---
tests/avocado/tcg_plugins.py | 4 ++--
tests/qemu-iotests/meson.build | 34 ++++++++++++++---------------
tests/qemu-iotests/testenv.py | 3 +++
tests/qtest/fuzz-e1000e-test.c | 2 +-
@ -19,15 +26,16 @@ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
tests/qtest/intel-hda-test.c | 2 +-
tests/qtest/libqos/meson.build | 2 +-
tests/qtest/lpc-ich9-test.c | 2 +-
tests/qtest/meson.build | 1 -
tests/qtest/meson.build | 3 +--
tests/qtest/pvpanic-test.c | 2 +-
tests/qtest/virtio-net-failover.c | 1 +
13 files changed, 33 insertions(+), 30 deletions(-)
14 files changed, 34 insertions(+), 31 deletions(-)
diff --git a/tests/avocado/replay_kernel.py b/tests/avocado/replay_kernel.py
index 10d99403a4..c3422ea1e4 100644
index e22c200a36..cb7ca19b1b 100644
--- a/tests/avocado/replay_kernel.py
+++ b/tests/avocado/replay_kernel.py
@@ -166,7 +166,7 @@ def test_aarch64_virt(self):
@@ -193,7 +193,7 @@ def test_aarch64_virt(self):
"""
:avocado: tags=arch:aarch64
:avocado: tags=machine:virt
@ -37,10 +45,10 @@ index 10d99403a4..c3422ea1e4 100644
kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
'/linux/releases/29/Everything/aarch64/os/images/pxeboot'
diff --git a/tests/avocado/reverse_debugging.py b/tests/avocado/reverse_debugging.py
index 92855a02a5..87822074b6 100644
index f24287cd0a..3880b81df6 100644
--- a/tests/avocado/reverse_debugging.py
+++ b/tests/avocado/reverse_debugging.py
@@ -230,7 +230,7 @@ def test_aarch64_virt(self):
@@ -228,7 +228,7 @@ def test_aarch64_virt(self):
"""
:avocado: tags=arch:aarch64
:avocado: tags=machine:virt
@ -50,7 +58,7 @@ index 92855a02a5..87822074b6 100644
kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
'/linux/releases/29/Everything/aarch64/os/images/pxeboot'
diff --git a/tests/avocado/tcg_plugins.py b/tests/avocado/tcg_plugins.py
index 15fd87b2c1..f0d9d89c93 100644
index a6ff457e27..5172ee9b9e 100644
--- a/tests/avocado/tcg_plugins.py
+++ b/tests/avocado/tcg_plugins.py
@@ -66,7 +66,7 @@ def test_aarch64_virt_insn(self):
@ -67,15 +75,6 @@ index 15fd87b2c1..f0d9d89c93 100644
:avocado: tags=arch:aarch64
:avocado: tags=machine:virt
- :avocado: tags=cpu:cortex-a53
+ :avocado: tags=cpu:cortex-a57
"""
kernel_path = self._grab_aarch64_kernel()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
@@ -126,7 +126,7 @@ def test_aarch64_virt_mem_icount(self):
:avocado: tags=accel:tcg
:avocado: tags=arch:aarch64
:avocado: tags=machine:virt
- :avocado: tags=cpu:cortex-a53
+ :avocado: tags=cpu:cortex-a57
"""
kernel_path = self._grab_aarch64_kernel()
@ -124,10 +123,10 @@ index fad340ad59..3c0d5241f6 100644
+# endforeach
endforeach
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
index 588f30a4f1..3929a3634f 100644
index c8848f2ec2..d515e5b8b0 100644
--- a/tests/qemu-iotests/testenv.py
+++ b/tests/qemu-iotests/testenv.py
@@ -244,6 +244,9 @@ def __init__(self, source_dir: str, build_dir: str,
@@ -249,6 +249,9 @@ def __init__(self, source_dir: str, build_dir: str,
if self.qemu_prog.endswith(f'qemu-system-{suffix}'):
self.qemu_options += f' -machine {machine}'
@ -177,7 +176,7 @@ index 663bb6c485..2efc43e3f7 100644
"-device intel-hda,id=" HDA_ID CODEC_DEVICES);
diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
index 3aed6efcb8..119613237e 100644
index 1b2b2dbb22..86afbddb58 100644
--- a/tests/qtest/libqos/meson.build
+++ b/tests/qtest/libqos/meson.build
@@ -44,7 +44,7 @@ libqos_srcs = files(
@ -203,10 +202,19 @@ index 8ac95b89f7..0e118b76eb 100644
qtest_outl(s, 0xcf8, 0x8000f840); /* PMBASE */
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 36c5c13a7b..a2887d6057 100644
index 2f0d3ef080..134c48c10e 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -101,7 +101,6 @@ qtests_i386 = \
@@ -91,7 +91,7 @@ qtests_i386 = \
config_all_devices.has_key('CONFIG_PARALLEL') ? ['bios-tables-test'] : []) + \
qtests_pci + \
qtests_cxl + \
- ['fdc-test',
+ [
'ide-test',
'hd-geo-test',
'boot-order-test',
@@ -102,7 +102,6 @@ qtests_i386 = \
'drive_del-test',
'tco-test',
'cpu-plug-test',
@ -214,6 +222,19 @@ index 36c5c13a7b..a2887d6057 100644
'vmgenid-test',
'migration-test',
'test-x86-cpuid-compat',
diff --git a/tests/qtest/pvpanic-test.c b/tests/qtest/pvpanic-test.c
index c18f63e255..57fb129ae4 100644
--- a/tests/qtest/pvpanic-test.c
+++ b/tests/qtest/pvpanic-test.c
@@ -65,7 +65,7 @@ static void test_pvshutdown(void)
QDict *response, *data;
QTestState *qts;
- qts = qtest_init("-device pvpanic");
+ qts = qtest_init("-M q35 -device pvpanic");
val = qtest_inb(qts, 0x505);
g_assert_cmpuint(val, ==, PVPANIC_EVENTS);
diff --git a/tests/qtest/virtio-net-failover.c b/tests/qtest/virtio-net-failover.c
index 73dfabc272..a9dd304781 100644
--- a/tests/qtest/virtio-net-failover.c

@ -1,29 +0,0 @@
From f24c7a1feef2a6f153582c06f10871b78a014bf1 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Fri, 26 Apr 2024 05:58:31 -0400
Subject: Disable FDC devices
---
configs/devices/x86_64-softmmu/x86_64-rh-devices.mak | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
index d60ff1bcfc..ee75bb4c21 100644
--- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
@@ -19,9 +19,9 @@ CONFIG_DIMM=y
CONFIG_E1000E_PCI_EXPRESS=y
CONFIG_E1000_PCI=y
CONFIG_EDU=y
-CONFIG_FDC=y
-CONFIG_FDC_SYSBUS=y
-CONFIG_FDC_ISA=y
+#CONFIG_FDC=y
+#CONFIG_FDC_SYSBUS=y
+#CONFIG_FDC_ISA=y
CONFIG_FW_CFG_DMA=y
CONFIG_HDA=y
CONFIG_HYPERV=y
--
2.39.3

@ -1,4 +1,4 @@
From 8ba1a6d1a432e2ae82ae532253c2b254e6ce82a7 Mon Sep 17 00:00:00 2001
From 9813098fb73e899dd1d824f9c1e7e570a87b1771 Mon Sep 17 00:00:00 2001
From: Bandan Das <bsd@redhat.com>
Date: Tue, 3 Dec 2013 20:05:13 +0100
Subject: vfio: cap number of devices that can be assigned
@ -23,7 +23,7 @@ Signed-off-by: Bandan Das <bsd@redhat.com>
2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 64780d1b79..57ac63c10c 100644
index 2407720c35..82a47edc89 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -50,6 +50,9 @@
@ -36,19 +36,16 @@ index 64780d1b79..57ac63c10c 100644
static void vfio_disable_interrupts(VFIOPCIDevice *vdev);
static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled);
static void vfio_msi_disable_common(VFIOPCIDevice *vdev);
@@ -2946,13 +2949,36 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
@@ -2963,10 +2966,33 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
ERRP_GUARD();
VFIOPCIDevice *vdev = VFIO_PCI(pdev);
VFIODevice *vbasedev = &vdev->vbasedev;
+ VFIODevice *vbasedev_iter;
+ VFIOGroup *group;
char *tmp, *subsys;
Error *err = NULL;
- int i, ret;
+ int ret, i = 0;
bool is_mdev;
+ VFIODevice *vbasedev_iter;
+ VFIOGroup *group;
char uuid[UUID_STR_LEN];
char *name;
g_autofree char *name = NULL;
+ if (device_limit && device_limit != vdev->assigned_device_limit) {
+ error_setg(errp, "Assigned device limit has been redefined. "
@ -74,7 +71,7 @@ index 64780d1b79..57ac63c10c 100644
if (vbasedev->fd < 0 && !vbasedev->sysfsdev) {
if (!(~vdev->host.domain || ~vdev->host.bus ||
~vdev->host.slot || ~vdev->host.function)) {
@@ -3370,6 +3396,9 @@ static Property vfio_pci_dev_properties[] = {
@@ -3388,6 +3414,9 @@ static Property vfio_pci_dev_properties[] = {
DEFINE_PROP_BOOL("x-no-kvm-msix", VFIOPCIDevice, no_kvm_msix, false),
DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice,
no_geforce_quirks, false),
@ -85,7 +82,7 @@ index 64780d1b79..57ac63c10c 100644
false),
DEFINE_PROP_BOOL("x-no-vfio-ioeventfd", VFIOPCIDevice, no_vfio_ioeventfd,
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 6e64a2654e..b7de39c010 100644
index bf67df2fbc..0d3c93fb2e 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -142,6 +142,7 @@ struct VFIOPCIDevice {

@ -1,4 +1,4 @@
From 7bc7a2d39bb2c00bcc8e573f05e629f5f21edc35 Mon Sep 17 00:00:00 2001
From e46f7b696ec32b18969c9cd7c1553d7d30e489b3 Mon Sep 17 00:00:00 2001
From: Eduardo Habkost <ehabkost@redhat.com>
Date: Wed, 4 Dec 2013 18:53:17 +0100
Subject: Add support statement to -help output
@ -12,10 +12,10 @@ Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
1 file changed, 9 insertions(+)
diff --git a/system/vl.c b/system/vl.c
index c644222982..03c3b0aa94 100644
index 01b8b8e77a..5359231bf5 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -869,9 +869,17 @@ static void version(void)
@@ -877,9 +877,17 @@ static void version(void)
QEMU_COPYRIGHT "\n");
}
@ -33,7 +33,7 @@ index c644222982..03c3b0aa94 100644
printf("usage: %s [options] [disk_image]\n\n"
"'disk_image' is a raw hard disk image for IDE hard disk 0\n\n",
g_get_prgname());
@@ -897,6 +905,7 @@ static void help(int exitcode)
@@ -905,6 +913,7 @@ static void help(int exitcode)
"\n"
QEMU_HELP_BOTTOM "\n");

@ -1,24 +0,0 @@
From fe8c6cb1cecb3cde16871c4ec7368e4d004fa42a Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Fri, 26 Apr 2024 05:59:53 -0400
Subject: Disable vga-cirrus device
---
configs/devices/x86_64-softmmu/x86_64-rh-devices.mak | 1 -
1 file changed, 1 deletion(-)
diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
index ee75bb4c21..fe69f04ead 100644
--- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
@@ -87,7 +87,6 @@ CONFIG_USB_XHCI_PCI=y
CONFIG_VFIO=y
CONFIG_VFIO_PCI=y
CONFIG_VGA=y
-CONFIG_VGA_CIRRUS=y
CONFIG_VGA_PCI=y
CONFIG_VHOST_USER=y
CONFIG_VHOST_USER_BLK=y
--
2.39.3

@ -1,4 +1,4 @@
From ec651d300d350a37219b09f5baab827ae6891006 Mon Sep 17 00:00:00 2001
From 40274d161d20719709d92356077175f93795ea1e Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 8 Jul 2020 08:35:50 +0200
Subject: Use qemu-kvm in documentation instead of qemu-system-<arch>
@ -27,10 +27,10 @@ index 52d6454b93..d74dbdeca9 100644
.. |I2C| replace:: I\ :sup:`2`\ C
.. |I2S| replace:: I\ :sup:`2`\ S
diff --git a/qemu-options.hx b/qemu-options.hx
index 8ce85d4559..4fc27ee2e2 100644
index d94e2cbbae..a7444abc7f 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3493,11 +3493,11 @@ SRST
@@ -3688,11 +3688,11 @@ SRST
::

@ -1,4 +1,4 @@
From 080f22d8fb8ca63996f1b6ecb3637033529d8016 Mon Sep 17 00:00:00 2001
From 728e3d8a124f4ec51c005ad6867270f3e60df16c Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Fri, 20 Aug 2021 18:25:12 +0200
Subject: qcow2: Deprecation warning when opening v2 images rw
@ -25,7 +25,7 @@ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2 files changed, 7 insertions(+)
diff --git a/block/qcow2.c b/block/qcow2.c
index 956128b409..0e8b2f7518 100644
index 70b19730a3..a4cffb628c 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1358,6 +1358,12 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
@ -42,7 +42,7 @@ index 956128b409..0e8b2f7518 100644
s->qcow_version = header.version;
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index 2846c83808..83472953a2 100644
index fc3c64bcb8..4b238954d5 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -83,6 +83,7 @@ _filter_qemu()

@ -0,0 +1,109 @@
From 03502faf7012e20fb7c4f1efee7e429ad3727fd1 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 15 May 2024 01:41:13 -0400
Subject: Add upstream compatibility bits
---
hw/arm/virt.c | 1 +
hw/core/machine.c | 17 +++++++++++++++++
hw/i386/pc_piix.c | 2 ++
hw/i386/pc_q35.c | 2 ++
hw/s390x/s390-virtio-ccw.c | 1 +
include/hw/boards.h | 3 +++
6 files changed, 26 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 903c0f2e9f..3374d3b0bc 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3582,6 +3582,7 @@ DEFINE_VIRT_MACHINE(2, 6)
static void virt_rhel_machine_9_4_0_options(MachineClass *mc)
{
+ compat_props_add(mc->compat_props, hw_compat_rhel_10_0, hw_compat_rhel_10_0_len);
compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
}
DEFINE_VIRT_MACHINE_AS_LATEST(9, 4, 0)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index f7fed78e4b..9cf8242b32 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -311,6 +311,23 @@ const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
const char *rhel_old_machine_deprecation =
"machine types for previous major releases are deprecated";
+GlobalProperty hw_compat_rhel_10_0[] = {
+ /* hw_compat_rhel_10_0 from hw_compat_9_0 */
+ {"arm-cpu", "backcompat-cntfrq", "true" },
+ /* hw_compat_rhel_10_0 from hw_compat_9_0 */
+ { "scsi-hd", "migrate-emulated-scsi-request", "false" },
+ /* hw_compat_rhel_10_0 from hw_compat_9_0 */
+ { "scsi-cd", "migrate-emulated-scsi-request", "false" },
+ /* hw_compat_rhel_10_0 from hw_compat_9_0 */
+ {"vfio-pci", "skip-vsc-check", "false" },
+ /* hw_compat_rhel_10_0 from hw_compat_9_0 */
+ { "virtio-pci", "x-pcie-pm-no-soft-reset", "off" },
+ /* hw_compat_rhel_10_0 from hw_compat_9_0 */
+ {"sd-card", "spec_version", "2" },
+};
+const size_t hw_compat_rhel_10_0_len = G_N_ELEMENTS(hw_compat_rhel_10_0);
+
+
GlobalProperty hw_compat_rhel_9_5[] = {
/* hw_compat_rhel_9_5 from hw_compat_8_2 */
{ "migration", "zero-page-detection", "legacy"},
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 5535e1ffbf..447f98b438 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -879,6 +879,8 @@ static void pc_i440fx_rhel_machine_7_6_0_options(MachineClass *m)
object_class_property_set_description(oc, "x-south-bridge",
"Use a different south bridge than PIIX3");
+ compat_props_add(m->compat_props, hw_compat_rhel_10_0,
+ hw_compat_rhel_10_0_len);
compat_props_add(m->compat_props, hw_compat_rhel_9_5,
hw_compat_rhel_9_5_len);
compat_props_add(m->compat_props, hw_compat_rhel_9_4,
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 2ca9ff3747..849b231a74 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -680,6 +680,8 @@ static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m)
pcmc->smbios_stream_product = "RHEL";
pcmc->smbios_stream_version = "9.4.0";
+ compat_props_add(m->compat_props, hw_compat_rhel_10_0,
+ hw_compat_rhel_10_0_len);
compat_props_add(m->compat_props, hw_compat_rhel_9_5,
hw_compat_rhel_9_5_len);
}
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 451017c50e..5db5fed1bf 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -1316,6 +1316,7 @@ static void ccw_rhel_machine_9_4_0_instance_options(MachineState *machine)
static void ccw_rhel_machine_9_4_0_class_options(MachineClass *mc)
{
+ compat_props_add(mc->compat_props, hw_compat_rhel_10_0, hw_compat_rhel_10_0_len);
compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
}
DEFINE_CCW_MACHINE_AS_LATEST(9, 4, 0);
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 3dea5cee73..6d98aaf4c7 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -802,6 +802,9 @@ extern const size_t hw_compat_2_2_len;
extern GlobalProperty hw_compat_2_1[];
extern const size_t hw_compat_2_1_len;
+extern GlobalProperty hw_compat_rhel_10_0[];
+extern const size_t hw_compat_rhel_10_0_len;
+
extern GlobalProperty hw_compat_rhel_9_5[];
extern const size_t hw_compat_rhel_9_5_len;
--
2.39.3

@ -0,0 +1,37 @@
From d27437e5baba347cb3392280399d402414dcb21c Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Mon, 26 Aug 2024 14:27:49 +0200
Subject: redhat: Add QEMU 9.1 compat handling to the s390x machine types
JIRA: https://issues.redhat.com/browse/RHEL-52319
Upstream changed the amount of information that is migrated for
the S390 interrupt controller (FLIC), so we have to switch on
a compatibility property for older machine types.
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
hw/s390x/s390-virtio-ccw.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 5db5fed1bf..feef81ed8b 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -1316,8 +1316,13 @@ static void ccw_rhel_machine_9_4_0_instance_options(MachineState *machine)
static void ccw_rhel_machine_9_4_0_class_options(MachineClass *mc)
{
+ static GlobalProperty compat[] = {
+ { TYPE_QEMU_S390_FLIC, "migrate-all-state", "off", },
+ };
+
compat_props_add(mc->compat_props, hw_compat_rhel_10_0, hw_compat_rhel_10_0_len);
compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_CCW_MACHINE_AS_LATEST(9, 4, 0);
--
2.39.3

@ -0,0 +1,66 @@
From 926a9d0ca2437b4c4270062f707ed24284ad469f Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Mon, 26 Aug 2024 14:42:24 +0200
Subject: redhat: Add rhel9.6.0 and rhel10.0.0 machine types
JIRA: https://issues.redhat.com/browse/RHEL-52319
Add a new machine types to enable the latest features by default.
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
hw/s390x/s390-virtio-ccw.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index feef81ed8b..b61392bac1 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -1310,8 +1310,29 @@ DEFINE_CCW_MACHINE(2, 4);
#endif
#endif /* disabled for RHEL */
+static void ccw_rhel_machine_10_0_0_instance_options(MachineState *machine)
+{
+}
+
+static void ccw_rhel_machine_10_0_0_class_options(MachineClass *mc)
+{
+}
+DEFINE_CCW_MACHINE_AS_LATEST(10, 0, 0);
+
+static void ccw_rhel_machine_9_6_0_instance_options(MachineState *machine)
+{
+ ccw_rhel_machine_10_0_0_instance_options(machine);
+}
+
+static void ccw_rhel_machine_9_6_0_class_options(MachineClass *mc)
+{
+ ccw_rhel_machine_10_0_0_class_options(mc);
+}
+DEFINE_CCW_MACHINE(9, 6, 0);
+
static void ccw_rhel_machine_9_4_0_instance_options(MachineState *machine)
{
+ ccw_rhel_machine_9_6_0_instance_options(machine);
}
static void ccw_rhel_machine_9_4_0_class_options(MachineClass *mc)
@@ -1320,11 +1341,13 @@ static void ccw_rhel_machine_9_4_0_class_options(MachineClass *mc)
{ TYPE_QEMU_S390_FLIC, "migrate-all-state", "off", },
};
+ ccw_rhel_machine_9_6_0_class_options(mc);
+
compat_props_add(mc->compat_props, hw_compat_rhel_10_0, hw_compat_rhel_10_0_len);
compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
}
-DEFINE_CCW_MACHINE_AS_LATEST(9, 4, 0);
+DEFINE_CCW_MACHINE(9, 4, 0);
static void ccw_rhel_machine_9_2_0_instance_options(MachineState *machine)
{
--
2.39.3

@ -0,0 +1,28 @@
From 6be70c681bf7a1b9666ed5896b5be8be7df2bf50 Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
Date: Wed, 4 Sep 2024 15:46:53 +0200
Subject: x86: ensure compatibility of pc-q35-rhel9*
Signed-off-by: Sebastian Ott <sebott@redhat.com>
---
hw/i386/pc_q35.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 849b231a74..a05df61cfc 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -680,6 +680,10 @@ static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m)
pcmc->smbios_stream_product = "RHEL";
pcmc->smbios_stream_version = "9.4.0";
+ /* From pc_q35_machine_9_0_options() */
+ pcmc->isa_bios_alias = false;
+ m->smbios_memory_device_size = 16 * GiB;
+
compat_props_add(m->compat_props, hw_compat_rhel_10_0,
hw_compat_rhel_10_0_len);
compat_props_add(m->compat_props, hw_compat_rhel_9_5,
--
2.39.3

@ -0,0 +1,27 @@
From 17c3bccf2f2804772ab60bf4f04d7437f13ed48a Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
Date: Wed, 4 Sep 2024 15:52:00 +0200
Subject: arm: ensure compatibility of virt-rhel9*
Signed-off-by: Sebastian Ott <sebott@redhat.com>
---
hw/arm/virt.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 3374d3b0bc..31a71a7f45 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3582,6 +3582,9 @@ DEFINE_VIRT_MACHINE(2, 6)
static void virt_rhel_machine_9_4_0_options(MachineClass *mc)
{
+ /* From virt_machine_9_0_options() */
+ mc->smbios_memory_device_size = 16 * GiB;
+
compat_props_add(mc->compat_props, hw_compat_rhel_10_0, hw_compat_rhel_10_0_len);
compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
}
--
2.39.3

@ -0,0 +1,507 @@
From eb742e8a7c75e3be5c158cb19185d9cf6ae4862c Mon Sep 17 00:00:00 2001
From: eabdullin <ed.abdullin.1@gmail.com>
Date: Tue, 15 Oct 2024 10:48:05 +0300
Subject: [PATCH] Add ppc64 support
---
.../ppc64-softmmu/ppc64-rh-devices.mak | 39 ++++++
hw/ppc/spapr.c | 125 +++++++++++++++++-
hw/ppc/spapr_cpu_core.c | 16 +++
include/hw/ppc/spapr.h | 3 +
target/ppc/compat.c | 11 ++
target/ppc/cpu-models.c | 9 +-
target/ppc/cpu.h | 1 +
target/ppc/kvm.c | 27 ++++
target/ppc/kvm_ppc.h | 13 ++
9 files changed, 237 insertions(+), 7 deletions(-)
create mode 100644 configs/devices/ppc64-softmmu/ppc64-rh-devices.mak
diff --git a/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak b/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak
new file mode 100644
index 000000000..4b801b126
--- /dev/null
+++ b/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak
@@ -0,0 +1,39 @@
+include ../rh-virtio.mak
+
+CONFIG_DIMM=y
+CONFIG_MEM_DEVICE=y
+CONFIG_NVDIMM=y
+CONFIG_PCI=y
+CONFIG_PCI_DEVICES=y
+CONFIG_PCI_TESTDEV=y
+CONFIG_PCI_EXPRESS=y
+CONFIG_PSERIES=y
+CONFIG_SCSI=y
+CONFIG_SPAPR_VSCSI=y
+CONFIG_TEST_DEVICES=y
+CONFIG_USB=y
+CONFIG_USB_OHCI=y
+CONFIG_USB_OHCI_PCI=y
+CONFIG_USB_SMARTCARD=y
+CONFIG_USB_STORAGE_CORE=y
+CONFIG_USB_STORAGE_CLASSIC=y
+CONFIG_USB_XHCI=y
+CONFIG_USB_XHCI_NEC=y
+CONFIG_USB_XHCI_PCI=y
+CONFIG_USB_HUB=y
+CONFIG_USB_HID=y
+CONFIG_VFIO=y
+CONFIG_VFIO_PCI=y
+CONFIG_VGA=y
+CONFIG_VGA_PCI=y
+CONFIG_VHOST_USER=y
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_VGA=y
+CONFIG_WDT_IB6300ESB=y
+CONFIG_XICS=y
+CONFIG_XIVE=y
+CONFIG_TPM=y
+CONFIG_TPM_SPAPR=y
+CONFIG_TPM_EMULATOR=y
+CONFIG_VHOST_VSOCK=y
+CONFIG_VHOST_USER_VSOCK=y
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 370d7c35d..aed36a4de 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1746,6 +1746,13 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason)
}
spapr_caps_apply(spapr);
spapr_nested_reset(spapr);
+ if (spapr->svm_allowed) {
+#ifdef CONFIG_KVM
+ kvmppc_svm_allow(&error_fatal);
+#else
+ error_setg(&error_fatal, "No PEF support in tcg, try x-svm-allowed=off");
+#endif
+ }
first_ppc_cpu = POWERPC_CPU(first_cpu);
if (kvm_enabled() && kvmppc_has_cap_mmu_radix() &&
@@ -3452,6 +3459,20 @@ static void spapr_set_host_serial(Object *obj, const char *value, Error **errp)
spapr->host_serial = g_strdup(value);
}
+static bool spapr_get_svm_allowed(Object *obj, Error **errp)
+{
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
+
+ return spapr->svm_allowed;
+}
+
+static void spapr_set_svm_allowed(Object *obj, bool value, Error **errp)
+{
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
+
+ spapr->svm_allowed = value;
+}
+
static void spapr_instance_init(Object *obj)
{
SpaprMachineState *spapr = SPAPR_MACHINE(obj);
@@ -3530,6 +3551,12 @@ static void spapr_instance_init(Object *obj)
spapr_get_host_serial, spapr_set_host_serial);
object_property_set_description(obj, "host-serial",
"Host serial number to advertise in guest device tree");
+ object_property_add_bool(obj, "x-svm-allowed",
+ spapr_get_svm_allowed,
+ spapr_set_svm_allowed);
+ object_property_set_description(obj, "x-svm-allowed",
+ "Allow the guest to become a Secure Guest"
+ " (experimental only)");
}
static void spapr_machine_finalizefn(Object *obj)
@@ -4775,6 +4802,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
vmc->client_architecture_support = spapr_vof_client_architecture_support;
vmc->quiesce = spapr_vof_quiesce;
vmc->setprop = spapr_vof_setprop;
+ smc->has_power9_support = true;
}
static const TypeInfo spapr_machine_info = {
@@ -4830,13 +4858,14 @@ static void spapr_machine_latest_class_options(MachineClass *mc)
} \
type_init(MACHINE_VER_SYM(register, spapr, __VA_ARGS__))
-#define DEFINE_SPAPR_MACHINE_AS_LATEST(major, minor) \
- DEFINE_SPAPR_MACHINE_IMPL(true, major, minor)
-#define DEFINE_SPAPR_MACHINE(major, minor) \
- DEFINE_SPAPR_MACHINE_IMPL(false, major, minor)
-#define DEFINE_SPAPR_MACHINE_TAGGED(major, minor, tag) \
- DEFINE_SPAPR_MACHINE_IMPL(false, major, minor, _, tag)
+#define DEFINE_SPAPR_MACHINE_AS_LATEST(major, minor, micro) \
+ DEFINE_SPAPR_MACHINE_IMPL(true, major, minor, micro)
+#define DEFINE_SPAPR_MACHINE(major, minor, micro) \
+ DEFINE_SPAPR_MACHINE_IMPL(false, major, minor, micro)
+#define DEFINE_SPAPR_MACHINE_TAGGED(major, minor, micro, tag) \
+ DEFINE_SPAPR_MACHINE_IMPL(false, major, minor, micro, _, tag)
+#if 0 /* Disabled for Red Hat Enterprise Linux */
/*
* pseries-9.1
*/
@@ -5056,6 +5085,9 @@ static bool phb_placement_4_0(SpaprMachineState *spapr, uint32_t index,
}
return true;
}
+#endif
+
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void spapr_machine_4_0_class_options(MachineClass *mc)
{
SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
@@ -5380,6 +5412,87 @@ static void spapr_machine_2_1_class_options(MachineClass *mc)
compat_props_add(mc->compat_props, hw_compat_2_1, hw_compat_2_1_len);
}
DEFINE_SPAPR_MACHINE(2, 1);
+#endif /* disabled for RHEL */
+
+static void spapr_rhel_machine_default_class_options(MachineClass *mc)
+{
+ /*
+ * Defaults for the latest behaviour inherited from the base class
+ * can be overriden here for all pseries-rhel* machines.
+ */
+
+ /* Maximum supported VCPU count */
+ mc->max_cpus = 384;
+}
+
+static void spapr_rhel_machine_10_0_0_class_options(MachineClass *mc)
+{
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
+ /* The default machine type must apply the RHEL specific defaults */
+ spapr_rhel_machine_default_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_10_0,
+ hw_compat_rhel_10_0_len);
+ smc->pre_6_2_numa_affinity = true;
+ mc->smp_props.prefer_sockets = true;
+}
+
+DEFINE_SPAPR_MACHINE_AS_LATEST(10, 0, 0);
+
+static void spapr_rhel_machine_9_5_0_class_options(MachineClass *mc)
+{
+ spapr_rhel_machine_10_0_0_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_5,
+ hw_compat_rhel_9_5_len);
+}
+
+DEFINE_SPAPR_MACHINE(9, 5, 0);
+
+static void spapr_rhel_machine_9_4_0_class_options(MachineClass *mc)
+{
+ spapr_rhel_machine_9_5_0_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_4,
+ hw_compat_rhel_9_4_len);
+}
+
+DEFINE_SPAPR_MACHINE(9, 4, 0);
+
+static void spapr_rhel_machine_9_3_0_class_options(MachineClass *mc)
+{
+ spapr_rhel_machine_9_4_0_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_3,
+ hw_compat_rhel_9_3_len);
+}
+
+DEFINE_SPAPR_MACHINE(9, 3, 0);
+
+static void spapr_rhel_machine_9_2_0_class_options(MachineClass *mc)
+{
+ spapr_rhel_machine_9_3_0_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_2,
+ hw_compat_rhel_9_2_len);
+}
+
+DEFINE_SPAPR_MACHINE(9, 2, 0);
+
+static void spapr_rhel_machine_9_1_0_class_options(MachineClass *mc)
+{
+ spapr_rhel_machine_9_2_0_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_1,
+ hw_compat_rhel_9_1_len);
+}
+
+DEFINE_SPAPR_MACHINE(9, 1, 0);
+
+static void spapr_rhel_machine_9_0_0_class_options(MachineClass *mc)
+{
+ spapr_rhel_machine_9_1_0_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_0,
+ hw_compat_rhel_9_0_len);
+}
+
+DEFINE_SPAPR_MACHINE(9, 0, 0);
+
static void spapr_machine_register_types(void)
{
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 56090abcd..e3371b24f 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -25,6 +25,7 @@
#include "sysemu/reset.h"
#include "sysemu/hw_accel.h"
#include "qemu/error-report.h"
+#include "cpu-models.h"
static void spapr_reset_vcpu(PowerPCCPU *cpu)
{
@@ -264,6 +265,7 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
{
CPUPPCState *env = &cpu->env;
CPUState *cs = CPU(cpu);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
if (!qdev_realize(DEVICE(cpu), NULL, errp)) {
return false;
@@ -280,6 +282,18 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
/* Set time-base frequency to 512 MHz. vhyp must be set first. */
cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
+ if (!smc->has_power9_support &&
+ (((spapr->max_compat_pvr &&
+ ppc_compat_cmp(spapr->max_compat_pvr,
+ CPU_POWERPC_LOGICAL_3_00) >= 0)) ||
+ (!spapr->max_compat_pvr &&
+ ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0, 0)))) {
+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+ "POWER9 CPU is not supported by this machine class");
+ return false;
+ }
+
+
if (spapr_irq_cpu_intc_create(spapr, cpu, errp) < 0) {
qdev_unrealize(DEVICE(cpu));
return false;
@@ -399,10 +413,12 @@ static const TypeInfo spapr_cpu_core_type_infos[] = {
.instance_size = sizeof(SpaprCpuCore),
.class_size = sizeof(SpaprCpuCoreClass),
},
+#if 0 /* Disabled for Red Hat Enterprise Linux */
DEFINE_SPAPR_CPU_CORE_TYPE("970_v2.2"),
DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.0"),
DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.1"),
DEFINE_SPAPR_CPU_CORE_TYPE("power5p_v2.1"),
+#endif
DEFINE_SPAPR_CPU_CORE_TYPE("power7_v2.3"),
DEFINE_SPAPR_CPU_CORE_TYPE("power7p_v2.1"),
DEFINE_SPAPR_CPU_CORE_TYPE("power8_v2.0"),
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index f6de3e997..3cc7ef0c0 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -157,6 +157,7 @@ struct SpaprMachineClass {
bool pre_5_2_numa_associativity;
bool pre_6_2_numa_affinity;
+ bool has_power9_support;
bool (*phb_placement)(SpaprMachineState *spapr, uint32_t index,
uint64_t *buid, hwaddr *pio,
hwaddr *mmio32, hwaddr *mmio64,
@@ -258,6 +259,8 @@ struct SpaprMachineState {
/* Set by -boot */
char *boot_device;
+ /* Secure Guest support via x-svm-allowed */
+ bool svm_allowed;
/*< public >*/
char *kvm_type;
diff --git a/target/ppc/compat.c b/target/ppc/compat.c
index ebef2ccce..ab7ed7680 100644
--- a/target/ppc/compat.c
+++ b/target/ppc/compat.c
@@ -114,6 +114,17 @@ static const CompatInfo *compat_by_pvr(uint32_t pvr)
return NULL;
}
+long ppc_compat_cmp(uint32_t pvr1, uint32_t pvr2)
+{
+ const CompatInfo *compat1 = compat_by_pvr(pvr1);
+ const CompatInfo *compat2 = compat_by_pvr(pvr2);
+
+ g_assert(compat1);
+ g_assert(compat2);
+
+ return compat1 - compat2;
+}
+
static bool pcc_compat(PowerPCCPUClass *pcc, uint32_t compat_pvr,
uint32_t min_compat_pvr, uint32_t max_compat_pvr)
{
diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
index f2301b43f..4c38fa517 100644
--- a/target/ppc/cpu-models.c
+++ b/target/ppc/cpu-models.c
@@ -66,6 +66,7 @@
#define POWERPC_DEF(_name, _pvr, _type, _desc) \
POWERPC_DEF_SVR(_name, _desc, _pvr, POWERPC_SVR_NONE, _type)
+#if 0 /* Embedded and 32-bit CPUs disabled for Red Hat Enterprise Linux */
/* Embedded PowerPC */
/* PowerPC 405 family */
/* PowerPC 405 cores */
@@ -698,8 +699,10 @@
"PowerPC 7447A v1.2 (G4)")
POWERPC_DEF("7457a_v1.2", CPU_POWERPC_74x7A_v12, 7455,
"PowerPC 7457A v1.2 (G4)")
+#endif
/* 64 bits PowerPC */
#if defined(TARGET_PPC64)
+#if 0 /* Disabled for Red Hat Enterprise Linux */
POWERPC_DEF("970_v2.2", CPU_POWERPC_970_v22, 970,
"PowerPC 970 v2.2")
POWERPC_DEF("970fx_v1.0", CPU_POWERPC_970FX_v10, 970,
@@ -718,6 +721,7 @@
"PowerPC 970MP v1.1")
POWERPC_DEF("power5p_v2.1", CPU_POWERPC_POWER5P_v21, POWER5P,
"POWER5+ v2.1")
+#endif
POWERPC_DEF("power7_v2.3", CPU_POWERPC_POWER7_v23, POWER7,
"POWER7 v2.3")
POWERPC_DEF("power7p_v2.1", CPU_POWERPC_POWER7P_v21, POWER7,
@@ -895,12 +899,14 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
{ "7457a", "7457a_v1.2" },
{ "apollo7pm", "7457a_v1.0" },
#if defined(TARGET_PPC64)
+#if 0 /* Disabled for Red Hat Enterprise Linux */
{ "970", "970_v2.2" },
{ "970fx", "970fx_v3.1" },
{ "970mp", "970mp_v1.1" },
{ "power5+", "power5p_v2.1" },
{ "power5+_v2.1", "power5p_v2.1" },
{ "power5gs", "power5+_v2.1" },
+#endif
{ "power7", "power7_v2.3" },
{ "power7+", "power7p_v2.1" },
{ "power7+_v2.1", "power7p_v2.1" },
@@ -910,13 +916,14 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
{ "power9", "power9_v2.2" },
{ "power10", "power10_v2.0" },
#endif
-
+#if 0 /* Disabled for Red Hat Enterprise Linux */
/* Generic PowerPCs */
#if defined(TARGET_PPC64)
{ "ppc64", "970fx_v3.1" },
#endif
{ "ppc32", "604" },
{ "ppc", "604" },
+#endif
{ NULL, NULL }
};
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 321ed2da7..e35a99762 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1673,6 +1673,7 @@ static inline int ppc_env_mmu_index(CPUPPCState *env, bool ifetch)
/* Compatibility modes */
#if defined(TARGET_PPC64)
+long ppc_compat_cmp(uint32_t pvr1, uint32_t pvr2);
bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr,
uint32_t min_compat_pvr, uint32_t max_compat_pvr);
bool ppc_type_check_compat(const char *cputype, uint32_t compat_pvr,
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 907dba60d..c942ff55b 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -92,6 +92,7 @@ static int cap_large_decr;
static int cap_fwnmi;
static int cap_rpt_invalidate;
static int cap_ail_mode_3;
+static int cap_ppc_secure_guest;
#ifdef CONFIG_PSERIES
static int cap_papr;
@@ -150,6 +151,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_resize_hpt = kvm_vm_check_extension(s, KVM_CAP_SPAPR_RESIZE_HPT);
kvmppc_get_cpu_characteristics(s);
cap_ppc_nested_kvm_hv = kvm_vm_check_extension(s, KVM_CAP_PPC_NESTED_HV);
+ cap_ppc_secure_guest = kvm_vm_check_extension(s, KVM_CAP_PPC_SECURE_GUEST);
cap_large_decr = kvmppc_get_dec_bits();
cap_fwnmi = kvm_vm_check_extension(s, KVM_CAP_PPC_FWNMI);
/*
@@ -2597,6 +2599,16 @@ bool kvmppc_supports_ail_3(void)
return cap_ail_mode_3;
}
+bool kvmppc_has_cap_secure_guest(void)
+{
+ return !!cap_ppc_secure_guest;
+}
+
+int kvmppc_enable_cap_secure_guest(void)
+{
+ return kvm_vm_enable_cap(kvm_state, KVM_CAP_PPC_SECURE_GUEST, 0, 1);
+}
+
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
{
uint32_t host_pvr = mfpvr();
@@ -3012,3 +3024,18 @@ static void kvm_cpu_accel_register_types(void)
type_register_static(&kvm_cpu_accel_type_info);
}
type_init(kvm_cpu_accel_register_types);
+
+void kvmppc_svm_allow(Error **errp)
+{
+ if (!kvm_enabled()) {
+ error_setg(errp, "No PEF support in tcg, try x-svm-allowed=off");
+ return;
+ }
+
+ if (!kvmppc_has_cap_secure_guest()) {
+ error_setg(errp, "KVM implementation does not support secure guests, "
+ "try x-svm-allowed=off");
+ } else if (kvmppc_enable_cap_secure_guest() < 0) {
+ error_setg(errp, "Error enabling x-svm-allowed, try x-svm-allowed=off");
+ }
+}
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index 1975fb5ee..d1017f98b 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -46,6 +46,7 @@ int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu);
target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu,
bool radix, bool gtse,
uint64_t proc_tbl);
+void kvmppc_svm_allow(Error **errp);
bool kvmppc_spapr_use_multitce(void);
int kvmppc_spapr_enable_inkernel_multitce(void);
void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t page_shift,
@@ -79,6 +80,8 @@ int kvmppc_enable_cap_large_decr(PowerPCCPU *cpu, int enable);
int kvmppc_has_cap_rpt_invalidate(void);
bool kvmppc_supports_ail_3(void);
int kvmppc_enable_hwrng(void);
+bool kvmppc_has_cap_secure_guest(void);
+int kvmppc_enable_cap_secure_guest(void);
int kvmppc_put_books_sregs(PowerPCCPU *cpu);
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
void kvmppc_check_papr_resize_hpt(Error **errp);
@@ -427,6 +430,16 @@ static inline bool kvmppc_supports_ail_3(void)
return false;
}
+static inline bool kvmppc_has_cap_secure_guest(void)
+{
+ return false;
+}
+
+static inline int kvmppc_enable_cap_secure_guest(void)
+{
+ return -1;
+}
+
static inline int kvmppc_enable_hwrng(void)
{
return -1;
--
2.39.5 (Apple Git-154)

@ -0,0 +1,21 @@
From 32c5296efbb9e9a4e7ede9591e37bd307f3b1ced Mon Sep 17 00:00:00 2001
From: Andrew Lukoshko <alukoshko@almalinux.org>
Date: Sat, 26 Oct 2024 20:09:06 +0000
Subject: [PATCH] Enable QXL device build
---
configs/devices/x86_64-softmmu/x86_64-rh-devices.mak | 1 +
1 file changed, 1 insertion(+)
diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
index 45a8a1529..2769c1eb4 100644
--- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
@@ -112,3 +112,4 @@ CONFIG_VHOST_USER_VSOCK=y
CONFIG_VHOST_USER_FS=y
CONFIG_IOMMUFD=y
CONFIG_VHOST_USER_SND=y
+CONFIG_QXL=y
--
2.43.5

@ -1,50 +0,0 @@
From ca89f2eb9588bfebe2796a579a563bd974dadf72 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 24 Jul 2024 07:31:12 -0400
Subject: [PATCH] Enable vhost-user-scmi devices
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-MergeRequest: 258: Enable vhost-user-scmi devices
RH-Jira: RHEL-50165
RH-Acked-by: Sandro Bonazzola <None>
RH-Commit: [1/1] edf95ef0fab99eb079beb16409fdab2a3cb0b94b (mrezanin/centos-src-qemu-kvm)
Enabling vhost-user-scmi and vhost-user-scmi-pci devices for qemu-kvm.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
configs/devices/aarch64-softmmu/aarch64-rh-devices.mak | 1 +
configs/devices/s390x-softmmu/s390x-rh-devices.mak | 1 +
configs/devices/x86_64-softmmu/x86_64-rh-devices.mak | 1 +
3 files changed, 3 insertions(+)
diff --git a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
index 0a95438e25..4495d033e5 100644
--- a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
+++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
@@ -41,3 +41,4 @@ CONFIG_VHOST_USER_VSOCK=y
CONFIG_VHOST_USER_FS=y
CONFIG_IOMMUFD=y
CONFIG_VHOST_USER_SND=y
+CONFIG_VHOST_USER_SCMI=y
diff --git a/configs/devices/s390x-softmmu/s390x-rh-devices.mak b/configs/devices/s390x-softmmu/s390x-rh-devices.mak
index 719f802565..963ec43b6c 100644
--- a/configs/devices/s390x-softmmu/s390x-rh-devices.mak
+++ b/configs/devices/s390x-softmmu/s390x-rh-devices.mak
@@ -18,3 +18,4 @@ CONFIG_VHOST_USER_VSOCK=y
CONFIG_VHOST_USER_FS=y
CONFIG_IOMMUFD=y
CONFIG_VHOST_USER_SND=y
+CONFIG_VHOST_USER_SCMI=y
diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
index b85bb1fe53..276397f3be 100644
--- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
@@ -110,3 +110,4 @@ CONFIG_VHOST_USER_VSOCK=y
CONFIG_VHOST_USER_FS=y
CONFIG_IOMMUFD=y
CONFIG_VHOST_USER_SND=y
+CONFIG_VHOST_USER_SCMI=y
--
2.39.3

@ -1,50 +0,0 @@
From d7256c0d15a3ae142c80462c66e0d68120ebd001 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 22 May 2024 03:56:55 -0400
Subject: [PATCH] Enable vhost-user-snd-pci device
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-MergeRequest: 242: Enable vhost-user-snd-pci device
RH-Jira: RHEL-37563
RH-Acked-by: Sandro Bonazzola <None>
RH-Commit: [1/1] 014f47770fc9f7d4bd0e7fac9a072911325f3283 (mrezanin/centos-src-qemu-kvm)
RHIVOS requires vhost-user-snd-pci device. Enabling it for aarch64 and x86_64 only.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
configs/devices/aarch64-softmmu/aarch64-rh-devices.mak | 1 +
configs/devices/s390x-softmmu/s390x-rh-devices.mak | 1 +
configs/devices/x86_64-softmmu/x86_64-rh-devices.mak | 1 +
3 files changed, 3 insertions(+)
diff --git a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
index b0191d3c69..0a95438e25 100644
--- a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
+++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
@@ -40,3 +40,4 @@ CONFIG_VHOST_VSOCK=y
CONFIG_VHOST_USER_VSOCK=y
CONFIG_VHOST_USER_FS=y
CONFIG_IOMMUFD=y
+CONFIG_VHOST_USER_SND=y
diff --git a/configs/devices/s390x-softmmu/s390x-rh-devices.mak b/configs/devices/s390x-softmmu/s390x-rh-devices.mak
index 24cf6dbd03..719f802565 100644
--- a/configs/devices/s390x-softmmu/s390x-rh-devices.mak
+++ b/configs/devices/s390x-softmmu/s390x-rh-devices.mak
@@ -17,3 +17,4 @@ CONFIG_VHOST_VSOCK=y
CONFIG_VHOST_USER_VSOCK=y
CONFIG_VHOST_USER_FS=y
CONFIG_IOMMUFD=y
+CONFIG_VHOST_USER_SND=y
diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
index fe69f04ead..b85bb1fe53 100644
--- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
@@ -109,3 +109,4 @@ CONFIG_VHOST_VSOCK=y
CONFIG_VHOST_USER_VSOCK=y
CONFIG_VHOST_USER_FS=y
CONFIG_IOMMUFD=y
+CONFIG_VHOST_USER_SND=y
--
2.39.3

@ -0,0 +1,50 @@
From 111d70a5bdc3ee0dde0a6def9e0c75ed20b4f093 Mon Sep 17 00:00:00 2001
From: Peter Xu <peterx@redhat.com>
Date: Tue, 17 Sep 2024 12:38:33 -0400
Subject: [PATCH 6/9] KVM: Define KVM_MEMSLOTS_NUM_MAX_DEFAULT
RH-Author: Peter Xu <peterx@redhat.com>
RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array
RH-Jira: RHEL-57685
RH-Acked-by: Juraj Marcin <None>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [5/7] e4c2a2c2f3a809c8efb709521c7a94ba0627c69b (peterx/qemu-kvm)
Make the default max nr_slots a macro, it's only used when KVM reports
nothing.
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/r/20240917163835.194664-3-peterx@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit b34a908c8f24eedb0a8e5ff486b059b58fd793f4)
Signed-off-by: Peter Xu <peterx@redhat.com>
---
accel/kvm/kvm-all.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 38393bc86b..87db0f9494 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -71,6 +71,8 @@
/* Default num of memslots to be allocated when VM starts */
#define KVM_MEMSLOTS_NR_ALLOC_DEFAULT 16
+/* Default max allowed memslots if kernel reported nothing */
+#define KVM_MEMSLOTS_NR_MAX_DEFAULT 32
struct KVMParkedVcpu {
unsigned long vcpu_id;
@@ -2617,7 +2619,7 @@ static int kvm_init(MachineState *ms)
/* If unspecified, use the default value */
if (!s->nr_slots) {
- s->nr_slots = 32;
+ s->nr_slots_max = KVM_MEMSLOTS_NR_MAX_DEFAULT;
}
s->nr_as = kvm_check_extension(s, KVM_CAP_MULTI_ADDRESS_SPACE);
--
2.39.3

@ -0,0 +1,251 @@
From c77a30265b8d0db43174b040ea82103f8fdb9911 Mon Sep 17 00:00:00 2001
From: Peter Xu <peterx@redhat.com>
Date: Tue, 17 Sep 2024 12:38:32 -0400
Subject: [PATCH 5/9] KVM: Dynamic sized kvm memslots array
RH-Author: Peter Xu <peterx@redhat.com>
RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array
RH-Jira: RHEL-57685
RH-Acked-by: Juraj Marcin <None>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [4/7] 46d4abec352a92112e593ea61b7cbf5ce5f94cdc (peterx/qemu-kvm)
Zhiyi reported an infinite loop issue in VFIO use case. The cause of that
was a separate discussion, however during that I found a regression of
dirty sync slowness when profiling.
Each KVMMemoryListerner maintains an array of kvm memslots. Currently it's
statically allocated to be the max supported by the kernel. However after
Linux commit 4fc096a99e ("KVM: Raise the maximum number of user memslots"),
the max supported memslots reported now grows to some number large enough
so that it may not be wise to always statically allocate with the max
reported.
What's worse, QEMU kvm code still walks all the allocated memslots entries
to do any form of lookups. It can drastically slow down all memslot
operations because each of such loop can run over 32K times on the new
kernels.
Fix this issue by making the memslots to be allocated dynamically.
Here the initial size was set to 16 because it should cover the basic VM
usages, so that the hope is the majority VM use case may not even need to
grow at all (e.g. if one starts a VM with ./qemu-system-x86_64 by default
it'll consume 9 memslots), however not too large to waste memory.
There can also be even better way to address this, but so far this is the
simplest and should be already better even than before we grow the max
supported memslots. For example, in the case of above issue when VFIO was
attached on a 32GB system, there are only ~10 memslots used. So it could
be good enough as of now.
In the above VFIO context, measurement shows that the precopy dirty sync
shrinked from ~86ms to ~3ms after this patch applied. It should also apply
to any KVM enabled VM even without VFIO.
NOTE: we don't have a FIXES tag for this patch because there's no real
commit that regressed this in QEMU. Such behavior existed for a long time,
but only start to be a problem when the kernel reports very large
nr_slots_max value. However that's pretty common now (the kernel change
was merged in 2021) so we attached cc:stable because we'll want this change
to be backported to stable branches.
Cc: qemu-stable <qemu-stable@nongnu.org>
Reported-by: Zhiyi Guo <zhguo@redhat.com>
Tested-by: Zhiyi Guo <zhguo@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Acked-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Link: https://lore.kernel.org/r/20240917163835.194664-2-peterx@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 5504a8126115d173687b37e657312a8ffe29fc0c)
Signed-off-by: Peter Xu <peterx@redhat.com>
---
accel/kvm/kvm-all.c | 87 +++++++++++++++++++++++++++++++++-------
accel/kvm/trace-events | 1 +
include/sysemu/kvm_int.h | 1 +
3 files changed, 74 insertions(+), 15 deletions(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 8187ad3964..38393bc86b 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -69,6 +69,9 @@
#define KVM_GUESTDBG_BLOCKIRQ 0
#endif
+/* Default num of memslots to be allocated when VM starts */
+#define KVM_MEMSLOTS_NR_ALLOC_DEFAULT 16
+
struct KVMParkedVcpu {
unsigned long vcpu_id;
int kvm_fd;
@@ -165,6 +168,57 @@ void kvm_resample_fd_notify(int gsi)
}
}
+/**
+ * kvm_slots_grow(): Grow the slots[] array in the KVMMemoryListener
+ *
+ * @kml: The KVMMemoryListener* to grow the slots[] array
+ * @nr_slots_new: The new size of slots[] array
+ *
+ * Returns: True if the array grows larger, false otherwise.
+ */
+static bool kvm_slots_grow(KVMMemoryListener *kml, unsigned int nr_slots_new)
+{
+ unsigned int i, cur = kml->nr_slots_allocated;
+ KVMSlot *slots;
+
+ if (nr_slots_new > kvm_state->nr_slots) {
+ nr_slots_new = kvm_state->nr_slots;
+ }
+
+ if (cur >= nr_slots_new) {
+ /* Big enough, no need to grow, or we reached max */
+ return false;
+ }
+
+ if (cur == 0) {
+ slots = g_new0(KVMSlot, nr_slots_new);
+ } else {
+ assert(kml->slots);
+ slots = g_renew(KVMSlot, kml->slots, nr_slots_new);
+ /*
+ * g_renew() doesn't initialize extended buffers, however kvm
+ * memslots require fields to be zero-initialized. E.g. pointers,
+ * memory_size field, etc.
+ */
+ memset(&slots[cur], 0x0, sizeof(slots[0]) * (nr_slots_new - cur));
+ }
+
+ for (i = cur; i < nr_slots_new; i++) {
+ slots[i].slot = i;
+ }
+
+ kml->slots = slots;
+ kml->nr_slots_allocated = nr_slots_new;
+ trace_kvm_slots_grow(cur, nr_slots_new);
+
+ return true;
+}
+
+static bool kvm_slots_double(KVMMemoryListener *kml)
+{
+ return kvm_slots_grow(kml, kml->nr_slots_allocated * 2);
+}
+
unsigned int kvm_get_max_memslots(void)
{
KVMState *s = KVM_STATE(current_accel());
@@ -193,15 +247,26 @@ unsigned int kvm_get_free_memslots(void)
/* Called with KVMMemoryListener.slots_lock held */
static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml)
{
- KVMState *s = kvm_state;
+ unsigned int n;
int i;
- for (i = 0; i < s->nr_slots; i++) {
+ for (i = 0; i < kml->nr_slots_allocated; i++) {
if (kml->slots[i].memory_size == 0) {
return &kml->slots[i];
}
}
+ /*
+ * If no free slots, try to grow first by doubling. Cache the old size
+ * here to avoid another round of search: if the grow succeeded, it
+ * means slots[] now must have the existing "n" slots occupied,
+ * followed by one or more free slots starting from slots[n].
+ */
+ n = kml->nr_slots_allocated;
+ if (kvm_slots_double(kml)) {
+ return &kml->slots[n];
+ }
+
return NULL;
}
@@ -222,10 +287,9 @@ static KVMSlot *kvm_lookup_matching_slot(KVMMemoryListener *kml,
hwaddr start_addr,
hwaddr size)
{
- KVMState *s = kvm_state;
int i;
- for (i = 0; i < s->nr_slots; i++) {
+ for (i = 0; i < kml->nr_slots_allocated; i++) {
KVMSlot *mem = &kml->slots[i];
if (start_addr == mem->start_addr && size == mem->memory_size) {
@@ -267,7 +331,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram,
int i, ret = 0;
kvm_slots_lock();
- for (i = 0; i < s->nr_slots; i++) {
+ for (i = 0; i < kml->nr_slots_allocated; i++) {
KVMSlot *mem = &kml->slots[i];
if (ram >= mem->ram && ram < mem->ram + mem->memory_size) {
@@ -1071,7 +1135,7 @@ static int kvm_physical_log_clear(KVMMemoryListener *kml,
kvm_slots_lock();
- for (i = 0; i < s->nr_slots; i++) {
+ for (i = 0; i < kml->nr_slots_allocated; i++) {
mem = &kml->slots[i];
/* Discard slots that are empty or do not overlap the section */
if (!mem->memory_size ||
@@ -1719,12 +1783,8 @@ static void kvm_log_sync_global(MemoryListener *l, bool last_stage)
/* Flush all kernel dirty addresses into KVMSlot dirty bitmap */
kvm_dirty_ring_flush();
- /*
- * TODO: make this faster when nr_slots is big while there are
- * only a few used slots (small VMs).
- */
kvm_slots_lock();
- for (i = 0; i < s->nr_slots; i++) {
+ for (i = 0; i < kml->nr_slots_allocated; i++) {
mem = &kml->slots[i];
if (mem->memory_size && mem->flags & KVM_MEM_LOG_DIRTY_PAGES) {
kvm_slot_sync_dirty_pages(mem);
@@ -1839,12 +1899,9 @@ void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml,
{
int i;
- kml->slots = g_new0(KVMSlot, s->nr_slots);
kml->as_id = as_id;
- for (i = 0; i < s->nr_slots; i++) {
- kml->slots[i].slot = i;
- }
+ kvm_slots_grow(kml, KVM_MEMSLOTS_NR_ALLOC_DEFAULT);
QSIMPLEQ_INIT(&kml->transaction_add);
QSIMPLEQ_INIT(&kml->transaction_del);
diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
index 37626c1ac5..ad2ae6fca5 100644
--- a/accel/kvm/trace-events
+++ b/accel/kvm/trace-events
@@ -36,3 +36,4 @@ kvm_io_window_exit(void) ""
kvm_run_exit_system_event(int cpu_index, uint32_t event_type) "cpu_index %d, system_even_type %"PRIu32
kvm_convert_memory(uint64_t start, uint64_t size, const char *msg) "start 0x%" PRIx64 " size 0x%" PRIx64 " %s"
kvm_memory_fault(uint64_t start, uint64_t size, uint64_t flags) "start 0x%" PRIx64 " size 0x%" PRIx64 " flags 0x%" PRIx64
+kvm_slots_grow(unsigned int old, unsigned int new) "%u -> %u"
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index 1d8fb1473b..48e496b3d4 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -46,6 +46,7 @@ typedef struct KVMMemoryListener {
MemoryListener listener;
KVMSlot *slots;
unsigned int nr_used_slots;
+ unsigned int nr_slots_allocated;
int as_id;
QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_add;
QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_del;
--
2.39.3

@ -0,0 +1,73 @@
From b1d082cfad79245ac0ffed45f723092388d1cf45 Mon Sep 17 00:00:00 2001
From: Peter Xu <peterx@redhat.com>
Date: Tue, 17 Sep 2024 12:38:34 -0400
Subject: [PATCH 7/9] KVM: Rename KVMMemoryListener.nr_used_slots to
nr_slots_used
RH-Author: Peter Xu <peterx@redhat.com>
RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array
RH-Jira: RHEL-57685
RH-Acked-by: Juraj Marcin <None>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [6/7] ed173123ee23edcf62a6c1940ca74cdfd6b545e9 (peterx/qemu-kvm)
This will make all nr_slots counters to be named in the same manner.
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/r/20240917163835.194664-4-peterx@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit dbdc00ba5b136bba80d850f61cc79a9cafaae1cd)
Signed-off-by: Peter Xu <peterx@redhat.com>
---
accel/kvm/kvm-all.c | 6 +++---
include/sysemu/kvm_int.h | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 87db0f9494..e99aaba486 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -239,7 +239,7 @@ unsigned int kvm_get_free_memslots(void)
if (!s->as[i].ml) {
continue;
}
- used_slots = MAX(used_slots, s->as[i].ml->nr_used_slots);
+ used_slots = MAX(used_slots, s->as[i].ml->nr_slots_used);
}
kvm_slots_unlock();
@@ -1516,7 +1516,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
}
start_addr += slot_size;
size -= slot_size;
- kml->nr_used_slots--;
+ kml->nr_slots_used--;
} while (size);
return;
}
@@ -1555,7 +1555,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
ram_start_offset += slot_size;
ram += slot_size;
size -= slot_size;
- kml->nr_used_slots++;
+ kml->nr_slots_used++;
} while (size);
}
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index 48e496b3d4..b705dfc9b4 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -45,7 +45,7 @@ typedef struct KVMMemoryUpdate {
typedef struct KVMMemoryListener {
MemoryListener listener;
KVMSlot *slots;
- unsigned int nr_used_slots;
+ unsigned int nr_slots_used;
unsigned int nr_slots_allocated;
int as_id;
QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_add;
--
2.39.3

@ -0,0 +1,90 @@
From 891fb13363d168760cd21d0c57368e1a413cad27 Mon Sep 17 00:00:00 2001
From: Peter Xu <peterx@redhat.com>
Date: Tue, 17 Sep 2024 12:38:35 -0400
Subject: [PATCH 8/9] KVM: Rename KVMState->nr_slots to nr_slots_max
RH-Author: Peter Xu <peterx@redhat.com>
RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array
RH-Jira: RHEL-57685
RH-Acked-by: Juraj Marcin <None>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [7/7] 7a1b28f04ee6a2c80b07db241fc88cb40f54e376 (peterx/qemu-kvm)
This value used to reflect the maximum supported memslots from KVM kernel.
Rename it to be clearer.
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/r/20240917163835.194664-5-peterx@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 943c742868c739c0b14fd996bad3adf744156fec)
Signed-off-by: Peter Xu <peterx@redhat.com>
---
accel/kvm/kvm-all.c | 12 ++++++------
include/sysemu/kvm_int.h | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index e99aaba486..dc6253895d 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -183,8 +183,8 @@ static bool kvm_slots_grow(KVMMemoryListener *kml, unsigned int nr_slots_new)
unsigned int i, cur = kml->nr_slots_allocated;
KVMSlot *slots;
- if (nr_slots_new > kvm_state->nr_slots) {
- nr_slots_new = kvm_state->nr_slots;
+ if (nr_slots_new > kvm_state->nr_slots_max) {
+ nr_slots_new = kvm_state->nr_slots_max;
}
if (cur >= nr_slots_new) {
@@ -225,7 +225,7 @@ unsigned int kvm_get_max_memslots(void)
{
KVMState *s = KVM_STATE(current_accel());
- return s->nr_slots;
+ return s->nr_slots_max;
}
unsigned int kvm_get_free_memslots(void)
@@ -243,7 +243,7 @@ unsigned int kvm_get_free_memslots(void)
}
kvm_slots_unlock();
- return s->nr_slots - used_slots;
+ return s->nr_slots_max - used_slots;
}
/* Called with KVMMemoryListener.slots_lock held */
@@ -2615,10 +2615,10 @@ static int kvm_init(MachineState *ms)
(kvm_supported_memory_attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE);
kvm_immediate_exit = kvm_check_extension(s, KVM_CAP_IMMEDIATE_EXIT);
- s->nr_slots = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
+ s->nr_slots_max = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
/* If unspecified, use the default value */
- if (!s->nr_slots) {
+ if (!s->nr_slots_max) {
s->nr_slots_max = KVM_MEMSLOTS_NR_MAX_DEFAULT;
}
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index b705dfc9b4..2c57194b6b 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -103,8 +103,8 @@ struct KVMDirtyRingReaper {
struct KVMState
{
AccelState parent_obj;
-
- int nr_slots;
+ /* Max number of KVM slots supported */
+ int nr_slots_max;
int fd;
int vmfd;
int coalesced_mmio;
--
2.39.3

@ -0,0 +1,76 @@
From 5110e137294163ae43a61376485a7f610bf496f3 Mon Sep 17 00:00:00 2001
From: Shaoqin Huang <shahuang@redhat.com>
Date: Wed, 22 May 2024 03:23:28 -0400
Subject: [PATCH 8/9] RH-Author: Shaoqin Huang <shahuang@redhat.com >
RH-MergeRequest: 271: hw/arm/virt: Fix Manufacturer and Product Name in
emulated SMBIOS mode RH-Jira: RHEL-38374 RH-Acked-by: Cornelia Huck
<cohuck@redhat.com> RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Eric Auger <eric.auger@redhat.com> RH-Commit: [8/8]
d1daacc6ed427094cf92a9ecc66af8171950c718 (shahuang/qemu-kvm)
---
hw/arm/virt.c | 15 +++++++++++++--
include/hw/arm/virt.h | 1 +
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 907c26c635..078098ec3a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1711,14 +1711,21 @@ static void virt_build_smbios(VirtMachineState *vms)
uint8_t *smbios_tables, *smbios_anchor;
size_t smbios_tables_len, smbios_anchor_len;
struct smbios_phys_mem_area mem_array;
+ const char *manufacturer = "QEMU";
const char *product = "QEMU Virtual Machine";
+ const char *version = vmc->smbios_old_sys_ver ? "1.0" : mc->name;
if (kvm_enabled()) {
product = "KVM Virtual Machine";
}
- smbios_set_defaults("QEMU", product,
- vmc->smbios_old_sys_ver ? "1.0" : mc->name,
+ if (!vmc->manufacturer_product_compat) {
+ manufacturer = "Red Hat";
+ product = "KVM";
+ version = mc->desc;
+ }
+
+ smbios_set_defaults(manufacturer, product, version,
NULL, NULL);
/* build the array of physical mem area from base_memmap */
@@ -3593,6 +3600,8 @@ DEFINE_VIRT_MACHINE(9, 6, 0)
static void virt_rhel_machine_9_4_0_options(MachineClass *mc)
{
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
+
virt_rhel_machine_9_6_0_options(mc);
/* From virt_machine_9_0_options() */
@@ -3600,6 +3609,8 @@ static void virt_rhel_machine_9_4_0_options(MachineClass *mc)
compat_props_add(mc->compat_props, hw_compat_rhel_10_0, hw_compat_rhel_10_0_len);
compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
+
+ vmc->manufacturer_product_compat = true;
}
DEFINE_VIRT_MACHINE(9, 4, 0)
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index a4d937ed45..2fc30a7626 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -134,6 +134,7 @@ struct VirtMachineClass {
bool no_cpu_topology;
bool no_tcg_lpa2;
bool no_ns_el2_virt_timer_irq;
+ bool manufacturer_product_compat;
};
struct VirtMachineState {
--
2.39.3

@ -1,67 +0,0 @@
From 53cc7daf2b6356f236a493cbe63d01afc5636fd3 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Mon, 6 May 2024 15:06:21 -0400
Subject: [PATCH 13/14] Revert "monitor: use aio_co_reschedule_self()"
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 253: Revert "monitor: use aio_co_reschedule_self()"
RH-Jira: RHEL-43409 RHEL-43410
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [1/2] 772eccc9da09e6c1793d46ab6cf9ee6615812154 (kmwolf/centos-qemu-kvm)
Commit 1f25c172f837 ("monitor: use aio_co_reschedule_self()") was a code
cleanup that uses aio_co_reschedule_self() instead of open coding
coroutine rescheduling.
Bug RHEL-34618 was reported and Kevin Wolf <kwolf@redhat.com> identified
the root cause. I missed that aio_co_reschedule_self() ->
qemu_get_current_aio_context() only knows about
qemu_aio_context/IOThread AioContexts and not about iohandler_ctx. It
does not function correctly when going back from the iohandler_ctx to
qemu_aio_context.
Go back to open coding the AioContext transitions to avoid this bug.
This reverts commit 1f25c172f83704e350c0829438d832384084a74d.
Cc: qemu-stable@nongnu.org
Buglink: https://issues.redhat.com/browse/RHEL-34618
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20240506190622.56095-2-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 719c6819ed9a9838520fa732f9861918dc693bda)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qapi/qmp-dispatch.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index f3488afeef..176b549473 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -212,7 +212,8 @@ QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *requ
* executing the command handler so that it can make progress if it
* involves an AIO_WAIT_WHILE().
*/
- aio_co_reschedule_self(qemu_get_aio_context());
+ aio_co_schedule(qemu_get_aio_context(), qemu_coroutine_self());
+ qemu_coroutine_yield();
}
monitor_set_cur(qemu_coroutine_self(), cur_mon);
@@ -226,7 +227,9 @@ QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *requ
* Move back to iohandler_ctx so that nested event loops for
* qemu_aio_context don't start new monitor commands.
*/
- aio_co_reschedule_self(iohandler_get_aio_context());
+ aio_co_schedule(iohandler_get_aio_context(),
+ qemu_coroutine_self());
+ qemu_coroutine_yield();
}
} else {
/*
--
2.39.3

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

@ -0,0 +1,144 @@
From 00a2dbf483a077bb31b1c9f70cced36319d22628 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Thu, 12 Sep 2024 11:48:38 +0530
Subject: [PATCH 4/9] accel/kvm: refactor dirty ring setup
RH-Author: Peter Xu <peterx@redhat.com>
RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array
RH-Jira: RHEL-57685
RH-Acked-by: Juraj Marcin <None>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [3/7] 94f345d1e7ad6437dd2ce67ca7cad224c67aa48f (peterx/qemu-kvm)
Refactor setting up of dirty ring code in kvm_init() so that is can be
reused in the future patchsets.
Signed-off-by: Ani Sinha <anisinha@redhat.com>
Link: https://lore.kernel.org/r/20240912061838.4501-1-anisinha@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 28ed7f9761eb273e7dedcfdc0507d158106d0451)
Signed-off-by: Peter Xu <peterx@redhat.com>
---
accel/kvm/kvm-all.c | 88 +++++++++++++++++++++++++--------------------
1 file changed, 50 insertions(+), 38 deletions(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index d86d1b515a..8187ad3964 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2439,6 +2439,55 @@ static int find_kvm_machine_type(MachineState *ms)
return type;
}
+static int kvm_setup_dirty_ring(KVMState *s)
+{
+ uint64_t dirty_log_manual_caps;
+ int ret;
+
+ /*
+ * Enable KVM dirty ring if supported, otherwise fall back to
+ * dirty logging mode
+ */
+ ret = kvm_dirty_ring_init(s);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /*
+ * KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is not needed when dirty ring is
+ * enabled. More importantly, KVM_DIRTY_LOG_INITIALLY_SET will assume no
+ * page is wr-protected initially, which is against how kvm dirty ring is
+ * usage - kvm dirty ring requires all pages are wr-protected at the very
+ * beginning. Enabling this feature for dirty ring causes data corruption.
+ *
+ * TODO: Without KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 and kvm clear dirty log,
+ * we may expect a higher stall time when starting the migration. In the
+ * future we can enable KVM_CLEAR_DIRTY_LOG to work with dirty ring too:
+ * instead of clearing dirty bit, it can be a way to explicitly wr-protect
+ * guest pages.
+ */
+ if (!s->kvm_dirty_ring_size) {
+ dirty_log_manual_caps =
+ kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
+ dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
+ KVM_DIRTY_LOG_INITIALLY_SET);
+ s->manual_dirty_log_protect = dirty_log_manual_caps;
+ if (dirty_log_manual_caps) {
+ ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0,
+ dirty_log_manual_caps);
+ if (ret) {
+ warn_report("Trying to enable capability %"PRIu64" of "
+ "KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but failed. "
+ "Falling back to the legacy mode. ",
+ dirty_log_manual_caps);
+ s->manual_dirty_log_protect = 0;
+ }
+ }
+ }
+
+ return 0;
+}
+
static int kvm_init(MachineState *ms)
{
MachineClass *mc = MACHINE_GET_CLASS(ms);
@@ -2458,7 +2507,6 @@ static int kvm_init(MachineState *ms)
const KVMCapabilityInfo *missing_cap;
int ret;
int type;
- uint64_t dirty_log_manual_caps;
qemu_mutex_init(&kml_slots_lock);
@@ -2570,47 +2618,11 @@ static int kvm_init(MachineState *ms)
s->coalesced_pio = s->coalesced_mmio &&
kvm_check_extension(s, KVM_CAP_COALESCED_PIO);
- /*
- * Enable KVM dirty ring if supported, otherwise fall back to
- * dirty logging mode
- */
- ret = kvm_dirty_ring_init(s);
+ ret = kvm_setup_dirty_ring(s);
if (ret < 0) {
goto err;
}
- /*
- * KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is not needed when dirty ring is
- * enabled. More importantly, KVM_DIRTY_LOG_INITIALLY_SET will assume no
- * page is wr-protected initially, which is against how kvm dirty ring is
- * usage - kvm dirty ring requires all pages are wr-protected at the very
- * beginning. Enabling this feature for dirty ring causes data corruption.
- *
- * TODO: Without KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 and kvm clear dirty log,
- * we may expect a higher stall time when starting the migration. In the
- * future we can enable KVM_CLEAR_DIRTY_LOG to work with dirty ring too:
- * instead of clearing dirty bit, it can be a way to explicitly wr-protect
- * guest pages.
- */
- if (!s->kvm_dirty_ring_size) {
- dirty_log_manual_caps =
- kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
- dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
- KVM_DIRTY_LOG_INITIALLY_SET);
- s->manual_dirty_log_protect = dirty_log_manual_caps;
- if (dirty_log_manual_caps) {
- ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0,
- dirty_log_manual_caps);
- if (ret) {
- warn_report("Trying to enable capability %"PRIu64" of "
- "KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but failed. "
- "Falling back to the legacy mode. ",
- dirty_log_manual_caps);
- s->manual_dirty_log_protect = 0;
- }
- }
- }
-
#ifdef KVM_CAP_VCPU_EVENTS
s->vcpu_events = kvm_check_extension(s, KVM_CAP_VCPU_EVENTS);
#endif
--
2.39.3

@ -1,64 +0,0 @@
From 6c8da957fd534b3546354a8b8252c01cf9ee3511 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Mon, 6 May 2024 15:06:22 -0400
Subject: [PATCH 14/14] aio: warn about iohandler_ctx special casing
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 253: Revert "monitor: use aio_co_reschedule_self()"
RH-Jira: RHEL-43409 RHEL-43410
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [2/2] 895231553731f09f51275c1abbf50c3440fe977f (kmwolf/centos-qemu-kvm)
The main loop has two AioContexts: qemu_aio_context and iohandler_ctx.
The main loop runs them both, but nested aio_poll() calls on
qemu_aio_context exclude iohandler_ctx.
Which one should qemu_get_current_aio_context() return when called from
the main loop? Document that it's always qemu_aio_context.
This has subtle effects on functions that use
qemu_get_current_aio_context(). For example, aio_co_reschedule_self()
does not work when moving from iohandler_ctx to qemu_aio_context because
qemu_get_current_aio_context() does not differentiate these two
AioContexts.
Document this in order to reduce the chance of future bugs.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20240506190622.56095-3-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit e669e800fc9ef8806af5c5578249ab758a4f8a5a)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
include/block/aio.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/include/block/aio.h b/include/block/aio.h
index 8378553eb9..4ee81936ed 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -629,6 +629,9 @@ void aio_co_schedule(AioContext *ctx, Coroutine *co);
*
* Move the currently running coroutine to new_ctx. If the coroutine is already
* running in new_ctx, do nothing.
+ *
+ * Note that this function cannot reschedule from iohandler_ctx to
+ * qemu_aio_context.
*/
void coroutine_fn aio_co_reschedule_self(AioContext *new_ctx);
@@ -661,6 +664,9 @@ void aio_co_enter(AioContext *ctx, Coroutine *co);
* If called from an IOThread this will be the IOThread's AioContext. If
* called from the main thread or with the "big QEMU lock" taken it
* will be the main loop AioContext.
+ *
+ * Note that the return value is never the main loop's iohandler_ctx and the
+ * return value is the main loop AioContext instead.
*/
AioContext *qemu_get_current_aio_context(void);
--
2.39.3

@ -0,0 +1,49 @@
From 60d59db99f0527eaf0ce8d3a18d8333aa77a03f2 Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
Date: Thu, 5 Sep 2024 13:53:13 +0200
Subject: [PATCH 2/9] arm: create new virt machine type for rhel 9.6
RH-Author: Sebastian Ott <sebott@redhat.com>
RH-MergeRequest: 270: RHEL10 machine types
RH-Jira: RHEL-29002 RHEL-29003 RHEL-35587 RHEL-38411 RHEL-45141 RHEL-52318 RHEL-52320
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
RH-Commit: [2/7] 0179f5a7a177f53b58ff9b82bd09217e183f258b (seott1/cos-qemu-kvm)
Signed-off-by: Sebastian Ott <sebott@redhat.com>
---
hw/arm/virt.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 31a71a7f45..f94be8656c 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3580,15 +3580,22 @@ static void virt_machine_2_6_options(MachineClass *mc)
DEFINE_VIRT_MACHINE(2, 6)
#endif /* disabled for RHEL */
+static void virt_rhel_machine_9_6_0_options(MachineClass *mc)
+{
+}
+DEFINE_VIRT_MACHINE_AS_LATEST(9, 6, 0)
+
static void virt_rhel_machine_9_4_0_options(MachineClass *mc)
{
+ virt_rhel_machine_9_6_0_options(mc);
+
/* From virt_machine_9_0_options() */
mc->smbios_memory_device_size = 16 * GiB;
compat_props_add(mc->compat_props, hw_compat_rhel_10_0, hw_compat_rhel_10_0_len);
compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
}
-DEFINE_VIRT_MACHINE_AS_LATEST(9, 4, 0)
+DEFINE_VIRT_MACHINE(9, 4, 0)
static void virt_rhel_machine_9_2_0_options(MachineClass *mc)
{
--
2.39.3

@ -0,0 +1,45 @@
From 704596b05f7dcdfa98857b71fed295d0005d4acc Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
Date: Thu, 22 Aug 2024 17:08:26 +0200
Subject: [PATCH 5/9] arm: create virt machine type for rhel10
RH-Author: Sebastian Ott <sebott@redhat.com>
RH-MergeRequest: 270: RHEL10 machine types
RH-Jira: RHEL-29002 RHEL-29003 RHEL-35587 RHEL-38411 RHEL-45141 RHEL-52318 RHEL-52320
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
RH-Commit: [5/7] cd8f31de4cd189cd1de69e68c84d823e43473e8c (seott1/cos-qemu-kvm)
Create a new default virt machine type for rhel 10.
Signed-off-by: Sebastian Ott <sebott@redhat.com>
---
hw/arm/virt.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f94be8656c..907c26c635 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3580,10 +3580,16 @@ static void virt_machine_2_6_options(MachineClass *mc)
DEFINE_VIRT_MACHINE(2, 6)
#endif /* disabled for RHEL */
+static void virt_rhel_machine_10_0_0_options(MachineClass *mc)
+{
+}
+DEFINE_VIRT_MACHINE_AS_LATEST(10, 0, 0)
+
static void virt_rhel_machine_9_6_0_options(MachineClass *mc)
{
+ virt_rhel_machine_10_0_0_options(mc);
}
-DEFINE_VIRT_MACHINE_AS_LATEST(9, 6, 0)
+DEFINE_VIRT_MACHINE(9, 6, 0)
static void virt_rhel_machine_9_4_0_options(MachineClass *mc)
{
--
2.39.3

@ -1,252 +0,0 @@
From 53153ebcf066e962cd73d7fcfeca53039be2a945 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Thu, 25 Apr 2024 14:56:02 +0200
Subject: [PATCH 4/4] block: Parse filenames only when explicitly requested
RH-Author: Hana Czenczek <hczenczek@redhat.com>
RH-MergeRequest: 1: CVE 2024-4467 (PRDSC)
RH-Jira: RHEL-46239
RH-CVE: CVE-2024-4467
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Commit: [4/4] f44c2941d4419e60f16dea3e9adca164e75aa78d
When handling image filenames from legacy options such as -drive or from
tools, these filenames are parsed for protocol prefixes, including for
the json:{} pseudo-protocol.
This behaviour is intended for filenames that come directly from the
command line and for backing files, which may come from the image file
itself. Higher level management tools generally take care to verify that
untrusted images don't contain a bad (or any) backing file reference;
'qemu-img info' is a suitable tool for this.
However, for other files that can be referenced in images, such as
qcow2 data files or VMDK extents, the string from the image file is
usually not verified by management tools - and 'qemu-img info' wouldn't
be suitable because in contrast to backing files, it already opens these
other referenced files. So here the string should be interpreted as a
literal local filename. More complex configurations need to be specified
explicitly on the command line or in QMP.
This patch changes bdrv_open_inherit() so that it only parses filenames
if a new parameter parse_filename is true. It is set for the top level
in bdrv_open(), for the file child and for the backing file child. All
other callers pass false and disable filename parsing this way.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Upstream: N/A, embargoed
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
---
block.c | 90 ++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 57 insertions(+), 33 deletions(-)
diff --git a/block.c b/block.c
index 468cf5e67d..50bdd197b7 100644
--- a/block.c
+++ b/block.c
@@ -86,6 +86,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
BlockDriverState *parent,
const BdrvChildClass *child_class,
BdrvChildRole child_role,
+ bool parse_filename,
Error **errp);
static bool bdrv_recurse_has_child(BlockDriverState *bs,
@@ -2058,7 +2059,8 @@ static void parse_json_protocol(QDict *options, const char **pfilename,
* block driver has been specified explicitly.
*/
static int bdrv_fill_options(QDict **options, const char *filename,
- int *flags, Error **errp)
+ int *flags, bool allow_parse_filename,
+ Error **errp)
{
const char *drvname;
bool protocol = *flags & BDRV_O_PROTOCOL;
@@ -2100,7 +2102,7 @@ static int bdrv_fill_options(QDict **options, const char *filename,
if (protocol && filename) {
if (!qdict_haskey(*options, "filename")) {
qdict_put_str(*options, "filename", filename);
- parse_filename = true;
+ parse_filename = allow_parse_filename;
} else {
error_setg(errp, "Can't specify 'file' and 'filename' options at "
"the same time");
@@ -3663,7 +3665,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
}
backing_hd = bdrv_open_inherit(backing_filename, reference, options, 0, bs,
- &child_of_bds, bdrv_backing_role(bs), errp);
+ &child_of_bds, bdrv_backing_role(bs), true,
+ errp);
if (!backing_hd) {
bs->open_flags |= BDRV_O_NO_BACKING;
error_prepend(errp, "Could not open backing file: ");
@@ -3697,7 +3700,8 @@ free_exit:
static BlockDriverState *
bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
BlockDriverState *parent, const BdrvChildClass *child_class,
- BdrvChildRole child_role, bool allow_none, Error **errp)
+ BdrvChildRole child_role, bool allow_none,
+ bool parse_filename, Error **errp)
{
BlockDriverState *bs = NULL;
QDict *image_options;
@@ -3728,7 +3732,8 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
}
bs = bdrv_open_inherit(filename, reference, image_options, 0,
- parent, child_class, child_role, errp);
+ parent, child_class, child_role, parse_filename,
+ errp);
if (!bs) {
goto done;
}
@@ -3738,6 +3743,33 @@ done:
return bs;
}
+static BdrvChild *bdrv_open_child_common(const char *filename,
+ QDict *options, const char *bdref_key,
+ BlockDriverState *parent,
+ const BdrvChildClass *child_class,
+ BdrvChildRole child_role,
+ bool allow_none, bool parse_filename,
+ Error **errp)
+{
+ BlockDriverState *bs;
+ BdrvChild *child;
+
+ GLOBAL_STATE_CODE();
+
+ bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class,
+ child_role, allow_none, parse_filename, errp);
+ if (bs == NULL) {
+ return NULL;
+ }
+
+ bdrv_graph_wrlock();
+ child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
+ errp);
+ bdrv_graph_wrunlock();
+
+ return child;
+}
+
/*
* Opens a disk image whose options are given as BlockdevRef in another block
* device's options.
@@ -3761,27 +3793,15 @@ BdrvChild *bdrv_open_child(const char *filename,
BdrvChildRole child_role,
bool allow_none, Error **errp)
{
- BlockDriverState *bs;
- BdrvChild *child;
-
- GLOBAL_STATE_CODE();
-
- bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class,
- child_role, allow_none, errp);
- if (bs == NULL) {
- return NULL;
- }
-
- bdrv_graph_wrlock();
- child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
- errp);
- bdrv_graph_wrunlock();
-
- return child;
+ return bdrv_open_child_common(filename, options, bdref_key, parent,
+ child_class, child_role, allow_none, false,
+ errp);
}
/*
- * Wrapper on bdrv_open_child() for most popular case: open primary child of bs.
+ * This does mostly the same as bdrv_open_child(), but for opening the primary
+ * child of a node. A notable difference from bdrv_open_child() is that it
+ * enables filename parsing for protocol names (including json:).
*
* @parent can move to a different AioContext in this function.
*/
@@ -3796,8 +3816,8 @@ int bdrv_open_file_child(const char *filename,
role = parent->drv->is_filter ?
(BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE;
- if (!bdrv_open_child(filename, options, bdref_key, parent,
- &child_of_bds, role, false, errp))
+ if (!bdrv_open_child_common(filename, options, bdref_key, parent,
+ &child_of_bds, role, false, true, errp))
{
return -EINVAL;
}
@@ -3842,7 +3862,8 @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
}
- bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, errp);
+ bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, false,
+ errp);
obj = NULL;
qobject_unref(obj);
visit_free(v);
@@ -3932,7 +3953,7 @@ static BlockDriverState * no_coroutine_fn
bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
int flags, BlockDriverState *parent,
const BdrvChildClass *child_class, BdrvChildRole child_role,
- Error **errp)
+ bool parse_filename, Error **errp)
{
int ret;
BlockBackend *file = NULL;
@@ -3980,9 +4001,11 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
}
/* json: syntax counts as explicit options, as if in the QDict */
- parse_json_protocol(options, &filename, &local_err);
- if (local_err) {
- goto fail;
+ if (parse_filename) {
+ parse_json_protocol(options, &filename, &local_err);
+ if (local_err) {
+ goto fail;
+ }
}
bs->explicit_options = qdict_clone_shallow(options);
@@ -4007,7 +4030,8 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
parent->open_flags, parent->options);
}
- ret = bdrv_fill_options(&options, filename, &flags, &local_err);
+ ret = bdrv_fill_options(&options, filename, &flags, parse_filename,
+ &local_err);
if (ret < 0) {
goto fail;
}
@@ -4076,7 +4100,7 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
file_bs = bdrv_open_child_bs(filename, options, "file", bs,
&child_of_bds, BDRV_CHILD_IMAGE,
- true, &local_err);
+ true, true, &local_err);
if (local_err) {
goto fail;
}
@@ -4225,7 +4249,7 @@ BlockDriverState *bdrv_open(const char *filename, const char *reference,
GLOBAL_STATE_CODE();
return bdrv_open_inherit(filename, reference, options, flags, NULL,
- NULL, 0, errp);
+ NULL, 0, true, errp);
}
/* Return true if the NULL-terminated @list contains @str */
--
2.39.3

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

@ -0,0 +1,41 @@
From ba9b7c8375aac784fbe23beaeb91484ddd8e6829 Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Mon, 11 Nov 2024 11:55:06 +0100
Subject: [PATCH 3/9] docs/system/bootindex: Make it clear that s390x can also
boot from virtio-net
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature
RH-Jira: RHEL-68444
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/8] ae20c66e424d64840012b4725166a1bde2579cbc (thuth/qemu-kvm-cs9)
Let's make it clear that s390x can also boot from virtio-net, to avoid
that people think that s390x can only boot from disk devices.
Reported-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Message-ID: <20241111105506.264640-1-thuth@redhat.com>
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit b8c5fdc6588f82d95807be0eb2215d215a3ba16e)
---
docs/system/bootindex.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/system/bootindex.rst b/docs/system/bootindex.rst
index 988f7b3beb..5e1b33ee22 100644
--- a/docs/system/bootindex.rst
+++ b/docs/system/bootindex.rst
@@ -53,7 +53,7 @@ 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. In the case of s390x BIOS, the BIOS will try up to
-8 total devices, any number of which may be disks.
+8 total devices, any number of which may be disks or virtio-net devices.
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
--
2.39.3

@ -0,0 +1,61 @@
From 3c57b3a6d48d7ddad44b67fdf9ccaebc40e5c125 Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Thu, 14 Nov 2024 19:27:42 -0500
Subject: [PATCH 2/9] docs/system/s390x/bootdevices: Update loadparm
documentation
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature
RH-Jira: RHEL-68444
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/8] bd74a0794bf0f2872061850ca410bab819c6a0d6 (thuth/qemu-kvm-cs9)
Update documentation to include per-device loadparm support.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241115002742.3576842-1-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 0271fdc650b212533b8aeaecbedfe8ccf6bbbef3)
---
docs/system/s390x/bootdevices.rst | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/docs/system/s390x/bootdevices.rst b/docs/system/s390x/bootdevices.rst
index 1a1a764c1c..97b3914785 100644
--- a/docs/system/s390x/bootdevices.rst
+++ b/docs/system/s390x/bootdevices.rst
@@ -79,7 +79,29 @@ The second way to use this parameter is to use a number in the range from 0
to 31. The numbers that can be used here correspond to the numbers that are
shown when using the ``PROMPT`` option, and the s390-ccw bios will then try
to automatically boot the kernel that is associated with the given number.
-Note that ``0`` can be used to boot the default entry.
+Note that ``0`` can be used to boot the default entry. If the machine
+``loadparm`` is not assigned a value, then the default entry is used.
+
+By default, the machine ``loadparm`` applies to all boot devices. If multiple
+devices are assigned a ``bootindex`` and the ``loadparm`` is to be different
+between them, an independent ``loadparm`` may be assigned on a per-device basis.
+
+An example guest using per-device ``loadparm``::
+
+ qemu-system-s390x -drive if=none,id=dr1,file=primary.qcow2 \
+ -device virtio-blk,drive=dr1,bootindex=1 \
+ -drive if=none,id=dr2,file=secondary.qcow2 \
+ -device virtio-blk,drive=dr2,bootindex=2,loadparm=3
+
+In this case, the primary boot device will attempt to IPL using the default
+entry (because no ``loadparm`` is specified for this device or for the
+machine). If that device fails to boot, the secondary device will attempt to
+IPL using entry number 3.
+
+If a ``loadparm`` is specified on both the machine and a device, the per-device
+value will superseded the machine value. Per-device ``loadparm`` values are
+only used for devices with an assigned ``bootindex``. The machine ``loadparm``
+is used when attempting to boot without a ``bootindex``.
Booting from a network device
--
2.39.3

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

@ -0,0 +1,61 @@
From d0163127a47250170e01e39f48250a2725f531c0 Mon Sep 17 00:00:00 2001
From: Gavin Shan <gshan@redhat.com>
Date: Tue, 1 Oct 2024 16:58:57 +1000
Subject: [PATCH] hostmem: Apply merge property after the memory region is
initialized
RH-Author: Gavin Shan <gshan@redhat.com>
RH-MergeRequest: 272: hostmem: Apply merge property after the memory region is initialized
RH-Jira: RHEL-58936
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
RH-Acked-by: David Hildenbrand <david@redhat.com>
RH-Commit: [1/1] aa47bedf64698b277bb8835f4689d4f1d5eca53c (gwshan/qemu-centos)
JIRA: https://issues.redhat.com/browse/RHEL-58936
The semantic change has been introduced by commit 5becdc0ab0 ("hostmem:
simplify the code for merge and dump properties") even it clarifies that
no senmatic change has been introduced. After the commit, the merge
property can be applied even the corresponding memory region isn't
initialized yet. This leads to crash dump by the following command
lines.
# /home/gavin/sandbox/qemu.main/build/qemu-system-aarch64 \
-accel kvm -machine virt -cpu host \
-object memory-backend-ram,id=mem-memN0,size=4096M,merge=off
:
qemu-system-aarch64: ../system/memory.c:2419: memory_region_get_ram_ptr: \
Assertion `mr->ram_block' failed.
Fix it by applying the merge property only when the memory region is
initialized.
Message-ID: <20240915233117.478169-1-gshan@redhat.com>
Fixes: 5becdc0ab083 ("hostmem: simplify the code for merge and dump properties")
Reported-by: Zhenyu Zhang <zhenyzha@redhat.com>
Tested-by: Zhenyu Zhang <zhenyzha@redhat.com>
Signed-off-by: Gavin Shan <gshan@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
(cherry picked from commit 78c8f780d3f0d6d17aa93d6f99ff72960080fdd7)
Signed-off-by: Gavin Shan <gshan@redhat.com>
---
backends/hostmem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 4e5576a4ad..181446626a 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -178,7 +178,7 @@ static void host_memory_backend_set_merge(Object *obj, bool value, Error **errp)
return;
}
- if (!host_memory_backend_mr_inited(backend) &&
+ if (host_memory_backend_mr_inited(backend) &&
value != backend->merge) {
void *ptr = memory_region_get_ram_ptr(&backend->mr);
uint64_t sz = memory_region_size(&backend->mr);
--
2.39.3

@ -0,0 +1,217 @@
From 4c90ff4c0b48df312c10defba45c9f182b535524 Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Fri, 15 Nov 2024 15:12:02 +0100
Subject: [PATCH 5/9] hw: Add "loadparm" property to scsi disk devices for
booting on s390x
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature
RH-Jira: RHEL-68444
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [4/8] 4b5e2afa65f7a529e0bb5509b36c9bf81894caee (thuth/qemu-kvm-cs9)
While adding the new flexible boot order feature on s390x recently,
we missed to add the "loadparm" property to the scsi-hd and scsi-cd
devices. This property is required on s390x to pass the information
to the boot loader about which kernel should be started or whether
the boot menu should be shown. But even more serious: The missing
property is now causing trouble with the corresponding libvirt patches
that assume that the "loadparm" property is either settable for all
bootable devices (when the "boot order" feature is implemented in
QEMU), or none (meaning the behaviour of older QEMUs that only allowed
one "loadparm" at the machine level). To fix this broken situation,
let's implement the "loadparm" property in for the SCSI devices, too.
Message-ID: <20241115141202.1877294-1-thuth@redhat.com>
Acked-by: Eric Farman <farman@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 429442e52d94f890fa194a151e8cd649b04e9e63)
---
hw/core/qdev-properties-system.c | 26 +++++++++++++++++
hw/s390x/ipl.c | 19 ++++---------
hw/scsi/scsi-disk.c | 43 +++++++++++++++++++++++++++++
include/hw/qdev-properties-system.h | 3 ++
4 files changed, 78 insertions(+), 13 deletions(-)
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index f13350b4fb..5cd527cdba 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -58,6 +58,32 @@ static bool check_prop_still_unset(Object *obj, const char *name,
return false;
}
+bool qdev_prop_sanitize_s390x_loadparm(uint8_t *loadparm, const char *str,
+ Error **errp)
+{
+ int i, len;
+
+ len = strlen(str);
+ if (len > 8) {
+ error_setg(errp, "'loadparm' can only contain up to 8 characters");
+ return false;
+ }
+
+ for (i = 0; i < len; i++) {
+ uint8_t c = qemu_toupper(str[i]); /* mimic HMC */
+
+ if (qemu_isalnum(c) || c == '.' || c == ' ') {
+ loadparm[i] = c;
+ } else {
+ error_setg(errp,
+ "invalid character in 'loadparm': '%c' (ASCII 0x%02x)",
+ c, c);
+ return false;
+ }
+ }
+
+ return true;
+}
/* --- drive --- */
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 5fbd43c346..8101825dfe 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -418,21 +418,9 @@ static uint64_t s390_ipl_map_iplb_chain(IplParameterBlock *iplb_chain)
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;
- }
- }
+ qdev_prop_sanitize_s390x_loadparm(loadparm, str, errp);
}
void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp)
@@ -452,6 +440,7 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
SCSIDevice *sd;
int devtype;
uint8_t *lp;
+ g_autofree void *scsi_lp = NULL;
/*
* Currently allow IPL only from CCW devices.
@@ -463,6 +452,10 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
switch (devtype) {
case CCW_DEVTYPE_SCSI:
sd = SCSI_DEVICE(dev_st);
+ scsi_lp = object_property_get_str(OBJECT(sd), "loadparm", NULL);
+ if (scsi_lp && strlen(scsi_lp) > 0) {
+ lp = scsi_lp;
+ }
iplb->len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
iplb->blk0_len =
cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - S390_IPLB_HEADER_LEN);
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 4d94b2b816..7566a5f531 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -32,6 +32,7 @@
#include "migration/vmstate.h"
#include "hw/scsi/emulation.h"
#include "scsi/constants.h"
+#include "sysemu/arch_init.h"
#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "hw/block/block.h"
@@ -111,6 +112,7 @@ struct SCSIDiskState {
char *vendor;
char *product;
char *device_id;
+ char *loadparm; /* only for s390x */
bool tray_open;
bool tray_locked;
/*
@@ -3135,6 +3137,43 @@ BlockAIOCB *scsi_dma_writev(int64_t offset, QEMUIOVector *iov,
return blk_aio_pwritev(s->qdev.conf.blk, offset, iov, 0, cb, cb_opaque);
}
+static char *scsi_property_get_loadparm(Object *obj, Error **errp)
+{
+ return g_strdup(SCSI_DISK_BASE(obj)->loadparm);
+}
+
+static void scsi_property_set_loadparm(Object *obj, const char *value,
+ Error **errp)
+{
+ void *lp_str;
+
+ if (object_property_get_int(obj, "bootindex", NULL) < 0) {
+ error_setg(errp, "'loadparm' is only valid for boot devices");
+ return;
+ }
+
+ lp_str = g_malloc0(strlen(value));
+ if (!qdev_prop_sanitize_s390x_loadparm(lp_str, value, errp)) {
+ g_free(lp_str);
+ return;
+ }
+ SCSI_DISK_BASE(obj)->loadparm = lp_str;
+}
+
+static void scsi_property_add_specifics(DeviceClass *dc)
+{
+ ObjectClass *oc = OBJECT_CLASS(dc);
+
+ /* The loadparm property is only supported on s390x */
+ if (arch_type & QEMU_ARCH_S390X) {
+ object_class_property_add_str(oc, "loadparm",
+ scsi_property_get_loadparm,
+ scsi_property_set_loadparm);
+ object_class_property_set_description(oc, "loadparm",
+ "load parameter (s390x only)");
+ }
+}
+
static void scsi_disk_base_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -3218,6 +3257,8 @@ static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
dc->desc = "virtual SCSI disk";
device_class_set_props(dc, scsi_hd_properties);
dc->vmsd = &vmstate_scsi_disk_state;
+
+ scsi_property_add_specifics(dc);
}
static const TypeInfo scsi_hd_info = {
@@ -3258,6 +3299,8 @@ static void scsi_cd_class_initfn(ObjectClass *klass, void *data)
dc->desc = "virtual SCSI CD-ROM";
device_class_set_props(dc, scsi_cd_properties);
dc->vmsd = &vmstate_scsi_disk_state;
+
+ scsi_property_add_specifics(dc);
}
static const TypeInfo scsi_cd_info = {
diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h
index 438f65389f..88e4257ad0 100644
--- a/include/hw/qdev-properties-system.h
+++ b/include/hw/qdev-properties-system.h
@@ -3,6 +3,9 @@
#include "hw/qdev-properties.h"
+bool qdev_prop_sanitize_s390x_loadparm(uint8_t *loadparm, const char *str,
+ Error **errp);
+
extern const PropertyInfo qdev_prop_chr;
extern const PropertyInfo qdev_prop_macaddr;
extern const PropertyInfo qdev_prop_reserved_region;
--
2.39.3

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

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

@ -0,0 +1,112 @@
From b9950c32c2845c9592650df49183c431a4190e7f Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Wed, 13 Nov 2024 12:47:41 +0100
Subject: [PATCH 4/9] hw/s390x: Restrict "loadparm" property to devices that
can be used for booting
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature
RH-Jira: RHEL-68444
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [3/8] 7b0fee6a1508649d66b913e6ebf23b4af29628dd (thuth/qemu-kvm-cs9)
Commit bb185de423 ("s390x: Add individual loadparm assignment to
CCW device") added a "loadparm" property to all CCW devices. This
was a little bit unfortunate, since this property is only useful
for devices that can be used for booting, but certainly it is not
useful for devices like virtio-gpu or virtio-tablet.
Thus let's restrict the property to CCW devices that we can boot from
(i.e. virtio-block, virtio-net and vfio-ccw devices).
Message-ID: <20241113114741.681096-1-thuth@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Jared Rossi <jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 6e7c96ae61e0542e97d385084f1f2281a0331054)
---
hw/s390x/ccw-device.c | 4 +---
hw/s390x/ccw-device.h | 5 +++++
hw/s390x/virtio-ccw-blk.c | 1 +
hw/s390x/virtio-ccw-net.c | 1 +
hw/vfio/ccw.c | 1 +
5 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/hw/s390x/ccw-device.c b/hw/s390x/ccw-device.c
index 4e54f34b1c..d7bb364579 100644
--- a/hw/s390x/ccw-device.c
+++ b/hw/s390x/ccw-device.c
@@ -73,7 +73,7 @@ static void ccw_device_set_loadparm(Object *obj, Visitor *v,
s390_ipl_fmt_loadparm(dev->loadparm, val, errp);
}
-static const PropertyInfo ccw_loadparm = {
+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",
@@ -85,8 +85,6 @@ 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 1e1737c0f3..4439feb140 100644
--- a/hw/s390x/ccw-device.h
+++ b/hw/s390x/ccw-device.h
@@ -51,4 +51,9 @@ static inline CcwDevice *to_ccw_dev_fast(DeviceState *d)
OBJECT_DECLARE_TYPE(CcwDevice, CCWDeviceClass, CCW_DEVICE)
+extern const PropertyInfo ccw_loadparm;
+
+#define DEFINE_PROP_CCW_LOADPARM(_n, _s, _f) \
+ DEFINE_PROP(_n, _s, _f, ccw_loadparm, typeof(uint8_t[8]))
+
#endif
diff --git a/hw/s390x/virtio-ccw-blk.c b/hw/s390x/virtio-ccw-blk.c
index 8e0e58b77d..2364432c6e 100644
--- a/hw/s390x/virtio-ccw-blk.c
+++ b/hw/s390x/virtio-ccw-blk.c
@@ -48,6 +48,7 @@ static Property virtio_ccw_blk_properties[] = {
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
VIRTIO_CCW_MAX_REV),
+ DEFINE_PROP_CCW_LOADPARM("loadparm", CcwDevice, loadparm),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/s390x/virtio-ccw-net.c b/hw/s390x/virtio-ccw-net.c
index 484e617659..a4a3f65c7e 100644
--- a/hw/s390x/virtio-ccw-net.c
+++ b/hw/s390x/virtio-ccw-net.c
@@ -51,6 +51,7 @@ static Property virtio_ccw_net_properties[] = {
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
VIRTIO_CCW_MAX_REV),
+ DEFINE_PROP_CCW_LOADPARM("loadparm", CcwDevice, loadparm),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 115862f430..99f16614ad 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -662,6 +662,7 @@ static Property vfio_ccw_properties[] = {
DEFINE_PROP_LINK("iommufd", VFIOCCWDevice, vdev.iommufd,
TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *),
#endif
+ DEFINE_PROP_CCW_LOADPARM("loadparm", CcwDevice, loadparm),
DEFINE_PROP_END_OF_LIST(),
};
--
2.39.3

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

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

@ -1,61 +0,0 @@
From 80e197ac72a4b0c810f69833e1f9e552a415e82a Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Thu, 25 Apr 2024 14:49:40 +0200
Subject: [PATCH 2/4] iotests/244: Don't store data-file with protocol in image
RH-Author: Hana Czenczek <hczenczek@redhat.com>
RH-MergeRequest: 1: CVE 2024-4467 (PRDSC)
RH-Jira: RHEL-46239
RH-CVE: CVE-2024-4467
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Commit: [2/4] 92e00dab8be1570b13172353d77d2af44cb4e22b
We want to disable filename parsing for data files because it's too easy
to abuse in malicious image files. Make the test ready for the change by
passing the data file explicitly in command line options.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Upstream: N/A, embargoed
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
---
tests/qemu-iotests/244 | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
index 3e61fa25bb..bb9cc6512f 100755
--- a/tests/qemu-iotests/244
+++ b/tests/qemu-iotests/244
@@ -215,9 +215,22 @@ $QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG"
$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG"
# blkdebug doesn't support copy offloading, so this tests the error path
-$QEMU_IMG amend -f $IMGFMT -o "data_file=blkdebug::$TEST_IMG.data" "$TEST_IMG"
-$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG"
-$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG"
+test_img_with_blkdebug="json:{
+ 'driver': 'qcow2',
+ 'file': {
+ 'driver': 'file',
+ 'filename': '$TEST_IMG'
+ },
+ 'data-file': {
+ 'driver': 'blkdebug',
+ 'image': {
+ 'driver': 'file',
+ 'filename': '$TEST_IMG.data'
+ }
+ }
+}"
+$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$test_img_with_blkdebug"
+$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$test_img_with_blkdebug"
echo
echo "=== Flushing should flush the data file ==="
--
2.39.3

@ -1,64 +0,0 @@
From bf01c03b0120f5ed8e54c2a30b7830901b22b893 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Thu, 25 Apr 2024 14:49:40 +0200
Subject: [PATCH 3/4] iotests/270: Don't store data-file with json: prefix in
image
RH-Author: Hana Czenczek <hczenczek@redhat.com>
RH-MergeRequest: 1: CVE 2024-4467 (PRDSC)
RH-Jira: RHEL-46239
RH-CVE: CVE-2024-4467
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Commit: [3/4] 705bcc2819ce8e0f8b9d660a93bc48de26413aec
We want to disable filename parsing for data files because it's too easy
to abuse in malicious image files. Make the test ready for the change by
passing the data file explicitly in command line options.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Upstream: N/A, embargoed
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
---
tests/qemu-iotests/270 | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/tests/qemu-iotests/270 b/tests/qemu-iotests/270
index 74352342db..c37b674aa2 100755
--- a/tests/qemu-iotests/270
+++ b/tests/qemu-iotests/270
@@ -60,8 +60,16 @@ _make_test_img -o cluster_size=2M,data_file="$TEST_IMG.orig" \
# "write" 2G of data without using any space.
# (qemu-img create does not like it, though, because null-co does not
# support image creation.)
-$QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \
- "$TEST_IMG"
+test_img_with_null_data="json:{
+ 'driver': '$IMGFMT',
+ 'file': {
+ 'filename': '$TEST_IMG'
+ },
+ 'data-file': {
+ 'driver': 'null-co',
+ 'size':'4294967296'
+ }
+}"
# This gives us a range of:
# 2^31 - 512 + 768 - 1 = 2^31 + 255 > 2^31
@@ -74,7 +82,7 @@ $QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \
# on L2 boundaries, we need large L2 tables; hence the cluster size of
# 2 MB. (Anything from 256 kB should work, though, because then one L2
# table covers 8 GB.)
-$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$test_img_with_null_data" | _filter_qemu_io
_check_test_img
--
2.39.3

@ -1,276 +0,0 @@
From 2f12be8abfc90dc383a221441f60bdaae6b617d2 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Fri, 17 May 2024 21:50:15 -0500
Subject: [PATCH 4/4] iotests: test NBD+TLS+iothread
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Eric Blake <eblake@redhat.com>
RH-MergeRequest: 257: nbd/server: fix TLS negotiation across coroutine context
RH-Jira: RHEL-40959
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [4/4] 39a37bf3ae6e7046577de151ef2f6fd1fd694e62 (ebblake/centos-qemu-kvm)
Prevent regressions when using NBD with TLS in the presence of
iothreads, adding coverage the fix to qio channels made in the
previous patch.
The shell function pick_unused_port() was copied from
nbdkit.git/tests/functions.sh.in, where it had all authors from Red
Hat, agreeing to the resulting relicensing from 2-clause BSD to GPLv2.
CC: qemu-stable@nongnu.org
CC: "Richard W.M. Jones" <rjones@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240531180639.1392905-6-eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit a73c99378022ebb785481e84cfe1e81097546268)
Jira: https://issues.redhat.com/browse/RHEL-40959
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/qemu-iotests/tests/nbd-tls-iothread | 168 ++++++++++++++++++
tests/qemu-iotests/tests/nbd-tls-iothread.out | 54 ++++++
2 files changed, 222 insertions(+)
create mode 100755 tests/qemu-iotests/tests/nbd-tls-iothread
create mode 100644 tests/qemu-iotests/tests/nbd-tls-iothread.out
diff --git a/tests/qemu-iotests/tests/nbd-tls-iothread b/tests/qemu-iotests/tests/nbd-tls-iothread
new file mode 100755
index 0000000000..a2fb07206e
--- /dev/null
+++ b/tests/qemu-iotests/tests/nbd-tls-iothread
@@ -0,0 +1,168 @@
+#!/usr/bin/env bash
+# group: rw quick
+#
+# Test of NBD+TLS+iothread
+#
+# Copyright (C) 2024 Red Hat, Inc.
+#
+# This program 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=eblake@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_qemu
+ _cleanup_test_img
+ rm -f "$dst_image"
+ tls_x509_cleanup
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+cd ..
+. ./common.rc
+. ./common.filter
+. ./common.qemu
+. ./common.tls
+. ./common.nbd
+
+_supported_fmt qcow2 # Hardcoded to qcow2 command line and QMP below
+_supported_proto file
+
+# pick_unused_port
+#
+# Picks and returns an "unused" port, setting the global variable
+# $port.
+#
+# This is inherently racy, but we need it because qemu does not currently
+# permit NBD+TLS over a Unix domain socket
+pick_unused_port ()
+{
+ if ! (ss --version) >/dev/null 2>&1; then
+ _notrun "ss utility required, skipped this test"
+ fi
+
+ # Start at a random port to make it less likely that two parallel
+ # tests will conflict.
+ port=$(( 50000 + (RANDOM%15000) ))
+ while ss -ltn | grep -sqE ":$port\b"; do
+ ((port++))
+ if [ $port -eq 65000 ]; then port=50000; fi
+ done
+ echo picked unused port
+}
+
+tls_x509_init
+
+size=1G
+DST_IMG="$TEST_DIR/dst.qcow2"
+
+echo
+echo "== preparing TLS creds and spare port =="
+
+pick_unused_port
+tls_x509_create_root_ca "ca1"
+tls_x509_create_server "ca1" "server1"
+tls_x509_create_client "ca1" "client1"
+tls_obj_base=tls-creds-x509,id=tls0,verify-peer=true,dir="${tls_dir}"
+
+echo
+echo "== preparing image =="
+
+_make_test_img $size
+$QEMU_IMG create -f qcow2 "$DST_IMG" $size | _filter_img_create
+
+echo
+echo === Starting Src QEMU ===
+echo
+
+_launch_qemu -machine q35 \
+ -object iothread,id=iothread0 \
+ -object "${tls_obj_base}"/client1,endpoint=client \
+ -device '{"driver":"pcie-root-port", "id":"root0", "multifunction":true,
+ "bus":"pcie.0"}' \
+ -device '{"driver":"virtio-scsi-pci", "id":"virtio_scsi_pci0",
+ "bus":"root0", "iothread":"iothread0"}' \
+ -device '{"driver":"scsi-hd", "id":"image1", "drive":"drive_image1",
+ "bus":"virtio_scsi_pci0.0"}' \
+ -blockdev '{"driver":"file", "cache":{"direct":true, "no-flush":false},
+ "filename":"'"$TEST_IMG"'", "node-name":"drive_sys1"}' \
+ -blockdev '{"driver":"qcow2", "node-name":"drive_image1",
+ "file":"drive_sys1"}'
+h1=$QEMU_HANDLE
+_send_qemu_cmd $h1 '{"execute": "qmp_capabilities"}' 'return'
+
+echo
+echo === Starting Dst VM2 ===
+echo
+
+_launch_qemu -machine q35 \
+ -object iothread,id=iothread0 \
+ -object "${tls_obj_base}"/server1,endpoint=server \
+ -device '{"driver":"pcie-root-port", "id":"root0", "multifunction":true,
+ "bus":"pcie.0"}' \
+ -device '{"driver":"virtio-scsi-pci", "id":"virtio_scsi_pci0",
+ "bus":"root0", "iothread":"iothread0"}' \
+ -device '{"driver":"scsi-hd", "id":"image1", "drive":"drive_image1",
+ "bus":"virtio_scsi_pci0.0"}' \
+ -blockdev '{"driver":"file", "cache":{"direct":true, "no-flush":false},
+ "filename":"'"$DST_IMG"'", "node-name":"drive_sys1"}' \
+ -blockdev '{"driver":"qcow2", "node-name":"drive_image1",
+ "file":"drive_sys1"}' \
+ -incoming defer
+h2=$QEMU_HANDLE
+_send_qemu_cmd $h2 '{"execute": "qmp_capabilities"}' 'return'
+
+echo
+echo === Dst VM: Enable NBD server for incoming storage migration ===
+echo
+
+_send_qemu_cmd $h2 '{"execute": "nbd-server-start", "arguments":
+ {"addr": {"type": "inet", "data": {"host": "127.0.0.1", "port": "'$port'"}},
+ "tls-creds": "tls0"}}' '{"return": {}}' | sed "s/\"$port\"/PORT/g"
+_send_qemu_cmd $h2 '{"execute": "block-export-add", "arguments":
+ {"node-name": "drive_image1", "type": "nbd", "writable": true,
+ "id": "drive_image1"}}' '{"return": {}}'
+
+echo
+echo === Src VM: Mirror to dst NBD for outgoing storage migration ===
+echo
+
+_send_qemu_cmd $h1 '{"execute": "blockdev-add", "arguments":
+ {"node-name": "mirror", "driver": "nbd",
+ "server": {"type": "inet", "host": "127.0.0.1", "port": "'$port'"},
+ "export": "drive_image1", "tls-creds": "tls0",
+ "tls-hostname": "127.0.0.1"}}' '{"return": {}}' | sed "s/\"$port\"/PORT/g"
+_send_qemu_cmd $h1 '{"execute": "blockdev-mirror", "arguments":
+ {"sync": "full", "device": "drive_image1", "target": "mirror",
+ "job-id": "drive_image1_53"}}' '{"return": {}}'
+_timed_wait_for $h1 '"ready"'
+
+echo
+echo === Cleaning up ===
+echo
+
+_send_qemu_cmd $h1 '{"execute":"quit"}' ''
+_send_qemu_cmd $h2 '{"execute":"quit"}' ''
+
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/tests/nbd-tls-iothread.out b/tests/qemu-iotests/tests/nbd-tls-iothread.out
new file mode 100644
index 0000000000..1d83d4f903
--- /dev/null
+++ b/tests/qemu-iotests/tests/nbd-tls-iothread.out
@@ -0,0 +1,54 @@
+QA output created by nbd-tls-iothread
+
+== preparing TLS creds and spare port ==
+picked unused port
+Generating a self signed certificate...
+Generating a signed certificate...
+Generating a signed certificate...
+
+== preparing image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
+Formatting 'TEST_DIR/dst.IMGFMT', fmt=IMGFMT size=1073741824
+
+=== Starting Src QEMU ===
+
+{"execute": "qmp_capabilities"}
+{"return": {}}
+
+=== Starting Dst VM2 ===
+
+{"execute": "qmp_capabilities"}
+{"return": {}}
+
+=== Dst VM: Enable NBD server for incoming storage migration ===
+
+{"execute": "nbd-server-start", "arguments":
+ {"addr": {"type": "inet", "data": {"host": "127.0.0.1", "port": PORT}},
+ "tls-creds": "tls0"}}
+{"return": {}}
+{"execute": "block-export-add", "arguments":
+ {"node-name": "drive_image1", "type": "nbd", "writable": true,
+ "id": "drive_image1"}}
+{"return": {}}
+
+=== Src VM: Mirror to dst NBD for outgoing storage migration ===
+
+{"execute": "blockdev-add", "arguments":
+ {"node-name": "mirror", "driver": "nbd",
+ "server": {"type": "inet", "host": "127.0.0.1", "port": PORT},
+ "export": "drive_image1", "tls-creds": "tls0",
+ "tls-hostname": "127.0.0.1"}}
+{"return": {}}
+{"execute": "blockdev-mirror", "arguments":
+ {"sync": "full", "device": "drive_image1", "target": "mirror",
+ "job-id": "drive_image1_53"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "drive_image1_53"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "drive_image1_53"}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "drive_image1_53"}}
+
+=== Cleaning up ===
+
+{"execute":"quit"}
+{"execute":"quit"}
+*** done
--
2.39.3

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

@ -0,0 +1,144 @@
From 67180363bdc1898462f90e16c1909db7331cc5e2 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Thu, 8 Aug 2024 17:08:38 +0530
Subject: [PATCH 3/9] kvm: refactor core virtual machine creation into its own
function
RH-Author: Peter Xu <peterx@redhat.com>
RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array
RH-Jira: RHEL-57685
RH-Acked-by: Juraj Marcin <None>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/7] a783111d9a2ef6590103543f1bd103bf90052872 (peterx/qemu-kvm)
Refactoring the core logic around KVM_CREATE_VM into its own separate function
so that it can be called from other functions in subsequent patches. There is
no functional change in this patch.
CC: pbonzini@redhat.com
CC: zhao1.liu@intel.com
Signed-off-by: Ani Sinha <anisinha@redhat.com>
Link: https://lore.kernel.org/r/20240808113838.1697366-1-anisinha@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 67388078da1cf6dac89e5a7c748cca3444d49690)
Signed-off-by: Peter Xu <peterx@redhat.com>
---
accel/kvm/kvm-all.c | 89 ++++++++++++++++++++++++++++-----------------
1 file changed, 56 insertions(+), 33 deletions(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 7432a54f39..d86d1b515a 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2385,6 +2385,60 @@ uint32_t kvm_dirty_ring_size(void)
return kvm_state->kvm_dirty_ring_size;
}
+static int do_kvm_create_vm(MachineState *ms, int type)
+{
+ KVMState *s;
+ int ret;
+
+ s = KVM_STATE(ms->accelerator);
+
+ do {
+ ret = kvm_ioctl(s, KVM_CREATE_VM, type);
+ } while (ret == -EINTR);
+
+ if (ret < 0) {
+ error_report("ioctl(KVM_CREATE_VM) failed: %s", strerror(-ret));
+
+#ifdef TARGET_S390X
+ if (ret == -EINVAL) {
+ error_printf("Host kernel setup problem detected."
+ " Please verify:\n");
+ error_printf("- for kernels supporting the"
+ " switch_amode or user_mode parameters, whether");
+ error_printf(" user space is running in primary address space\n");
+ error_printf("- for kernels supporting the vm.allocate_pgste"
+ " sysctl, whether it is enabled\n");
+ }
+#elif defined(TARGET_PPC)
+ if (ret == -EINVAL) {
+ error_printf("PPC KVM module is not loaded. Try modprobe kvm_%s.\n",
+ (type == 2) ? "pr" : "hv");
+ }
+#endif
+ }
+
+ return ret;
+}
+
+static int find_kvm_machine_type(MachineState *ms)
+{
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+ int type;
+
+ if (object_property_find(OBJECT(current_machine), "kvm-type")) {
+ g_autofree char *kvm_type;
+ kvm_type = object_property_get_str(OBJECT(current_machine),
+ "kvm-type",
+ &error_abort);
+ type = mc->kvm_type(ms, kvm_type);
+ } else if (mc->kvm_type) {
+ type = mc->kvm_type(ms, NULL);
+ } else {
+ type = kvm_arch_get_default_type(ms);
+ }
+ return type;
+}
+
static int kvm_init(MachineState *ms)
{
MachineClass *mc = MACHINE_GET_CLASS(ms);
@@ -2467,45 +2521,14 @@ static int kvm_init(MachineState *ms)
}
s->as = g_new0(struct KVMAs, s->nr_as);
- if (object_property_find(OBJECT(current_machine), "kvm-type")) {
- g_autofree char *kvm_type = object_property_get_str(OBJECT(current_machine),
- "kvm-type",
- &error_abort);
- type = mc->kvm_type(ms, kvm_type);
- } else if (mc->kvm_type) {
- type = mc->kvm_type(ms, NULL);
- } else {
- type = kvm_arch_get_default_type(ms);
- }
-
+ type = find_kvm_machine_type(ms);
if (type < 0) {
ret = -EINVAL;
goto err;
}
- do {
- ret = kvm_ioctl(s, KVM_CREATE_VM, type);
- } while (ret == -EINTR);
-
+ ret = do_kvm_create_vm(ms, type);
if (ret < 0) {
- error_report("ioctl(KVM_CREATE_VM) failed: %s", strerror(-ret));
-
-#ifdef TARGET_S390X
- if (ret == -EINVAL) {
- error_printf("Host kernel setup problem detected."
- " Please verify:\n");
- error_printf("- for kernels supporting the"
- " switch_amode or user_mode parameters, whether");
- error_printf(" user space is running in primary address space\n");
- error_printf("- for kernels supporting the vm.allocate_pgste"
- " sysctl, whether it is enabled\n");
- }
-#elif defined(TARGET_PPC)
- if (ret == -EINVAL) {
- error_printf("PPC KVM module is not loaded. Try modprobe kvm_%s.\n",
- (type == 2) ? "pr" : "hv");
- }
-#endif
goto err;
}
--
2.39.3

@ -0,0 +1,132 @@
From 522e19dd84eb5c4d88b3b70193ee104f67a5b89d Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Wed, 28 Aug 2024 18:15:39 +0530
Subject: [PATCH 2/9] kvm: replace fprintf with error_report()/printf() in
kvm_init()
RH-Author: Peter Xu <peterx@redhat.com>
RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array
RH-Jira: RHEL-57685
RH-Acked-by: Juraj Marcin <None>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/7] 6c1230a6d5033d928817df9458938a675058e995 (peterx/qemu-kvm)
error_report() is more appropriate for error situations. Replace fprintf with
error_report() and error_printf() as appropriate. Some improvement in error
reporting also happens as a part of this change. For example:
From:
$ ./qemu-system-x86_64 --accel kvm
Could not access KVM kernel module: No such file or directory
To:
$ ./qemu-system-x86_64 --accel kvm
qemu-system-x86_64: --accel kvm: Could not access KVM kernel module: No such file or directory
CC: qemu-trivial@nongnu.org
CC: zhao1.liu@intel.com
CC: armbru@redhat.com
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Ani Sinha <anisinha@redhat.com>
Link: https://lore.kernel.org/r/20240828124539.62672-1-anisinha@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 804dfbe3ef5e950328b162ae85741be2e228544f)
Signed-off-by: Peter Xu <peterx@redhat.com>
---
accel/kvm/kvm-all.c | 40 ++++++++++++++++++----------------------
1 file changed, 18 insertions(+), 22 deletions(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index c7f1cc64b6..7432a54f39 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2427,7 +2427,7 @@ static int kvm_init(MachineState *ms)
QLIST_INIT(&s->kvm_parked_vcpus);
s->fd = qemu_open_old(s->device ?: "/dev/kvm", O_RDWR);
if (s->fd == -1) {
- fprintf(stderr, "Could not access KVM kernel module: %m\n");
+ error_report("Could not access KVM kernel module: %m");
ret = -errno;
goto err;
}
@@ -2437,13 +2437,13 @@ static int kvm_init(MachineState *ms)
if (ret >= 0) {
ret = -EINVAL;
}
- fprintf(stderr, "kvm version too old\n");
+ error_report("kvm version too old");
goto err;
}
if (ret > KVM_API_VERSION) {
ret = -EINVAL;
- fprintf(stderr, "kvm version not supported\n");
+ error_report("kvm version not supported");
goto err;
}
@@ -2488,26 +2488,22 @@ static int kvm_init(MachineState *ms)
} while (ret == -EINTR);
if (ret < 0) {
- fprintf(stderr, "ioctl(KVM_CREATE_VM) failed: %d %s\n", -ret,
- strerror(-ret));
+ error_report("ioctl(KVM_CREATE_VM) failed: %s", strerror(-ret));
#ifdef TARGET_S390X
if (ret == -EINVAL) {
- fprintf(stderr,
- "Host kernel setup problem detected. Please verify:\n");
- fprintf(stderr, "- for kernels supporting the switch_amode or"
- " user_mode parameters, whether\n");
- fprintf(stderr,
- " user space is running in primary address space\n");
- fprintf(stderr,
- "- for kernels supporting the vm.allocate_pgste sysctl, "
- "whether it is enabled\n");
+ error_printf("Host kernel setup problem detected."
+ " Please verify:\n");
+ error_printf("- for kernels supporting the"
+ " switch_amode or user_mode parameters, whether");
+ error_printf(" user space is running in primary address space\n");
+ error_printf("- for kernels supporting the vm.allocate_pgste"
+ " sysctl, whether it is enabled\n");
}
#elif defined(TARGET_PPC)
if (ret == -EINVAL) {
- fprintf(stderr,
- "PPC KVM module is not loaded. Try modprobe kvm_%s.\n",
- (type == 2) ? "pr" : "hv");
+ error_printf("PPC KVM module is not loaded. Try modprobe kvm_%s.\n",
+ (type == 2) ? "pr" : "hv");
}
#endif
goto err;
@@ -2526,9 +2522,9 @@ static int kvm_init(MachineState *ms)
nc->name, nc->num, soft_vcpus_limit);
if (nc->num > hard_vcpus_limit) {
- fprintf(stderr, "Number of %s cpus requested (%d) exceeds "
- "the maximum cpus supported by KVM (%d)\n",
- nc->name, nc->num, hard_vcpus_limit);
+ error_report("Number of %s cpus requested (%d) exceeds "
+ "the maximum cpus supported by KVM (%d)",
+ nc->name, nc->num, hard_vcpus_limit);
exit(1);
}
}
@@ -2542,8 +2538,8 @@ static int kvm_init(MachineState *ms)
}
if (missing_cap) {
ret = -EINVAL;
- fprintf(stderr, "kvm does not support %s\n%s",
- missing_cap->name, upgrade_note);
+ error_report("kvm does not support %s", missing_cap->name);
+ error_printf("%s", upgrade_note);
goto err;
}
--
2.39.3

@ -1,126 +0,0 @@
From 11faa773637f76f573f5320c063f7e55263c3a84 Mon Sep 17 00:00:00 2001
From: Prasad Pandit <pjp@fedoraproject.org>
Date: Thu, 25 Apr 2024 12:34:12 +0530
Subject: [PATCH 1/5] linux-aio: add IO_CMD_FDSYNC command support
RH-Author: Prasad Pandit <None>
RH-MergeRequest: 260: linux-aio: add IO_CMD_FDSYNC command support
RH-Jira: RHEL-51901
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] 2830edc801f9fbbc373631cf5b12a396f4b2bced (pjp/cs-qemu-kvm)
Libaio defines IO_CMD_FDSYNC command to sync all outstanding
asynchronous I/O operations, by flushing out file data to the
disk storage. Enable linux-aio to submit such aio request.
When using aio=native without fdsync() support, QEMU creates
pthreads, and destroying these pthreads results in TLB flushes.
In a real-time guest environment, TLB flushes cause a latency
spike. This patch helps to avoid such spikes.
Jira: https://issues.redhat.com/browse/RHEL-51901
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Prasad Pandit <pjp@fedoraproject.org>
Message-ID: <20240425070412.37248-1-ppandit@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 24687abf237e3c15816d689a8e4b08d7c3190dcb)
Signed-off-by: Prasad Pandit <pjp@fedoraproject.org>
---
block/file-posix.c | 9 +++++++++
block/linux-aio.c | 21 ++++++++++++++++++++-
include/block/raw-aio.h | 1 +
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/block/file-posix.c b/block/file-posix.c
index 35684f7e21..9831b08fb6 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -159,6 +159,7 @@ typedef struct BDRVRawState {
bool has_discard:1;
bool has_write_zeroes:1;
bool use_linux_aio:1;
+ bool has_laio_fdsync:1;
bool use_linux_io_uring:1;
int page_cache_inconsistent; /* errno from fdatasync failure */
bool has_fallocate;
@@ -718,6 +719,9 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
ret = -EINVAL;
goto fail;
}
+ if (s->use_linux_aio) {
+ s->has_laio_fdsync = laio_has_fdsync(s->fd);
+ }
#else
if (s->use_linux_aio) {
error_setg(errp, "aio=native was specified, but is not supported "
@@ -2599,6 +2603,11 @@ static int coroutine_fn raw_co_flush_to_disk(BlockDriverState *bs)
if (raw_check_linux_io_uring(s)) {
return luring_co_submit(bs, s->fd, 0, NULL, QEMU_AIO_FLUSH);
}
+#endif
+#ifdef CONFIG_LINUX_AIO
+ if (s->has_laio_fdsync && raw_check_linux_aio(s)) {
+ return laio_co_submit(s->fd, 0, NULL, QEMU_AIO_FLUSH, 0);
+ }
#endif
return raw_thread_pool_submit(handle_aiocb_flush, &acb);
}
diff --git a/block/linux-aio.c b/block/linux-aio.c
index ec05d946f3..e3b5ec9aba 100644
--- a/block/linux-aio.c
+++ b/block/linux-aio.c
@@ -384,6 +384,9 @@ static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
case QEMU_AIO_READ:
io_prep_preadv(iocbs, fd, qiov->iov, qiov->niov, offset);
break;
+ case QEMU_AIO_FLUSH:
+ io_prep_fdsync(iocbs, fd);
+ break;
/* Currently Linux kernel does not support other operations */
default:
fprintf(stderr, "%s: invalid AIO request type 0x%x.\n",
@@ -412,7 +415,7 @@ int coroutine_fn laio_co_submit(int fd, uint64_t offset, QEMUIOVector *qiov,
AioContext *ctx = qemu_get_current_aio_context();
struct qemu_laiocb laiocb = {
.co = qemu_coroutine_self(),
- .nbytes = qiov->size,
+ .nbytes = qiov ? qiov->size : 0,
.ctx = aio_get_linux_aio(ctx),
.ret = -EINPROGRESS,
.is_read = (type == QEMU_AIO_READ),
@@ -486,3 +489,19 @@ void laio_cleanup(LinuxAioState *s)
}
g_free(s);
}
+
+bool laio_has_fdsync(int fd)
+{
+ struct iocb cb;
+ struct iocb *cbs[] = {&cb, NULL};
+
+ io_context_t ctx = 0;
+ io_setup(1, &ctx);
+
+ /* check if host kernel supports IO_CMD_FDSYNC */
+ io_prep_fdsync(&cb, fd);
+ int ret = io_submit(ctx, 1, cbs);
+
+ io_destroy(ctx);
+ return (ret == -EINVAL) ? false : true;
+}
diff --git a/include/block/raw-aio.h b/include/block/raw-aio.h
index 20e000b8ef..626706827f 100644
--- a/include/block/raw-aio.h
+++ b/include/block/raw-aio.h
@@ -60,6 +60,7 @@ void laio_cleanup(LinuxAioState *s);
int coroutine_fn laio_co_submit(int fd, uint64_t offset, QEMUIOVector *qiov,
int type, uint64_t dev_max_batch);
+bool laio_has_fdsync(int);
void laio_detach_aio_context(LinuxAioState *s, AioContext *old_context);
void laio_attach_aio_context(LinuxAioState *s, AioContext *new_context);
#endif
--
2.39.3

@ -0,0 +1,116 @@
From 3f4762ae8fd1fb148b97cd713209d3b55e8ea489 Mon Sep 17 00:00:00 2001
From: Peter Xu <peterx@redhat.com>
Date: Wed, 20 Nov 2024 11:01:32 -0500
Subject: [PATCH] migration: Allow pipes to keep working for fd migrations
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Peter Xu <peterx@redhat.com>
RH-MergeRequest: 302: migration: Allow pipes to keep working for fd migrations
RH-Jira: RHEL-69047
RH-Acked-by: Juraj Marcin <None>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] f5c0af772cbd3ced12a7b260f86f98e74d8345d1 (peterx/qemu-kvm)
Libvirt may still use pipes for old file migrations in fd: URI form,
especially when loading old images dumped from Libvirt's compression
algorithms.
In that case, Libvirt needs to compress / uncompress the images on its own
over the migration binary stream, and pipes are passed over to QEMU for
outgoing / incoming migrations in "fd:" URIs.
For future such use case, it should be suggested to use mapped-ram when
saving such VM image. However there can still be old images that was
compressed in such way, so libvirt needs to be able to load those images,
uncompress them and use the same pipe mechanism to pass that over to QEMU.
It means, even if new file migrations can be gradually moved over to
mapped-ram (after Libvirt start supporting it), Libvirt still needs the
uncompressor for the old images to be able to load like before.
Meanwhile since Libvirt currently exposes the compression capability to
guest images, it may needs its own lifecycle management to move that over
to mapped-ram, maybe can be done after mapped-ram saved the image, however
Dan and PeterK raised concern on temporary double disk space consumption.
I suppose for now the easiest is to enable pipes for both sides of "fd:"
migrations, until all things figured out from Libvirt side on how to move
on.
And for "channels" QMP interface support on "migrate" / "migrate-incoming"
commands, we'll also need to move away from pipe. But let's leave that for
later too.
So far, still allow pipes to happen like before on both save/load sides,
just like we would allow sockets to pass.
Cc: qemu-stable <qemu-stable@nongnu.org>
Cc: Fabiano Rosas <farosas@suse.de>
Cc: Peter Krempa <pkrempa@redhat.com>
Cc: Daniel P. Berrangé <berrange@redhat.com>
Fixes: c55deb860c ("migration: Deprecate fd: for file migration")
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Link: https://lore.kernel.org/r/20241120160132.3659735-1-peterx@redhat.com
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit 87ae45e602e2943d58509e470e3a1d4ba084ab2f)
Signed-off-by: Peter Xu <peterx@redhat.com>
---
migration/fd.c | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/migration/fd.c b/migration/fd.c
index aab5189eac..9bf9be6acb 100644
--- a/migration/fd.c
+++ b/migration/fd.c
@@ -25,6 +25,29 @@
#include "io/channel-util.h"
#include "trace.h"
+static bool fd_is_pipe(int fd)
+{
+ struct stat statbuf;
+
+ if (fstat(fd, &statbuf) == -1) {
+ return false;
+ }
+
+ return S_ISFIFO(statbuf.st_mode);
+}
+
+static bool migration_fd_valid(int fd)
+{
+ if (fd_is_socket(fd)) {
+ return true;
+ }
+
+ if (fd_is_pipe(fd)) {
+ return true;
+ }
+
+ return false;
+}
void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp)
{
@@ -34,7 +57,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **
return;
}
- if (!fd_is_socket(fd)) {
+ if (!migration_fd_valid(fd)) {
warn_report("fd: migration to a file is deprecated."
" Use file: instead.");
}
@@ -68,7 +91,7 @@ void fd_start_incoming_migration(const char *fdname, Error **errp)
return;
}
- if (!fd_is_socket(fd)) {
+ if (!migration_fd_valid(fd)) {
warn_report("fd: migration to a file is deprecated."
" Use file: instead.");
}
--
2.39.3

@ -0,0 +1,92 @@
From 6be2f51c147df1ab1dd7c68c6b554512dfc05e6f Mon Sep 17 00:00:00 2001
From: Hanna Czenczek <hreitz@redhat.com>
Date: Tue, 15 Oct 2024 19:04:37 +0200
Subject: [PATCH 1/9] migration: Ensure vmstate_save() sets errp
RH-Author: Hanna Czenczek <hreitz@redhat.com>
RH-MergeRequest: 288: migration: Ensure vmstate_save() sets errp
RH-Jira: RHEL-63051
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
RH-Acked-by: German Maglione <None>
RH-Commit: [1/1] 4d5a65c294ae83a29db885e42fb3f2ca913c36f0 (hreitz/qemu-kvm-c-9-s)
migration/savevm.c contains some calls to vmstate_save() that are
followed by migrate_set_error() if the integer return value indicates an
error. migrate_set_error() requires that the `Error *` object passed to
it is set. Therefore, vmstate_save() is assumed to always set *errp on
error.
Right now, that assumption is not met: vmstate_save_state_v() (called
internally by vmstate_save()) will not set *errp if
vmstate_subsection_save() or vmsd->post_save() fail. Fix that by adding
an *errp parameter to vmstate_subsection_save(), and by generating a
generic error in case post_save() fails (as is already done for
pre_save()).
Without this patch, qemu will crash after vmstate_subsection_save() or
post_save() have failed inside of a vmstate_save() call (unless
migrate_set_error() then happen to discard the new error because
s->error is already set). This happens e.g. when receiving the state
from a virtio-fs back-end (virtiofsd) fails.
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
Link: https://lore.kernel.org/r/20241015170437.310358-1-hreitz@redhat.com
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit 37dfcba1a04989830c706f9cbc00450e5d3a7447)
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
---
migration/vmstate.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/migration/vmstate.c b/migration/vmstate.c
index ff5d589a6d..fa002b24e8 100644
--- a/migration/vmstate.c
+++ b/migration/vmstate.c
@@ -22,7 +22,8 @@
#include "trace.h"
static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
- void *opaque, JSONWriter *vmdesc);
+ void *opaque, JSONWriter *vmdesc,
+ Error **errp);
static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque);
@@ -441,12 +442,13 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
json_writer_end_array(vmdesc);
}
- ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc);
+ ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc, errp);
if (vmsd->post_save) {
int ps_ret = vmsd->post_save(opaque);
- if (!ret) {
+ if (!ret && ps_ret) {
ret = ps_ret;
+ error_setg(errp, "post-save failed: %s", vmsd->name);
}
}
return ret;
@@ -518,7 +520,8 @@ static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
}
static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
- void *opaque, JSONWriter *vmdesc)
+ void *opaque, JSONWriter *vmdesc,
+ Error **errp)
{
const VMStateDescription * const *sub = vmsd->subsections;
bool vmdesc_has_subsections = false;
@@ -546,7 +549,7 @@ static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
qemu_put_byte(f, len);
qemu_put_buffer(f, (uint8_t *)vmsdsub->name, len);
qemu_put_be32(f, vmsdsub->version_id);
- ret = vmstate_save_state(f, vmsdsub, opaque, vmdesc);
+ ret = vmstate_save_state_with_err(f, vmsdsub, opaque, vmdesc, errp);
if (ret) {
return ret;
}
--
2.39.3

@ -1,101 +0,0 @@
From 3732f1491d8981e85f699fcd125d903aba77fa32 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Thu, 22 Aug 2024 09:35:29 -0500
Subject: [PATCH] nbd/server: CVE-2024-7409: Avoid use-after-free when closing
server
RH-Author: Eric Blake <eblake@redhat.com>
RH-MergeRequest: 267: nbd/server: CVE-2024-7409: Avoid use-after-free when closing server
RH-Jira: RHEL-52599
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: e7d52e5d1372eaec00325d4854772ee78fe650b7 (ebblake/centos-qemu-kvm)
Commit 3e7ef738 plugged the use-after-free of the global nbd_server
object, but overlooked a use-after-free of nbd_server->listener.
Although this race is harder to hit, notice that our shutdown path
first drops the reference count of nbd_server->listener, then triggers
actions that can result in a pending client reaching the
nbd_blockdev_client_closed() callback, which in turn calls
qio_net_listener_set_client_func on a potentially stale object.
If we know we don't want any more clients to connect, and have already
told the listener socket to shut down, then we should not be trying to
update the listener socket's associated function.
Reproducer:
> #!/usr/bin/python3
>
> import os
> from threading import Thread
>
> def start_stop():
> while 1:
> os.system('virsh qemu-monitor-command VM \'{"execute": "nbd-server-start",
+"arguments":{"addr":{"type":"unix","data":{"path":"/tmp/nbd-sock"}}}}\'')
> os.system('virsh qemu-monitor-command VM \'{"execute": "nbd-server-stop"}\'')
>
> def nbd_list():
> while 1:
> os.system('/path/to/build/qemu-nbd -L -k /tmp/nbd-sock')
>
> def test():
> sst = Thread(target=start_stop)
> sst.start()
> nlt = Thread(target=nbd_list)
> nlt.start()
>
> sst.join()
> nlt.join()
>
> test()
Fixes: CVE-2024-7409
Fixes: 3e7ef738c8 ("nbd/server: CVE-2024-7409: Close stray clients at server-stop")
CC: qemu-stable@nongnu.org
Reported-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240822143617.800419-2-eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 3874f5f73c441c52f1c699c848d463b0eda01e4c)
Jira: https://issues.redhat.com/browse/RHEL-52599
Signed-off-by: Eric Blake <eblake@redhat.com>
---
blockdev-nbd.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index f73409ae49..b36f41b7c5 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -92,10 +92,13 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
static void nbd_update_server_watch(NBDServerData *s)
{
- if (!s->max_connections || s->connections < s->max_connections) {
- qio_net_listener_set_client_func(s->listener, nbd_accept, NULL, NULL);
- } else {
- qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
+ if (s->listener) {
+ if (!s->max_connections || s->connections < s->max_connections) {
+ qio_net_listener_set_client_func(s->listener, nbd_accept, NULL,
+ NULL);
+ } else {
+ qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
+ }
}
}
@@ -113,6 +116,7 @@ static void nbd_server_free(NBDServerData *server)
*/
qio_net_listener_disconnect(server->listener);
object_unref(OBJECT(server->listener));
+ server->listener = NULL;
QLIST_FOREACH_SAFE(conn, &server->conns, next, tmp) {
qio_channel_shutdown(QIO_CHANNEL(conn->cioc), QIO_CHANNEL_SHUTDOWN_BOTH,
NULL);
--
2.39.3

@ -1,184 +0,0 @@
From 20b179691fcd3a58aaf76269e66bd102dfbd0d2e Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Tue, 6 Aug 2024 13:53:00 -0500
Subject: [PATCH 3/5] nbd/server: CVE-2024-7409: Cap default max-connections to
100
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Eric Blake <eblake@redhat.com>
RH-MergeRequest: 263: nbd/server: fix CVE-2024-7409 (qemu crash on nbd-server-stop) [RHEL 10.0]
RH-Jira: RHEL-52599
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/4] ad547c43ee9bae4cf6476408176aa7a7892427ff (redhat/centos-stream/src/qemu-kvm)
Allowing an unlimited number of clients to any web service is a recipe
for a rudimentary denial of service attack: the client merely needs to
open lots of sockets without closing them, until qemu no longer has
any more fds available to allocate.
For qemu-nbd, we default to allowing only 1 connection unless more are
explicitly asked for (-e or --shared); this was historically picked as
a nice default (without an explicit -t, a non-persistent qemu-nbd goes
away after a client disconnects, without needing any additional
follow-up commands), and we are not going to change that interface now
(besides, someday we want to point people towards qemu-storage-daemon
instead of qemu-nbd).
But for qemu proper, and the newer qemu-storage-daemon, the QMP
nbd-server-start command has historically had a default of unlimited
number of connections, in part because unlike qemu-nbd it is
inherently persistent until nbd-server-stop. Allowing multiple client
sockets is particularly useful for clients that can take advantage of
MULTI_CONN (creating parallel sockets to increase throughput),
although known clients that do so (such as libnbd's nbdcopy) typically
use only 8 or 16 connections (the benefits of scaling diminish once
more sockets are competing for kernel attention). Picking a number
large enough for typical use cases, but not unlimited, makes it
slightly harder for a malicious client to perform a denial of service
merely by opening lots of connections withot progressing through the
handshake.
This change does not eliminate CVE-2024-7409 on its own, but reduces
the chance for fd exhaustion or unlimited memory usage as an attack
surface. On the other hand, by itself, it makes it more obvious that
with a finite limit, we have the problem of an unauthenticated client
holding 100 fds opened as a way to block out a legitimate client from
being able to connect; thus, later patches will further add timeouts
to reject clients that are not making progress.
This is an INTENTIONAL change in behavior, and will break any client
of nbd-server-start that was not passing an explicit max-connections
parameter, yet expects more than 100 simultaneous connections. We are
not aware of any such client (as stated above, most clients aware of
MULTI_CONN get by just fine on 8 or 16 connections, and probably cope
with later connections failing by relying on the earlier connections;
libvirt has not yet been passing max-connections, but generally
creates NBD servers with the intent for a single client for the sake
of live storage migration; meanwhile, the KubeSAN project anticipates
a large cluster sharing multiple clients [up to 8 per node, and up to
100 nodes in a cluster], but it currently uses qemu-nbd with an
explicit --shared=0 rather than qemu-storage-daemon with
nbd-server-start).
We considered using a deprecation period (declare that omitting
max-parameters is deprecated, and make it mandatory in 3 releases -
then we don't need to pick an arbitrary default); that has zero risk
of breaking any apps that accidentally depended on more than 100
connections, and where such breakage might not be noticed under unit
testing but only under the larger loads of production usage. But it
does not close the denial-of-service hole until far into the future,
and requires all apps to change to add the parameter even if 100 was
good enough. It also has a drawback that any app (like libvirt) that
is accidentally relying on an unlimited default should seriously
consider their own CVE now, at which point they are going to change to
pass explicit max-connections sooner than waiting for 3 qemu releases.
Finally, if our changed default breaks an app, that app can always
pass in an explicit max-parameters with a larger value.
It is also intentional that the HMP interface to nbd-server-start is
not changed to expose max-connections (any client needing to fine-tune
things should be using QMP).
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240807174943.771624-12-eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
[ericb: Expand commit message to summarize Dan's argument for why we
break corner-case back-compat behavior without a deprecation period]
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit c8a76dbd90c2f48df89b75bef74917f90a59b623)
Jira: https://issues.redhat.com/browse/RHEL-52599
Signed-off-by: Eric Blake <eblake@redhat.com>
---
block/monitor/block-hmp-cmds.c | 3 ++-
blockdev-nbd.c | 8 ++++++++
include/block/nbd.h | 7 +++++++
qapi/block-export.json | 4 ++--
4 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index d954bec6f1..bdf2eb50b6 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -402,7 +402,8 @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
goto exit;
}
- nbd_server_start(addr, NULL, NULL, 0, &local_err);
+ nbd_server_start(addr, NULL, NULL, NBD_DEFAULT_MAX_CONNECTIONS,
+ &local_err);
qapi_free_SocketAddress(addr);
if (local_err != NULL) {
goto exit;
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 267a1de903..24ba5382db 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -170,6 +170,10 @@ void nbd_server_start(SocketAddress *addr, const char *tls_creds,
void nbd_server_start_options(NbdServerOptions *arg, Error **errp)
{
+ if (!arg->has_max_connections) {
+ arg->max_connections = NBD_DEFAULT_MAX_CONNECTIONS;
+ }
+
nbd_server_start(arg->addr, arg->tls_creds, arg->tls_authz,
arg->max_connections, errp);
}
@@ -182,6 +186,10 @@ void qmp_nbd_server_start(SocketAddressLegacy *addr,
{
SocketAddress *addr_flat = socket_address_flatten(addr);
+ if (!has_max_connections) {
+ max_connections = NBD_DEFAULT_MAX_CONNECTIONS;
+ }
+
nbd_server_start(addr_flat, tls_creds, tls_authz, max_connections, errp);
qapi_free_SocketAddress(addr_flat);
}
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 1d4d65922d..d4f8b21aec 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -39,6 +39,13 @@ extern const BlockExportDriver blk_exp_nbd;
*/
#define NBD_DEFAULT_HANDSHAKE_MAX_SECS 10
+/*
+ * NBD_DEFAULT_MAX_CONNECTIONS: Number of client sockets to allow at
+ * once; must be large enough to allow a MULTI_CONN-aware client like
+ * nbdcopy to create its typical number of 8-16 sockets.
+ */
+#define NBD_DEFAULT_MAX_CONNECTIONS 100
+
/* Handshake phase structs - this struct is passed on the wire */
typedef struct NBDOption {
diff --git a/qapi/block-export.json b/qapi/block-export.json
index 3919a2d5b9..f45e4fd481 100644
--- a/qapi/block-export.json
+++ b/qapi/block-export.json
@@ -28,7 +28,7 @@
# @max-connections: The maximum number of connections to allow at the
# same time, 0 for unlimited. Setting this to 1 also stops the
# server from advertising multiple client support (since 5.2;
-# default: 0)
+# default: 100)
#
# Since: 4.2
##
@@ -63,7 +63,7 @@
# @max-connections: The maximum number of connections to allow at the
# same time, 0 for unlimited. Setting this to 1 also stops the
# server from advertising multiple client support (since 5.2;
-# default: 0).
+# default: 100).
#
# Errors:
# - if the server is already running
--
2.39.3

@ -1,173 +0,0 @@
From 1b4bf69b064815a41ac18ef7276ceab0b9e0eb5b Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 7 Aug 2024 12:23:13 -0500
Subject: [PATCH 5/5] nbd/server: CVE-2024-7409: Close stray clients at
server-stop
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Eric Blake <eblake@redhat.com>
RH-MergeRequest: 263: nbd/server: fix CVE-2024-7409 (qemu crash on nbd-server-stop) [RHEL 10.0]
RH-Jira: RHEL-52599
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [4/4] 6c5c7b5daa2b450122e98eb08ade1e1db56d20ae (redhat/centos-stream/src/qemu-kvm)
A malicious client can attempt to connect to an NBD server, and then
intentionally delay progress in the handshake, including if it does
not know the TLS secrets. Although the previous two patches reduce
this behavior by capping the default max-connections parameter and
killing slow clients, they did not eliminate the possibility of a
client waiting to close the socket until after the QMP nbd-server-stop
command is executed, at which point qemu would SEGV when trying to
dereference the NULL nbd_server global which is no longer present.
This amounts to a denial of service attack. Worse, if another NBD
server is started before the malicious client disconnects, I cannot
rule out additional adverse effects when the old client interferes
with the connection count of the new server (although the most likely
is a crash due to an assertion failure when checking
nbd_server->connections > 0).
For environments without this patch, the CVE can be mitigated by
ensuring (such as via a firewall) that only trusted clients can
connect to an NBD server. Note that using frameworks like libvirt
that ensure that TLS is used and that nbd-server-stop is not executed
while any trusted clients are still connected will only help if there
is also no possibility for an untrusted client to open a connection
but then stall on the NBD handshake.
Given the previous patches, it would be possible to guarantee that no
clients remain connected by having nbd-server-stop sleep for longer
than the default handshake deadline before finally freeing the global
nbd_server object, but that could make QMP non-responsive for a long
time. So intead, this patch fixes the problem by tracking all client
sockets opened while the server is running, and forcefully closing any
such sockets remaining without a completed handshake at the time of
nbd-server-stop, then waiting until the coroutines servicing those
sockets notice the state change. nbd-server-stop now has a second
AIO_WAIT_WHILE_UNLOCKED (the first is indirectly through the
blk_exp_close_all_type() that disconnects all clients that completed
handshakes), but forced socket shutdown is enough to progress the
coroutines and quickly tear down all clients before the server is
freed, thus finally fixing the CVE.
This patch relies heavily on the fact that nbd/server.c guarantees
that it only calls nbd_blockdev_client_closed() from the main loop
(see the assertion in nbd_client_put() and the hoops used in
nbd_client_put_nonzero() to achieve that); if we did not have that
guarantee, we would also need a mutex protecting our accesses of the
list of connections to survive re-entrancy from independent iothreads.
Although I did not actually try to test old builds, it looks like this
problem has existed since at least commit 862172f45c (v2.12.0, 2017) -
even back when that patch started using a QIONetListener to handle
listening on multiple sockets, nbd_server_free() was already unaware
that the nbd_blockdev_client_closed callback can be reached later by a
client thread that has not completed handshakes (and therefore the
client's socket never got added to the list closed in
nbd_export_close_all), despite that patch intentionally tearing down
the QIONetListener to prevent new clients.
Reported-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
Fixes: CVE-2024-7409
CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240807174943.771624-14-eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 3e7ef738c8462c45043a1d39f702a0990406a3b3)
Jira: https://issues.redhat.com/browse/RHEL-52599
Signed-off-by: Eric Blake <eblake@redhat.com>
---
blockdev-nbd.c | 35 ++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 24ba5382db..f73409ae49 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -21,12 +21,18 @@
#include "io/channel-socket.h"
#include "io/net-listener.h"
+typedef struct NBDConn {
+ QIOChannelSocket *cioc;
+ QLIST_ENTRY(NBDConn) next;
+} NBDConn;
+
typedef struct NBDServerData {
QIONetListener *listener;
QCryptoTLSCreds *tlscreds;
char *tlsauthz;
uint32_t max_connections;
uint32_t connections;
+ QLIST_HEAD(, NBDConn) conns;
} NBDServerData;
static NBDServerData *nbd_server;
@@ -51,6 +57,14 @@ int nbd_server_max_connections(void)
static void nbd_blockdev_client_closed(NBDClient *client, bool ignored)
{
+ NBDConn *conn = nbd_client_owner(client);
+
+ assert(qemu_in_main_thread() && nbd_server);
+
+ object_unref(OBJECT(conn->cioc));
+ QLIST_REMOVE(conn, next);
+ g_free(conn);
+
nbd_client_put(client);
assert(nbd_server->connections > 0);
nbd_server->connections--;
@@ -60,14 +74,20 @@ static void nbd_blockdev_client_closed(NBDClient *client, bool ignored)
static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
gpointer opaque)
{
+ NBDConn *conn = g_new0(NBDConn, 1);
+
+ assert(qemu_in_main_thread() && nbd_server);
nbd_server->connections++;
+ object_ref(OBJECT(cioc));
+ conn->cioc = cioc;
+ QLIST_INSERT_HEAD(&nbd_server->conns, conn, next);
nbd_update_server_watch(nbd_server);
qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server");
/* TODO - expose handshake timeout as QMP option */
nbd_client_new(cioc, NBD_DEFAULT_HANDSHAKE_MAX_SECS,
nbd_server->tlscreds, nbd_server->tlsauthz,
- nbd_blockdev_client_closed, NULL);
+ nbd_blockdev_client_closed, conn);
}
static void nbd_update_server_watch(NBDServerData *s)
@@ -81,12 +101,25 @@ static void nbd_update_server_watch(NBDServerData *s)
static void nbd_server_free(NBDServerData *server)
{
+ NBDConn *conn, *tmp;
+
if (!server) {
return;
}
+ /*
+ * Forcefully close the listener socket, and any clients that have
+ * not yet disconnected on their own.
+ */
qio_net_listener_disconnect(server->listener);
object_unref(OBJECT(server->listener));
+ QLIST_FOREACH_SAFE(conn, &server->conns, next, tmp) {
+ qio_channel_shutdown(QIO_CHANNEL(conn->cioc), QIO_CHANNEL_SHUTDOWN_BOTH,
+ NULL);
+ }
+
+ AIO_WAIT_WHILE_UNLOCKED(NULL, server->connections > 0);
+
if (server->tlscreds) {
object_unref(OBJECT(server->tlscreds));
}
--
2.39.3

@ -1,134 +0,0 @@
From 97012ea86a4a0a28fef68e43b989d858c8392e2a Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Thu, 8 Aug 2024 16:05:08 -0500
Subject: [PATCH 4/5] nbd/server: CVE-2024-7409: Drop non-negotiating clients
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Eric Blake <eblake@redhat.com>
RH-MergeRequest: 263: nbd/server: fix CVE-2024-7409 (qemu crash on nbd-server-stop) [RHEL 10.0]
RH-Jira: RHEL-52599
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [3/4] c3dad94d423d2f431d1e605c412099b9fe0bd76e (redhat/centos-stream/src/qemu-kvm)
A client that opens a socket but does not negotiate is merely hogging
qemu's resources (an open fd and a small amount of memory); and a
malicious client that can access the port where NBD is listening can
attempt a denial of service attack by intentionally opening and
abandoning lots of unfinished connections. The previous patch put a
default bound on the number of such ongoing connections, but once that
limit is hit, no more clients can connect (including legitimate ones).
The solution is to insist that clients complete handshake within a
reasonable time limit, defaulting to 10 seconds. A client that has
not successfully completed NBD_OPT_GO by then (including the case of
where the client didn't know TLS credentials to even reach the point
of NBD_OPT_GO) is wasting our time and does not deserve to stay
connected. Later patches will allow fine-tuning the limit away from
the default value (including disabling it for doing integration
testing of the handshake process itself).
Note that this patch in isolation actually makes it more likely to see
qemu SEGV after nbd-server-stop, as any client socket still connected
when the server shuts down will now be closed after 10 seconds rather
than at the client's whims. That will be addressed in the next patch.
For a demo of this patch in action:
$ qemu-nbd -f raw -r -t -e 10 file &
$ nbdsh --opt-mode -c '
H = list()
for i in range(20):
print(i)
H.insert(i, nbd.NBD())
H[i].set_opt_mode(True)
H[i].connect_uri("nbd://localhost")
'
$ kill $!
where later connections get to start progressing once earlier ones are
forcefully dropped for taking too long, rather than hanging.
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240807174943.771624-13-eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
[eblake: rebase to changes earlier in series, reduce scope of timer]
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit b9b72cb3ce15b693148bd09cef7e50110566d8a0)
Jira: https://issues.redhat.com/browse/RHEL-52599
Signed-off-by: Eric Blake <eblake@redhat.com>
---
nbd/server.c | 28 +++++++++++++++++++++++++++-
nbd/trace-events | 1 +
2 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/nbd/server.c b/nbd/server.c
index e50012499f..39285cc971 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -3186,22 +3186,48 @@ static void nbd_client_receive_next_request(NBDClient *client)
}
}
+static void nbd_handshake_timer_cb(void *opaque)
+{
+ QIOChannel *ioc = opaque;
+
+ trace_nbd_handshake_timer_cb();
+ qio_channel_shutdown(ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
+}
+
static coroutine_fn void nbd_co_client_start(void *opaque)
{
NBDClient *client = opaque;
Error *local_err = NULL;
+ QEMUTimer *handshake_timer = NULL;
qemu_co_mutex_init(&client->send_lock);
- /* TODO - utilize client->handshake_max_secs */
+ /*
+ * Create a timer to bound the time spent in negotiation. If the
+ * timer expires, it is likely nbd_negotiate will fail because the
+ * socket was shutdown.
+ */
+ if (client->handshake_max_secs > 0) {
+ handshake_timer = aio_timer_new(qemu_get_aio_context(),
+ QEMU_CLOCK_REALTIME,
+ SCALE_NS,
+ nbd_handshake_timer_cb,
+ client->sioc);
+ timer_mod(handshake_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_REALTIME) +
+ client->handshake_max_secs * NANOSECONDS_PER_SECOND);
+ }
+
if (nbd_negotiate(client, &local_err)) {
if (local_err) {
error_report_err(local_err);
}
+ timer_free(handshake_timer);
client_close(client, false);
return;
}
+ timer_free(handshake_timer);
WITH_QEMU_LOCK_GUARD(&client->lock) {
nbd_client_receive_next_request(client);
}
diff --git a/nbd/trace-events b/nbd/trace-events
index 00ae3216a1..cbd0a4ab7e 100644
--- a/nbd/trace-events
+++ b/nbd/trace-events
@@ -76,6 +76,7 @@ nbd_co_receive_request_payload_received(uint64_t cookie, uint64_t len) "Payload
nbd_co_receive_ext_payload_compliance(uint64_t from, uint64_t len) "client sent non-compliant write without payload flag: from=0x%" PRIx64 ", len=0x%" PRIx64
nbd_co_receive_align_compliance(const char *op, uint64_t from, uint64_t len, uint32_t align) "client sent non-compliant unaligned %s request: from=0x%" PRIx64 ", len=0x%" PRIx64 ", align=0x%" PRIx32
nbd_trip(void) "Reading request"
+nbd_handshake_timer_cb(void) "client took too long to negotiate"
# client-connection.c
nbd_connect_thread_sleep(uint64_t timeout) "timeout %" PRIu64
--
2.39.3

@ -1,330 +0,0 @@
From 55e78a14c6a6956a3ac65f36b9b8b8c49eff959b Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Mon, 8 Apr 2024 11:00:44 -0500
Subject: [PATCH 2/4] nbd/server: Mark negotiation functions as coroutine_fn
RH-Author: Eric Blake <eblake@redhat.com>
RH-MergeRequest: 257: nbd/server: fix TLS negotiation across coroutine context
RH-Jira: RHEL-40959
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/4] f364e5cd2a9eac2d4f6af2841479f1dfb2f8df58 (ebblake/centos-qemu-kvm)
nbd_negotiate() is already marked coroutine_fn. And given the fix in
the previous patch to have nbd_negotiate_handle_starttls not create
and wait on a g_main_loop (as that would violate coroutine
constraints), it is worth marking the rest of the related static
functions reachable only during option negotiation as also being
coroutine_fn.
Suggested-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240408160214.1200629-6-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
[eblake: drop one spurious coroutine_fn marking]
Signed-off-by: Eric Blake <eblake@redhat.com>
Jira: https://issues.redhat.com/browse/RHEL-40959
(cherry picked from commit 4fa333e08dd96395a99ea8dd9e4c73a29dd23344)
Signed-off-by: Eric Blake <eblake@redhat.com>
---
nbd/server.c | 102 +++++++++++++++++++++++++++++----------------------
1 file changed, 59 insertions(+), 43 deletions(-)
diff --git a/nbd/server.c b/nbd/server.c
index 98ae0e1632..892797bb11 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -195,8 +195,9 @@ static inline void set_be_option_rep(NBDOptionReply *rep, uint32_t option,
/* Send a reply header, including length, but no payload.
* Return -errno on error, 0 on success. */
-static int nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type,
- uint32_t len, Error **errp)
+static coroutine_fn int
+nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type,
+ uint32_t len, Error **errp)
{
NBDOptionReply rep;
@@ -211,15 +212,15 @@ static int nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type,
/* Send a reply header with default 0 length.
* Return -errno on error, 0 on success. */
-static int nbd_negotiate_send_rep(NBDClient *client, uint32_t type,
- Error **errp)
+static coroutine_fn int
+nbd_negotiate_send_rep(NBDClient *client, uint32_t type, Error **errp)
{
return nbd_negotiate_send_rep_len(client, type, 0, errp);
}
/* Send an error reply.
* Return -errno on error, 0 on success. */
-static int G_GNUC_PRINTF(4, 0)
+static coroutine_fn int G_GNUC_PRINTF(4, 0)
nbd_negotiate_send_rep_verr(NBDClient *client, uint32_t type,
Error **errp, const char *fmt, va_list va)
{
@@ -259,7 +260,7 @@ nbd_sanitize_name(const char *name)
/* Send an error reply.
* Return -errno on error, 0 on success. */
-static int G_GNUC_PRINTF(4, 5)
+static coroutine_fn int G_GNUC_PRINTF(4, 5)
nbd_negotiate_send_rep_err(NBDClient *client, uint32_t type,
Error **errp, const char *fmt, ...)
{
@@ -275,7 +276,7 @@ nbd_negotiate_send_rep_err(NBDClient *client, uint32_t type,
/* Drop remainder of the current option, and send a reply with the
* given error type and message. Return -errno on read or write
* failure; or 0 if connection is still live. */
-static int G_GNUC_PRINTF(4, 0)
+static coroutine_fn int G_GNUC_PRINTF(4, 0)
nbd_opt_vdrop(NBDClient *client, uint32_t type, Error **errp,
const char *fmt, va_list va)
{
@@ -288,7 +289,7 @@ nbd_opt_vdrop(NBDClient *client, uint32_t type, Error **errp,
return ret;
}
-static int G_GNUC_PRINTF(4, 5)
+static coroutine_fn int G_GNUC_PRINTF(4, 5)
nbd_opt_drop(NBDClient *client, uint32_t type, Error **errp,
const char *fmt, ...)
{
@@ -302,7 +303,7 @@ nbd_opt_drop(NBDClient *client, uint32_t type, Error **errp,
return ret;
}
-static int G_GNUC_PRINTF(3, 4)
+static coroutine_fn int G_GNUC_PRINTF(3, 4)
nbd_opt_invalid(NBDClient *client, Error **errp, const char *fmt, ...)
{
int ret;
@@ -319,8 +320,9 @@ nbd_opt_invalid(NBDClient *client, Error **errp, const char *fmt, ...)
* If @check_nul, require that no NUL bytes appear in buffer.
* Return -errno on I/O error, 0 if option was completely handled by
* sending a reply about inconsistent lengths, or 1 on success. */
-static int nbd_opt_read(NBDClient *client, void *buffer, size_t size,
- bool check_nul, Error **errp)
+static coroutine_fn int
+nbd_opt_read(NBDClient *client, void *buffer, size_t size,
+ bool check_nul, Error **errp)
{
if (size > client->optlen) {
return nbd_opt_invalid(client, errp,
@@ -343,7 +345,8 @@ static int nbd_opt_read(NBDClient *client, void *buffer, size_t size,
/* Drop size bytes from the unparsed payload of the current option.
* Return -errno on I/O error, 0 if option was completely handled by
* sending a reply about inconsistent lengths, or 1 on success. */
-static int nbd_opt_skip(NBDClient *client, size_t size, Error **errp)
+static coroutine_fn int
+nbd_opt_skip(NBDClient *client, size_t size, Error **errp)
{
if (size > client->optlen) {
return nbd_opt_invalid(client, errp,
@@ -366,8 +369,9 @@ static int nbd_opt_skip(NBDClient *client, size_t size, Error **errp)
* Return -errno on I/O error, 0 if option was completely handled by
* sending a reply about inconsistent lengths, or 1 on success.
*/
-static int nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length,
- Error **errp)
+static coroutine_fn int
+nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length,
+ Error **errp)
{
int ret;
uint32_t len;
@@ -402,8 +406,8 @@ static int nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length,
/* Send a single NBD_REP_SERVER reply to NBD_OPT_LIST, including payload.
* Return -errno on error, 0 on success. */
-static int nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp,
- Error **errp)
+static coroutine_fn int
+nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp, Error **errp)
{
ERRP_GUARD();
size_t name_len, desc_len;
@@ -444,7 +448,8 @@ static int nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp,
/* Process the NBD_OPT_LIST command, with a potential series of replies.
* Return -errno on error, 0 on success. */
-static int nbd_negotiate_handle_list(NBDClient *client, Error **errp)
+static coroutine_fn int
+nbd_negotiate_handle_list(NBDClient *client, Error **errp)
{
NBDExport *exp;
assert(client->opt == NBD_OPT_LIST);
@@ -459,7 +464,8 @@ static int nbd_negotiate_handle_list(NBDClient *client, Error **errp)
return nbd_negotiate_send_rep(client, NBD_REP_ACK, errp);
}
-static void nbd_check_meta_export(NBDClient *client, NBDExport *exp)
+static coroutine_fn void
+nbd_check_meta_export(NBDClient *client, NBDExport *exp)
{
if (exp != client->contexts.exp) {
client->contexts.count = 0;
@@ -468,8 +474,9 @@ static void nbd_check_meta_export(NBDClient *client, NBDExport *exp)
/* Send a reply to NBD_OPT_EXPORT_NAME.
* Return -errno on error, 0 on success. */
-static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes,
- Error **errp)
+static coroutine_fn int
+nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes,
+ Error **errp)
{
ERRP_GUARD();
g_autofree char *name = NULL;
@@ -536,9 +543,9 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes,
/* Send a single NBD_REP_INFO, with a buffer @buf of @length bytes.
* The buffer does NOT include the info type prefix.
* Return -errno on error, 0 if ready to send more. */
-static int nbd_negotiate_send_info(NBDClient *client,
- uint16_t info, uint32_t length, void *buf,
- Error **errp)
+static coroutine_fn int
+nbd_negotiate_send_info(NBDClient *client, uint16_t info, uint32_t length,
+ void *buf, Error **errp)
{
int rc;
@@ -565,7 +572,8 @@ static int nbd_negotiate_send_info(NBDClient *client,
* -errno transmission error occurred or @fatal was requested, errp is set
* 0 error message successfully sent to client, errp is not set
*/
-static int nbd_reject_length(NBDClient *client, bool fatal, Error **errp)
+static coroutine_fn int
+nbd_reject_length(NBDClient *client, bool fatal, Error **errp)
{
int ret;
@@ -583,7 +591,8 @@ static int nbd_reject_length(NBDClient *client, bool fatal, Error **errp)
/* Handle NBD_OPT_INFO and NBD_OPT_GO.
* Return -errno on error, 0 if ready for next option, and 1 to move
* into transmission phase. */
-static int nbd_negotiate_handle_info(NBDClient *client, Error **errp)
+static coroutine_fn int
+nbd_negotiate_handle_info(NBDClient *client, Error **errp)
{
int rc;
g_autofree char *name = NULL;
@@ -755,7 +764,8 @@ struct NBDTLSServerHandshakeData {
Coroutine *co;
};
-static void nbd_server_tls_handshake(QIOTask *task, void *opaque)
+static void
+nbd_server_tls_handshake(QIOTask *task, void *opaque)
{
struct NBDTLSServerHandshakeData *data = opaque;
@@ -768,8 +778,8 @@ static void nbd_server_tls_handshake(QIOTask *task, void *opaque)
/* Handle NBD_OPT_STARTTLS. Return NULL to drop connection, or else the
* new channel for all further (now-encrypted) communication. */
-static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
- Error **errp)
+static coroutine_fn QIOChannel *
+nbd_negotiate_handle_starttls(NBDClient *client, Error **errp)
{
QIOChannel *ioc;
QIOChannelTLS *tioc;
@@ -821,10 +831,9 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
*
* For NBD_OPT_LIST_META_CONTEXT @context_id is ignored, 0 is used instead.
*/
-static int nbd_negotiate_send_meta_context(NBDClient *client,
- const char *context,
- uint32_t context_id,
- Error **errp)
+static coroutine_fn int
+nbd_negotiate_send_meta_context(NBDClient *client, const char *context,
+ uint32_t context_id, Error **errp)
{
NBDOptionReplyMetaContext opt;
struct iovec iov[] = {
@@ -849,8 +858,9 @@ static int nbd_negotiate_send_meta_context(NBDClient *client,
* Return true if @query matches @pattern, or if @query is empty when
* the @client is performing _LIST_.
*/
-static bool nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern,
- const char *query)
+static coroutine_fn bool
+nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern,
+ const char *query)
{
if (!*query) {
trace_nbd_negotiate_meta_query_parse("empty");
@@ -867,7 +877,8 @@ static bool nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern,
/*
* Return true and adjust @str in place if it begins with @prefix.
*/
-static bool nbd_strshift(const char **str, const char *prefix)
+static coroutine_fn bool
+nbd_strshift(const char **str, const char *prefix)
{
size_t len = strlen(prefix);
@@ -883,8 +894,9 @@ static bool nbd_strshift(const char **str, const char *prefix)
* Handle queries to 'base' namespace. For now, only the base:allocation
* context is available. Return true if @query has been handled.
*/
-static bool nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta,
- const char *query)
+static coroutine_fn bool
+nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta,
+ const char *query)
{
if (!nbd_strshift(&query, "base:")) {
return false;
@@ -903,8 +915,9 @@ static bool nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta,
* and qemu:allocation-depth contexts are available. Return true if @query
* has been handled.
*/
-static bool nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta,
- const char *query)
+static coroutine_fn bool
+nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta,
+ const char *query)
{
size_t i;
@@ -968,8 +981,9 @@ static bool nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta,
*
* Return -errno on I/O error, 0 if option was completely handled by
* sending a reply about inconsistent lengths, or 1 on success. */
-static int nbd_negotiate_meta_query(NBDClient *client,
- NBDMetaContexts *meta, Error **errp)
+static coroutine_fn int
+nbd_negotiate_meta_query(NBDClient *client,
+ NBDMetaContexts *meta, Error **errp)
{
int ret;
g_autofree char *query = NULL;
@@ -1008,7 +1022,8 @@ static int nbd_negotiate_meta_query(NBDClient *client,
* Handle NBD_OPT_LIST_META_CONTEXT and NBD_OPT_SET_META_CONTEXT
*
* Return -errno on I/O error, or 0 if option was completely handled. */
-static int nbd_negotiate_meta_queries(NBDClient *client, Error **errp)
+static coroutine_fn int
+nbd_negotiate_meta_queries(NBDClient *client, Error **errp)
{
int ret;
g_autofree char *export_name = NULL;
@@ -1136,7 +1151,8 @@ static int nbd_negotiate_meta_queries(NBDClient *client, Error **errp)
* 1 if client sent NBD_OPT_ABORT, i.e. on valid disconnect,
* errp is not set
*/
-static int nbd_negotiate_options(NBDClient *client, Error **errp)
+static coroutine_fn int
+nbd_negotiate_options(NBDClient *client, Error **errp)
{
uint32_t flags;
bool fixedNewstyle = false;
--
2.39.3

@ -1,175 +0,0 @@
From 785893c171d994bbcffe0585953ca0d290f3c27e Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 7 Aug 2024 08:50:01 -0500
Subject: [PATCH 2/5] nbd/server: Plumb in new args to nbd_client_add()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Eric Blake <eblake@redhat.com>
RH-MergeRequest: 263: nbd/server: fix CVE-2024-7409 (qemu crash on nbd-server-stop) [RHEL 10.0]
RH-Jira: RHEL-52599
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/4] 68e9f83d467704d3dfbf0a879b2bb4d9a568f81c (redhat/centos-stream/src/qemu-kvm)
Upcoming patches to fix a CVE need to track an opaque pointer passed
in by the owner of a client object, as well as request for a time
limit on how fast negotiation must complete. Prepare for that by
changing the signature of nbd_client_new() and adding an accessor to
get at the opaque pointer, although for now the two servers
(qemu-nbd.c and blockdev-nbd.c) do not change behavior even though
they pass in a new default timeout value.
Suggested-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240807174943.771624-11-eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
[eblake: s/LIMIT/MAX_SECS/ as suggested by Dan]
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit fb1c2aaa981e0a2fa6362c9985f1296b74f055ac)
Jira: https://issues.redhat.com/browse/RHEL-52599
Signed-off-by: Eric Blake <eblake@redhat.com>
---
blockdev-nbd.c | 6 ++++--
include/block/nbd.h | 11 ++++++++++-
nbd/server.c | 20 +++++++++++++++++---
qemu-nbd.c | 4 +++-
4 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 213012435f..267a1de903 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -64,8 +64,10 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
nbd_update_server_watch(nbd_server);
qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server");
- nbd_client_new(cioc, nbd_server->tlscreds, nbd_server->tlsauthz,
- nbd_blockdev_client_closed);
+ /* TODO - expose handshake timeout as QMP option */
+ nbd_client_new(cioc, NBD_DEFAULT_HANDSHAKE_MAX_SECS,
+ nbd_server->tlscreds, nbd_server->tlsauthz,
+ nbd_blockdev_client_closed, NULL);
}
static void nbd_update_server_watch(NBDServerData *s)
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 4e7bd6342f..1d4d65922d 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -33,6 +33,12 @@ typedef struct NBDMetaContexts NBDMetaContexts;
extern const BlockExportDriver blk_exp_nbd;
+/*
+ * NBD_DEFAULT_HANDSHAKE_MAX_SECS: Number of seconds in which client must
+ * succeed at NBD_OPT_GO before being forcefully dropped as too slow.
+ */
+#define NBD_DEFAULT_HANDSHAKE_MAX_SECS 10
+
/* Handshake phase structs - this struct is passed on the wire */
typedef struct NBDOption {
@@ -403,9 +409,12 @@ AioContext *nbd_export_aio_context(NBDExport *exp);
NBDExport *nbd_export_find(const char *name);
void nbd_client_new(QIOChannelSocket *sioc,
+ uint32_t handshake_max_secs,
QCryptoTLSCreds *tlscreds,
const char *tlsauthz,
- void (*close_fn)(NBDClient *, bool));
+ void (*close_fn)(NBDClient *, bool),
+ void *owner);
+void *nbd_client_owner(NBDClient *client);
void nbd_client_get(NBDClient *client);
void nbd_client_put(NBDClient *client);
diff --git a/nbd/server.c b/nbd/server.c
index 892797bb11..e50012499f 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -124,12 +124,14 @@ struct NBDMetaContexts {
struct NBDClient {
int refcount; /* atomic */
void (*close_fn)(NBDClient *client, bool negotiated);
+ void *owner;
QemuMutex lock;
NBDExport *exp;
QCryptoTLSCreds *tlscreds;
char *tlsauthz;
+ uint32_t handshake_max_secs;
QIOChannelSocket *sioc; /* The underlying data channel */
QIOChannel *ioc; /* The current I/O channel which may differ (eg TLS) */
@@ -3191,6 +3193,7 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
qemu_co_mutex_init(&client->send_lock);
+ /* TODO - utilize client->handshake_max_secs */
if (nbd_negotiate(client, &local_err)) {
if (local_err) {
error_report_err(local_err);
@@ -3205,14 +3208,17 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
}
/*
- * Create a new client listener using the given channel @sioc.
+ * Create a new client listener using the given channel @sioc and @owner.
* Begin servicing it in a coroutine. When the connection closes, call
- * @close_fn with an indication of whether the client completed negotiation.
+ * @close_fn with an indication of whether the client completed negotiation
+ * within @handshake_max_secs seconds (0 for unbounded).
*/
void nbd_client_new(QIOChannelSocket *sioc,
+ uint32_t handshake_max_secs,
QCryptoTLSCreds *tlscreds,
const char *tlsauthz,
- void (*close_fn)(NBDClient *, bool))
+ void (*close_fn)(NBDClient *, bool),
+ void *owner)
{
NBDClient *client;
Coroutine *co;
@@ -3225,13 +3231,21 @@ void nbd_client_new(QIOChannelSocket *sioc,
object_ref(OBJECT(client->tlscreds));
}
client->tlsauthz = g_strdup(tlsauthz);
+ client->handshake_max_secs = handshake_max_secs;
client->sioc = sioc;
qio_channel_set_delay(QIO_CHANNEL(sioc), false);
object_ref(OBJECT(client->sioc));
client->ioc = QIO_CHANNEL(sioc);
object_ref(OBJECT(client->ioc));
client->close_fn = close_fn;
+ client->owner = owner;
co = qemu_coroutine_create(nbd_co_client_start, client);
qemu_coroutine_enter(co);
}
+
+void *
+nbd_client_owner(NBDClient *client)
+{
+ return client->owner;
+}
diff --git a/qemu-nbd.c b/qemu-nbd.c
index d7b3ccab21..48e2fa5858 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -390,7 +390,9 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
nb_fds++;
nbd_update_server_watch();
- nbd_client_new(cioc, tlscreds, tlsauthz, nbd_client_closed);
+ /* TODO - expose handshake timeout as command line option */
+ nbd_client_new(cioc, NBD_DEFAULT_HANDSHAKE_MAX_SECS,
+ tlscreds, tlsauthz, nbd_client_closed, NULL);
}
static void nbd_update_server_watch(void)
--
2.39.3

@ -1,208 +0,0 @@
From 484fe3af54a3e421be9e370d47eabe0d8cc5c50d Mon Sep 17 00:00:00 2001
From: Zhu Yangyang <zhuyangyang14@huawei.com>
Date: Mon, 8 Apr 2024 11:00:43 -0500
Subject: [PATCH 1/4] nbd/server: do not poll within a coroutine context
RH-Author: Eric Blake <eblake@redhat.com>
RH-MergeRequest: 257: nbd/server: fix TLS negotiation across coroutine context
RH-Jira: RHEL-40959
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/4] 379f38d46d204890e47a5eb744292d728badc7db (ebblake/centos-qemu-kvm)
Coroutines are not supposed to block. Instead, they should yield.
The client performs TLS upgrade outside of an AIOContext, during
synchronous handshake; this still requires g_main_loop. But the
server responds to TLS upgrade inside a coroutine, so a nested
g_main_loop is wrong. Since the two callbacks no longer share more
than the setting of data.complete and data.error, it's just as easy to
use static helpers instead of trying to share a common code path. It
is also possible to add assertions that no other code is interfering
with the eventual path to qio reaching the callback, whether or not it
required a yield or main loop.
Fixes: f95910f ("nbd: implement TLS support in the protocol negotiation")
Signed-off-by: Zhu Yangyang <zhuyangyang14@huawei.com>
[eblake: move callbacks to their use point, add assertions]
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240408160214.1200629-5-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Jira: https://issues.redhat.com/browse/RHEL-40959
(cherry picked from commit ae6d91a7e9b77abb029ed3fa9fad461422286942)
Signed-off-by: Eric Blake <eblake@redhat.com>
---
nbd/client.c | 28 ++++++++++++++++++++++++----
nbd/common.c | 11 -----------
nbd/nbd-internal.h | 10 ----------
nbd/server.c | 28 +++++++++++++++++++++++-----
4 files changed, 47 insertions(+), 30 deletions(-)
diff --git a/nbd/client.c b/nbd/client.c
index 29ffc609a4..c89c750467 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -596,13 +596,31 @@ static int nbd_request_simple_option(QIOChannel *ioc, int opt, bool strict,
return 1;
}
+/* Callback to learn when QIO TLS upgrade is complete */
+struct NBDTLSClientHandshakeData {
+ bool complete;
+ Error *error;
+ GMainLoop *loop;
+};
+
+static void nbd_client_tls_handshake(QIOTask *task, void *opaque)
+{
+ struct NBDTLSClientHandshakeData *data = opaque;
+
+ qio_task_propagate_error(task, &data->error);
+ data->complete = true;
+ if (data->loop) {
+ g_main_loop_quit(data->loop);
+ }
+}
+
static QIOChannel *nbd_receive_starttls(QIOChannel *ioc,
QCryptoTLSCreds *tlscreds,
const char *hostname, Error **errp)
{
int ret;
QIOChannelTLS *tioc;
- struct NBDTLSHandshakeData data = { 0 };
+ struct NBDTLSClientHandshakeData data = { 0 };
ret = nbd_request_simple_option(ioc, NBD_OPT_STARTTLS, true, errp);
if (ret <= 0) {
@@ -619,18 +637,20 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *ioc,
return NULL;
}
qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-client-tls");
- data.loop = g_main_loop_new(g_main_context_default(), FALSE);
trace_nbd_receive_starttls_tls_handshake();
qio_channel_tls_handshake(tioc,
- nbd_tls_handshake,
+ nbd_client_tls_handshake,
&data,
NULL,
NULL);
if (!data.complete) {
+ data.loop = g_main_loop_new(g_main_context_default(), FALSE);
g_main_loop_run(data.loop);
+ assert(data.complete);
+ g_main_loop_unref(data.loop);
}
- g_main_loop_unref(data.loop);
+
if (data.error) {
error_propagate(errp, data.error);
object_unref(OBJECT(tioc));
diff --git a/nbd/common.c b/nbd/common.c
index 3247c1d618..589a748cfe 100644
--- a/nbd/common.c
+++ b/nbd/common.c
@@ -47,17 +47,6 @@ int nbd_drop(QIOChannel *ioc, size_t size, Error **errp)
}
-void nbd_tls_handshake(QIOTask *task,
- void *opaque)
-{
- struct NBDTLSHandshakeData *data = opaque;
-
- qio_task_propagate_error(task, &data->error);
- data->complete = true;
- g_main_loop_quit(data->loop);
-}
-
-
const char *nbd_opt_lookup(uint32_t opt)
{
switch (opt) {
diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h
index dfa02f77ee..91895106a9 100644
--- a/nbd/nbd-internal.h
+++ b/nbd/nbd-internal.h
@@ -72,16 +72,6 @@ static inline int nbd_write(QIOChannel *ioc, const void *buffer, size_t size,
return qio_channel_write_all(ioc, buffer, size, errp) < 0 ? -EIO : 0;
}
-struct NBDTLSHandshakeData {
- GMainLoop *loop;
- bool complete;
- Error *error;
-};
-
-
-void nbd_tls_handshake(QIOTask *task,
- void *opaque);
-
int nbd_drop(QIOChannel *ioc, size_t size, Error **errp);
#endif
diff --git a/nbd/server.c b/nbd/server.c
index c3484cc1eb..98ae0e1632 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -748,6 +748,23 @@ static int nbd_negotiate_handle_info(NBDClient *client, Error **errp)
return rc;
}
+/* Callback to learn when QIO TLS upgrade is complete */
+struct NBDTLSServerHandshakeData {
+ bool complete;
+ Error *error;
+ Coroutine *co;
+};
+
+static void nbd_server_tls_handshake(QIOTask *task, void *opaque)
+{
+ struct NBDTLSServerHandshakeData *data = opaque;
+
+ qio_task_propagate_error(task, &data->error);
+ data->complete = true;
+ if (!qemu_coroutine_entered(data->co)) {
+ aio_co_wake(data->co);
+ }
+}
/* Handle NBD_OPT_STARTTLS. Return NULL to drop connection, or else the
* new channel for all further (now-encrypted) communication. */
@@ -756,7 +773,7 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
{
QIOChannel *ioc;
QIOChannelTLS *tioc;
- struct NBDTLSHandshakeData data = { 0 };
+ struct NBDTLSServerHandshakeData data = { 0 };
assert(client->opt == NBD_OPT_STARTTLS);
@@ -777,17 +794,18 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-server-tls");
trace_nbd_negotiate_handle_starttls_handshake();
- data.loop = g_main_loop_new(g_main_context_default(), FALSE);
+ data.co = qemu_coroutine_self();
qio_channel_tls_handshake(tioc,
- nbd_tls_handshake,
+ nbd_server_tls_handshake,
&data,
NULL,
NULL);
if (!data.complete) {
- g_main_loop_run(data.loop);
+ qemu_coroutine_yield();
+ assert(data.complete);
}
- g_main_loop_unref(data.loop);
+
if (data.error) {
object_unref(OBJECT(tioc));
error_propagate(errp, data.error);
--
2.39.3

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

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

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

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

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

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

@ -0,0 +1,41 @@
From b2add99e201168c36eed56a3982ab02f63e5717a Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Mon, 11 Nov 2024 14:11:20 +0100
Subject: [PATCH 9/9] pc-bios/s390-ccw: Re-initialize receive queue index
before each boot attempt
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature
RH-Jira: RHEL-68444
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [8/8] 8d40508aaf993f2e1b94d471f0e50d0f375e22d2 (thuth/qemu-kvm-cs9)
Now that we can boot from multiple boot devices, we have to make sure
to reinitialize static variables like rx_last_idx to avoid that they
contain garbage data during the second boot attempt (which can lead to
crashes when the code tries to access the wrong ring data).
Message-ID: <20241111131120.317796-1-thuth@redhat.com>
Reviewed-by: Jared Rossi <jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 6ba1f714c00f8839a8df9f643e0058f00da3fd25)
---
pc-bios/s390-ccw/virtio-net.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/pc-bios/s390-ccw/virtio-net.c b/pc-bios/s390-ccw/virtio-net.c
index f9854a22c3..578c89d0c5 100644
--- a/pc-bios/s390-ccw/virtio-net.c
+++ b/pc-bios/s390-ccw/virtio-net.c
@@ -51,6 +51,8 @@ int virtio_net_init(void *mac_addr)
void *buf;
int i;
+ rx_last_idx = 0;
+
vdev->guest_features[0] = VIRTIO_NET_F_MAC_BIT;
virtio_setup_ccw(vdev);
--
2.39.3

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

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

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

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

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

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

@ -0,0 +1,39 @@
From f0e7e2ae018cabdee3a87fa562ad7a4482d235b4 Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Fri, 8 Nov 2024 14:41:36 -0500
Subject: [PATCH 7/9] pc-bios/s390x: Initialize cdrom type to false for each
IPL device
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature
RH-Jira: RHEL-68444
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [6/8] efbe12669e2a20d1c8412edfc5e2350475b84dda (thuth/qemu-kvm-cs9)
Clear information about cdrom type so that current IPL device isn't tainted
by stale data from previous devices.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241108194136.2833932-1-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 8c797468116d19940fb758efa749eae414616e3a)
---
pc-bios/s390-ccw/main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index a4d1c05aac..7509755e36 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -242,6 +242,7 @@ static bool find_boot_device(void)
static int virtio_setup(void)
{
VDev *vdev = virtio_get_device();
+ vdev->is_cdrom = false;
int ret;
switch (vdev->senseid.cu_model) {
--
2.39.3

@ -0,0 +1,51 @@
From 2d9158563e5d34f9147e660f943f631bad80b6dd Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Thu, 14 Nov 2024 11:19:52 -0500
Subject: [PATCH 8/9] pc-bios/s390x: Initialize machine loadparm before probing
IPL devices
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature
RH-Jira: RHEL-68444
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [7/8] 7513fec6ef170ab0c2068a7641a79b77537f1608 (thuth/qemu-kvm-cs9)
Commit bb185de423 ("s390x: Add individual loadparm assignment to
CCW device") allowed boot devices to be assigned a loadparm value independent
of the machine value, however, when no boot devices are defined, the machine
loadparm becomes ignored. Therefore, let's check the machine loadparm
prior to probing the devices.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241114161952.3508554-1-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 1056ca1e70dc6e0458238141bcebfb7810cede6d)
---
pc-bios/s390-ccw/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 7509755e36..76bf743900 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -191,7 +191,7 @@ static void boot_setup(void)
{
char lpmsg[] = "LOADPARM=[________]\n";
- if (memcmp(iplb.loadparm, NO_LOADPARM, LOADPARM_LEN) != 0) {
+ if (have_iplb && 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);
@@ -316,6 +316,7 @@ void main(void)
css_setup();
have_iplb = store_iplb(&iplb);
if (!have_iplb) {
+ boot_setup();
probe_boot_device();
}
--
2.39.3

@ -1,117 +0,0 @@
From 57ec055ce7615d4838ae19c4980c2a1799c6cb3d Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Thu, 11 Apr 2024 15:06:01 +0200
Subject: [PATCH 1/4] qcow2: Don't open data_file with BDRV_O_NO_IO
RH-Author: Hana Czenczek <hczenczek@redhat.com>
RH-MergeRequest: 1: CVE 2024-4467 (PRDSC)
RH-Jira: RHEL-46239
RH-CVE: CVE-2024-4467
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Commit: [1/4] f9843ce5c519901654a7d8ba43ee95ce25ca13c2
One use case for 'qemu-img info' is verifying that untrusted images
don't reference an unwanted external file, be it as a backing file or an
external data file. To make sure that calling 'qemu-img info' can't
already have undesired side effects with a malicious image, just don't
open the data file at all with BDRV_O_NO_IO. If nothing ever tries to do
I/O, we don't need to have it open.
This changes the output of iotests case 061, which used 'qemu-img info'
to show that opening an image with an invalid data file fails. After
this patch, it succeeds. Replace this part of the test with a qemu-io
call, but keep the final 'qemu-img info' to show that the invalid data
file is correctly displayed in the output.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Upstream: N/A, embargoed
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
---
block/qcow2.c | 17 ++++++++++++++++-
tests/qemu-iotests/061 | 6 ++++--
tests/qemu-iotests/061.out | 8 ++++++--
3 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/block/qcow2.c b/block/qcow2.c
index 0e8b2f7518..3b8d2db9f9 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1642,7 +1642,22 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
- if (open_data_file) {
+ if (open_data_file && (flags & BDRV_O_NO_IO)) {
+ /*
+ * Don't open the data file for 'qemu-img info' so that it can be used
+ * to verify that an untrusted qcow2 image doesn't refer to external
+ * files.
+ *
+ * Note: This still makes has_data_file() return true.
+ */
+ if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
+ s->data_file = NULL;
+ } else {
+ s->data_file = bs->file;
+ }
+ qdict_extract_subqdict(options, NULL, "data-file.");
+ qdict_del(options, "data-file");
+ } else if (open_data_file) {
/* Open external data file */
bdrv_graph_co_rdunlock();
s->data_file = bdrv_co_open_child(NULL, options, "data-file", bs,
diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
index 53c7d428e3..b71ac097d1 100755
--- a/tests/qemu-iotests/061
+++ b/tests/qemu-iotests/061
@@ -326,12 +326,14 @@ $QEMU_IMG amend -o "data_file=foo" "$TEST_IMG"
echo
_make_test_img -o "compat=1.1,data_file=$TEST_IMG.data" 64M
$QEMU_IMG amend -o "data_file=foo" "$TEST_IMG"
-_img_info --format-specific
+$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt
+$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io
TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts
echo
$QEMU_IMG amend -o "data_file=" --image-opts "data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG"
-_img_info --format-specific
+$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt
+$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io
TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts
echo
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
index 139fc68177..24c33add7c 100644
--- a/tests/qemu-iotests/061.out
+++ b/tests/qemu-iotests/061.out
@@ -545,7 +545,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-img: data-file can only be set for images that use an external data file
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data
-qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Could not open 'foo': No such file or directory
+qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open 'foo': No such file or directory
+read 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64 MiB (67108864 bytes)
@@ -560,7 +562,9 @@ Format specific information:
corrupt: false
extended l2: false
-qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image
+qemu-io: can't open device TEST_DIR/t.IMGFMT: 'data-file' is required for this image
+read 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64 MiB (67108864 bytes)
--
2.39.3

@ -0,0 +1,39 @@
From 18c53acff0c50491dddac1e9d023b9ad5f540f7f Mon Sep 17 00:00:00 2001
From: Dehan Meng <demeng@redhat.com>
Date: Wed, 4 Sep 2024 16:39:51 +0800
Subject: [PATCH 9/9] qemu-guest-agent: Update the logfile path of
qga-fsfreeze-hook.log
RH-Author: Dehan Meng <demeng@redhat.com>
RH-MergeRequest: 269: qemu-guest-agent: Update the logfile path of qga-fsfreeze-hook.log
RH-Jira: RHEL-57028
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [45/45] eebec1989edade851807d775de75d4d14da01cf2 (6-dehan/src_centosupstream_qemu-kvm)
Since '/var/log/qga-fsfreeze-hook.log' is not included to proper
selinux context 'system_u:object_r:virt_qemu_ga_log_t:s0', it
should be changed to '/var/log/qemu-ga/qga-fsfreeze-hook.log'. And
it's worth to mention that this is RHEL-only change for matching
existing SELinux boolean and policy.
Signed-off-by: Dehan Meng <demeng@redhat.com>
---
scripts/qemu-guest-agent/fsfreeze-hook | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/qemu-guest-agent/fsfreeze-hook b/scripts/qemu-guest-agent/fsfreeze-hook
index e9b84ec028..70536ba3e3 100755
--- a/scripts/qemu-guest-agent/fsfreeze-hook
+++ b/scripts/qemu-guest-agent/fsfreeze-hook
@@ -7,7 +7,7 @@
# "freeze" argument before the filesystem is frozen. And for fsfreeze-thaw
# request, it is issued with "thaw" argument after filesystem is thawed.
-LOGFILE=/var/log/qga-fsfreeze-hook.log
+LOGFILE=/var/log/qemu-ga/qga-fsfreeze-hook.log
FSFREEZE_D=$(dirname -- "$(realpath $0)")/fsfreeze-hook.d
# Check whether file $1 is a backup or rpm-generated file and should be ignored
--
2.39.3

@ -1,130 +0,0 @@
From 120a2c8a7d936e24948f8f4ada6b781b6cbc9931 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Fri, 17 May 2024 21:50:14 -0500
Subject: [PATCH 3/4] qio: Inherit follow_coroutine_ctx across TLS
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Eric Blake <eblake@redhat.com>
RH-MergeRequest: 257: nbd/server: fix TLS negotiation across coroutine context
RH-Jira: RHEL-40959
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [3/4] b7fd03af5985bbc5504b1a8e2f5cd165f6e438e5 (ebblake/centos-qemu-kvm)
Since qemu 8.2, the combination of NBD + TLS + iothread crashes on an
assertion failure:
qemu-kvm: ../io/channel.c:534: void qio_channel_restart_read(void *): Assertion `qemu_get_current_aio_context() == qemu_coroutine_get_aio_context(co)' failed.
It turns out that when we removed AioContext locking, we did so by
having NBD tell its qio channels that it wanted to opt in to
qio_channel_set_follow_coroutine_ctx(); but while we opted in on the
main channel, we did not opt in on the TLS wrapper channel.
qemu-iotests has coverage of NBD+iothread and NBD+TLS, but apparently
no coverage of NBD+TLS+iothread, or we would have noticed this
regression sooner. (I'll add that in the next patch)
But while we could manually opt in to the TLS channel in nbd/server.c
(a one-line change), it is more generic if all qio channels that wrap
other channels inherit the follow status, in the same way that they
inherit feature bits.
CC: Stefan Hajnoczi <stefanha@redhat.com>
CC: Daniel P. Berrangé <berrange@redhat.com>
CC: qemu-stable@nongnu.org
Fixes: https://issues.redhat.com/browse/RHEL-34786
Fixes: 06e0f098 ("io: follow coroutine AioContext in qio_channel_yield()", v8.2.0)
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20240518025246.791593-5-eblake@redhat.com>
(cherry picked from commit 199e84de1c903ba5aa1f7256310bbc4a20dd930b)
Jira: https://issues.redhat.com/browse/RHEL-40959
Signed-off-by: Eric Blake <eblake@redhat.com>
---
io/channel-tls.c | 26 +++++++++++++++-----------
io/channel-websock.c | 1 +
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/io/channel-tls.c b/io/channel-tls.c
index 1d9c9c72bf..67b9700006 100644
--- a/io/channel-tls.c
+++ b/io/channel-tls.c
@@ -69,37 +69,40 @@ qio_channel_tls_new_server(QIOChannel *master,
const char *aclname,
Error **errp)
{
- QIOChannelTLS *ioc;
+ QIOChannelTLS *tioc;
+ QIOChannel *ioc;
- ioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS));
+ tioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS));
+ ioc = QIO_CHANNEL(tioc);
- ioc->master = master;
+ tioc->master = master;
+ ioc->follow_coroutine_ctx = master->follow_coroutine_ctx;
if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
- qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_SHUTDOWN);
+ qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
}
object_ref(OBJECT(master));
- ioc->session = qcrypto_tls_session_new(
+ tioc->session = qcrypto_tls_session_new(
creds,
NULL,
aclname,
QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
errp);
- if (!ioc->session) {
+ if (!tioc->session) {
goto error;
}
qcrypto_tls_session_set_callbacks(
- ioc->session,
+ tioc->session,
qio_channel_tls_write_handler,
qio_channel_tls_read_handler,
- ioc);
+ tioc);
- trace_qio_channel_tls_new_server(ioc, master, creds, aclname);
- return ioc;
+ trace_qio_channel_tls_new_server(tioc, master, creds, aclname);
+ return tioc;
error:
- object_unref(OBJECT(ioc));
+ object_unref(OBJECT(tioc));
return NULL;
}
@@ -116,6 +119,7 @@ qio_channel_tls_new_client(QIOChannel *master,
ioc = QIO_CHANNEL(tioc);
tioc->master = master;
+ ioc->follow_coroutine_ctx = master->follow_coroutine_ctx;
if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
}
diff --git a/io/channel-websock.c b/io/channel-websock.c
index a12acc27cf..de39f0d182 100644
--- a/io/channel-websock.c
+++ b/io/channel-websock.c
@@ -883,6 +883,7 @@ qio_channel_websock_new_server(QIOChannel *master)
ioc = QIO_CHANNEL(wioc);
wioc->master = master;
+ ioc->follow_coroutine_ctx = master->follow_coroutine_ctx;
if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
}
--
2.39.3

@ -1,46 +0,0 @@
From 2c7512b27b8d8862e26c6e07169752078513f40c Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Mon, 10 Jun 2024 21:22:58 +0530
Subject: [PATCH 01/14] qtest/x86/numa-test: do not use the obsolete 'pentium'
cpu
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 243: target/cpu-models/x86: Remove the existing deprecated CPU models on c10s
RH-Jira: RHEL-28972
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
RH-Acked-by: MST <mst@redhat.com>
RH-Commit: [1/4] a9b38ebd4e772a0a1fe40301a6f1abab6b961cd7 (anisinha/centos-qemu-kvm)
'pentium' cpu is old and obsolete and should be avoided for running tests if
its not strictly needed. Use 'max' cpu instead for generic non-cpu specific
numa test.
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Tested-by: Mario Casquero <mcasquer@redhat.com>
Signed-off-by: Ani Sinha <anisinha@redhat.com>
Message-ID: <20240610155303.7933-2-anisinha@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 07c8d9ac0fa30712fdf78046a7998ee8d2231d6f)
---
tests/qtest/numa-test.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
index 4f4404a4b1..a512f743c4 100644
--- a/tests/qtest/numa-test.c
+++ b/tests/qtest/numa-test.c
@@ -125,7 +125,8 @@ static void pc_numa_cpu(const void *data)
QTestState *qts;
g_autofree char *cli = NULL;
- cli = make_cli(data, "-cpu pentium -machine smp.cpus=8,smp.sockets=2,smp.cores=2,smp.threads=2 "
+ cli = make_cli(data,
+ "-cpu max -machine smp.cpus=8,smp.sockets=2,smp.cores=2,smp.threads=2 "
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
"-numa cpu,node-id=1,socket-id=0 "
"-numa cpu,node-id=0,socket-id=1,core-id=0 "
--
2.39.3

@ -0,0 +1,425 @@
From 3cb4688b0b353296724b75772725e80fe2486958 Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
Date: Fri, 19 Apr 2024 17:20:49 +0200
Subject: [PATCH 7/9] remove stale compat definitions
RH-Author: Sebastian Ott <sebott@redhat.com>
RH-MergeRequest: 270: RHEL10 machine types
RH-Jira: RHEL-29002 RHEL-29003 RHEL-35587 RHEL-38411 RHEL-45141 RHEL-52318 RHEL-52320
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
RH-Commit: [7/7] b8dd0980c40974787ed80ccd216c299f0a1aefb7 (seott1/cos-qemu-kvm)
Get rid of unused [pc|hw_compat]_rhel_[7|8]* definitions.
Signed-off-by: Sebastian Ott <sebott@redhat.com>
---
hw/core/machine.c | 196 -------------------------------------------
hw/i386/pc.c | 115 -------------------------
include/hw/boards.h | 24 ------
include/hw/i386/pc.h | 21 -----
4 files changed, 356 deletions(-)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 9cf8242b32..d95f246f66 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -407,202 +407,6 @@ GlobalProperty hw_compat_rhel_9_0[] = {
};
const size_t hw_compat_rhel_9_0_len = G_N_ELEMENTS(hw_compat_rhel_9_0);
-GlobalProperty hw_compat_rhel_8_6[] = {
- /* hw_compat_rhel_8_6 bz 2065589 */
- /*
- * vhost-vsock device in RHEL 8 kernels doesn't support seqpacket, so
- * we need do disable it downstream on the latest hw_compat_rhel_8.
- */
- { "vhost-vsock-device", "seqpacket", "off" },
-};
-const size_t hw_compat_rhel_8_6_len = G_N_ELEMENTS(hw_compat_rhel_8_6);
-
-/*
- * Mostly the same as hw_compat_6_0 and hw_compat_6_1
- */
-GlobalProperty hw_compat_rhel_8_5[] = {
- /* hw_compat_rhel_8_5 from hw_compat_6_0 */
- { "gpex-pcihost", "allow-unmapped-accesses", "false" },
- /* hw_compat_rhel_8_5 from hw_compat_6_0 */
- { "i8042", "extended-state", "false"},
- /* hw_compat_rhel_8_5 from hw_compat_6_0 */
- { "nvme-ns", "eui64-default", "off"},
- /* hw_compat_rhel_8_5 from hw_compat_6_0 */
- { "e1000", "init-vet", "off" },
- /* hw_compat_rhel_8_5 from hw_compat_6_0 */
- { "e1000e", "init-vet", "off" },
- /* hw_compat_rhel_8_5 from hw_compat_6_0 */
- { "vhost-vsock-device", "seqpacket", "off" },
- /* hw_compat_rhel_8_5 from hw_compat_6_1 */
- { "vhost-user-vsock-device", "seqpacket", "off" },
- /* hw_compat_rhel_8_5 from hw_compat_6_1 */
- { "nvme-ns", "shared", "off" },
-};
-const size_t hw_compat_rhel_8_5_len = G_N_ELEMENTS(hw_compat_rhel_8_5);
-
-/*
- * Mostly the same as hw_compat_5_2
- */
-GlobalProperty hw_compat_rhel_8_4[] = {
- /* hw_compat_rhel_8_4 from hw_compat_5_2 */
- { "ICH9-LPC", "smm-compat", "on"},
- /* hw_compat_rhel_8_4 from hw_compat_5_2 */
- { "PIIX4_PM", "smm-compat", "on"},
- /* hw_compat_rhel_8_4 from hw_compat_5_2 */
- { "virtio-blk-device", "report-discard-granularity", "off" },
- /* hw_compat_rhel_8_4 from hw_compat_5_2 */
- /*
- * Upstream incorrectly had "virtio-net-pci" instead of "virtio-net-pci-base",
- * (https://bugzilla.redhat.com/show_bug.cgi?id=1999141)
- */
- { "virtio-net-pci-base", "vectors", "3"},
-};
-const size_t hw_compat_rhel_8_4_len = G_N_ELEMENTS(hw_compat_rhel_8_4);
-
-/*
- * Mostly the same as hw_compat_5_1
- */
-GlobalProperty hw_compat_rhel_8_3[] = {
- /* hw_compat_rhel_8_3 from hw_compat_5_1 */
- { "vhost-scsi", "num_queues", "1"},
- /* hw_compat_rhel_8_3 from hw_compat_5_1 */
- { "vhost-user-blk", "num-queues", "1"},
- /* hw_compat_rhel_8_3 from hw_compat_5_1 */
- { "vhost-user-scsi", "num_queues", "1"},
- /* hw_compat_rhel_8_3 from hw_compat_5_1 */
- { "virtio-blk-device", "num-queues", "1"},
- /* hw_compat_rhel_8_3 from hw_compat_5_1 */
- { "virtio-scsi-device", "num_queues", "1"},
- /* hw_compat_rhel_8_3 from hw_compat_5_1 */
- { "nvme", "use-intel-id", "on"},
- /* hw_compat_rhel_8_3 from hw_compat_5_1 */
- { "pvpanic", "events", "1"}, /* PVPANIC_PANICKED */
- /* hw_compat_rhel_8_3 from hw_compat_5_1 */
- { "pl011", "migrate-clk", "off" },
- /* hw_compat_rhel_8_3 bz 1912846 */
- { "pci-xhci", "x-rh-late-msi-cap", "off" },
- /* hw_compat_rhel_8_3 from hw_compat_5_1 */
- { "virtio-pci", "x-ats-page-aligned", "off"},
-};
-const size_t hw_compat_rhel_8_3_len = G_N_ELEMENTS(hw_compat_rhel_8_3);
-
-/*
- * The same as hw_compat_4_2 + hw_compat_5_0
- */
-GlobalProperty hw_compat_rhel_8_2[] = {
- /* hw_compat_rhel_8_2 from hw_compat_4_2 */
- { "virtio-blk-device", "queue-size", "128"},
- /* hw_compat_rhel_8_2 from hw_compat_4_2 */
- { "virtio-scsi-device", "virtqueue_size", "128"},
- /* hw_compat_rhel_8_2 from hw_compat_4_2 */
- { "virtio-blk-device", "x-enable-wce-if-config-wce", "off" },
- /* hw_compat_rhel_8_2 from hw_compat_4_2 */
- { "virtio-blk-device", "seg-max-adjust", "off"},
- /* hw_compat_rhel_8_2 from hw_compat_4_2 */
- { "virtio-scsi-device", "seg_max_adjust", "off"},
- /* hw_compat_rhel_8_2 from hw_compat_4_2 */
- { "vhost-blk-device", "seg_max_adjust", "off"},
- /* hw_compat_rhel_8_2 from hw_compat_4_2 */
- { "usb-host", "suppress-remote-wake", "off" },
- /* hw_compat_rhel_8_2 from hw_compat_4_2 */
- { "usb-redir", "suppress-remote-wake", "off" },
- /* hw_compat_rhel_8_2 from hw_compat_4_2 */
- { "qxl", "revision", "4" },
- /* hw_compat_rhel_8_2 from hw_compat_4_2 */
- { "qxl-vga", "revision", "4" },
- /* hw_compat_rhel_8_2 from hw_compat_4_2 */
- { "fw_cfg", "acpi-mr-restore", "false" },
- /* hw_compat_rhel_8_2 from hw_compat_4_2 */
- { "virtio-device", "use-disabled-flag", "false" },
- /* hw_compat_rhel_8_2 from hw_compat_5_0 */
- { "pci-host-bridge", "x-config-reg-migration-enabled", "off" },
- /* hw_compat_rhel_8_2 from hw_compat_5_0 */
- { "virtio-balloon-device", "page-poison", "false" },
- /* hw_compat_rhel_8_2 from hw_compat_5_0 */
- { "vmport", "x-read-set-eax", "off" },
- /* hw_compat_rhel_8_2 from hw_compat_5_0 */
- { "vmport", "x-signal-unsupported-cmd", "off" },
- /* hw_compat_rhel_8_2 from hw_compat_5_0 */
- { "vmport", "x-report-vmx-type", "off" },
- /* hw_compat_rhel_8_2 from hw_compat_5_0 */
- { "vmport", "x-cmds-v2", "off" },
- /* hw_compat_rhel_8_2 from hw_compat_5_0 */
- { "virtio-device", "x-disable-legacy-check", "true" },
-};
-const size_t hw_compat_rhel_8_2_len = G_N_ELEMENTS(hw_compat_rhel_8_2);
-
-/*
- * The same as hw_compat_4_1
- */
-GlobalProperty hw_compat_rhel_8_1[] = {
- /* hw_compat_rhel_8_1 from hw_compat_4_1 */
- { "virtio-pci", "x-pcie-flr-init", "off" },
-};
-const size_t hw_compat_rhel_8_1_len = G_N_ELEMENTS(hw_compat_rhel_8_1);
-
-/* The same as hw_compat_3_1
- * format of array has been changed by:
- * 6c36bddf5340 ("machine: Use shorter format for GlobalProperty arrays")
- */
-GlobalProperty hw_compat_rhel_8_0[] = {
- /* hw_compat_rhel_8_0 from hw_compat_3_1 */
- { "pcie-root-port", "x-speed", "2_5" },
- /* hw_compat_rhel_8_0 from hw_compat_3_1 */
- { "pcie-root-port", "x-width", "1" },
- /* hw_compat_rhel_8_0 from hw_compat_3_1 */
- { "memory-backend-file", "x-use-canonical-path-for-ramblock-id", "true" },
- /* hw_compat_rhel_8_0 from hw_compat_3_1 */
- { "memory-backend-memfd", "x-use-canonical-path-for-ramblock-id", "true" },
- /* hw_compat_rhel_8_0 from hw_compat_3_1 */
- { "tpm-crb", "ppi", "false" },
- /* hw_compat_rhel_8_0 from hw_compat_3_1 */
- { "tpm-tis", "ppi", "false" },
- /* hw_compat_rhel_8_0 from hw_compat_3_1 */
- { "usb-kbd", "serial", "42" },
- /* hw_compat_rhel_8_0 from hw_compat_3_1 */
- { "usb-mouse", "serial", "42" },
- /* hw_compat_rhel_8_0 from hw_compat_3_1 */
- { "usb-tablet", "serial", "42" },
- /* hw_compat_rhel_8_0 from hw_compat_3_1 */
- { "virtio-blk-device", "discard", "false" },
- /* hw_compat_rhel_8_0 from hw_compat_3_1 */
- { "virtio-blk-device", "write-zeroes", "false" },
- /* hw_compat_rhel_8_0 from hw_compat_4_0 */
- { "VGA", "edid", "false" },
- /* hw_compat_rhel_8_0 from hw_compat_4_0 */
- { "secondary-vga", "edid", "false" },
- /* hw_compat_rhel_8_0 from hw_compat_4_0 */
- { "bochs-display", "edid", "false" },
- /* hw_compat_rhel_8_0 from hw_compat_4_0 */
- { "virtio-vga", "edid", "false" },
- /* hw_compat_rhel_8_0 from hw_compat_4_0 */
- { "virtio-gpu-device", "edid", "false" },
- /* hw_compat_rhel_8_0 from hw_compat_4_0 */
- { "virtio-device", "use-started", "false" },
- /* hw_compat_rhel_8_0 from hw_compat_3_1 - that was added in 4.1 */
- { "pcie-root-port-base", "disable-acs", "true" },
-};
-const size_t hw_compat_rhel_8_0_len = G_N_ELEMENTS(hw_compat_rhel_8_0);
-
-/* The same as hw_compat_3_0 + hw_compat_2_12
- * except that
- * there's nothing in 3_0
- * migration.decompress-error-check=off was in 7.5 from bz 1584139
- */
-GlobalProperty hw_compat_rhel_7_6[] = {
- /* hw_compat_rhel_7_6 from hw_compat_2_12 */
- { "hda-audio", "use-timer", "false" },
- /* hw_compat_rhel_7_6 from hw_compat_2_12 */
- { "cirrus-vga", "global-vmstate", "true" },
- /* hw_compat_rhel_7_6 from hw_compat_2_12 */
- { "VGA", "global-vmstate", "true" },
- /* hw_compat_rhel_7_6 from hw_compat_2_12 */
- { "vmware-svga", "global-vmstate", "true" },
- /* hw_compat_rhel_7_6 from hw_compat_2_12 */
- { "qxl-vga", "global-vmstate", "true" },
-};
-const size_t hw_compat_rhel_7_6_len = G_N_ELEMENTS(hw_compat_rhel_7_6);
-
MachineState *current_machine;
static char *machine_get_kernel(Object *obj, Error **errp)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index a49d346d2e..7af762065f 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -316,121 +316,6 @@ GlobalProperty pc_rhel_9_0_compat[] = {
};
const size_t pc_rhel_9_0_compat_len = G_N_ELEMENTS(pc_rhel_9_0_compat);
-GlobalProperty pc_rhel_8_5_compat[] = {
- /* pc_rhel_8_5_compat from pc_compat_6_0 */
- { "qemu64" "-" TYPE_X86_CPU, "family", "6" },
- /* pc_rhel_8_5_compat from pc_compat_6_0 */
- { "qemu64" "-" TYPE_X86_CPU, "model", "6" },
- /* pc_rhel_8_5_compat from pc_compat_6_0 */
- { "qemu64" "-" TYPE_X86_CPU, "stepping", "3" },
- /* pc_rhel_8_5_compat from pc_compat_6_0 */
- { TYPE_X86_CPU, "x-vendor-cpuid-only", "off" },
- /* pc_rhel_8_5_compat from pc_compat_6_0 */
- { "ICH9-LPC", ACPI_PM_PROP_ACPI_PCIHP_BRIDGE, "off" },
-
- /* pc_rhel_8_5_compat from pc_compat_6_1 */
- { TYPE_X86_CPU, "hv-version-id-build", "0x1bbc" },
- /* pc_rhel_8_5_compat from pc_compat_6_1 */
- { TYPE_X86_CPU, "hv-version-id-major", "0x0006" },
- /* pc_rhel_8_5_compat from pc_compat_6_1 */
- { TYPE_X86_CPU, "hv-version-id-minor", "0x0001" },
-};
-const size_t pc_rhel_8_5_compat_len = G_N_ELEMENTS(pc_rhel_8_5_compat);
-
-GlobalProperty pc_rhel_8_4_compat[] = {
- /* pc_rhel_8_4_compat from pc_compat_5_2 */
- { "ICH9-LPC", "x-smi-cpu-hotunplug", "off" },
- { TYPE_X86_CPU, "kvm-asyncpf-int", "off" },
-};
-const size_t pc_rhel_8_4_compat_len = G_N_ELEMENTS(pc_rhel_8_4_compat);
-
-GlobalProperty pc_rhel_8_3_compat[] = {
- /* pc_rhel_8_3_compat from pc_compat_5_1 */
- { "ICH9-LPC", "x-smi-cpu-hotplug", "off" },
-};
-const size_t pc_rhel_8_3_compat_len = G_N_ELEMENTS(pc_rhel_8_3_compat);
-
-GlobalProperty pc_rhel_8_2_compat[] = {
- /* pc_rhel_8_2_compat from pc_compat_4_2 */
- { "mch", "smbase-smram", "off" },
-};
-const size_t pc_rhel_8_2_compat_len = G_N_ELEMENTS(pc_rhel_8_2_compat);
-
-/* pc_rhel_8_1_compat is empty since pc_4_1_compat is */
-GlobalProperty pc_rhel_8_1_compat[] = { };
-const size_t pc_rhel_8_1_compat_len = G_N_ELEMENTS(pc_rhel_8_1_compat);
-
-GlobalProperty pc_rhel_8_0_compat[] = {
- /* pc_rhel_8_0_compat from pc_compat_3_1 */
- { "intel-iommu", "dma-drain", "off" },
- /* pc_rhel_8_0_compat from pc_compat_3_1 */
- { "Opteron_G3" "-" TYPE_X86_CPU, "rdtscp", "off" },
- /* pc_rhel_8_0_compat from pc_compat_3_1 */
- { "Opteron_G4" "-" TYPE_X86_CPU, "rdtscp", "off" },
- /* pc_rhel_8_0_compat from pc_compat_3_1 */
- { "Opteron_G4" "-" TYPE_X86_CPU, "npt", "off" },
- /* pc_rhel_8_0_compat from pc_compat_3_1 */
- { "Opteron_G4" "-" TYPE_X86_CPU, "nrip-save", "off" },
- /* pc_rhel_8_0_compat from pc_compat_3_1 */
- { "Opteron_G5" "-" TYPE_X86_CPU, "rdtscp", "off" },
- /* pc_rhel_8_0_compat from pc_compat_3_1 */
- { "Opteron_G5" "-" TYPE_X86_CPU, "npt", "off" },
- /* pc_rhel_8_0_compat from pc_compat_3_1 */
- { "Opteron_G5" "-" TYPE_X86_CPU, "nrip-save", "off" },
- /* pc_rhel_8_0_compat from pc_compat_3_1 */
- { "EPYC" "-" TYPE_X86_CPU, "npt", "off" },
- /* pc_rhel_8_0_compat from pc_compat_3_1 */
- { "EPYC" "-" TYPE_X86_CPU, "nrip-save", "off" },
- /* pc_rhel_8_0_compat from pc_compat_3_1 */
- { "EPYC-IBPB" "-" TYPE_X86_CPU, "npt", "off" },
- /* pc_rhel_8_0_compat from pc_compat_3_1 */
- { "EPYC-IBPB" "-" TYPE_X86_CPU, "nrip-save", "off" },
- /** The mpx=on entries from pc_compat_3_1 are in pc_rhel_7_6_compat **/
- /* pc_rhel_8_0_compat from pc_compat_3_1 */
- { "Cascadelake-Server" "-" TYPE_X86_CPU, "stepping", "5" },
- /* pc_rhel_8_0_compat from pc_compat_3_1 */
- { TYPE_X86_CPU, "x-intel-pt-auto-level", "off" },
-};
-const size_t pc_rhel_8_0_compat_len = G_N_ELEMENTS(pc_rhel_8_0_compat);
-
-/* Similar to PC_COMPAT_3_0 + PC_COMPAT_2_12, but:
- * all of the 2_12 stuff was already in 7.6 from bz 1481253
- * x-migrate-smi-count comes from PC_COMPAT_2_11 but
- * is really tied to kernel version so keep it off on 7.x
- * machine types irrespective of host.
- */
-GlobalProperty pc_rhel_7_6_compat[] = {
- /* pc_rhel_7_6_compat from pc_compat_3_0 */
- { TYPE_X86_CPU, "x-hv-synic-kvm-only", "on" },
- /* pc_rhel_7_6_compat from pc_compat_3_0 */
- { "Skylake-Server" "-" TYPE_X86_CPU, "pku", "off" },
- /* pc_rhel_7_6_compat from pc_compat_3_0 */
- { "Skylake-Server-IBRS" "-" TYPE_X86_CPU, "pku", "off" },
- /* pc_rhel_7_6_compat from pc_compat_2_11 */
- { TYPE_X86_CPU, "x-migrate-smi-count", "off" },
- /* pc_rhel_7_6_compat from pc_compat_2_11 */
- { "Skylake-Client" "-" TYPE_X86_CPU, "mpx", "on" },
- /* pc_rhel_7_6_compat from pc_compat_2_11 */
- { "Skylake-Client-IBRS" "-" TYPE_X86_CPU, "mpx", "on" },
- /* pc_rhel_7_6_compat from pc_compat_2_11 */
- { "Skylake-Server" "-" TYPE_X86_CPU, "mpx", "on" },
- /* pc_rhel_7_6_compat from pc_compat_2_11 */
- { "Skylake-Server-IBRS" "-" TYPE_X86_CPU, "mpx", "on" },
- /* pc_rhel_7_6_compat from pc_compat_2_11 */
- { "Cascadelake-Server" "-" TYPE_X86_CPU, "mpx", "on" },
- /* pc_rhel_7_6_compat from pc_compat_2_11 */
- { "Icelake-Client" "-" TYPE_X86_CPU, "mpx", "on" },
- /* pc_rhel_7_6_compat from pc_compat_2_11 */
- { "Icelake-Server" "-" TYPE_X86_CPU, "mpx", "on" },
-};
-const size_t pc_rhel_7_6_compat_len = G_N_ELEMENTS(pc_rhel_7_6_compat);
-
-/*
- * The PC_RHEL_*_COMPAT serve the same purpose for RHEL-7 machine
- * types as the PC_COMPAT_* do for upstream types.
- * PC_RHEL_7_*_COMPAT apply both to i440fx and q35 types.
- */
-
GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled)
{
GSIState *s;
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 6d98aaf4c7..ac917b87fb 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -823,29 +823,5 @@ extern const size_t hw_compat_rhel_9_1_len;
extern GlobalProperty hw_compat_rhel_9_0[];
extern const size_t hw_compat_rhel_9_0_len;
-extern GlobalProperty hw_compat_rhel_8_6[];
-extern const size_t hw_compat_rhel_8_6_len;
-
-extern GlobalProperty hw_compat_rhel_8_5[];
-extern const size_t hw_compat_rhel_8_5_len;
-
-extern GlobalProperty hw_compat_rhel_8_4[];
-extern const size_t hw_compat_rhel_8_4_len;
-
-extern GlobalProperty hw_compat_rhel_8_3[];
-extern const size_t hw_compat_rhel_8_3_len;
-
-extern GlobalProperty hw_compat_rhel_8_2[];
-extern const size_t hw_compat_rhel_8_2_len;
-
-extern GlobalProperty hw_compat_rhel_8_1[];
-extern const size_t hw_compat_rhel_8_1_len;
-
-extern GlobalProperty hw_compat_rhel_8_0[];
-extern const size_t hw_compat_rhel_8_0_len;
-
-extern GlobalProperty hw_compat_rhel_7_6[];
-extern const size_t hw_compat_rhel_7_6_len;
-
extern const char *rhel_old_machine_deprecation;
#endif
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 8e9597f40f..61609027d0 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -314,27 +314,6 @@ extern const size_t pc_rhel_9_2_compat_len;
extern GlobalProperty pc_rhel_9_0_compat[];
extern const size_t pc_rhel_9_0_compat_len;
-extern GlobalProperty pc_rhel_8_5_compat[];
-extern const size_t pc_rhel_8_5_compat_len;
-
-extern GlobalProperty pc_rhel_8_4_compat[];
-extern const size_t pc_rhel_8_4_compat_len;
-
-extern GlobalProperty pc_rhel_8_3_compat[];
-extern const size_t pc_rhel_8_3_compat_len;
-
-extern GlobalProperty pc_rhel_8_2_compat[];
-extern const size_t pc_rhel_8_2_compat_len;
-
-extern GlobalProperty pc_rhel_8_1_compat[];
-extern const size_t pc_rhel_8_1_compat_len;
-
-extern GlobalProperty pc_rhel_8_0_compat[];
-extern const size_t pc_rhel_8_0_compat_len;
-
-extern GlobalProperty pc_rhel_7_6_compat[];
-extern const size_t pc_rhel_7_6_compat_len;
-
#define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \
static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *data) \
{ \
--
2.39.3

@ -1,36 +0,0 @@
From 44ee061e1904c20cae9cab5e8a62f1b506395383 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
Date: Wed, 5 Jun 2024 10:28:20 +0400
Subject: [PATCH 07/14] rhel 9.4.0 machine type compat for virtio-gpu migration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
RH-MergeRequest: 250: virtio-gpu: fix v2 migration
RH-Jira: RHEL-36329
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/2] 66c98702c691e3454377f5a98230fd1f619a9a87 (marcandre.lureau-rh/qemu-kvm-centos)
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hw/core/machine.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index cf1d7faaaf..92609aae27 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -310,6 +310,8 @@ GlobalProperty hw_compat_rhel_9_5[] = {
{ TYPE_VIRTIO_IOMMU_PCI, "granule", "4k" },
/* hw_compat_rhel_9_5 from hw_compat_8_2 */
{ TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" },
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { "virtio-gpu-device", "x-scanout-vmstate-version", "1" },
};
const size_t hw_compat_rhel_9_5_len = G_N_ELEMENTS(hw_compat_rhel_9_5);
--
2.39.3

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

@ -0,0 +1,264 @@
From ad587091d8716dbc118776b8edb61db12f6da122 Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:50 -0400
Subject: [PATCH 18/38] s390x: Rebuild IPLB for SCSI device directly from
DIAG308
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [17/23] 8267b7ecd71f2af5409e2e41890b6e5bb56fabd2 (thuth/qemu-kvm-cs9)
Because virtio-scsi type devices use a non-architected IPLB pbt code they cannot
be set and stored normally. Instead, the IPLB must be rebuilt during re-ipl.
As s390x does not natively support multiple boot devices, the devno field is
used to store the position in the boot order for the device.
Handling the rebuild as part of DIAG308 removes the need to check the devices
for invalid IPLBs later in the IPL.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Acked-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-17-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 455e3bc3f74ee76964efec2e0c646db15095d0d2)
---
hw/s390x/ipl.c | 74 ++++++-------------------------------
hw/s390x/ipl.h | 11 ++++--
include/hw/s390x/ipl/qipl.h | 3 +-
pc-bios/s390-ccw/jump2ipl.c | 11 ++++--
target/s390x/diag.c | 9 ++++-
5 files changed, 38 insertions(+), 70 deletions(-)
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index f4576f8822..5fbd43c346 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -448,7 +448,6 @@ void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp)
static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
{
- S390IPLState *ipl = get_ipl_device();
CcwDevice *ccw_dev = NULL;
SCSIDevice *sd;
int devtype;
@@ -481,9 +480,6 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
iplb->ccw.ssid = ccw_dev->sch->ssid & 3;
break;
case CCW_DEVTYPE_VIRTIO_NET:
- /* The S390IPLState netboot is true if ANY IPLB may use netboot */
- ipl->netboot = true;
- /* Fall through to CCW_DEVTYPE_VIRTIO case */
case CCW_DEVTYPE_VIRTIO:
iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
iplb->blk0_len =
@@ -508,6 +504,16 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
return false;
}
+void s390_rebuild_iplb(uint16_t dev_index, IplParameterBlock *iplb)
+{
+ S390IPLState *ipl = get_ipl_device();
+ uint16_t index;
+ index = ipl->rebuilt_iplb ? ipl->iplb_index : dev_index;
+
+ ipl->rebuilt_iplb = s390_build_iplb(get_boot_device(index), iplb);
+ ipl->iplb_index = index;
+}
+
static bool s390_init_all_iplbs(S390IPLState *ipl)
{
int iplb_num = 0;
@@ -564,44 +570,6 @@ static bool s390_init_all_iplbs(S390IPLState *ipl)
return iplb_num;
}
-static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb,
- int virtio_id)
-{
- uint8_t cssid;
- uint8_t ssid;
- uint16_t devno;
- uint16_t schid;
- SubchDev *sch = NULL;
-
- if (iplb->pbt != S390_IPL_TYPE_CCW) {
- return false;
- }
-
- devno = be16_to_cpu(iplb->ccw.devno);
- ssid = iplb->ccw.ssid & 3;
-
- for (schid = 0; schid < MAX_SCHID; schid++) {
- for (cssid = 0; cssid < MAX_CSSID; cssid++) {
- sch = css_find_subch(1, cssid, ssid, schid);
-
- if (sch && sch->devno == devno) {
- return sch->id.cu_model == virtio_id;
- }
- }
- }
- return false;
-}
-
-static bool is_virtio_net_device(IplParameterBlock *iplb)
-{
- return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_NET);
-}
-
-static bool is_virtio_scsi_device(IplParameterBlock *iplb)
-{
- return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_SCSI);
-}
-
static void update_machine_ipl_properties(IplParameterBlock *iplb)
{
Object *machine = qdev_get_machine();
@@ -641,7 +609,7 @@ void s390_ipl_update_diag308(IplParameterBlock *iplb)
ipl->iplb = *iplb;
ipl->iplb_valid = true;
}
- ipl->netboot = is_virtio_net_device(iplb);
+
update_machine_ipl_properties(iplb);
}
@@ -668,32 +636,14 @@ IplParameterBlock *s390_ipl_get_iplb(void)
void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type)
{
S390IPLState *ipl = get_ipl_device();
-
if (reset_type == S390_RESET_EXTERNAL || reset_type == S390_RESET_REIPL) {
/* use CPU 0 for full resets */
ipl->reset_cpu_index = 0;
} else {
ipl->reset_cpu_index = cs->cpu_index;
}
- ipl->reset_type = reset_type;
- if (reset_type == S390_RESET_REIPL &&
- ipl->iplb_valid &&
- !ipl->netboot &&
- ipl->iplb.pbt == S390_IPL_TYPE_CCW &&
- is_virtio_scsi_device(&ipl->iplb)) {
- CcwDevice *ccw_dev = s390_get_ccw_device(get_boot_device(0), NULL);
-
- if (ccw_dev &&
- cpu_to_be16(ccw_dev->sch->devno) == ipl->iplb.ccw.devno &&
- (ccw_dev->sch->ssid & 3) == ipl->iplb.ccw.ssid) {
- /*
- * this is the original boot device's SCSI
- * so restore IPL parameter info from it
- */
- ipl->iplb_valid = s390_build_iplb(get_boot_device(0), &ipl->iplb);
- }
- }
+ ipl->reset_type = reset_type;
if (reset_type == S390_RESET_MODIFIED_CLEAR ||
reset_type == S390_RESET_LOAD_NORMAL ||
reset_type == S390_RESET_PV) {
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index 54eb48fd6e..d7d0b7bfd2 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -24,6 +24,7 @@
void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp);
void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp);
+void s390_rebuild_iplb(uint16_t index, IplParameterBlock *iplb);
void s390_ipl_update_diag308(IplParameterBlock *iplb);
int s390_ipl_prepare_pv_header(Error **errp);
int s390_ipl_pv_unpack(void);
@@ -65,7 +66,8 @@ struct S390IPLState {
bool enforce_bios;
bool iplb_valid;
bool iplb_valid_pv;
- bool netboot;
+ bool rebuilt_iplb;
+ uint16_t iplb_index;
/* reset related properties don't have to be migrated or reset */
enum s390_reset reset_type;
int reset_cpu_index;
@@ -172,11 +174,14 @@ static inline bool iplb_valid_pv(IplParameterBlock *iplb)
static inline bool iplb_valid(IplParameterBlock *iplb)
{
+ uint32_t len = be32_to_cpu(iplb->len);
+
switch (iplb->pbt) {
case S390_IPL_TYPE_FCP:
- return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN;
+ return len >= S390_IPLB_MIN_FCP_LEN;
case S390_IPL_TYPE_CCW:
- return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN;
+ return len >= S390_IPLB_MIN_CCW_LEN;
+ case S390_IPL_TYPE_QEMU_SCSI:
default:
return false;
}
diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h
index 1da4f75aa8..6824391111 100644
--- a/include/hw/s390x/ipl/qipl.h
+++ b/include/hw/s390x/ipl/qipl.h
@@ -29,7 +29,8 @@
*/
struct QemuIplParameters {
uint8_t qipl_flags;
- uint8_t reserved1[3];
+ uint8_t index;
+ uint8_t reserved1[2];
uint64_t reserved2;
uint32_t boot_menu_timeout;
uint8_t reserved3[2];
diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
index 8db1764ff3..99d18947d1 100644
--- a/pc-bios/s390-ccw/jump2ipl.c
+++ b/pc-bios/s390-ccw/jump2ipl.c
@@ -39,10 +39,15 @@ int jump_to_IPL_code(uint64_t address)
write_subsystem_identification();
write_iplb_location();
- /* prevent unknown IPL types in the guest */
+ /*
+ * The IPLB for QEMU SCSI type devices must be rebuilt during re-ipl. The
+ * iplb.devno is set to the boot position of the target SCSI device.
+ */
if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
- iplb.pbt = S390_IPL_TYPE_CCW;
- set_iplb(&iplb);
+ iplb.devno = qipl.index;
+ if (!set_iplb(&iplb)) {
+ panic("Failed to set IPLB");
+ }
}
/*
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
index 27ffd48576..a1fd54ddac 100644
--- a/target/s390x/diag.c
+++ b/target/s390x/diag.c
@@ -133,7 +133,14 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
valid = subcode == DIAG308_PV_SET ? iplb_valid_pv(iplb) : iplb_valid(iplb);
if (!valid) {
- env->regs[r1 + 1] = DIAG_308_RC_INVALID;
+ if (subcode == DIAG308_SET && iplb->pbt == S390_IPL_TYPE_QEMU_SCSI) {
+ s390_rebuild_iplb(iplb->devno, iplb);
+ s390_ipl_update_diag308(iplb);
+ env->regs[r1 + 1] = DIAG_308_RC_OK;
+ } else {
+ env->regs[r1 + 1] = DIAG_308_RC_INVALID;
+ }
+
goto out;
}
--
2.39.3

@ -1,164 +0,0 @@
From eb773f38d127117597a1640cd623f1fcd000c067 Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
Date: Fri, 19 Apr 2024 16:37:57 +0200
Subject: [PATCH 08/14] s390x: remove deprecated rhel machine types
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 252: s390x: remove legacy CPU types
RH-Jira: RHEL-39898
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/5] 5ed0651c38584980b1fe51592a788032526c0f2f (thuth/qemu-kvm-cs9)
Upstream-status: N/A
Remove the following deprecated s390x rhel specific machine types:
s390-ccw-virtio-rhel8.6.0
s390-ccw-virtio-rhel8.5.0
s390-ccw-virtio-rhel8.4.0
s390-ccw-virtio-rhel8.2.0
s390-ccw-virtio-rhel7.6.0
Signed-off-by: Sebastian Ott <sebott@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
hw/s390x/s390-virtio-ccw.c | 106 +------------------------------------
1 file changed, 2 insertions(+), 104 deletions(-)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 9ad54682c6..b0b903b78c 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -610,6 +610,7 @@ static void s390_nmi(NMIState *n, int cpu_index, Error **errp)
s390_cpu_restart(S390_CPU(cs));
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static ram_addr_t s390_fixup_ram_size(ram_addr_t sz)
{
/* same logic as in sclp.c */
@@ -629,6 +630,7 @@ static ram_addr_t s390_fixup_ram_size(ram_addr_t sz)
}
return newsz;
}
+#endif /* disabled for RHEL */
static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp)
{
@@ -1329,110 +1331,6 @@ static void ccw_machine_rhel900_class_options(MachineClass *mc)
}
DEFINE_CCW_MACHINE(rhel900, "rhel9.0.0", false);
-static void ccw_machine_rhel860_instance_options(MachineState *machine)
-{
- /* Note: The -rhel8.6.0 and -rhel9.0.0 machines are technically identical */
- ccw_machine_rhel900_instance_options(machine);
-}
-
-static void ccw_machine_rhel860_class_options(MachineClass *mc)
-{
- static GlobalProperty compat[] = {
- { TYPE_S390_PCI_DEVICE, "interpret", "on", },
- { TYPE_S390_PCI_DEVICE, "forwarding-assist", "on", },
- };
-
- ccw_machine_rhel900_class_options(mc);
- compat_props_add(mc->compat_props, hw_compat_rhel_8_6, hw_compat_rhel_8_6_len);
- compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
-
- /* All RHEL machines for prior major releases are deprecated */
- mc->deprecation_reason = rhel_old_machine_deprecation;
-}
-DEFINE_CCW_MACHINE(rhel860, "rhel8.6.0", false);
-
-static void ccw_machine_rhel850_instance_options(MachineState *machine)
-{
- static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_0 };
-
- ccw_machine_rhel860_instance_options(machine);
-
- s390_set_qemu_cpu_model(0x2964, 13, 2, qemu_cpu_feat);
-
- s390_cpudef_featoff_greater(16, 1, S390_FEAT_NNPA);
- s390_cpudef_featoff_greater(16, 1, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2);
- s390_cpudef_featoff_greater(16, 1, S390_FEAT_BEAR_ENH);
- s390_cpudef_featoff_greater(16, 1, S390_FEAT_RDP);
- s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAI);
-}
-
-static void ccw_machine_rhel850_class_options(MachineClass *mc)
-{
- static GlobalProperty compat[] = {
- { TYPE_S390_PCI_DEVICE, "interpret", "off", },
- { TYPE_S390_PCI_DEVICE, "forwarding-assist", "off", },
- };
-
- ccw_machine_rhel860_class_options(mc);
- compat_props_add(mc->compat_props, hw_compat_rhel_8_5, hw_compat_rhel_8_5_len);
- compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
- mc->smp_props.prefer_sockets = true;
-}
-DEFINE_CCW_MACHINE(rhel850, "rhel8.5.0", false);
-
-static void ccw_machine_rhel840_instance_options(MachineState *machine)
-{
- ccw_machine_rhel850_instance_options(machine);
-}
-
-static void ccw_machine_rhel840_class_options(MachineClass *mc)
-{
- ccw_machine_rhel850_class_options(mc);
- compat_props_add(mc->compat_props, hw_compat_rhel_8_4, hw_compat_rhel_8_4_len);
-}
-DEFINE_CCW_MACHINE(rhel840, "rhel8.4.0", false);
-
-static void ccw_machine_rhel820_instance_options(MachineState *machine)
-{
- ccw_machine_rhel840_instance_options(machine);
-}
-
-static void ccw_machine_rhel820_class_options(MachineClass *mc)
-{
- ccw_machine_rhel840_class_options(mc);
- mc->fixup_ram_size = s390_fixup_ram_size;
- /* we did not publish a rhel8.3.0 machine */
- compat_props_add(mc->compat_props, hw_compat_rhel_8_3, hw_compat_rhel_8_3_len);
- compat_props_add(mc->compat_props, hw_compat_rhel_8_2, hw_compat_rhel_8_2_len);
-}
-DEFINE_CCW_MACHINE(rhel820, "rhel8.2.0", false);
-
-static void ccw_machine_rhel760_instance_options(MachineState *machine)
-{
- static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V3_1 };
-
- ccw_machine_rhel820_instance_options(machine);
-
- s390_set_qemu_cpu_model(0x2827, 12, 2, qemu_cpu_feat);
-
- /* The multiple-epoch facility was not available with rhel7.6.0 on z14GA1 */
- s390_cpudef_featoff(14, 1, S390_FEAT_MULTIPLE_EPOCH);
- s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_QSIE);
- s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_QTOUE);
- s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_STOE);
- s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_STOUE);
-}
-
-static void ccw_machine_rhel760_class_options(MachineClass *mc)
-{
- ccw_machine_rhel820_class_options(mc);
- /* We never published the s390x version of RHEL-AV 8.0 and 8.1, so add this here */
- compat_props_add(mc->compat_props, hw_compat_rhel_8_1, hw_compat_rhel_8_1_len);
- compat_props_add(mc->compat_props, hw_compat_rhel_8_0, hw_compat_rhel_8_0_len);
- compat_props_add(mc->compat_props, hw_compat_rhel_7_6, hw_compat_rhel_7_6_len);
-}
-DEFINE_CCW_MACHINE(rhel760, "rhel7.6.0", false);
-
static void ccw_machine_register_types(void)
{
type_register_static(&ccw_machine_info);
--
2.39.3

@ -1,41 +0,0 @@
From 874c2ad98804caf0db862c2a45db66a9bceb4fc4 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Thu, 9 May 2024 19:00:35 +0200
Subject: [PATCH 09/14] s390x: select correct components for no-board build
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 252: s390x: remove legacy CPU types
RH-Jira: RHEL-39898
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/5] 441dfae234f21f801ac9f9e417e96e2edff48bd4 (thuth/qemu-kvm-cs9)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20240509170044.190795-5-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit e799b65faef129f2905bd9bf66c30aaaa7115dac)
Conflicts:
.gitlab-ci.d/buildtest.yml
(skipped the changes to the CI files, they don't apply and
are not needed in downstream)
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
target/s390x/Kconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/s390x/Kconfig b/target/s390x/Kconfig
index 72da48136c..d886be48b4 100644
--- a/target/s390x/Kconfig
+++ b/target/s390x/Kconfig
@@ -1,2 +1,4 @@
config S390X
bool
+ select PCI
+ select S390_FLIC
--
2.39.3

@ -0,0 +1,44 @@
From f03d8c917543a5b92e26fcd8bd7c1cf006ea37df Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Tue, 19 Nov 2024 22:31:22 +0100
Subject: [PATCH 6/9] scsi: fix allocation for s390x loadparm
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature
RH-Jira: RHEL-68444
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [5/8] b5a906d74fb4ad5a89e1880f07447bd3a5b3f2e9 (thuth/qemu-kvm-cs9)
Coverity reports a possible buffer overrun due to a non-NUL-terminated
string in scsi_property_set_loadparm(). While things are not so easy,
because qdev_prop_sanitize_s390x_loadparm is designed to operate on a
buffer that is not NUL-terminated, in this case the string *does* have
to be NUL-terminated because it is read by scsi_property_get_loadparm
and s390_build_iplb.
Reviewed-by: jrossi@linux.ibm.com
Cc: thuth@redhat.com
Fixes: 429442e52d9 ("hw: Add "loadparm" property to scsi disk devices for booting on s390x", 2024-11-18)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit b73d7eff1eedb2399cd594bc872d5db13506d951)
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
hw/scsi/scsi-disk.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 7566a5f531..de0c295173 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -3152,7 +3152,7 @@ static void scsi_property_set_loadparm(Object *obj, const char *value,
return;
}
- lp_str = g_malloc0(strlen(value));
+ lp_str = g_malloc0(strlen(value) + 1);
if (!qdev_prop_sanitize_s390x_loadparm(lp_str, value, errp)) {
g_free(lp_str);
return;
--
2.39.3

@ -1,62 +0,0 @@
From 0d3444e4ba998bbebce282fe1367ef16b635e3ae Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Fri, 14 Jun 2024 13:34:47 +0530
Subject: [PATCH 04/14] target/cpu-models/x86: Remove the existing deprecated
CPU models on c10s
RH-Author: Ani Sinha <anisinha@redhat.com>
RH-MergeRequest: 243: target/cpu-models/x86: Remove the existing deprecated CPU models on c10s
RH-Jira: RHEL-28972
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
RH-Acked-by: MST <mst@redhat.com>
RH-Commit: [4/4] ca6905d2f6cae5f120d3acef973cadb1164e0864 (anisinha/centos-qemu-kvm)
The cpu models that were deprecated in c9s can be removed in c10s. This change
compiled out these cpu models. For x86, 'qemu64' cpu model is still kept as is
as its the default cpu model.
Signed-off-by: Ani Sinha <anisinha@redhat.com>
---
target/i386/cpu.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index be7b0663cd..c83d585c9b 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2215,6 +2215,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x8000000A,
.model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
},
+#if 0 // Deprecated CPU models are removed in RHEL-10
{
.name = "phenom",
.deprecation_note = RHEL_CPU_DEPRECATION,
@@ -2593,6 +2594,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
},
+#endif // Removal of deprecated CPU models in RHEL-10
{
.name = "Nehalem",
.level = 11,
@@ -4410,6 +4412,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Intel Xeon Phi Processor (Knights Mill)",
},
+#if 0 // Deprecated CPU models are removed in RHEL-10
{
.name = "Opteron_G1",
.deprecation_note = RHEL_CPU_DEPRECATION,
@@ -4480,6 +4483,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
},
+#endif
{
.name = "Opteron_G4",
.level = 0xd,
--
2.39.3

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

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save