Enable QXL device build

Enable building for ppc64le

Re-added Spice support

Don't remove slof.bin for ppc64le
This commit is contained in:
Eduard Abdullin 2025-12-04 10:26:13 +00:00 committed by root
parent 7292cc4ffa
commit 1d80fe5c7d
371 changed files with 31571 additions and 23126 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
qemu-9.1.0.tar.xz
qemu-10.0.0.tar.xz

View File

@ -1,4 +1,4 @@
From 7e57931a524e1e805ba8d68e75828e98c591e975 Mon Sep 17 00:00:00 2001
From ff5cdaa4c69d89d7c6429b30fbdc5b9e1f0a6968 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,33 +13,57 @@ 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.
We are rebasing from qemu-kvm-9.1.0-17.el10.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase notes (9.1.0 rc0):
Rebase notes (9.1.0):
- Remove --disable-block-migration and --disable-pvrdma configure options (upstream)
- Removed --disable-avx512f configure option
- Removed qemu-vsmr-helper (changed upstream)
Rebase notes (10.0.0 rc0):
- Split --disable-sanitazers configure option (upstream change)
- Removed s390x-netboot.img (upstream)
- accel-tcg module no longer built (upstream)
- Removed new upstream npcm8xx board rom
- Not package hw-uefi-vars.so
- Not package pnv-pnor.bin on build
Rebase notes (10.0.0):
- Include riscv support
Merged patches (9.1.0):
- b206b8f7cb redhat: Remove the s390-netboot.img from the spec file
- 95605107f1 Require new dtrace package
Merged patches (10.0.0 rc0):
- 07c8c9b9ff qemu-guest-agent: Update the logfile path of qga-fsfreeze-hook.log
Merged patches (10.0.0 rc1):
- 1f54babd2a Recommend systemtap-client from qemu-tools
Merged patches (10.0.0 rc3):
- 3e4d2a0fb8 Also recommend systemtap-devel from qemu-tools
---
.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 | 1332 +++++++++++++++++++++++
.distro/qemu-kvm.spec.template | 1606 +++++++++++++++++++++++
.distro/rpminspect.yaml | 6 +-
.distro/scripts/extract_build_cmd.py | 12 +
.distro/scripts/frh.py | 4 +-
.distro/scripts/process-patches.sh | 6 +-
.gitignore | 1 +
README.systemtap | 43 +
scripts/qemu-guest-agent/fsfreeze-hook | 2 +-
scripts/qemu-guest-agent/fsfreeze-hook | 4 +-
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, 1593 insertions(+), 7 deletions(-)
16 files changed, 1868 insertions(+), 8 deletions(-)
create mode 100644 .distro/Makefile
create mode 100644 .distro/Makefile.common
create mode 100644 .distro/README.tests
@ -99,14 +123,16 @@ index 0000000000..ad913fc990
+3. Translate the trace record to readable format.
+ # /usr/share/qemu-kvm/simpletrace.py --no-header /usr/share/qemu-kvm/trace-events /tmp/trace.log
diff --git a/scripts/qemu-guest-agent/fsfreeze-hook b/scripts/qemu-guest-agent/fsfreeze-hook
index 13aafd4845..e9b84ec028 100755
index c1feb6f5ce..d5d8d4daf8 100755
--- a/scripts/qemu-guest-agent/fsfreeze-hook
+++ b/scripts/qemu-guest-agent/fsfreeze-hook
@@ -8,7 +8,7 @@
@@ -7,8 +7,8 @@
# "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/qga-fsfreeze-hook.log
-FSFREEZE_D=$(dirname -- "$0")/fsfreeze-hook.d
+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
@ -129,7 +155,7 @@ index 0000000000..c04abf9449
@@ -0,0 +1 @@
+probe qemu.kvm.simpletrace.handle_qmp_command,qemu.kvm.simpletrace.monitor_protocol_*,qemu.kvm.simpletrace.migrate_set_state {}
diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
index 47fdae5b21..2a950caa2a 100644
index 3f4cfc471d..09dafba18d 100644
--- a/ui/vnc-auth-sasl.c
+++ b/ui/vnc-auth-sasl.c
@@ -42,7 +42,7 @@

View File

@ -1,4 +1,4 @@
From 003f37e17fb03b8977effd968426a0aeb5855028 Mon Sep 17 00:00:00 2001
From e56f9e1921ab836e454ee003812487cd520580b1 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
@ -8,24 +8,32 @@ 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):
Rebase notes (9.1.0):
- 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):
Rebase notes (10.0.0 rc0):
- Added CONFIG_PCI_BRIDGE for aarch64 and x86_64 (new upstream)
- Do not add deprecation_note member as it was added upstream (target/arm/cpu.h)
- Rename CONFIG_ARM_GICV3_TCG to CONFIG_ARM_GICV3
Rebase notes (10.0.0 rc1):
- Remove deprecated line change for code commented out
- Do not change minimal revision for piix4
- Remove YongFeng vcpu
Rebase notes (10.0.0):
- Add rebase devices changes
- Enable virtio-mem on s390x
Merged commits (9.1.0):
- f24c7a1fee Disable FDC devices
- fe8c6cb1ce Disable vga-cirrus device
- fccd117a12 Enable vhost-user-snd-pci device
@ -34,15 +42,14 @@ Merged commits (9.1.0 rc0):
- 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 | 20 +--
.../aarch64-softmmu/aarch64-rh-devices.mak | 46 +++++++
.../aarch64-softmmu/aarch64-rh-devices.mak | 47 +++++++
configs/devices/rh-virtio.mak | 10 ++
.../s390x-softmmu/s390x-rh-devices.mak | 19 +++
.../x86_64-softmmu/x86_64-rh-devices.mak | 114 ++++++++++++++++++
.../riscv64-softmmu/riscv64-rh-devices.mak | 39 ++++++
.../s390x-softmmu/s390x-rh-devices.mak | 20 +++
.../x86_64-softmmu/x86_64-rh-devices.mak | 115 ++++++++++++++++++
hw/arm/virt.c | 4 +
hw/cxl/meson.build | 3 +-
hw/ide/piix.c | 5 +-
@ -51,37 +58,39 @@ Merged commits (9.1.0 rc4):
hw/usb/meson.build | 2 +-
hw/virtio/meson.build | 6 +-
target/arm/arm-qmp-cmds.c | 2 +
target/arm/cpu.c | 4 +
target/arm/cpu.h | 3 +
target/arm/cpu.h | 2 +
target/arm/cpu64.c | 12 +-
target/arm/tcg/cpu32.c | 2 +
target/arm/tcg/cpu64.c | 8 ++
target/arm/tcg/meson.build | 2 +-
target/i386/cpu.c | 19 +++
target/i386/cpu.c | 18 +++
target/riscv/cpu.c | 6 +
target/s390x/cpu_models.c | 2 +-
tests/qtest/arm-cpu-features.c | 4 +
22 files changed, 275 insertions(+), 16 deletions(-)
23 files changed, 317 insertions(+), 16 deletions(-)
create mode 100644 configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
create mode 100644 configs/devices/rh-virtio.mak
create mode 100644 configs/devices/riscv64-softmmu/riscv64-rh-devices.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..58075e2812
index 0000000000..dce5fca821
--- /dev/null
+++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
@@ -0,0 +1,46 @@
@@ -0,0 +1,47 @@
+include ../rh-virtio.mak
+
+CONFIG_ARM_GIC_KVM=y
+CONFIG_ARM_GICV3_TCG=y
+CONFIG_ARM_GICV3=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_SMMUV3=y
+CONFIG_ARM_VIRT=y
+CONFIG_CXL=y
+CONFIG_CXL_MEM_DEVICE=y
+CONFIG_EDID=y
+CONFIG_PCI_BRIDGE=y
+CONFIG_PCIE_PORT=y
+CONFIG_PCIE_PCI_BRIDGE=y
+CONFIG_PCI_DEVICES=y
@ -134,12 +143,57 @@ index 0000000000..94ede1b5f6
+CONFIG_VIRTIO_RNG=y
+CONFIG_VIRTIO_SCSI=y
+CONFIG_VIRTIO_SERIAL=y
diff --git a/configs/devices/riscv64-softmmu/riscv64-rh-devices.mak b/configs/devices/riscv64-softmmu/riscv64-rh-devices.mak
new file mode 100644
index 0000000000..b5e55de916
--- /dev/null
+++ b/configs/devices/riscv64-softmmu/riscv64-rh-devices.mak
@@ -0,0 +1,39 @@
+include ../rh-virtio.mak
+
+CONFIG_RISCV_VIRT=y
+CONFIG_CXL=y
+CONFIG_CXL_MEM_DEVICE=y
+CONFIG_EDID=y
+CONFIG_PCI_BRIDGE=y
+CONFIG_PCIE_PORT=y
+CONFIG_PCIE_PCI_BRIDGE=y
+CONFIG_PCI_DEVICES=y
+CONFIG_PCI_TESTDEV=y
+CONFIG_PFLASH_CFI01=y
+CONFIG_SCSI=y
+CONFIG_SEMIHOSTING=y
+CONFIG_USB=y
+CONFIG_USB_XHCI=y
+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
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_IOMMU=y
+CONFIG_XIO3130=y
+CONFIG_ACPI_APEI=y
+CONFIG_TPM=y
+CONFIG_TPM_EMULATOR=y
+CONFIG_TPM_TIS_SYSBUS=y
+CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
+CONFIG_PVPANIC_PCI=y
+CONFIG_PXB=y
+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
new file mode 100644
index 0000000000..24cf6dbd03
index 0000000000..834281d872
--- /dev/null
+++ b/configs/devices/s390x-softmmu/s390x-rh-devices.mak
@@ -0,0 +1,19 @@
@@ -0,0 +1,20 @@
+include ../rh-virtio.mak
+
+CONFIG_PCI=y
@ -154,6 +208,7 @@ index 0000000000..24cf6dbd03
+CONFIG_VFIO_PCI=y
+CONFIG_VHOST_USER=y
+CONFIG_VIRTIO_CCW=y
+CONFIG_VIRTIO_MEM=y
+CONFIG_WDT_DIAG288=y
+CONFIG_VHOST_VSOCK=y
+CONFIG_VHOST_USER_VSOCK=y
@ -161,10 +216,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..45a8a15291
index 0000000000..8da1a8f82f
--- /dev/null
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
@@ -0,0 +1,114 @@
@@ -0,0 +1,115 @@
+include ../rh-virtio.mak
+
+CONFIG_ACPI=y
@ -227,6 +282,7 @@ index 0000000000..45a8a15291
+CONFIG_PCSPK=y
+CONFIG_PC_ACPI=y
+CONFIG_PC_PCI=y
+CONFIG_PCI_BRIDGE=y
+CONFIG_PCIE_PCI_BRIDGE=y
+CONFIG_PFLASH_CFI01=y
+CONFIG_PVPANIC_ISA=y
@ -280,10 +336,10 @@ index 0000000000..45a8a15291
+CONFIG_IOMMUFD=y
+CONFIG_VHOST_USER_SND=y
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 687fe0bb8b..eea7d2d038 100644
index a96452f17a..68bb983ecf 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3032,6 +3032,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
@@ -3129,6 +3129,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[] = {
@ -291,7 +347,7 @@ index 687fe0bb8b..eea7d2d038 100644
#ifdef CONFIG_TCG
ARM_CPU_TYPE_NAME("cortex-a7"),
ARM_CPU_TYPE_NAME("cortex-a15"),
@@ -3047,8 +3048,11 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
@@ -3144,8 +3145,11 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
ARM_CPU_TYPE_NAME("neoverse-n2"),
#endif /* TARGET_AARCH64 */
#endif /* CONFIG_TCG */
@ -318,7 +374,7 @@ index 3e375f61a9..613adb3ebb 100644
if_false: files(
'cxl-host-stubs.c',
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 80efc633d3..9cb82b8eea 100644
index 818ff60d6f..2a1caca7f7 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -191,7 +191,8 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data)
@ -341,10 +397,10 @@ index 80efc633d3..9cb82b8eea 100644
static const TypeInfo piix4_ide_info = {
diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
index 74f10b640f..2e85ecf476 100644
index fa0c549eb9..9aa92c1f76 100644
--- a/hw/input/pckbd.c
+++ b/hw/input/pckbd.c
@@ -952,6 +952,8 @@ static void i8042_class_initfn(ObjectClass *klass, void *data)
@@ -950,6 +950,8 @@ static void i8042_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_kbd_isa;
adevc->build_dev_aml = i8042_build_aml;
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
@ -354,10 +410,10 @@ index 74f10b640f..2e85ecf476 100644
static const TypeInfo i8042_info = {
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 5012b96464..b435e54228 100644
index 3d0b227703..6b96be40ef 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1746,6 +1746,7 @@ static const E1000Info e1000_devices[] = {
@@ -1745,6 +1745,7 @@ static const E1000Info e1000_devices[] = {
.revision = 0x03,
.phy_id2 = E1000_PHY_ID2_8254xx_DEFAULT,
},
@ -365,7 +421,7 @@ index 5012b96464..b435e54228 100644
{
.name = "e1000-82544gc",
.device_id = E1000_DEV_ID_82544GC_COPPER,
@@ -1758,6 +1759,7 @@ static const E1000Info e1000_devices[] = {
@@ -1757,6 +1758,7 @@ static const E1000Info e1000_devices[] = {
.revision = 0x03,
.phy_id2 = E1000_PHY_ID2_8254xx_DEFAULT,
},
@ -374,10 +430,10 @@ index 5012b96464..b435e54228 100644
static void e1000_register_types(void)
diff --git a/hw/usb/meson.build b/hw/usb/meson.build
index d7de1003e3..1cdc0a1ba0 100644
index 17360a5b5a..3c4fdfc31d 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
@@ -53,7 +53,7 @@ system_ss.add(when: 'CONFIG_USB_SMARTCARD', if_true: files('dev-smartcard-reader
if cacard.found()
usbsmartcard_ss = ss.source_set()
usbsmartcard_ss.add(when: 'CONFIG_USB_SMARTCARD',
@ -387,10 +443,10 @@ index d7de1003e3..1cdc0a1ba0 100644
endif
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index 621fc65454..c38bdd6fa4 100644
index 164f6fd995..43f9c477da 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -20,7 +20,8 @@ if have_vhost
@@ -21,7 +21,8 @@ if have_vhost
system_virtio_ss.add(files('vhost-user-base.c'))
# MMIO Stubs
@ -400,7 +456,7 @@ index 621fc65454..c38bdd6fa4 100644
system_virtio_ss.add(when: 'CONFIG_VHOST_USER_GPIO', if_true: files('vhost-user-gpio.c'))
system_virtio_ss.add(when: 'CONFIG_VHOST_USER_I2C', if_true: files('vhost-user-i2c.c'))
system_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: files('vhost-user-rng.c'))
@@ -28,7 +29,8 @@ if have_vhost
@@ -29,7 +30,8 @@ if have_vhost
system_virtio_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: files('vhost-user-input.c'))
# PCI Stubs
@ -411,7 +467,7 @@ index 621fc65454..c38bdd6fa4 100644
if_true: files('vhost-user-gpio-pci.c'))
system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_I2C'],
diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
index 3cc8cc738b..6f21fea1f5 100644
index 883c0a0e8c..dc06eb6778 100644
--- a/target/arm/arm-qmp-cmds.c
+++ b/target/arm/arm-qmp-cmds.c
@@ -223,6 +223,7 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
@ -430,23 +486,8 @@ index 3cc8cc738b..6f21fea1f5 100644
QAPI_LIST_PREPEND(*cpu_list, info);
}
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 19191c2391..465f423d25 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -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";
+
+ if (acc->info->deprecation_note) {
+ cc->deprecation_note = acc->info->deprecation_note;
+ }
}
void arm_cpu_register(const ARMCPUInfo *info)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 9a3fd59562..1261eae94d 100644
index a8177c6c2e..6d1055a90c 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -35,6 +35,8 @@
@ -458,19 +499,11 @@ index 9a3fd59562..1261eae94d 100644
#define EXCP_UDEF 1 /* undefined instruction */
#define EXCP_SWI 2 /* software interrupt */
#define EXCP_PREFETCH_ABORT 3
@@ -1110,6 +1112,7 @@ typedef struct ARMCPUInfo {
const char *name;
void (*initfn)(Object *obj);
void (*class_init)(ObjectClass *oc, void *data);
+ const char *deprecation_note;
} ARMCPUInfo;
/**
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 262a1d6c0b..800514d3fc 100644
index 8188ede5cc..550232f362 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -653,6 +653,7 @@ static void aarch64_a57_initfn(Object *obj)
@@ -675,6 +675,7 @@ static void aarch64_a57_initfn(Object *obj)
define_cortex_a72_a57_a53_cp_reginfo(cpu);
}
@ -478,7 +511,7 @@ index 262a1d6c0b..800514d3fc 100644
static void aarch64_a53_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
@@ -710,6 +711,7 @@ static void aarch64_a53_initfn(Object *obj)
@@ -735,6 +736,7 @@ static void aarch64_a53_initfn(Object *obj)
cpu->gic_pribits = 5;
define_cortex_a72_a57_a53_cp_reginfo(cpu);
}
@ -486,7 +519,7 @@ index 262a1d6c0b..800514d3fc 100644
static void aarch64_host_initfn(Object *obj)
{
@@ -748,8 +750,11 @@ static void aarch64_max_initfn(Object *obj)
@@ -773,8 +775,11 @@ static void aarch64_max_initfn(Object *obj)
}
static const ARMCPUInfo aarch64_cpus[] = {
@ -499,7 +532,7 @@ index 262a1d6c0b..800514d3fc 100644
{ .name = "max", .initfn = aarch64_max_initfn },
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
{ .name = "host", .initfn = aarch64_host_initfn },
@@ -820,8 +825,13 @@ static void aarch64_cpu_instance_init(Object *obj)
@@ -845,8 +850,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);
@ -514,7 +547,7 @@ index 262a1d6c0b..800514d3fc 100644
void aarch64_cpu_register(const ARMCPUInfo *info)
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
index 20c2737f17..7e66fb6f14 100644
index 2c45b7eddd..09c5f3f74a 100644
--- a/target/arm/tcg/cpu32.c
+++ b/target/arm/tcg/cpu32.c
@@ -120,6 +120,7 @@ void aa32_max_features(ARMCPU *cpu)
@ -525,13 +558,13 @@ index 20c2737f17..7e66fb6f14 100644
/* CPU models. These are not needed for the AArch64 linux-user build. */
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
@@ -1066,3 +1067,4 @@ static void arm_tcg_cpu_register_types(void)
@@ -1078,3 +1079,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 fe232eb306..2678047488 100644
index 29ab0ac79d..be3baf5fba 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -29,6 +29,7 @@
@ -539,10 +572,10 @@ index fe232eb306..2678047488 100644
#include "cpregs.h"
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static uint64_t make_ccsidr64(unsigned assoc, unsigned linesize,
unsigned cachesize)
static void aarch64_a35_initfn(Object *obj)
{
@@ -135,6 +136,7 @@ static void aarch64_a35_initfn(Object *obj)
ARMCPU *cpu = ARM_CPU(obj);
@@ -112,6 +113,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);
}
@ -550,8 +583,8 @@ index fe232eb306..2678047488 100644
static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
@@ -224,6 +226,7 @@ static void cpu_max_get_l0gptsz(Object *obj, Visitor *v, const char *name,
static Property arm_cpu_lpa2_property =
@@ -201,6 +203,7 @@ static void cpu_max_get_l0gptsz(Object *obj, Visitor *v, const char *name,
static const Property arm_cpu_lpa2_property =
DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true);
+#if 0 /* Disabled for Red Hat Enterprise Linux */
@ -566,7 +599,7 @@ index fe232eb306..2678047488 100644
/*
* -cpu max: a CPU with as many features enabled as our emulation supports.
@@ -1295,6 +1299,7 @@ void aarch64_max_tcg_initfn(Object *obj)
@@ -1299,6 +1303,7 @@ void aarch64_max_tcg_initfn(Object *obj)
qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
}
@ -574,7 +607,7 @@ index fe232eb306..2678047488 100644
static const ARMCPUInfo aarch64_cpus[] = {
{ .name = "cortex-a35", .initfn = aarch64_a35_initfn },
{ .name = "cortex-a55", .initfn = aarch64_a55_initfn },
@@ -1306,14 +1311,17 @@ static const ARMCPUInfo aarch64_cpus[] = {
@@ -1310,14 +1315,17 @@ static const ARMCPUInfo aarch64_cpus[] = {
{ .name = "neoverse-v1", .initfn = aarch64_neoverse_v1_initfn },
{ .name = "neoverse-n2", .initfn = aarch64_neoverse_n2_initfn },
};
@ -593,10 +626,10 @@ index fe232eb306..2678047488 100644
type_init(aarch64_cpu_register_types)
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
index 508932a249..1293647501 100644
index dd12ccedb1..545c2cc3a7 100644
--- a/target/arm/tcg/meson.build
+++ b/target/arm/tcg/meson.build
@@ -58,5 +58,5 @@ arm_system_ss.add(files(
@@ -61,5 +61,5 @@ arm_system_ss.add(files(
'psci.c',
))
@ -604,10 +637,10 @@ index 508932a249..1293647501 100644
+#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/i386/cpu.c b/target/i386/cpu.c
index 85ef7452c0..34e0ce5e62 100644
index 1b64ceaaba..0b09990a8f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2411,9 +2411,13 @@ static const CPUCaches epyc_genoa_cache_info = {
@@ -2481,9 +2481,13 @@ static const CPUCaches epyc_genoa_cache_info = {
* PT in VMX operation
*/
@ -621,7 +654,7 @@ index 85ef7452c0..34e0ce5e62 100644
.level = 0xd,
.vendor = CPUID_VENDOR_AMD,
.family = 15,
@@ -2432,6 +2436,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
@@ -2502,6 +2506,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x8000000A,
.model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
},
@ -629,7 +662,7 @@ index 85ef7452c0..34e0ce5e62 100644
{
.name = "phenom",
.level = 5,
@@ -2796,8 +2801,10 @@ static const X86CPUDefinition builtin_x86_defs[] = {
@@ -2866,8 +2871,10 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
},
@ -640,7 +673,7 @@ index 85ef7452c0..34e0ce5e62 100644
.level = 11,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2875,6 +2882,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
@@ -2945,6 +2952,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Westmere",
@ -648,7 +681,7 @@ index 85ef7452c0..34e0ce5e62 100644
.level = 11,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2956,6 +2964,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
@@ -3026,6 +3034,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "SandyBridge",
@ -656,7 +689,7 @@ index 85ef7452c0..34e0ce5e62 100644
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -3042,6 +3051,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
@@ -3112,6 +3121,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "IvyBridge",
@ -664,7 +697,7 @@ index 85ef7452c0..34e0ce5e62 100644
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -4469,6 +4479,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
@@ -4711,6 +4721,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Denverton",
@ -672,7 +705,7 @@ index 85ef7452c0..34e0ce5e62 100644
.level = 21,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -4579,6 +4590,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
@@ -4821,6 +4832,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Snowridge",
@ -680,34 +713,15 @@ index 85ef7452c0..34e0ce5e62 100644
.level = 27,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -4760,8 +4772,10 @@ static const X86CPUDefinition builtin_x86_defs[] = {
@@ -5002,6 +5014,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,
.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[] = {
@@ -5069,8 +5082,10 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
},
@ -718,7 +732,7 @@ index 85ef7452c0..34e0ce5e62 100644
.level = 0xd,
.vendor = CPUID_VENDOR_AMD,
.family = 21,
@@ -4861,6 +4879,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
@@ -5103,6 +5118,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Opteron_G5",
@ -726,8 +740,76 @@ index 85ef7452c0..34e0ce5e62 100644
.level = 0xd,
.vendor = CPUID_VENDOR_AMD,
.family = 21,
@@ -5498,6 +5514,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.model_id = "AMD EPYC-Genoa Processor",
.cache_info = &epyc_genoa_cache_info,
},
+#if 0 // Disabled for Red Hat Enterprise Linux
{
.name = "YongFeng",
.level = 0x1F,
@@ -5622,6 +5639,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Zhaoxin YongFeng Processor",
},
+#endif
};
/*
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 09ded6829a..1893ad2f0d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -481,6 +481,7 @@ static void riscv_max_cpu_init(Object *obj)
#endif
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
#if defined(TARGET_RISCV64)
static void rv64_base_cpu_init(Object *obj)
{
@@ -831,6 +832,7 @@ static void rv32e_bare_cpu_init(Object *obj)
riscv_cpu_set_misa_ext(env, RVE);
}
#endif
+#endif /* disabled for RHEL */
static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
{
@@ -2970,6 +2972,7 @@ static const Property riscv_cpu_properties[] = {
DEFINE_PROP_BOOL("x-misa-w", RISCVCPU, cfg.misa_w, false),
};
+#if 0 /* Disabled for Red Hat Enterprise Linux */
#if defined(TARGET_RISCV64)
static void rva22u64_profile_cpu_init(Object *obj)
{
@@ -2999,6 +3002,7 @@ static void rva23s64_profile_cpu_init(Object *obj)
RVA23S64.enabled = true;
}
#endif
+#endif /* disabled for RHEL */
static const gchar *riscv_gdb_arch_name(CPUState *cs)
{
@@ -3236,6 +3240,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX, MXL_RV64, riscv_max_cpu_init),
#endif
+#if 0 /* Disabled for Red Hat Enterprise Linux */
#if defined(TARGET_RISCV32) || \
(defined(TARGET_RISCV64) && !defined(CONFIG_USER_ONLY))
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE32, MXL_RV32, rv32_base_cpu_init),
@@ -3271,6 +3276,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA23U64, MXL_RV64, rva23u64_profile_cpu_init),
DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA23S64, MXL_RV64, rva23s64_profile_cpu_init),
#endif /* TARGET_RISCV64 */
+#endif /* disabled for RHEL */
};
DEFINE_TYPES(riscv_cpu_type_infos)
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index a27f4b6f79..798c18f940 100644
index 93a05e43d7..111d46a59a 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -72,7 +72,6 @@ static S390CPUDef s390_cpu_defs[] = {
@ -747,10 +829,10 @@ index a27f4b6f79..798c18f940 100644
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 cfd6f77353..3016e6233c 100644
index eb8ddebffb..2d3304bb4a 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)
@@ -459,8 +459,10 @@ static void test_query_cpu_model_expansion(const void *data)
assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL);
/* Test expected feature presence/absence for some cpu types */
@ -761,7 +843,7 @@ index cfd6f77353..3016e6233c 100644
/* Enabling and disabling pmu should always work. */
assert_has_feature_enabled(qts, "max", "pmu");
@@ -470,6 +472,7 @@ static void test_query_cpu_model_expansion(const void *data)
@@ -477,6 +479,7 @@ static void test_query_cpu_model_expansion(const void *data)
assert_has_feature_enabled(qts, "cortex-a57", "pmu");
assert_has_feature_enabled(qts, "cortex-a57", "aarch64");
@ -769,7 +851,7 @@ index cfd6f77353..3016e6233c 100644
assert_has_feature_enabled(qts, "a64fx", "pmu");
assert_has_feature_enabled(qts, "a64fx", "aarch64");
/*
@@ -482,6 +485,7 @@ static void test_query_cpu_model_expansion(const void *data)
@@ -489,6 +492,7 @@ static void test_query_cpu_model_expansion(const void *data)
"{ 'sve384': true }");
assert_error(qts, "a64fx", "cannot enable sve640",
"{ 'sve640': true }");

View File

@ -1,4 +1,4 @@
From 18ae40658bedd6dceab0ffe0bce77ba48e6f0fae Mon Sep 17 00:00:00 2001
From db31addfd949b587e937dc39137fc93aa9596990 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
@ -10,30 +10,43 @@ architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase notes (9.1.0 rc0):
Rebase notes (9.1.0):
- Upstream removed uuid_encoced argument on smbios_set_defaults
Merged commits (9.1.0 rc0):
Rebase notes (10.0.0 rc0):
- Solve conflicting xhci_pci_properties (downstream vs upstream)
Rebase notes (10.0.0):
- Add riscv changes
- Added upstream compat changes
Merged commits (9.1.0):
- 043ad5ce97 Add upstream compatibility bits (partial)
- bfbdab5824 rhel 9.4.0 machine type compat for virtio-gpu migration
Merged commits (10.0.0 rc0):
- 03502faf70 Add upstream compatibility bits (partial)
- f53dbf7532 remove stale compat definitions (partial)
- d93fcb3940 virtio-net: disable USO for all RHEL9 (partial)
---
hw/acpi/piix4.c | 2 +-
hw/arm/virt.c | 3 +-
hw/core/machine.c | 281 +++++++++++++++++++++++++++++++++++
hw/core/machine.c | 133 +++++++++++++++++++++++++++++++++++
hw/i386/fw_cfg.c | 3 +-
hw/net/rtl8139.c | 4 +-
hw/smbios/smbios.c | 46 +++++-
hw/riscv/virt.c | 4 +-
hw/smbios/smbios.c | 46 +++++++++++-
hw/timer/i8254_common.c | 2 +-
hw/usb/hcd-xhci-pci.c | 59 ++++++--
hw/usb/hcd-xhci-pci.c | 55 +++++++++++----
hw/usb/hcd-xhci-pci.h | 1 +
hw/virtio/virtio-mem.c | 3 +-
include/hw/boards.h | 43 ++++++
include/hw/boards.h | 28 ++++++++
include/hw/firmware/smbios.h | 4 +-
include/hw/i386/pc.h | 3 +
13 files changed, 430 insertions(+), 24 deletions(-)
14 files changed, 265 insertions(+), 26 deletions(-)
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index debe1adb84..e8ddcd716e 100644
index 6d023e595b..8b8aa6b3aa 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -245,7 +245,7 @@ static bool vmstate_test_migrate_acpi_index(void *opaque, int version_id)
@ -46,10 +59,10 @@ 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 eea7d2d038..b2aa3f1355 100644
index 68bb983ecf..904596ae3b 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1699,7 +1699,8 @@ static void virt_build_smbios(VirtMachineState *vms)
@@ -1715,7 +1715,8 @@ static void virt_build_smbios(VirtMachineState *vms)
}
smbios_set_defaults("QEMU", product,
@ -60,12 +73,12 @@ index eea7d2d038..b2aa3f1355 100644
/* 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 27dcda0248..f7fed78e4b 100644
index 63c6ef93d2..c219ae589c 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -305,6 +305,287 @@ GlobalProperty hw_compat_2_1[] = {
@@ -298,6 +298,139 @@ GlobalProperty hw_compat_2_4[] = {
};
const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
const size_t hw_compat_2_4_len = G_N_ELEMENTS(hw_compat_2_4);
+/*
+ * RHEL only: machine types for previous major releases are deprecated
@ -73,6 +86,54 @@ index 27dcda0248..f7fed78e4b 100644
+const char *rhel_old_machine_deprecation =
+ "machine types for previous major releases are deprecated";
+
+GlobalProperty hw_compat_rhel_10_1[] = {
+ /* hw_compat_rhel_10_1 from hw_compat_9_1 */
+ { TYPE_PCI_DEVICE, "x-pcie-ext-tag", "false" },
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
+ {"arm-cpu", "backcompat-pauth-default-use-qarma5", "true"},
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
+ { "virtio-balloon-pci", "vectors", "0" },
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
+ { "virtio-balloon-pci-transitional", "vectors", "0" },
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
+ { "virtio-balloon-pci-non-transitional", "vectors", "0" },
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
+ { "virtio-mem-pci", "vectors", "0" },
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
+ { "migration", "multifd-clean-tls-termination", "false" },
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
+ { "migration", "send-switchover-start", "off"},
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
+ { "vfio-pci", "x-migration-multifd-transfer", "off" },
+};
+const size_t hw_compat_rhel_10_1_len = G_N_ELEMENTS(hw_compat_rhel_10_1);
+
+
+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);
+
+/* Apply this to all RHEL9 boards going backward and forward */
+GlobalProperty hw_compat_rhel_9[] = {
+ /* supported by userspace, but RHEL 9 *kernels* do not support USO. */
+ { TYPE_VIRTIO_NET, "host_uso", "off"},
+ { TYPE_VIRTIO_NET, "guest_uso4", "off"},
+ { TYPE_VIRTIO_NET, "guest_uso6", "off"},
+};
+const size_t hw_compat_rhel_9_len = G_N_ELEMENTS(hw_compat_rhel_9);
+
+GlobalProperty hw_compat_rhel_9_5[] = {
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { "migration", "zero-page-detection", "legacy"},
@ -151,211 +212,15 @@ index 27dcda0248..f7fed78e4b 100644
+ { "PIIX4_PM", "x-not-migrate-acpi-index", "on"},
+};
+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/fw_cfg.c b/hw/i386/fw_cfg.c
index 0e4494627c..33ef280420 100644
index 5c0bcd5f8a..07df7281d2 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -73,7 +73,8 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
@@ -75,7 +75,8 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
if (pcmc->smbios_defaults) {
/* These values are guest ABI, do not change */
@ -366,10 +231,10 @@ index 0e4494627c..33ef280420 100644
/* tell smbios about cpuid version and features */
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 03a204ef8a..f2fe057535 100644
index 135ab57160..6c57a8985b 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -3173,7 +3173,7 @@ static int rtl8139_pre_save(void *opaque)
@@ -3171,7 +3171,7 @@ static int rtl8139_pre_save(void *opaque)
static const VMStateDescription vmstate_rtl8139 = {
.name = "rtl8139",
@ -378,7 +243,7 @@ index 03a204ef8a..f2fe057535 100644
.minimum_version_id = 3,
.post_load = rtl8139_post_load,
.pre_save = rtl8139_pre_save,
@@ -3254,7 +3254,9 @@ static const VMStateDescription vmstate_rtl8139 = {
@@ -3252,7 +3252,9 @@ static const VMStateDescription vmstate_rtl8139 = {
VMSTATE_UINT32(tally_counters.TxMCol, RTL8139State),
VMSTATE_UINT64(tally_counters.RxOkPhy, RTL8139State),
VMSTATE_UINT64(tally_counters.RxOkBrd, RTL8139State),
@ -388,8 +253,30 @@ index 03a204ef8a..f2fe057535 100644
VMSTATE_UINT16(tally_counters.TxAbt, RTL8139State),
VMSTATE_UINT16(tally_counters.TxUndrn, RTL8139State),
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index e517002fdf..b8d20575af 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1400,7 +1400,7 @@ static void virt_build_smbios(RISCVVirtState *s)
product = "KVM Virtual Machine";
}
- smbios_set_defaults("QEMU", product, mc->name);
+ smbios_set_defaults("QEMU", product, mc->name, NULL, NULL);
if (riscv_is_32bit(&s->soc[0])) {
smbios_set_default_processor_family(0x200);
@@ -1919,7 +1919,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->desc = "RISC-V VirtIO board";
mc->init = virt_machine_init;
mc->max_cpus = VIRT_CPUS_MAX;
- mc->default_cpu_type = TYPE_RISCV_CPU_BASE;
+ mc->default_cpu_type = TYPE_RISCV_CPU_MAX;
mc->block_default_type = IF_VIRTIO;
mc->no_cdrom = 1;
mc->pci_allow_0_address = true;
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index a394514264..88642ccce0 100644
index ad4cd6721e..813b9b43ec 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -38,6 +38,10 @@ size_t usr_blobs_len;
@ -467,7 +354,7 @@ index a394514264..88642ccce0 100644
SMBIOS_SET_DEFAULT(type3.manufacturer, manufacturer);
SMBIOS_SET_DEFAULT(type3.version, version);
diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c
index 28fdabc321..bad13ec224 100644
index 29105afcc3..cef91c9a79 100644
--- a/hw/timer/i8254_common.c
+++ b/hw/timer/i8254_common.c
@@ -229,7 +229,7 @@ static const VMStateDescription vmstate_pit_common = {
@ -480,10 +367,10 @@ 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 264d7ebb77..2b9a3e06d4 100644
index d908eb787d..401a2734ed 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)
@@ -120,6 +120,33 @@ static int xhci_pci_vmstate_post_load(void *opaque, int version_id)
return 0;
}
@ -517,7 +404,7 @@ index 264d7ebb77..2b9a3e06d4 100644
static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
{
int ret;
@@ -125,23 +152,12 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
@@ -144,23 +171,12 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
s->xhci.nec_quirks = true;
}
@ -544,7 +431,7 @@ index 264d7ebb77..2b9a3e06d4 100644
}
pci_register_bar(dev, 0,
PCI_BASE_ADDRESS_SPACE_MEMORY |
@@ -153,6 +169,14 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
@@ -172,6 +188,14 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
assert(ret > 0);
}
@ -559,42 +446,35 @@ index 264d7ebb77..2b9a3e06d4 100644
if (s->msix != ON_OFF_AUTO_OFF) {
/* TODO check for errors, and should fail when msix=on */
msix_init(dev, s->xhci.numintrs,
@@ -197,11 +221,18 @@ static void xhci_instance_init(Object *obj)
qdev_alias_all_properties(DEVICE(&s->xhci), obj);
}
+static Property xhci_pci_properties[] = {
@@ -221,8 +245,11 @@ static const Property xhci_pci_properties[] = {
DEFINE_PROP_ON_OFF_AUTO("msix", XHCIPciState, msix, ON_OFF_AUTO_AUTO),
DEFINE_PROP_BOOL("conditional-intr-mapping", XHCIPciState,
conditional_intr_mapping, false),
+ /* RH bz 1912846 */
+ DEFINE_PROP_BOOL("x-rh-late-msi-cap", XHCIPciState, rh_late_msi_cap, true),
+ DEFINE_PROP_END_OF_LIST()
+};
};
+
static void xhci_class_init(ObjectClass *klass, void *data)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
+ device_class_set_props(dc, xhci_pci_properties);
dc->reset = xhci_pci_reset;
dc->vmsd = &vmstate_xhci_pci;
set_bit(DEVICE_CATEGORY_USB, dc->categories);
diff --git a/hw/usb/hcd-xhci-pci.h b/hw/usb/hcd-xhci-pci.h
index 08f70ce97c..1be7527c1b 100644
index 5b61ae8455..3170db064b 100644
--- a/hw/usb/hcd-xhci-pci.h
+++ b/hw/usb/hcd-xhci-pci.h
@@ -40,6 +40,7 @@ typedef struct XHCIPciState {
XHCIState xhci;
@@ -41,6 +41,7 @@ typedef struct XHCIPciState {
OnOffAuto msi;
OnOffAuto msix;
bool conditional_intr_mapping;
+ bool rh_late_msi_cap; /* bz 1912846 */
} XHCIPciState;
#endif
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index ef64bf1b4a..ba11aa4646 100644
index 5f57eccbb6..391d85c652 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -1694,8 +1694,9 @@ static Property virtio_mem_properties[] = {
@@ -1717,8 +1717,9 @@ static const Property virtio_mem_properties[] = {
#endif
DEFINE_PROP_BOOL(VIRTIO_MEM_EARLY_MIGRATION_PROP, VirtIOMEM,
early_migration, true),
@ -602,17 +482,26 @@ index ef64bf1b4a..ba11aa4646 100644
DEFINE_PROP_BOOL(VIRTIO_MEM_DYNAMIC_MEMSLOTS_PROP, VirtIOMEM,
- dynamic_memslots, false),
+ dynamic_memslots, true),
DEFINE_PROP_END_OF_LIST(),
};
static uint64_t virtio_mem_rdm_get_min_granularity(const RamDiscardManager *rdm,
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 48ff6d8b93..ccfc3e10eb 100644
index f22b2e7fc7..d7fa968dca 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -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;
@@ -848,4 +848,32 @@ extern const size_t hw_compat_2_5_len;
extern GlobalProperty hw_compat_2_4[];
extern const size_t hw_compat_2_4_len;
+extern GlobalProperty hw_compat_rhel_10_1[];
+extern const size_t hw_compat_rhel_10_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[];
+extern const size_t hw_compat_rhel_9_len;
+
+extern GlobalProperty hw_compat_rhel_9_5[];
+extern const size_t hw_compat_rhel_9_5_len;
+
@ -631,30 +520,6 @@ index 48ff6d8b93..ccfc3e10eb 100644
+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/firmware/smbios.h b/include/hw/firmware/smbios.h
@ -673,7 +538,7 @@ index f066ab7262..e805d25fbe 100644
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 4e55d7ef6e..8776a3c937 100644
index 103b54301f..e4d32f8aea 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -103,6 +103,9 @@ struct PCMachineClass {

View File

@ -1,4 +1,4 @@
From 16946c2c7be0ae23dc1f267323cfc7630a1c9e87 Mon Sep 17 00:00:00 2001
From 6871c5dd1655c578d9605015b2f88cba38715767 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
@ -13,17 +13,17 @@ fine grained patch splits.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Rebase notes (9.1.0 rc0)
Rebase notes (9.1.0)
- New patch
---
meson.build | 1 +
1 file changed, 1 insertion(+)
diff --git a/meson.build b/meson.build
index fbda17c987..161d496d55 100644
index 41f68d3806..066ca7a2c9 100644
--- a/meson.build
+++ b/meson.build
@@ -651,6 +651,7 @@ warn_flags = [
@@ -747,6 +747,7 @@ warn_flags = [
'-Wno-string-plus-int',
'-Wno-tautological-type-limit-compare',
'-Wno-typedef-redefinition',

View File

@ -1,4 +1,4 @@
From 2f0ba1a1ed66a8ae32e7a92f3d3b744d8b59b879 Mon Sep 17 00:00:00 2001
From af51df70a29fec7ae9e8bb64006dab26487c1a35 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
@ -13,7 +13,7 @@ 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):
Rebase notes (9.1.0):
- Split off commits adding RHEL machine types
---
hw/arm/virt.c | 2 ++
@ -23,35 +23,35 @@ Rebase notes (9.1.0 rc0):
4 files changed, 8 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index b2aa3f1355..5396e7cb24 100644
index 904596ae3b..6d5ea31e46 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3306,6 +3306,7 @@ static void machvirt_machine_init(void)
@@ -3413,6 +3413,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)
static void virt_machine_10_0_options(MachineClass *mc)
{
}
@@ -3552,3 +3553,4 @@ static void virt_machine_2_6_options(MachineClass *mc)
@@ -3677,3 +3678,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
index 6c91e2d292..1b58988c9a 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);
@@ -452,6 +452,7 @@ static void pc_i440fx_init(MachineState *machine)
#define DEFINE_I440FX_MACHINE_AS_LATEST(major, minor) \
DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, true, "pc", 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)
@@ -794,6 +795,7 @@ static void pc_i440fx_machine_2_4_options(MachineClass *m)
}
DEFINE_I440FX_MACHINE(2, 4);
@ -60,36 +60,36 @@ index 347afa4c37..67107b174a 100644
#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
index fd96d0345c..97a40a3a9c 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)
@@ -361,6 +361,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)
static void pc_q35_machine_10_0_options(MachineClass *m)
{
pc_q35_machine_options(m);
@@ -668,3 +669,4 @@ static void pc_q35_machine_2_4_options(MachineClass *m)
@@ -689,3 +690,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
index 75b32182eb..5aa5910399 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 = {
@@ -921,6 +921,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)
static void ccw_machine_10_0_instance_options(MachineState *machine)
{
}
@@ -1305,6 +1306,7 @@ static void ccw_machine_2_4_class_options(MachineClass *mc)
DEFINE_CCW_MACHINE(2, 4);
@@ -1295,6 +1296,7 @@ static void ccw_machine_2_9_class_options(MachineClass *mc)
DEFINE_CCW_MACHINE(2, 9);
#endif
+#endif /* disabled for RHEL */

View File

@ -1,4 +1,4 @@
From ccb1eaa95ce9c92a196fe034c033502f582a324b Mon Sep 17 00:00:00 2001
From d74a60788160bf1cefe391430bb7ef2f2bd0d29c 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
@ -31,10 +31,10 @@ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
8 files changed, 30 insertions(+), 42 deletions(-)
diff --git a/include/hw/boards.h b/include/hw/boards.h
index ccfc3e10eb..7f7eb4ec40 100644
index d7fa968dca..1f6bba7d64 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -548,16 +548,16 @@ struct MachineState {
@@ -577,16 +577,16 @@ struct MachineState {
* "{prefix}-{major}.{minor}.{micro}-{tag}"
*/
#define _MACHINE_VER_TYPE_NAME2(prefix, major, minor) \
@ -55,7 +55,7 @@ index ccfc3e10eb..7f7eb4ec40 100644
#define MACHINE_VER_TYPE_NAME(prefix, ...) \
_MACHINE_VER_PICK(__VA_ARGS__, \
@@ -585,16 +585,16 @@ struct MachineState {
@@ -614,16 +614,16 @@ struct MachineState {
* {prefix}_machine_{major}_{minor}_{micro}_{tag}_{sym}
*/
#define _MACHINE_VER_SYM2(sym, prefix, major, minor) \
@ -76,7 +76,7 @@ index ccfc3e10eb..7f7eb4ec40 100644
#define MACHINE_VER_SYM(sym, prefix, ...) \
_MACHINE_VER_PICK(__VA_ARGS__, \
@@ -605,26 +605,22 @@ struct MachineState {
@@ -634,26 +634,22 @@ struct MachineState {
/*
@ -110,7 +110,7 @@ index ccfc3e10eb..7f7eb4ec40 100644
#define _MACHINE_VER_IS_EXPIRED2(cutoff, major, minor) \
_MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor)
@@ -686,32 +682,14 @@ struct MachineState {
@@ -715,32 +711,14 @@ struct MachineState {
* This must be unconditionally used in the register
* method for all machine types which support versioning.
*
@ -148,10 +148,10 @@ index ccfc3e10eb..7f7eb4ec40 100644
} while (0)
diff --git a/meson.build b/meson.build
index 161d496d55..2de5ab024f 100644
index 066ca7a2c9..38ad60fc10 100644
--- a/meson.build
+++ b/meson.build
@@ -2440,6 +2440,7 @@ config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
@@ -2594,6 +2594,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])
@ -160,7 +160,7 @@ index 161d496d55..2de5ab024f 100644
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
index 59d973bca0..ad6996178c 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -2,6 +2,8 @@
@ -173,25 +173,25 @@ index 0269fa0f16..aa2ba0baef 100644
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
index 3e8e00852b..e9edc8a919 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'
@@ -75,6 +75,7 @@ meson_options_help() {
printf "%s\n" ' [QEMU]'
printf "%s\n" ' --qemu-ga-version=VALUE version number for qemu-ga installer'
printf "%s\n" ' --rtsig-map=VALUE default value of QEMU_RTSIG_MAP [NULL]'
+ 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() {
@@ -464,6 +465,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 ;;
--rtsig-map=*) quote_sh "-Drtsig_map=$2" ;;
--
2.39.3

View File

@ -1,4 +1,4 @@
From 551632921a8330cff09e7d92429aa45cf51c75e6 Mon Sep 17 00:00:00 2001
From 4d25fc36b02293e78f93ce3512fe485d799fa8f5 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
@ -13,17 +13,17 @@ machine type.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Rebase notes (9.1.0 rc0)
Rebase notes (9.1.0)
- 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
index 1f6bba7d64..182c11dc2c 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -608,7 +608,7 @@ struct MachineState {
@@ -637,7 +637,7 @@ struct MachineState {
* How many RHEL major releases for each phase
* of the life cycle.
*/

View File

@ -1,4 +1,4 @@
From 6cb1d3cf4ac08fe8c435e98500224a022d019e55 Mon Sep 17 00:00:00 2001
From 9da015b8759b082330459277058c014e71bff62b 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
@ -7,32 +7,53 @@ Adding changes to add RHEL machine types for aarch64 architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase notes (9.1.0 rc0):
Rebase notes (9.1.0):
- 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):
Rebase notes (10.0.0)
- Removed unwanted sysbus dev
- Set no_nested_smmu
- Use upstream compat
Merged patches (9.1.0):
- 043ad5ce97 Add upstream compatibility bits (partial)
Merged patches (10.0.0 rc0):
- 03502faf70 Add upstream compatibility bits
- 17c3bccf2f arm: ensure compatibility of virt-rhel9*
- 12e5b038be arm: create new virt machine type for rhel 9.6
- fb1bc2766e arm: create virt machine type for rhel10
- 727307e5ed hw/arm/virt: Fix Manufacturer and Product Name in emulated SMBIOS mode
- d93fcb3940 virtio-net: disable USO for all RHEL9 (partial)
- 0440f3d003 arm: disable pauth for virt-rhel9* in RHEL10
---
hw/arm/virt.c | 101 ++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 81 insertions(+), 20 deletions(-)
hw/arm/virt.c | 152 ++++++++++++++++++++++++++++++++++++------
include/hw/arm/virt.h | 1 +
2 files changed, 134 insertions(+), 19 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 5396e7cb24..903c0f2e9f 100644
index 6d5ea31e46..12bf754b6a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -90,6 +90,22 @@ static GlobalProperty arm_virt_compat[] = {
@@ -93,6 +93,32 @@ static GlobalProperty arm_virt_compat[] = {
};
static const size_t arm_virt_compat_len = G_N_ELEMENTS(arm_virt_compat);
+/*
+ * RHEL9 kernels have pauth disabled while RHEL10 has it enabled,
+ * since qemu will setup the VM with pauth when KVM supports it we
+ * have to disable it for virt-rhel9* to support upgrades / migration.
+ */
+GlobalProperty arm_rhel9_compat[] = {
+ {TYPE_ARM_CPU, "pauth", "off", .optional = true},
+};
+const size_t arm_rhel9_compat_len = G_N_ELEMENTS(arm_rhel9_compat);
+
+/*
+ * This variable is for changes to properties that are RHEL specific,
+ * different to the current upstream and to be applied to the latest
@ -52,7 +73,7 @@ index 5396e7cb24..903c0f2e9f 100644
/*
* 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)
@@ -102,6 +128,8 @@ static void arm_virt_compat_set(MachineClass *mc)
{
compat_props_add(mc->compat_props, arm_virt_compat,
arm_virt_compat_len);
@ -61,7 +82,7 @@ index 5396e7cb24..903c0f2e9f 100644
}
#define DEFINE_VIRT_MACHINE_IMPL(latest, ...) \
@@ -109,10 +127,11 @@ static void arm_virt_compat_set(MachineClass *mc)
@@ -112,10 +140,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); \
@ -74,7 +95,7 @@ index 5396e7cb24..903c0f2e9f 100644
} \
} \
static const TypeInfo MACHINE_VER_SYM(info, virt, __VA_ARGS__) = \
@@ -128,10 +147,10 @@ static void arm_virt_compat_set(MachineClass *mc)
@@ -131,10 +160,10 @@ static void arm_virt_compat_set(MachineClass *mc)
} \
type_init(MACHINE_VER_SYM(register, virt, __VA_ARGS__));
@ -89,7 +110,31 @@ index 5396e7cb24..903c0f2e9f 100644
/* Number of external interrupt lines to configure the GIC with */
@@ -2434,6 +2453,7 @@ static void machvirt_init(MachineState *machine)
@@ -1708,14 +1737,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 */
@@ -2464,6 +2500,7 @@ static void machvirt_init(MachineState *machine)
qemu_add_machine_init_done_notifier(&vms->machine_done);
}
@ -97,7 +142,7 @@ index 5396e7cb24..903c0f2e9f 100644
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)
@@ -2491,6 +2528,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp)
vms->virt = value;
}
@ -105,7 +150,7 @@ index 5396e7cb24..903c0f2e9f 100644
static bool virt_get_highmem(Object *obj, Error **errp)
{
@@ -2476,6 +2497,7 @@ static void virt_set_highmem(Object *obj, bool value, Error **errp)
@@ -2506,6 +2544,7 @@ static void virt_set_highmem(Object *obj, bool value, Error **errp)
vms->highmem = value;
}
@ -113,7 +158,7 @@ index 5396e7cb24..903c0f2e9f 100644
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)
@@ -2519,6 +2558,7 @@ static void virt_set_compact_highmem(Object *obj, bool value, Error **errp)
vms->highmem_compact = value;
}
@ -121,7 +166,7 @@ index 5396e7cb24..903c0f2e9f 100644
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)
@@ -2611,6 +2651,7 @@ static void virt_set_its(Object *obj, bool value, Error **errp)
vms->its = value;
}
@ -129,7 +174,7 @@ index 5396e7cb24..903c0f2e9f 100644
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)
@@ -2624,6 +2665,7 @@ static void virt_set_dtb_randomness(Object *obj, bool value, Error **errp)
vms->dtb_randomness = value;
}
@ -137,7 +182,7 @@ index 5396e7cb24..903c0f2e9f 100644
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)
@@ -2707,6 +2749,7 @@ static void virt_set_ras(Object *obj, bool value, Error **errp)
vms->ras = value;
}
@ -145,7 +190,7 @@ index 5396e7cb24..903c0f2e9f 100644
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)
@@ -2720,6 +2763,7 @@ static void virt_set_mte(Object *obj, bool value, Error **errp)
vms->mte = value;
}
@ -153,7 +198,7 @@ index 5396e7cb24..903c0f2e9f 100644
static char *virt_get_gic_version(Object *obj, Error **errp)
{
@@ -3063,16 +3090,10 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
@@ -3160,16 +3204,16 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
NULL
};
@ -164,16 +209,19 @@ index 5396e7cb24..903c0f2e9f 100644
- * 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;
+#if 0 /* Disabled for Red Hat Enterprise Linux */
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);
+#endif
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_UEFI_VARS_SYSBUS);
#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)
@@ -3181,11 +3225,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;
@ -186,7 +234,7 @@ index 5396e7cb24..903c0f2e9f 100644
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)
@@ -3210,6 +3250,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
NULL, NULL);
object_class_property_set_description(oc, "acpi",
"Enable ACPI");
@ -194,7 +242,7 @@ index 5396e7cb24..903c0f2e9f 100644
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)
@@ -3222,6 +3263,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");
@ -202,7 +250,7 @@ index 5396e7cb24..903c0f2e9f 100644
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)
@@ -3229,12 +3271,14 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
"Set on/off to enable/disable using "
"physical address space above 32 bits");
@ -217,7 +265,7 @@ index 5396e7cb24..903c0f2e9f 100644
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)
@@ -3270,7 +3314,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. "
@ -226,7 +274,7 @@ index 5396e7cb24..903c0f2e9f 100644
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)
@@ -3290,11 +3334,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");
@ -240,7 +288,7 @@ index 5396e7cb24..903c0f2e9f 100644
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)
@@ -3302,6 +3348,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
"Set on/off to enable/disable "
"ITS instantiation");
@ -248,7 +296,7 @@ index 5396e7cb24..903c0f2e9f 100644
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)
@@ -3314,6 +3361,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");
@ -256,16 +304,46 @@ index 5396e7cb24..903c0f2e9f 100644
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)
@@ -3679,3 +3727,69 @@ 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)
+{
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
+
+ /* QEMU 9.1 and earlier have only a stage-1 SMMU, not a nested s1+2 one */
+ vmc->no_nested_smmu = true;
+ compat_props_add(mc->compat_props, hw_compat_rhel_10_1, hw_compat_rhel_10_1_len);
+}
+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);
+
+ compat_props_add(mc->compat_props, arm_rhel9_compat, arm_rhel9_compat_len);
+ /* NB: remember to move this line to the *latest* RHEL 9 machine */
+ compat_props_add(mc->compat_props, hw_compat_rhel_9, hw_compat_rhel_9_len);
+}
+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() */
+ 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);
+
+ vmc->manufacturer_product_compat = true;
+}
+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)
+{
@ -296,6 +374,18 @@ index 5396e7cb24..903c0f2e9f 100644
+ vmc->no_highmem_compact = true;
+}
+DEFINE_VIRT_MACHINE(9, 0, 0)
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index c8e94e6aed..26cfdf1d41 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -135,6 +135,7 @@ struct VirtMachineClass {
bool no_tcg_lpa2;
bool no_ns_el2_virt_timer_irq;
bool no_nested_smmu;
+ bool manufacturer_product_compat;
};
struct VirtMachineState {
--
2.39.3

View File

@ -1,4 +1,4 @@
From 24d6b22e10c87e9a4bf4df834738f42caa1d5014 Mon Sep 17 00:00:00 2001
From 68460abb11ff9a65c7e9d988609954c2845d32e4 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
@ -7,24 +7,34 @@ Adding changes to add RHEL machine types for s390x architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
--
Rebase notes(9.1.0 rc0):
Rebase notes(9.1.0):
- Convert to new DEFINE_CCW_MACHINE macros
Merged patches (9.1.0 rc0):
Rebase notes (10.0.0):
- Use upstream compat
- Disabled relaxed-translation for older types
Merged patches (9.1.0):
- 043ad5ce97 Add upstream compatibility bits (partial)
- 04596b496e s390x: remove deprecated rhel machine types
Merged patches (10.0.0 rc0):
- 03502faf70 Add upstream compatibility bits (partial)
- d27437e5ba redhat: Add QEMU 9.1 compat handling to the s390x machine types
- 926a9d0ca2 redhat: Add rhel9.6.0 and rhel10.0.0 machine types
- d93fcb3940 virtio-net: disable USO for all RHEL9 (partial)
---
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(-)
hw/s390x/s390-virtio-ccw.c | 103 +++++++++++++++++++++++++++++--
target/s390x/cpu_models.c | 11 ++++
target/s390x/cpu_models.h | 2 +
target/s390x/cpu_models_system.c | 2 +
4 files changed, 113 insertions(+), 5 deletions(-)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 86bfc9d2eb..451017c50e 100644
index 5aa5910399..59b545740e 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)
@@ -696,6 +696,7 @@ static void s390_nmi(NMIState *n, int cpu_index, Error **errp)
s390_cpu_restart(S390_CPU(cs));
}
@ -32,7 +42,7 @@ index 86bfc9d2eb..451017c50e 100644
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)
@@ -715,6 +716,7 @@ static ram_addr_t s390_fixup_ram_size(ram_addr_t sz)
}
return newsz;
}
@ -40,16 +50,16 @@ index 86bfc9d2eb..451017c50e 100644
static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp)
{
@@ -837,7 +839,7 @@ static const TypeInfo ccw_machine_info = {
@@ -893,7 +895,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__) ")"; \
mc->init = MACHINE_VER_SYM(mach_init, ccw, __VA_ARGS__); \
MACHINE_VER_DEPRECATION(__VA_ARGS__); \
if (latest) { \
mc->alias = "s390-ccw-virtio"; \
@@ -864,11 +866,11 @@ static const TypeInfo ccw_machine_info = {
@@ -914,11 +916,11 @@ static const TypeInfo ccw_machine_info = {
} \
type_init(MACHINE_VER_SYM(register, ccw, __VA_ARGS__))
@ -65,19 +75,57 @@ index 86bfc9d2eb..451017c50e 100644
#if 0 /* Disabled for Red Hat Enterprise Linux */
@@ -1308,6 +1310,59 @@ DEFINE_CCW_MACHINE(2, 4);
@@ -1298,6 +1300,97 @@ DEFINE_CCW_MACHINE(2, 9);
#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)
+{
+ static GlobalProperty compat[] = {
+ { TYPE_S390_PCI_DEVICE, "relaxed-translation", "off", },
+ };
+
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
+ compat_props_add(mc->compat_props, hw_compat_rhel_10_1, hw_compat_rhel_10_1_len);
+}
+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);
+
+ /* NB: remember to move this line to the *latest* RHEL 9 machine */
+ compat_props_add(mc->compat_props, hw_compat_rhel_9, hw_compat_rhel_9_len);
+}
+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)
+{
+ static GlobalProperty compat[] = {
+ { 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)
+{
@ -126,7 +174,7 @@ index 86bfc9d2eb..451017c50e 100644
{
type_register_static(&ccw_machine_info);
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 798c18f940..8afa9af1a5 100644
index 111d46a59a..156bcf0d22 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -47,6 +47,9 @@
@ -139,7 +187,7 @@ index 798c18f940..8afa9af1a5 100644
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)
@@ -932,22 +935,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);
@ -183,10 +231,10 @@ index 71d4bc2dd4..d6c7c2cb50 100644
} 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
diff --git a/target/s390x/cpu_models_system.c b/target/s390x/cpu_models_system.c
index 4351182f72..4074124c44 100644
--- a/target/s390x/cpu_models_system.c
+++ b/target/s390x/cpu_models_system.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));

View File

@ -1,4 +1,4 @@
From c8510c21f0fde361d6cbce81bfb2f4acb6941b58 Mon Sep 17 00:00:00 2001
From 869dc39b548550c0b7b6a2bd8ab13746ec1b50c1 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
@ -7,33 +7,49 @@ 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):
Rebase notes (9.1.0):
- 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):
Rebase notes (10.0.0 rc0):
- Do not use bugfix macro for q35
- Use upstream compat
- Add downstream specific compat
- Fixing rhel-9.4 compat issue
Merged patches (9.1.0):
- 043ad5ce97 Add upstream compatibility bits (partial)
Merged patches (10.0.0 rc0):
- 03502faf70 Add upstream compatibility bits
- 6be70c681b x86: ensure compatibility of pc-q35-rhel9*
- d6b6ae511c x86: create new pc-q35 machine type for rhel 9.6
- fcf4da60bd x86: create pc-i440fx machine type for rhel10
- 4acb295fa2 x86: create pc-q35 machine type for rhel10
- 0489497df8 x86: remove deprecated rhel machine types
- f53dbf7532 remove stale compat definitions (partial)
- 379e14ba88 pc: q35: Bump max_cpus to 4096 vcpus
- d93fcb3940 virtio-net: disable USO for all RHEL9 (partial)
---
hw/i386/fw_cfg.c | 2 +-
hw/i386/pc.c | 159 ++++++++++++++++++++++++++++-
hw/i386/pc_piix.c | 102 ++++++++++++++++++-
hw/i386/pc_q35.c | 204 +++++++++++++++++++++++++++++++++++--
hw/i386/pc.c | 63 +++++++++++++++++++-
hw/i386/pc_piix.c | 49 +++++++++++++--
hw/i386/pc_q35.c | 119 ++++++++++++++++++++++++++++++++++---
include/hw/boards.h | 2 +
include/hw/i386/pc.h | 33 ++++++
include/hw/i386/pc.h | 18 ++++++
target/i386/kvm/kvm-cpu.c | 1 +
target/i386/kvm/kvm.c | 4 +
target/i386/kvm/kvm.c | 4 ++
tests/qtest/meson.build | 2 +-
tests/qtest/pvpanic-test.c | 5 +-
9 files changed, 499 insertions(+), 13 deletions(-)
10 files changed, 247 insertions(+), 18 deletions(-)
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index 33ef280420..a322709ffa 100644
index 07df7281d2..8009f5f31f 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -73,7 +73,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
@@ -75,7 +75,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
if (pcmc->smbios_defaults) {
/* These values are guest ABI, do not change */
@ -43,10 +59,10 @@ index 33ef280420..a322709ffa 100644
}
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 7779c88a91..a49d346d2e 100644
index 01d0581f62..5ae388789b 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -276,6 +276,161 @@ const size_t pc_compat_2_4_len = G_N_ELEMENTS(pc_compat_2_4);
@@ -287,6 +287,65 @@ const size_t pc_compat_2_4_len = G_N_ELEMENTS(pc_compat_2_4);
*/
#define PC_FW_DATA (0x20000 + 0x8000)
@ -72,6 +88,25 @@ index 7779c88a91..a49d346d2e 100644
+};
+const size_t pc_rhel_compat_len = G_N_ELEMENTS(pc_rhel_compat);
+
+GlobalProperty pc_rhel_10_1_compat[] = {
+ /* pc_rhel_10_1_compat from pc_compat_9_1 */
+ { "ICH9-LPC", "x-smi-swsmi-timer", "off" },
+ { "ICH9-LPC", "x-smi-periodic-timer", "off" },
+ { TYPE_INTEL_IOMMU_DEVICE, "stale-tm", "on" },
+ { TYPE_INTEL_IOMMU_DEVICE, "aw-bits", "39" },
+};
+const size_t pc_rhel_10_1_compat_len = G_N_ELEMENTS(pc_rhel_10_1_compat);
+
+GlobalProperty pc_rhel_10_0_compat[] = {
+ /* pc_rhel_10_0_compat from pc_compat_9_0 */
+ { TYPE_X86_CPU, "x-amd-topoext-features-only", "false" },
+ { TYPE_X86_CPU, "x-l1-cache-per-thread", "false" },
+ { TYPE_X86_CPU, "guest-phys-bits", "0" },
+ { "sev-guest", "legacy-vm-type", "on" },
+ { TYPE_X86_CPU, "legacy-multi-node", "on" },
+};
+const size_t pc_rhel_10_0_compat_len = G_N_ELEMENTS(pc_rhel_10_0_compat);
+
+GlobalProperty pc_rhel_9_3_compat[] = {
+ /* pc_rhel_9_3_compat from pc_compat_8_0 */
+ { "virtio-mem", "unplugged-inaccessible", "auto" },
@ -89,126 +124,11 @@ index 7779c88a91..a49d346d2e 100644
+ { "virtio-mem", "unplugged-inaccessible", "off" },
+};
+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;
@@ -1767,6 +1922,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
@@ -1780,6 +1839,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);
@ -216,7 +136,7 @@ index 7779c88a91..a49d346d2e 100644
mc->get_hotplug_handler = pc_get_hotplug_handler;
mc->hotplug_allowed = pc_hotplug_allowed;
mc->auto_enable_numa_with_memhp = true;
@@ -1774,7 +1930,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
@@ -1787,7 +1847,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;
@ -227,76 +147,55 @@ index 7779c88a91..a49d346d2e 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 67107b174a..5535e1ffbf 100644
index 1b58988c9a..78e9534a2c 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -52,6 +52,7 @@
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "sysemu/xen.h"
#include "system/xen.h"
+#include "migration/migration.h"
#ifdef CONFIG_XEN
#include <xen/hvm/hvm_info_table.h>
#include "hw/xen/xen_pt.h"
@@ -445,8 +446,8 @@ static void pc_i440fx_init(MachineState *machine)
@@ -446,11 +447,11 @@ static void pc_i440fx_init(MachineState *machine)
pc_init1(machine, TYPE_I440FX_PCI_DEVICE);
}
-#define DEFINE_I440FX_MACHINE(major, minor) \
- DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, major, minor);
- DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, false, NULL, major, minor);
+#define DEFINE_I440FX_MACHINE(major, minor, micro) \
+ DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, major, minor, micro);
+ DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, false, NULL, major, minor, micro);
-#define DEFINE_I440FX_MACHINE_AS_LATEST(major, minor) \
- DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, true, "pc", major, minor);
+#define DEFINE_I440FX_MACHINE_AS_LATEST(major, minor, micro) \
+ DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, true, "pc", 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)
@@ -845,3 +846,43 @@ static void xenfv_machine_3_1_options(MachineClass *m)
DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init,
xenfv_machine_3_1_options);
#endif
+
+/* Red Hat Enterprise Linux machine types */
+
+/* Options for the latest rhel7 machine type */
+static void pc_machine_rhel7_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ m->family = "pc_piix_Y";
+ m->default_machine_opts = "firmware=bios-256k.bin,hpet=off";
+ pcmc->pci_root_uid = 0;
+ m->default_nic = "e1000";
+ m->default_display = "std";
+ m->no_parallel = 1;
+ m->numa_mem_supported = true;
+ m->auto_enable_numa_with_memdev = false;
+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
+ compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len);
+ m->alias = "pc";
+ m->is_default = 1;
+ m->smp_props.prefer_sockets = true;
+}
+
+static void pc_i440fx_rhel_machine_7_6_0_options(MachineClass *m)
+static void pc_machine_rhel10_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ ObjectClass *oc = OBJECT_CLASS(m);
+ pc_machine_rhel7_options(m);
+ m->desc = "RHEL 7.6.0 PC (i440FX + PIIX, 1996)";
+ m->async_pf_vmexit_disable = true;
+ m->smbus_no_migration_support = true;
+
+ pcmc->pvh_enabled = false;
+ pcmc->default_cpu_version = CPU_VERSION_LEGACY;
+ pcmc->kvmclock_create_always = false;
+ /* From pc_i440fx_5_1_machine_options() */
+ pcmc->pci_root_uid = 1;
+ /* From pc_i440fx_7_0_machine_options() */
+ pcmc->enforce_amd_1tb_hole = false;
+ /* From pc_i440fx_8_0_machine_options() */
+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
+ /* From pc_i440fx_8_1_machine_options() */
+ pcmc->broken_32bit_mem_addr_check = true;
+ /* Introduced in QEMU 8.2 */
+ pcmc->default_south_bridge = TYPE_PIIX3_DEVICE;
+ pcmc->pci_root_uid = 0;
+ pcmc->default_cpu_version = 1;
+
+ m->family = "pc_piix_Y";
+ m->default_machine_opts = "firmware=bios-256k.bin";
+ m->default_display = "std";
+ m->default_nic = "e1000";
+ m->no_parallel = 1;
+ m->no_floppy = 1;
+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
+
+ object_class_property_add_enum(oc, "x-south-bridge", "PCSouthBridgeOption",
+ &PCSouthBridgeOption_lookup,
@ -304,57 +203,42 @@ index 67107b174a..5535e1ffbf 100644
+ pc_set_south_bridge);
+ 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,
+ hw_compat_rhel_9_3_len);
+ compat_props_add(m->compat_props, pc_rhel_9_3_compat,
+ pc_rhel_9_3_compat_len);
+ compat_props_add(m->compat_props, hw_compat_rhel_9_2,
+ hw_compat_rhel_9_2_len);
+ compat_props_add(m->compat_props, pc_rhel_9_2_compat,
+ pc_rhel_9_2_compat_len);
+ compat_props_add(m->compat_props, hw_compat_rhel_9_1,
+ hw_compat_rhel_9_1_len);
+ compat_props_add(m->compat_props, hw_compat_rhel_9_0,
+ hw_compat_rhel_9_0_len);
+ compat_props_add(m->compat_props, pc_rhel_9_0_compat,
+ pc_rhel_9_0_compat_len);
+ compat_props_add(m->compat_props, hw_compat_rhel_8_6,
+ hw_compat_rhel_8_6_len);
+ compat_props_add(m->compat_props, hw_compat_rhel_8_5,
+ hw_compat_rhel_8_5_len);
+ compat_props_add(m->compat_props, pc_rhel_8_5_compat,
+ pc_rhel_8_5_compat_len);
+ compat_props_add(m->compat_props, hw_compat_rhel_8_4,
+ hw_compat_rhel_8_4_len);
+ compat_props_add(m->compat_props, pc_rhel_8_4_compat,
+ pc_rhel_8_4_compat_len);
+ compat_props_add(m->compat_props, hw_compat_rhel_8_3,
+ hw_compat_rhel_8_3_len);
+ compat_props_add(m->compat_props, pc_rhel_8_3_compat,
+ pc_rhel_8_3_compat_len);
+ compat_props_add(m->compat_props, hw_compat_rhel_8_2,
+ hw_compat_rhel_8_2_len);
+ compat_props_add(m->compat_props, pc_rhel_8_2_compat,
+ pc_rhel_8_2_compat_len);
+ compat_props_add(m->compat_props, hw_compat_rhel_8_1, hw_compat_rhel_8_1_len);
+ compat_props_add(m->compat_props, pc_rhel_8_1_compat, pc_rhel_8_1_compat_len);
+ compat_props_add(m->compat_props, hw_compat_rhel_8_0, hw_compat_rhel_8_0_len);
+ compat_props_add(m->compat_props, pc_rhel_8_0_compat, pc_rhel_8_0_compat_len);
+ compat_props_add(m->compat_props, hw_compat_rhel_7_6, hw_compat_rhel_7_6_len);
+ compat_props_add(m->compat_props, pc_rhel_7_6_compat, pc_rhel_7_6_compat_len);
+}
+
+DEFINE_I440FX_MACHINE(7, 6, 0);
+static void pc_i440fx_rhel_machine_10_0_0_options(MachineClass *m)
+{
+ pc_machine_rhel10_options(m);
+
+ m->desc = "RHEL 10.0.0 PC (i440FX + PIIX, 1996)";
+ m->deprecation_reason = rhel_old_machine_deprecation;
+
+ compat_props_add(m->compat_props, hw_compat_rhel_10_1,
+ hw_compat_rhel_10_1_len);
+ compat_props_add(m->compat_props, pc_rhel_10_1_compat,
+ pc_rhel_10_1_compat_len);
+}
+DEFINE_I440FX_MACHINE_AS_LATEST(10, 0, 0);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 5fb283f2df..2ca9ff3747 100644
index 97a40a3a9c..2f19204304 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -338,20 +338,19 @@ static void pc_q35_machine_options(MachineClass *m)
@@ -327,11 +327,11 @@ static void pc_q35_init(MachineState *machine)
}
}
-#define DEFINE_Q35_MACHINE(major, minor) \
- DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, NULL, major, minor);
+#define DEFINE_Q35_MACHINE(major, minor, micro) \
+ DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, NULL, major, minor, micro);
-#define DEFINE_Q35_MACHINE_AS_LATEST(major, minor) \
- DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, "q35", major, minor);
+#define DEFINE_Q35_MACHINE_AS_LATEST(major, minor, micro) \
+ DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, "q35", major, minor, micro);
#define DEFINE_Q35_MACHINE_BUGFIX(major, minor, micro) \
DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, NULL, major, minor, micro);
@@ -342,21 +342,21 @@ static void pc_q35_machine_options(MachineClass *m)
pcmc->pci_root_uid = 0;
pcmc->default_cpu_version = 1;
@ -368,46 +252,85 @@ index 5fb283f2df..2ca9ff3747 100644
m->default_nic = "e1000e";
- m->default_kernel_irqchip_split = false;
m->no_floppy = 1;
- m->max_cpus = 4096;
m->max_cpus = 4096;
- m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL);
+ m->max_cpus = 710;
+ m->no_parallel = 1;
+ m->alias = "q35";
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";
machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
machine_class_allow_dynamic_sysbus_dev(m, TYPE_UEFI_VARS_X64);
+ 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);
}
@@ -670,3 +669,194 @@ static void pc_q35_machine_2_4_options(MachineClass *m)
@@ -691,3 +691,104 @@ static void pc_q35_machine_2_4_options(MachineClass *m)
DEFINE_Q35_MACHINE(2, 4);
#endif /* Disabled for Red Hat Enterprise Linux */
+
+/* Red Hat Enterprise Linux machine types */
+
+static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m)
+static void pc_q35_rhel_machine_10_0_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_options(m);
+ m->desc = "RHEL-10.0.0 PC (Q35 + ICH9, 2009)";
+ pcmc->smbios_stream_product = "RHEL";
+ pcmc->smbios_stream_version = "10.0.0";
+
+ compat_props_add(m->compat_props, hw_compat_rhel_10_1,
+ hw_compat_rhel_10_1_len);
+ compat_props_add(m->compat_props, pc_rhel_10_1_compat,
+ pc_rhel_10_1_compat_len);
+}
+DEFINE_Q35_MACHINE_AS_LATEST(10, 0, 0);
+
+static void pc_q35_rhel_machine_9_6_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_rhel_machine_10_0_0_options(m);
+ m->desc = "RHEL-9.6.0 PC (Q35 + ICH9, 2009)";
+ pcmc->smbios_stream_product = "RHEL";
+ pcmc->smbios_stream_version = "9.6.0";
+
+ /* NB: remember to move this line to the *latest* RHEL 9 machine */
+ compat_props_add(m->compat_props, hw_compat_rhel_9, hw_compat_rhel_9_len);
+}
+
+DEFINE_Q35_MACHINE(9, 6, 0);
+
+static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_rhel_machine_9_6_0_options(m);
+
+ /* older RHEL machines continue to support 710 vcpus */
+ m->max_cpus = 710;
+ m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)";
+ 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,
+ hw_compat_rhel_9_5_len);
+ compat_props_add(m->compat_props, pc_rhel_10_0_compat,
+ pc_rhel_10_0_compat_len);
+}
+
+DEFINE_Q35_MACHINE_BUGFIX(9, 4, 0);
+DEFINE_Q35_MACHINE(9, 4, 0);
+
+static void pc_q35_rhel_machine_9_2_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(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";
+ pcmc->smbios_stream_version = "9.2.0";
+
@ -428,14 +351,13 @@ index 5fb283f2df..2ca9ff3747 100644
+ pc_rhel_9_2_compat_len);
+}
+
+DEFINE_Q35_MACHINE_BUGFIX(9, 2, 0);
+DEFINE_Q35_MACHINE(9, 2, 0);
+
+static void pc_q35_rhel_machine_9_0_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(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";
+ pcmc->smbios_stream_version = "9.0.0";
+ pcmc->enforce_amd_1tb_hole = false;
@ -447,140 +369,12 @@ index 5fb283f2df..2ca9ff3747 100644
+ pc_rhel_9_0_compat_len);
+}
+
+DEFINE_Q35_MACHINE_BUGFIX(9, 0, 0);
+
+static void pc_q35_rhel_machine_8_6_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_rhel_machine_9_0_0_options(m);
+ m->desc = "RHEL-8.6.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL;
+
+ 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_Q35_MACHINE_BUGFIX(8, 6, 0);
+
+static void pc_q35_rhel_machine_8_5_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(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";
+ pcmc->smbios_stream_version = "8.5.0";
+ compat_props_add(m->compat_props, hw_compat_rhel_8_5,
+ hw_compat_rhel_8_5_len);
+ compat_props_add(m->compat_props, pc_rhel_8_5_compat,
+ pc_rhel_8_5_compat_len);
+ m->smp_props.prefer_sockets = true;
+}
+
+DEFINE_Q35_MACHINE_BUGFIX(8, 5, 0);
+
+static void pc_q35_rhel_machine_8_4_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(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";
+ pcmc->smbios_stream_version = "8.4.0";
+ compat_props_add(m->compat_props, hw_compat_rhel_8_4,
+ hw_compat_rhel_8_4_len);
+ compat_props_add(m->compat_props, pc_rhel_8_4_compat,
+ pc_rhel_8_4_compat_len);
+}
+
+DEFINE_Q35_MACHINE_BUGFIX(8, 4, 0);
+
+static void pc_q35_rhel_machine_8_3_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(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";
+ pcmc->smbios_stream_version = "8.3.0";
+ compat_props_add(m->compat_props, hw_compat_rhel_8_3,
+ hw_compat_rhel_8_3_len);
+ compat_props_add(m->compat_props, pc_rhel_8_3_compat,
+ pc_rhel_8_3_compat_len);
+ /* From pc_q35_5_1_machine_options() */
+ pcmc->kvmclock_create_always = false;
+ /* From pc_q35_5_1_machine_options() */
+ pcmc->pci_root_uid = 1;
+}
+
+DEFINE_Q35_MACHINE_BUGFIX(8, 3, 0);
+
+static void pc_q35_rhel_machine_8_2_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(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;
+ m->auto_enable_numa_with_memdev = false;
+ pcmc->smbios_stream_product = "RHEL-AV";
+ pcmc->smbios_stream_version = "8.2.0";
+ compat_props_add(m->compat_props, hw_compat_rhel_8_2,
+ hw_compat_rhel_8_2_len);
+ compat_props_add(m->compat_props, pc_rhel_8_2_compat,
+ pc_rhel_8_2_compat_len);
+}
+
+DEFINE_Q35_MACHINE_BUGFIX(8, 2, 0);
+
+static void pc_q35_rhel_machine_8_1_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(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;
+ pcmc->smbios_stream_version = NULL;
+ compat_props_add(m->compat_props, hw_compat_rhel_8_1, hw_compat_rhel_8_1_len);
+ compat_props_add(m->compat_props, pc_rhel_8_1_compat, pc_rhel_8_1_compat_len);
+}
+
+DEFINE_Q35_MACHINE_BUGFIX(8, 1, 0);
+
+static void pc_q35_rhel_machine_8_0_0_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(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;
+ pcmc->pvh_enabled = false;
+ pcmc->default_cpu_version = CPU_VERSION_LEGACY;
+ compat_props_add(m->compat_props, hw_compat_rhel_8_0, hw_compat_rhel_8_0_len);
+ compat_props_add(m->compat_props, pc_rhel_8_0_compat, pc_rhel_8_0_compat_len);
+}
+
+DEFINE_Q35_MACHINE_BUGFIX(8, 0, 0);
+
+static void pc_q35_rhel_machine_7_6_0_options(MachineClass *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;
+ compat_props_add(m->compat_props, hw_compat_rhel_7_6, hw_compat_rhel_7_6_len);
+ compat_props_add(m->compat_props, pc_rhel_7_6_compat, pc_rhel_7_6_compat_len);
+}
+
+DEFINE_Q35_MACHINE_BUGFIX(7, 6, 0);
+
+DEFINE_Q35_MACHINE(9, 0, 0);
diff --git a/include/hw/boards.h b/include/hw/boards.h
index fd5a957cad..3dea5cee73 100644
index 182c11dc2c..a43847767f 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -289,6 +289,8 @@ struct MachineClass {
@@ -309,6 +309,8 @@ struct MachineClass {
strList *allowed_dynamic_sysbus_devices;
bool auto_enable_numa_with_memhp;
bool auto_enable_numa_with_memdev;
@ -590,16 +384,22 @@ index fd5a957cad..3dea5cee73 100644
bool smbus_no_migration_support;
bool nvdimm_supported;
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 8776a3c937..8e9597f40f 100644
index e4d32f8aea..5306b6d7cb 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -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;
@@ -305,6 +305,24 @@ extern const size_t pc_compat_2_5_len;
extern GlobalProperty pc_compat_2_4[];
extern const size_t pc_compat_2_4_len;
+extern GlobalProperty pc_rhel_compat[];
+extern const size_t pc_rhel_compat_len;
+
+extern GlobalProperty pc_rhel_10_1_compat[];
+extern const size_t pc_rhel_10_1_compat_len;
+
+extern GlobalProperty pc_rhel_10_0_compat[];
+extern const size_t pc_rhel_10_0_compat_len;
+
+extern GlobalProperty pc_rhel_9_3_compat[];
+extern const size_t pc_rhel_9_3_compat_len;
+
@ -608,36 +408,15 @@ index 8776a3c937..8e9597f40f 100644
+
+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) \
{ \
diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c
index 6bf8dcfc60..684e731cbc 100644
index 6269fa8045..8f455c24e9 100644
--- a/target/i386/kvm/kvm-cpu.c
+++ b/target/i386/kvm/kvm-cpu.c
@@ -178,6 +178,7 @@ static PropValue kvm_default_props[] = {
@@ -174,6 +174,7 @@ static PropValue kvm_default_props[] = {
{ "acpi", "off" },
{ "monitor", "off" },
{ "svm", "off" },
@ -646,10 +425,10 @@ index 6bf8dcfc60..684e731cbc 100644
};
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 2fa88ef1e3..2b28c18693 100644
index 6c749d4ee8..9cb2512c7c 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -4244,6 +4244,7 @@ static int kvm_get_msrs(X86CPU *cpu)
@@ -4366,6 +4366,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;
@ -657,7 +436,7 @@ index 2fa88ef1e3..2b28c18693 100644
kvm_msr_buf_reset(cpu);
@@ -4636,6 +4637,9 @@ static int kvm_get_msrs(X86CPU *cpu)
@@ -4763,6 +4764,9 @@ static int kvm_get_msrs(X86CPU *cpu)
break;
case MSR_KVM_ASYNC_PF_EN:
env->async_pf_en_msr = msrs[i].data;
@ -667,8 +446,28 @@ index 2fa88ef1e3..2b28c18693 100644
break;
case MSR_KVM_ASYNC_PF_INT:
env->async_pf_int_msr = msrs[i].data;
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 3136d15e0f..7749ec4b2f 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -49,6 +49,7 @@ qtests_filter = \
(get_option('default_devices') and host_os != 'windows' ? ['test-filter-mirror'] : []) + \
(get_option('default_devices') and host_os != 'windows' ? ['test-filter-redirector'] : [])
+# RHEL: Removed intel-iommu-test as it's not working with 10.0 machine type
qtests_i386 = \
(slirp.found() ? ['pxe-test'] : []) + \
qtests_filter + \
@@ -94,7 +95,6 @@ qtests_i386 = \
(config_all_devices.has_key('CONFIG_SB16') ? ['fuzz-sb16-test'] : []) + \
(config_all_devices.has_key('CONFIG_SDHCI_PCI') ? ['fuzz-sdcard-test'] : []) + \
(config_all_devices.has_key('CONFIG_ESP_PCI') ? ['am53c974-test'] : []) + \
- (config_all_devices.has_key('CONFIG_VTD') ? ['intel-iommu-test'] : []) + \
(host_os != 'windows' and \
config_all_devices.has_key('CONFIG_ACPI_ERST') ? ['erst-test'] : []) + \
(config_all_devices.has_key('CONFIG_PCIE_PORT') and \
diff --git a/tests/qtest/pvpanic-test.c b/tests/qtest/pvpanic-test.c
index d49d2ba931..c18f63e255 100644
index 5606baf47b..094c56b0cd 100644
--- a/tests/qtest/pvpanic-test.c
+++ b/tests/qtest/pvpanic-test.c
@@ -18,7 +18,7 @@ static void test_panic_nopause(void)

View File

@ -1,4 +1,4 @@
From bd6f1170d3a011c475ec4a8315512c7c190de3e4 Mon Sep 17 00:00:00 2001
From 54d447640d3c550143e07610a516e4cdf474260e 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"
@ -16,10 +16,10 @@ Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
1 file changed, 1 deletion(-)
diff --git a/meson.build b/meson.build
index 2de5ab024f..b3529aa0e1 100644
index 38ad60fc10..0607c1313b 100644
--- a/meson.build
+++ b/meson.build
@@ -651,7 +651,6 @@ warn_flags = [
@@ -747,7 +747,6 @@ warn_flags = [
'-Wno-string-plus-int',
'-Wno-tautological-type-limit-compare',
'-Wno-typedef-redefinition',

View File

@ -1,4 +1,4 @@
From 3c4bab07566d32859e227ca1083b0dc64111e3f7 Mon Sep 17 00:00:00 2001
From bd972a5dfe6cec33302ae52d7503a23b7b8506af 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
@ -9,41 +9,37 @@ 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):
Rebase notes (9.1.0):
- Disable fdc-test
- 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 | 4 ++--
tests/qemu-iotests/meson.build | 34 ++++++++++++++---------------
tests/qemu-iotests/testenv.py | 3 +++
tests/qtest/fuzz-e1000e-test.c | 2 +-
tests/qtest/fuzz-virtio-scsi-test.c | 2 +-
tests/qtest/intel-hda-test.c | 2 +-
tests/qtest/libqos/meson.build | 2 +-
tests/qtest/lpc-ich9-test.c | 2 +-
tests/qtest/meson.build | 3 +--
tests/qtest/pvpanic-test.c | 2 +-
tests/qtest/virtio-net-failover.c | 1 +
14 files changed, 34 insertions(+), 31 deletions(-)
diff --git a/tests/avocado/replay_kernel.py b/tests/avocado/replay_kernel.py
index e22c200a36..cb7ca19b1b 100644
--- a/tests/avocado/replay_kernel.py
+++ b/tests/avocado/replay_kernel.py
@@ -193,7 +193,7 @@ def test_aarch64_virt(self):
"""
:avocado: tags=arch:aarch64
:avocado: tags=machine:virt
- :avocado: tags=cpu:cortex-a53
+ :avocado: tags=cpu:cortex-a57
"""
kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
'/linux/releases/29/Everything/aarch64/os/images/pxeboot'
Rebase notes (10.0.0 rc0)
- Disable mem_addr_space functional test
- Updated removal of q35 test (upstream change)
Rebase notes (10.0.0):
- Add riscv changes
---
.distro/qemu-kvm.spec.template | 4 +--
tests/avocado/reverse_debugging.py | 2 +-
tests/functional/meson.build | 2 +-
tests/functional/test_aarch64_replay.py | 2 +-
tests/functional/test_aarch64_tcg_plugins.py | 4 +--
tests/qemu-iotests/meson.build | 34 ++++++++++----------
tests/qemu-iotests/testenv.py | 3 ++
tests/qtest/bios-tables-test.c | 6 ++++
tests/qtest/fuzz-e1000e-test.c | 2 +-
tests/qtest/fuzz-virtio-scsi-test.c | 2 +-
tests/qtest/intel-hda-test.c | 2 +-
tests/qtest/libqos/meson.build | 2 +-
tests/qtest/lpc-ich9-test.c | 2 +-
tests/qtest/machine-none-test.c | 2 +-
tests/qtest/meson.build | 1 -
tests/qtest/pvpanic-test.c | 2 +-
tests/qtest/riscv-csr-test.c | 4 +++
tests/qtest/virtio-net-failover.c | 1 +
18 files changed, 45 insertions(+), 32 deletions(-)
diff --git a/tests/avocado/reverse_debugging.py b/tests/avocado/reverse_debugging.py
index f24287cd0a..3880b81df6 100644
--- a/tests/avocado/reverse_debugging.py
@ -57,28 +53,54 @@ index f24287cd0a..3880b81df6 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 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):
: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()
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
index 0f8be30fe2..4463f6bb0d 100644
--- a/tests/functional/meson.build
+++ b/tests/functional/meson.build
@@ -291,7 +291,7 @@ tests_sparc64_system_thorough = [
tests_x86_64_system_quick = [
'cpu_queries',
- 'mem_addr_space',
+# 'mem_addr_space',
'migration',
'pc_cpu_hotplug_props',
'virtio_version',
diff --git a/tests/functional/test_aarch64_replay.py b/tests/functional/test_aarch64_replay.py
index bd6609d914..ddf93814fd 100755
--- a/tests/functional/test_aarch64_replay.py
+++ b/tests/functional/test_aarch64_replay.py
@@ -18,7 +18,7 @@ class Aarch64Replay(ReplayKernelBase):
def test_aarch64_virt(self):
self.set_machine('virt')
- self.cpu = 'cortex-a53'
+ self.cpu = 'cortex-a57'
kernel_path = self.ASSET_KERNEL.fetch()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
@@ -96,7 +96,7 @@ def test_aarch64_virt_insn_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()
'console=ttyAMA0')
diff --git a/tests/functional/test_aarch64_tcg_plugins.py b/tests/functional/test_aarch64_tcg_plugins.py
index 4ea71f5f88..0b1043f3dc 100755
--- a/tests/functional/test_aarch64_tcg_plugins.py
+++ b/tests/functional/test_aarch64_tcg_plugins.py
@@ -65,7 +65,7 @@ class PluginKernelNormal(PluginKernelBase):
def test_aarch64_virt_insn(self):
self.set_machine('virt')
- self.cpu='cortex-a53'
+ self.cpu='cortex-a57'
kernel_path = self.ASSET_KERNEL.fetch()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'console=ttyAMA0')
@@ -91,7 +91,7 @@ def test_aarch64_virt_insn(self):
def test_aarch64_virt_insn_icount(self):
self.set_machine('virt')
- self.cpu='cortex-a53'
+ self.cpu='cortex-a57'
kernel_path = self.ASSET_KERNEL.fetch()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'console=ttyAMA0')
diff --git a/tests/qemu-iotests/meson.build b/tests/qemu-iotests/meson.build
index fad340ad59..3c0d5241f6 100644
--- a/tests/qemu-iotests/meson.build
@ -123,10 +145,10 @@ index fad340ad59..3c0d5241f6 100644
+# endforeach
endforeach
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
index c8848f2ec2..d515e5b8b0 100644
index 6326e46b7b..bc849ae9cf 100644
--- a/tests/qemu-iotests/testenv.py
+++ b/tests/qemu-iotests/testenv.py
@@ -249,6 +249,9 @@ def __init__(self, source_dir: str, build_dir: str,
@@ -252,6 +252,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}'
@ -136,6 +158,57 @@ index c8848f2ec2..d515e5b8b0 100644
# QEMU_DEFAULT_MACHINE
self.qemu_default_machine = get_default_machine(self.qemu_prog)
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 0a333ec435..e24098fc70 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1707,6 +1707,7 @@ static void test_acpi_microvm_ioapic2_tcg(void)
free_test_data(&data);
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void test_acpi_riscv64_virt_tcg_numamem(void)
{
test_data data = {
@@ -1732,6 +1733,7 @@ static void test_acpi_riscv64_virt_tcg_numamem(void)
&data);
free_test_data(&data);
}
+#endif /* disabled for RHEL */
static void test_acpi_aarch64_virt_tcg_numamem(void)
{
@@ -2085,6 +2087,7 @@ static void test_acpi_microvm_acpi_erst(void)
}
#endif /* CONFIG_POSIX */
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void test_acpi_riscv64_virt_tcg(void)
{
test_data data = {
@@ -2106,6 +2109,7 @@ static void test_acpi_riscv64_virt_tcg(void)
test_acpi_one("-cpu rva22s64 ", &data);
free_test_data(&data);
}
+#endif /* disabled for RHEL */
static void test_acpi_aarch64_virt_tcg(void)
{
@@ -2587,12 +2591,14 @@ int main(int argc, char *argv[])
qtest_add_func("acpi/virt/viot", test_acpi_aarch64_virt_viot);
}
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
} else if (strcmp(arch, "riscv64") == 0) {
if (has_tcg && qtest_has_device("virtio-blk-pci")) {
qtest_add_func("acpi/virt", test_acpi_riscv64_virt_tcg);
qtest_add_func("acpi/virt/numamem",
test_acpi_riscv64_virt_tcg_numamem);
}
+#endif /* disabled for RHEL */
}
ret = g_test_run();
boot_sector_cleanup(disk);
diff --git a/tests/qtest/fuzz-e1000e-test.c b/tests/qtest/fuzz-e1000e-test.c
index 5052883fb6..8242190170 100644
--- a/tests/qtest/fuzz-e1000e-test.c
@ -176,10 +249,10 @@ 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 1b2b2dbb22..86afbddb58 100644
index 1ddaf7b095..1cb403e90d 100644
--- a/tests/qtest/libqos/meson.build
+++ b/tests/qtest/libqos/meson.build
@@ -44,7 +44,7 @@ libqos_srcs = files(
@@ -43,7 +43,7 @@ libqos_srcs = files(
'virtio-rng.c',
'virtio-scsi.c',
'virtio-serial.c',
@ -201,29 +274,33 @@ index 8ac95b89f7..0e118b76eb 100644
"-nographic -monitor none -serial none");
qtest_outl(s, 0xcf8, 0x8000f840); /* PMBASE */
diff --git a/tests/qtest/machine-none-test.c b/tests/qtest/machine-none-test.c
index b6a87d27ed..423ba12159 100644
--- a/tests/qtest/machine-none-test.c
+++ b/tests/qtest/machine-none-test.c
@@ -49,7 +49,7 @@ static struct arch2cpu cpus_map[] = {
{ "xtensa", "dc233c" },
{ "xtensaeb", "fsf" },
{ "hppa", "hppa" },
- { "riscv64", "rv64" },
+ { "riscv64", "max" },
{ "riscv32", "rv32" },
{ "rx", "rx62n" },
{ "loongarch64", "la464"},
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 2f0d3ef080..134c48c10e 100644
index 7749ec4b2f..6e2d08acc5 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -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',
- 'q35-test',
'vmgenid-test',
'migration-test',
'test-x86-cpuid-compat',
@@ -91,7 +91,6 @@ qtests_i386 = \
(config_all_devices.has_key('CONFIG_LSI_SCSI_PCI') ? ['fuzz-lsi53c895a-test'] : []) + \
(config_all_devices.has_key('CONFIG_VIRTIO_SCSI') ? ['fuzz-virtio-scsi-test'] : []) + \
(config_all_devices.has_key('CONFIG_VIRTIO_BALLOON') ? ['virtio-balloon-test'] : []) + \
- (config_all_devices.has_key('CONFIG_Q35') ? ['q35-test'] : []) + \
(config_all_devices.has_key('CONFIG_SB16') ? ['fuzz-sb16-test'] : []) + \
(config_all_devices.has_key('CONFIG_SDHCI_PCI') ? ['fuzz-sdcard-test'] : []) + \
(config_all_devices.has_key('CONFIG_ESP_PCI') ? ['am53c974-test'] : []) + \
diff --git a/tests/qtest/pvpanic-test.c b/tests/qtest/pvpanic-test.c
index c18f63e255..57fb129ae4 100644
index 094c56b0cd..338f94dcd9 100644
--- a/tests/qtest/pvpanic-test.c
+++ b/tests/qtest/pvpanic-test.c
@@ -65,7 +65,7 @@ static void test_pvshutdown(void)
@ -235,11 +312,39 @@ index c18f63e255..57fb129ae4 100644
val = qtest_inb(qts, 0x505);
g_assert_cmpuint(val, ==, PVPANIC_EVENTS);
diff --git a/tests/qtest/riscv-csr-test.c b/tests/qtest/riscv-csr-test.c
index ff5c29e6c6..cc3b08a976 100644
--- a/tests/qtest/riscv-csr-test.c
+++ b/tests/qtest/riscv-csr-test.c
@@ -20,6 +20,7 @@
#define CSR_MVENDORID 0xf11
#define CSR_MISELECT 0x350
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void run_test_csr(void)
{
uint64_t res;
@@ -45,12 +46,15 @@ static void run_test_csr(void)
qtest_quit(qts);
}
+#endif /* disabled for RHEL */
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
+#if 0 /* Disabled for Red Hat Enterprise Linux */
qtest_add_func("/cpu/csr", run_test_csr);
+#endif /* disabled for RHEL */
return g_test_run();
}
diff --git a/tests/qtest/virtio-net-failover.c b/tests/qtest/virtio-net-failover.c
index 73dfabc272..a9dd304781 100644
index 5baf81c3e6..aa87bf5698 100644
--- a/tests/qtest/virtio-net-failover.c
+++ b/tests/qtest/virtio-net-failover.c
@@ -26,6 +26,7 @@
@@ -27,6 +27,7 @@
#define PCI_SEL_BASE 0x0010
#define BASE_MACHINE "-M q35 -nodefaults " \

View File

@ -1,4 +1,4 @@
From 9813098fb73e899dd1d824f9c1e7e570a87b1771 Mon Sep 17 00:00:00 2001
From 194c56d4231e0ea6e86c04d905a3941e376c9a55 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 2407720c35..82a47edc89 100644
index 7f1532fbed..a71fe1ca7a 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -50,6 +50,9 @@
@ -36,7 +36,7 @@ index 2407720c35..82a47edc89 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);
@@ -2963,10 +2966,33 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
@@ -2966,10 +2969,33 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
ERRP_GUARD();
VFIOPCIDevice *vdev = VFIO_PCI(pdev);
VFIODevice *vbasedev = &vdev->vbasedev;
@ -71,7 +71,7 @@ index 2407720c35..82a47edc89 100644
if (vbasedev->fd < 0 && !vbasedev->sysfsdev) {
if (!(~vdev->host.domain || ~vdev->host.bus ||
~vdev->host.slot || ~vdev->host.function)) {
@@ -3388,6 +3414,9 @@ static Property vfio_pci_dev_properties[] = {
@@ -3380,6 +3406,9 @@ static const 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),
@ -82,7 +82,7 @@ index 2407720c35..82a47edc89 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 bf67df2fbc..0d3c93fb2e 100644
index d94ecaba68..3854bbcb26 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -142,6 +142,7 @@ struct VFIOPCIDevice {

View File

@ -1,4 +1,4 @@
From e46f7b696ec32b18969c9cd7c1553d7d30e489b3 Mon Sep 17 00:00:00 2001
From f3ef3004dc20bd1d6a1de3797fc46259f6503541 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 01b8b8e77a..5359231bf5 100644
index ec93988a03..c2bd30dc93 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -877,9 +877,17 @@ static void version(void)
@@ -870,9 +870,17 @@ static void version(void)
QEMU_COPYRIGHT "\n");
}
@ -33,7 +33,7 @@ index 01b8b8e77a..5359231bf5 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());
@@ -905,6 +913,7 @@ static void help(int exitcode)
@@ -898,6 +906,7 @@ static void help(int exitcode)
"\n"
QEMU_HELP_BOTTOM "\n");

View File

@ -1,4 +1,4 @@
From 40274d161d20719709d92356077175f93795ea1e Mon Sep 17 00:00:00 2001
From 5c4d190b3a79b22c86b59929ffe83433074c64a8 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 d94e2cbbae..a7444abc7f 100644
index dc694a99a3..5eb668b1e2 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3688,11 +3688,11 @@ SRST
@@ -3672,11 +3672,11 @@ SRST
::

View File

@ -1,4 +1,4 @@
From 728e3d8a124f4ec51c005ad6867270f3e60df16c Mon Sep 17 00:00:00 2001
From 1453ce2b1fa98c0d9f952827bc40b3a90d0f70be 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 70b19730a3..a4cffb628c 100644
index 7774e7f090..b6ade4755d 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1358,6 +1358,12 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,

View File

@ -1,109 +0,0 @@
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

View File

@ -1,37 +0,0 @@
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

View File

@ -1,66 +0,0 @@
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

View File

@ -1,28 +0,0 @@
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

View File

@ -1,27 +0,0 @@
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

View File

@ -1,19 +1,20 @@
From eb742e8a7c75e3be5c158cb19185d9cf6ae4862c Mon Sep 17 00:00:00 2001
From 9928955dc717c10f4c1084ef1ba71308fef68376 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 +++
hw/ppc/spapr.c | 128 +++++++++++++++++-
hw/ppc/spapr_cpu_core.c | 15 ++
include/hw/ppc/spapr.h | 3 +
target/ppc/compat.c | 11 ++
target/ppc/cpu-models.c | 9 +-
target/ppc/cpu-models.c | 8 ++
target/ppc/cpu.h | 1 +
target/ppc/kvm.c | 27 ++++
target/ppc/kvm_ppc.h | 13 ++
9 files changed, 237 insertions(+), 7 deletions(-)
target/ppc/misc_helper.c | 8 --
10 files changed, 240 insertions(+), 13 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
@ -62,13 +63,14 @@ index 000000000..4b801b126
+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
index b0a0f8c68..5369bbba4 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1746,6 +1746,13 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason)
@@ -1717,7 +1717,13 @@ static void spapr_machine_reset(MachineState *machine, ResetType type)
}
spapr_caps_apply(spapr);
spapr_nested_reset(spapr);
-
+ if (spapr->svm_allowed) {
+#ifdef CONFIG_KVM
+ kvmppc_svm_allow(&error_fatal);
@ -76,10 +78,10 @@ index 370d7c35d..aed36a4de 100644
+ 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)
ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00, 0,
@@ -3408,6 +3414,21 @@ static void spapr_set_host_serial(Object *obj, const char *value, Error **errp)
spapr->host_serial = g_strdup(value);
}
@ -96,11 +98,12 @@ index 370d7c35d..aed36a4de 100644
+
+ 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)
@@ -3486,6 +3507,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");
@ -113,7 +116,7 @@ index 370d7c35d..aed36a4de 100644
}
static void spapr_machine_finalizefn(Object *obj)
@@ -4775,6 +4802,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
@@ -4706,6 +4733,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;
@ -121,7 +124,7 @@ index 370d7c35d..aed36a4de 100644
}
static const TypeInfo spapr_machine_info = {
@@ -4830,13 +4858,14 @@ static void spapr_machine_latest_class_options(MachineClass *mc)
@@ -4761,11 +4789,12 @@ static void spapr_machine_latest_class_options(MachineClass *mc)
} \
type_init(MACHINE_VER_SYM(register, spapr, __VA_ARGS__))
@ -129,33 +132,19 @@ index 370d7c35d..aed36a4de 100644
- 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
* pseries-10.0
*/
@@ -5056,6 +5085,9 @@ static bool phb_placement_4_0(SpaprMachineState *spapr, uint32_t index,
}
return true;
@@ -5060,6 +5089,95 @@ static void spapr_machine_3_0_class_options(MachineClass *mc)
}
+#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);
DEFINE_SPAPR_MACHINE(3, 0);
+#endif /* disabled for RHEL */
+
+static void spapr_rhel_machine_default_class_options(MachineClass *mc)
@ -183,9 +172,18 @@ index 370d7c35d..aed36a4de 100644
+
+DEFINE_SPAPR_MACHINE_AS_LATEST(10, 0, 0);
+
+static void spapr_rhel_machine_9_5_0_class_options(MachineClass *mc)
+static void spapr_rhel_machine_9_6_0_class_options(MachineClass *mc)
+{
+ spapr_rhel_machine_10_0_0_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9,
+ hw_compat_rhel_9_len);
+}
+
+DEFINE_SPAPR_MACHINE(9, 6, 0);
+
+static void spapr_rhel_machine_9_5_0_class_options(MachineClass *mc)
+{
+ spapr_rhel_machine_9_6_0_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_5,
+ hw_compat_rhel_9_5_len);
+}
@ -236,23 +234,22 @@ index 370d7c35d..aed36a4de 100644
+}
+
+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
index faf9170ba..df3bde0db 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 "system/reset.h"
#include "system/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,
@@ -268,6 +269,7 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
{
CPUPPCState *env = &cpu->env;
CPUState *cs = CPU(cpu);
@ -260,7 +257,7 @@ index 56090abcd..e3371b24f 100644
if (!qdev_realize(DEVICE(cpu), NULL, errp)) {
return false;
@@ -280,6 +282,18 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
@@ -286,6 +288,17 @@ 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);
@ -274,12 +271,11 @@ index 56090abcd..e3371b24f 100644
+ "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[] = {
@@ -401,10 +414,12 @@ static const TypeInfo spapr_cpu_core_type_infos[] = {
.instance_size = sizeof(SpaprCpuCore),
.class_size = sizeof(SpaprCpuCoreClass),
},
@ -293,10 +289,10 @@ index 56090abcd..e3371b24f 100644
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
index 39bd5bd5e..e50e8328d 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -157,6 +157,7 @@ struct SpaprMachineClass {
@@ -156,6 +156,7 @@ struct SpaprMachineClass {
bool pre_5_2_numa_associativity;
bool pre_6_2_numa_affinity;
@ -314,10 +310,10 @@ index f6de3e997..3cc7ef0c0 100644
/*< public >*/
char *kvm_type;
diff --git a/target/ppc/compat.c b/target/ppc/compat.c
index ebef2ccce..ab7ed7680 100644
index 55de3bd5d..1bf6994da 100644
--- a/target/ppc/compat.c
+++ b/target/ppc/compat.c
@@ -114,6 +114,17 @@ static const CompatInfo *compat_by_pvr(uint32_t pvr)
@@ -121,6 +121,17 @@ static const CompatInfo *compat_by_pvr(uint32_t pvr)
return NULL;
}
@ -336,7 +332,7 @@ index ebef2ccce..ab7ed7680 100644
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
index ece348178..6cfa71eec 100644
--- a/target/ppc/cpu-models.c
+++ b/target/ppc/cpu-models.c
@@ -66,6 +66,7 @@
@ -366,7 +362,7 @@ index f2301b43f..4c38fa517 100644
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[] = {
@@ -897,12 +901,14 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
{ "7457a", "7457a_v1.2" },
{ "apollo7pm", "7457a_v1.0" },
#if defined(TARGET_PPC64)
@ -381,11 +377,10 @@ index f2301b43f..4c38fa517 100644
{ "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" },
@@ -914,12 +920,14 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
{ "power11", "power11_v2.0" },
#endif
-
+#if 0 /* Disabled for Red Hat Enterprise Linux */
/* Generic PowerPCs */
#if defined(TARGET_PPC64)
@ -398,10 +393,10 @@ index f2301b43f..4c38fa517 100644
{ NULL, NULL }
};
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 321ed2da7..e35a99762 100644
index 3ee83517d..121e57482 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)
@@ -1686,6 +1686,7 @@ static inline int ppc_env_mmu_index(CPUPPCState *env, bool ifetch)
/* Compatibility modes */
#if defined(TARGET_PPC64)
@ -410,26 +405,26 @@ index 321ed2da7..e35a99762 100644
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
index 992356cb7..43c468343 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -92,6 +92,7 @@ static int cap_large_decr;
static int cap_fwnmi;
@@ -93,6 +93,7 @@ static int cap_fwnmi;
static int cap_rpt_invalidate;
static int cap_ail_mode_3;
static int cap_dawr1;
+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)
@@ -151,6 +152,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)
cap_dawr1 = kvm_vm_check_extension(s, KVM_CAP_PPC_DAWR1);
@@ -2609,6 +2611,16 @@ bool kvmppc_supports_ail_3(void)
return cap_ail_mode_3;
}
@ -446,7 +441,7 @@ index 907dba60d..c942ff55b 100644
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)
@@ -3024,3 +3036,18 @@ static void kvm_cpu_accel_register_types(void)
type_register_static(&kvm_cpu_accel_type_info);
}
type_init(kvm_cpu_accel_register_types);
@ -466,7 +461,7 @@ index 907dba60d..c942ff55b 100644
+ }
+}
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index 1975fb5ee..d1017f98b 100644
index a8768c1df..59f50cb79 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -46,6 +46,7 @@ int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu);
@ -477,7 +472,7 @@ index 1975fb5ee..d1017f98b 100644
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);
@@ -81,6 +82,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);
@ -486,7 +481,7 @@ index 1975fb5ee..d1017f98b 100644
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)
@@ -439,6 +442,16 @@ static inline bool kvmppc_supports_ail_3(void)
return false;
}
@ -503,5 +498,31 @@ index 1975fb5ee..d1017f98b 100644
static inline int kvmppc_enable_hwrng(void)
{
return -1;
diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c
index 46ae454af..607ed3735 100644
--- a/target/ppc/misc_helper.c
+++ b/target/ppc/misc_helper.c
@@ -332,10 +332,6 @@ target_ulong helper_load_sprd(CPUPPCState *env)
PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
target_ulong sprc = env->spr[SPR_POWER_SPRC];
- if (pc->big_core) {
- pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
- }
-
switch (sprc & 0x3e0) {
case 0: /* SCRATCH0-3 */
case 1: /* SCRATCH4-7 */
@@ -372,10 +368,6 @@ void helper_store_sprd(CPUPPCState *env, target_ulong val)
PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
int nr;
- if (pc->big_core) {
- pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
- }
-
switch (sprc & 0x3e0) {
case 0: /* SCRATCH0-3 */
case 1: /* SCRATCH4-7 */
--
2.39.5 (Apple Git-154)

View File

@ -11,11 +11,10 @@ diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devi
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
@@ -118,3 +118,4 @@ CONFIG_VHOST_USER_FS=y
CONFIG_VHOST_USER_SND=y
CONFIG_VHOST_USER_GPU=y
CONFIG_UEFI_VARS=y
+CONFIG_QXL=y
--
2.43.5

View File

@ -0,0 +1,56 @@
From e4a324ce1f4ffca214b6d5b5681b9eca630707bf Mon Sep 17 00:00:00 2001
From: Laurent Vivier <lvivier@redhat.com>
Date: Tue, 29 Jul 2025 17:00:50 +0200
Subject: [PATCH] Declare rtl8139 as deprecated
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Laurent Vivier <lvivier@redhat.com>
RH-MergeRequest: 396: Declare rtl8139 as deprecated
RH-Jira: RHEL-45624
RH-Acked-by: Eugenio Pérez <eperezma@redhat.com>
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Cindy Lu <lulu@redhat.com>
RH-Commit: [1/1] d44c1b68b59f1442b01c84b43e07aed5f4d254bc (lvivier/qemu-kvm-centos)
JIRA: https://issues.redhat.com/browse/RHEL-45624
Upstream: RHEL ONLY
The e1000+e1000e pair should be more than sufficient for the
"ancient non-virtio NIC" use case.
There does not appear to be any compelling reason to continue supporting
the rtl8139 NIC, so we should deprecate it in RHEL-10, with a view to
deleting it in RHEL-11.
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---
hw/net/rtl8139.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 31a6956252..7609006394 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -57,6 +57,7 @@
#include "system/dma.h"
#include "qemu/module.h"
#include "qemu/timer.h"
+#include "qemu/error-report.h"
#include "net/net.h"
#include "net/eth.h"
#include "system/system.h"
@@ -3364,6 +3365,9 @@ static void pci_rtl8139_realize(PCIDevice *dev, Error **errp)
DeviceState *d = DEVICE(dev);
uint8_t *pci_conf;
+ warn_report("'rtl8139' is deprecated, "
+ "please use a different Network Interface Card");
+
pci_conf = dev->config;
pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */
/* TODO: start of capability list, but no capability
--
2.39.3

View File

@ -0,0 +1,54 @@
From 12720b4c0434d9549f0e41ed5951890fdd9aedd4 Mon Sep 17 00:00:00 2001
From: Andrea Bolognani <abologna@redhat.com>
Date: Tue, 10 Jun 2025 14:27:29 +0200
Subject: [PATCH 5/5] Disable virtio-net-pci romfile loading on riscv64
RH-Author: Andrea Bolognani <None>
RH-MergeRequest: 373: Various small fixes
RH-Jira: RHEL-96057
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [4/4] b490ef3c3ab6a47f90c67016f685e19a65d97100 (abologna/centos-stream-qemu-kvm)
Same motivation for disabling it as on aarch64.
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
---
hw/riscv/virt.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index b8d20575af..5b9291a906 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -59,6 +59,18 @@
#include "hw/virtio/virtio-iommu.h"
#include "hw/uefi/var-service-api.h"
+/*
+ * virtio-net-pci variant romfiles are not needed because edk2 does
+ * fully support the pxe boot. Besides virtio romfiles are not shipped
+ * on rhel/riscv64.
+ */
+static GlobalProperty riscv_virt_compat[] = {
+ {"virtio-net-pci", "romfile", "" },
+ {"virtio-net-pci-transitional", "romfile", "" },
+ {"virtio-net-pci-non-transitional", "romfile", "" },
+};
+const size_t riscv_virt_compat_len = G_N_ELEMENTS(riscv_virt_compat);
+
/* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU. */
static bool virt_use_kvm_aia_aplic_imsic(RISCVVirtAIAType aia_type)
{
@@ -1977,6 +1989,9 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
NULL, NULL);
object_class_property_set_description(oc, "iommu-sys",
"Enable IOMMU platform device");
+
+ compat_props_add(mc->compat_props, riscv_virt_compat,
+ riscv_virt_compat_len);
}
static const TypeInfo virt_machine_typeinfo = {
--
2.39.3

View File

@ -0,0 +1,38 @@
From 7b15a63367901d3d3fad7cd17c3960662f2f88f0 Mon Sep 17 00:00:00 2001
From: John Allen <john.allen@amd.com>
Date: Wed, 11 Jun 2025 15:41:14 -0500
Subject: [PATCH 42/43] Enable amd-iommu device
RH-Author: John Allen <None>
RH-MergeRequest: 383: Add ability to manually specify the AMDVI-PCI device
RH-Jira: RHEL-85649
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [3/3] 401f99c41c07746b736300bf40175df11a3330d0 (johnalle/qemu-kvm-fork)
Now that the amdvi-pci device that amd-iommu creates can be specified
manually, amd-iommu device can be enabled.
JIRA: https://issues.redhat.com/browse/RHEL-85649
Upstream: RHEL ONLY
Signed-off-by: John Allen <johnalle@redhat.com>
---
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 097dad9003..26e51b1edf 100644
--- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
@@ -97,6 +97,7 @@ CONFIG_VIRTIO_MEM=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_VGA=y
CONFIG_VIRTIO_IOMMU=y
+CONFIG_AMD_IOMMU=y
CONFIG_VMMOUSE=y
CONFIG_VMPORT=y
CONFIG_VTD=y
--
2.39.3

View File

@ -0,0 +1,45 @@
From 058b99a669b3cdd55a8c0c685d2fbfae0935d79e Mon Sep 17 00:00:00 2001
From: Shaoqin Huang <shahuang@redhat.com>
Date: Wed, 6 Aug 2025 22:31:50 -0400
Subject: [PATCH] Enable uefi variable service for edk2
RH-Author: Shaoqin Huang <shahuang@redhat.com>
RH-MergeRequest: 398: Enable uefi variable service for edk2
RH-Jira: RHEL-102325
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
RH-Commit: [1/1] b498b1f4fbdb31b7bb1122caaacd8f391124b1a0 (shahuang/qemu-kvm)
JIRA: https://issues.redhat.com/browse/RHEL-102325
To support secure boot, we need the uefi variable service for edk2 to be
available.
Signed-off-by: Shaoqin Huang <shahuang@redhat.com>
---
configs/devices/aarch64-softmmu/aarch64-rh-devices.mak | 1 +
configs/devices/x86_64-softmmu/x86_64-rh-devices.mak | 1 +
2 files changed, 2 insertions(+)
diff --git a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
index 197fabeb00..855278f70e 100644
--- a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
+++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
@@ -46,3 +46,4 @@ CONFIG_IOMMUFD=y
CONFIG_VHOST_USER_SND=y
CONFIG_VHOST_USER_SCMI=y
CONFIG_VHOST_USER_GPU=y
+CONFIG_UEFI_VARS=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 26e51b1edf..828cb8aa6f 100644
--- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
@@ -115,3 +115,4 @@ CONFIG_VHOST_USER_FS=y
CONFIG_IOMMUFD=y
CONFIG_VHOST_USER_SND=y
CONFIG_VHOST_USER_GPU=y
+CONFIG_UEFI_VARS=y
--
2.39.3

View File

@ -0,0 +1,39 @@
From 86f52a84c158f7b31455596c9700124977696314 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Tue, 29 Apr 2025 09:09:51 -0400
Subject: [PATCH 4/4] Enable vhost-user-gpu-pci for RHIVOS
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-MergeRequest: 356: Enable vhost-user-gpu-pci for RHIVOS
RH-Jira: RHEL-86056
RH-Commit: [1/1] d323301596f82a3b0a98b0ac99f839d39199ab32 (mrezanin/centos-src-qemu-kvm)
RHIVOS needs vhost-user-gpu-pci device to be available.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
configs/devices/aarch64-softmmu/aarch64-rh-devices.mak | 1 +
configs/devices/x86_64-softmmu/x86_64-rh-devices.mak | 1 +
2 files changed, 2 insertions(+)
diff --git a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
index dce5fca821..197fabeb00 100644
--- a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
+++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
@@ -45,3 +45,4 @@ CONFIG_VHOST_USER_FS=y
CONFIG_IOMMUFD=y
CONFIG_VHOST_USER_SND=y
CONFIG_VHOST_USER_SCMI=y
+CONFIG_VHOST_USER_GPU=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 8da1a8f82f..097dad9003 100644
--- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
@@ -113,3 +113,4 @@ CONFIG_VHOST_USER_VSOCK=y
CONFIG_VHOST_USER_FS=y
CONFIG_IOMMUFD=y
CONFIG_VHOST_USER_SND=y
+CONFIG_VHOST_USER_GPU=y
--
2.39.3

View File

@ -1,50 +0,0 @@
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

View File

@ -1,251 +0,0 @@
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

View File

@ -1,73 +0,0 @@
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

View File

@ -1,90 +0,0 @@
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

View File

@ -1,76 +0,0 @@
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

View File

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

View File

@ -1,144 +0,0 @@
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

View File

@ -1,49 +0,0 @@
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

View File

@ -1,45 +0,0 @@
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

View File

@ -1,60 +0,0 @@
From d36ac428991e700dd5cec62dfa16f1d414a9dda8 Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
Date: Fri, 17 Jan 2025 05:50:54 -0500
Subject: [PATCH 6/6] arm: disable pauth for virt-rhel9* in RHEL10
RH-Author: Sebastian Ott <sebott@redhat.com>
RH-MergeRequest: 327: arm: disable pauth for virt-rhel9* in RHEL10
RH-Jira: RHEL-71761
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
RH-Acked-by: Kashyap Chamarthy <None>
RH-Acked-by: Gavin Shan <gshan@redhat.com>
RH-Commit: [1/1] fef388b1aafce66fa1a176739264bca49596bb94 (seott1/cos-qemu-kvm)
RHEL9 kernels have pauth disabled while RHEL10 has it enabled,
since qemu will setup the VM/VCPU with pauth when KVM supports it
the guest visible ID registers will differ between RHEL9 and RHEL10
(on a host with pauth support) leading to migration / upgrade failures.
Fix this by disabling pauth for virt-rhel9* machine types in RHEL10.
Signed-off-by: Sebastian Ott <sebott@redhat.com>
JIRA: https://issues.redhat.com/browse/RHEL-71761
---
hw/arm/virt.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 6d55bba241..55bd92e6d0 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -90,6 +90,16 @@ static GlobalProperty arm_virt_compat[] = {
};
static const size_t arm_virt_compat_len = G_N_ELEMENTS(arm_virt_compat);
+/*
+ * RHEL9 kernels have pauth disabled while RHEL10 has it enabled,
+ * since qemu will setup the VM with pauth when KVM supports it we
+ * have to disable it for virt-rhel9* to support upgrades / migration.
+ */
+GlobalProperty arm_rhel9_compat[] = {
+ {TYPE_ARM_CPU, "pauth", "off", .optional = true},
+};
+const size_t arm_rhel9_compat_len = G_N_ELEMENTS(arm_rhel9_compat);
+
/*
* This variable is for changes to properties that are RHEL specific,
* different to the current upstream and to be applied to the latest
@@ -3596,6 +3606,8 @@ static void virt_rhel_machine_9_6_0_options(MachineClass *mc)
{
virt_rhel_machine_10_0_0_options(mc);
+ compat_props_add(mc->compat_props, arm_rhel9_compat, arm_rhel9_compat_len);
+
/* NB: remember to move this line to the *latest* RHEL 9 machine */
compat_props_add(mc->compat_props, hw_compat_rhel_9, hw_compat_rhel_9_len);
}
--
2.39.3

View File

@ -1,317 +0,0 @@
From 01973563401bf804505e36fecf0c229fd548eda4 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 4 Feb 2025 22:13:52 +0100
Subject: [PATCH 07/22] block: Add 'active' field to BlockDeviceInfo
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 340: QMP command for block device reactivation after migration
RH-Jira: RHEL-54670
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [7/22] 944b834b1aa3138d87bdbfce3c9fce105bd09a9d (kmwolf/centos-qemu-kvm)
This allows querying from QMP (and also HMP) whether an image is
currently active or inactive (in the sense of BDRV_O_INACTIVE).
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250204211407.381505-2-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit aec81049c2daa8a97b89e59f03733b21ae0f8c2d)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 4 ++++
block/monitor/block-hmp-cmds.c | 5 +++--
block/qapi.c | 1 +
include/block/block-global-state.h | 3 +++
qapi/block-core.json | 6 +++++-
tests/qemu-iotests/184.out | 2 ++
tests/qemu-iotests/191.out | 16 ++++++++++++++++
tests/qemu-iotests/273.out | 5 +++++
8 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/block.c b/block.c
index c317de9eaa..c94d78eefd 100644
--- a/block.c
+++ b/block.c
@@ -6824,6 +6824,10 @@ void bdrv_init_with_whitelist(void)
bdrv_init();
}
+bool bdrv_is_inactive(BlockDriverState *bs) {
+ return bs->open_flags & BDRV_O_INACTIVE;
+}
+
int bdrv_activate(BlockDriverState *bs, Error **errp)
{
BdrvChild *child, *parent;
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index bdf2eb50b6..cc832549e1 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -630,11 +630,12 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
}
if (inserted) {
- monitor_printf(mon, ": %s (%s%s%s)\n",
+ monitor_printf(mon, ": %s (%s%s%s%s)\n",
inserted->file,
inserted->drv,
inserted->ro ? ", read-only" : "",
- inserted->encrypted ? ", encrypted" : "");
+ inserted->encrypted ? ", encrypted" : "",
+ inserted->active ? "" : ", inactive");
} else {
monitor_printf(mon, ": [not inserted]\n");
}
diff --git a/block/qapi.c b/block/qapi.c
index 2b5793f1d9..709170e63d 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -63,6 +63,7 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
info->file = g_strdup(bs->filename);
info->ro = bdrv_is_read_only(bs);
info->drv = g_strdup(bs->drv->format_name);
+ info->active = !bdrv_is_inactive(bs);
info->encrypted = bs->encrypted;
info->cache = g_new(BlockdevCacheInfo, 1);
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
index bd7cecd1cf..a826bf5f78 100644
--- a/include/block/block-global-state.h
+++ b/include/block/block-global-state.h
@@ -175,6 +175,9 @@ BlockDriverState * GRAPH_RDLOCK
check_to_replace_node(BlockDriverState *parent_bs, const char *node_name,
Error **errp);
+
+bool GRAPH_RDLOCK bdrv_is_inactive(BlockDriverState *bs);
+
int no_coroutine_fn GRAPH_RDLOCK
bdrv_activate(BlockDriverState *bs, Error **errp);
diff --git a/qapi/block-core.json b/qapi/block-core.json
index aa40d44f1d..92af032744 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -486,6 +486,10 @@
# @backing_file_depth: number of files in the backing file chain
# (since: 1.2)
#
+# @active: true if the backend is active; typical cases for inactive backends
+# are on the migration source instance after migration completes and on the
+# destination before it completes. (since: 10.0)
+#
# @encrypted: true if the backing device is encrypted
#
# @detect_zeroes: detect and optimize zero writes (Since 2.1)
@@ -556,7 +560,7 @@
{ 'struct': 'BlockDeviceInfo',
'data': { 'file': 'str', '*node-name': 'str', 'ro': 'bool', 'drv': 'str',
'*backing_file': 'str', 'backing_file_depth': 'int',
- 'encrypted': 'bool',
+ 'active': 'bool', 'encrypted': 'bool',
'detect_zeroes': 'BlockdevDetectZeroesOptions',
'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int',
diff --git a/tests/qemu-iotests/184.out b/tests/qemu-iotests/184.out
index e8f631f853..52692b6b3b 100644
--- a/tests/qemu-iotests/184.out
+++ b/tests/qemu-iotests/184.out
@@ -26,6 +26,7 @@ Testing:
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"backing-image": {
"virtual-size": 1073741824,
@@ -59,6 +60,7 @@ Testing:
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"virtual-size": 1073741824,
"filename": "null-co://",
diff --git a/tests/qemu-iotests/191.out b/tests/qemu-iotests/191.out
index c3309e4bc6..2a72ca7106 100644
--- a/tests/qemu-iotests/191.out
+++ b/tests/qemu-iotests/191.out
@@ -114,6 +114,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"backing-image": {
"virtual-size": 67108864,
@@ -155,6 +156,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"virtual-size": 197120,
"filename": "TEST_DIR/t.IMGFMT.ovl2",
@@ -183,6 +185,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"backing-image": {
"virtual-size": 67108864,
@@ -224,6 +227,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"virtual-size": 197120,
"filename": "TEST_DIR/t.IMGFMT",
@@ -252,6 +256,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"backing-image": {
"virtual-size": 67108864,
@@ -293,6 +298,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"virtual-size": 393216,
"filename": "TEST_DIR/t.IMGFMT.mid",
@@ -321,6 +327,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"virtual-size": 67108864,
"filename": "TEST_DIR/t.IMGFMT.base",
@@ -350,6 +357,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"virtual-size": 393216,
"filename": "TEST_DIR/t.IMGFMT.base",
@@ -521,6 +529,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"backing-image": {
"virtual-size": 67108864,
@@ -562,6 +571,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"virtual-size": 197120,
"filename": "TEST_DIR/t.IMGFMT.ovl2",
@@ -590,6 +600,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"backing-image": {
"backing-image": {
@@ -642,6 +653,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"virtual-size": 197120,
"filename": "TEST_DIR/t.IMGFMT.ovl3",
@@ -670,6 +682,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"virtual-size": 67108864,
"filename": "TEST_DIR/t.IMGFMT.base",
@@ -699,6 +712,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"virtual-size": 393216,
"filename": "TEST_DIR/t.IMGFMT.base",
@@ -727,6 +741,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"backing-image": {
"virtual-size": 67108864,
@@ -768,6 +783,7 @@ wrote 65536/65536 bytes at offset 1048576
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"virtual-size": 197120,
"filename": "TEST_DIR/t.IMGFMT",
diff --git a/tests/qemu-iotests/273.out b/tests/qemu-iotests/273.out
index 71843f02de..c19753c685 100644
--- a/tests/qemu-iotests/273.out
+++ b/tests/qemu-iotests/273.out
@@ -23,6 +23,7 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"backing-image": {
"backing-image": {
@@ -74,6 +75,7 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"virtual-size": 197120,
"filename": "TEST_DIR/t.IMGFMT",
@@ -102,6 +104,7 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"backing-image": {
"virtual-size": 197120,
@@ -142,6 +145,7 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"virtual-size": 197120,
"filename": "TEST_DIR/t.IMGFMT.mid",
@@ -170,6 +174,7 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev
{
"iops_rd": 0,
"detect_zeroes": "off",
+ "active": true,
"image": {
"virtual-size": 197120,
"filename": "TEST_DIR/t.IMGFMT.base",
--
2.39.3

View File

@ -1,187 +0,0 @@
From d2cb8b847b6f88b4cbabea12a0b62f323d9000ff Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 4 Feb 2025 22:13:59 +0100
Subject: [PATCH 14/22] block: Add blockdev-set-active QMP command
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 340: QMP command for block device reactivation after migration
RH-Jira: RHEL-54670
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [14/22] 0fbba1347acea9983b4fb3d35d1a4c00a09e5579 (kmwolf/centos-qemu-kvm)
The system emulator tries to automatically activate and inactivate block
nodes at the right point during migration. However, there are still
cases where it's necessary that the user can do this manually.
Images are only activated on the destination VM of a migration when the
VM is actually resumed. If the VM was paused, this doesn't happen
automatically. The user may want to perform some operation on a block
device (e.g. taking a snapshot or starting a block job) without also
resuming the VM yet. This is an example where a manual command is
necessary.
Another example is VM migration when the image files are opened by an
external qemu-storage-daemon instance on each side. In this case, the
process that needs to hand over the images isn't even part of the
migration and can't know when the migration completes. Management tools
need a way to explicitly inactivate images on the source and activate
them on the destination.
This adds a new blockdev-set-active QMP command that lets the user
change the status of individual nodes (this is necessary in
qemu-storage-daemon because it could be serving multiple VMs and only
one of them migrates at a time). For convenience, operating on all
devices (like QEMU does automatically during migration) is offered as an
option, too, and can be used in the context of single VM.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250204211407.381505-9-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 8cd37207f8a90c5f995283ecf95f1cb5f7518a77)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 21 ++++++++++++++++++++
blockdev.c | 32 ++++++++++++++++++++++++++++++
include/block/block-global-state.h | 3 +++
qapi/block-core.json | 32 ++++++++++++++++++++++++++++++
4 files changed, 88 insertions(+)
diff --git a/block.c b/block.c
index fd2ac177ef..2140a5d3b7 100644
--- a/block.c
+++ b/block.c
@@ -7052,6 +7052,27 @@ bdrv_inactivate_recurse(BlockDriverState *bs, bool top_level)
return 0;
}
+int bdrv_inactivate(BlockDriverState *bs, Error **errp)
+{
+ int ret;
+
+ GLOBAL_STATE_CODE();
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
+
+ if (bdrv_has_bds_parent(bs, true)) {
+ error_setg(errp, "Node has active parent node");
+ return -EPERM;
+ }
+
+ ret = bdrv_inactivate_recurse(bs, true);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to inactivate node");
+ return ret;
+ }
+
+ return 0;
+}
+
int bdrv_inactivate_all(void)
{
BlockDriverState *bs = NULL;
diff --git a/blockdev.c b/blockdev.c
index 81430122df..70046b6690 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3468,6 +3468,38 @@ void qmp_blockdev_del(const char *node_name, Error **errp)
bdrv_unref(bs);
}
+void qmp_blockdev_set_active(const char *node_name, bool active, Error **errp)
+{
+ int ret;
+
+ GLOBAL_STATE_CODE();
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
+
+ if (!node_name) {
+ if (active) {
+ bdrv_activate_all(errp);
+ } else {
+ ret = bdrv_inactivate_all();
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to inactivate all nodes");
+ }
+ }
+ } else {
+ BlockDriverState *bs = bdrv_find_node(node_name);
+ if (!bs) {
+ error_setg(errp, "Failed to find node with node-name='%s'",
+ node_name);
+ return;
+ }
+
+ if (active) {
+ bdrv_activate(bs, errp);
+ } else {
+ bdrv_inactivate(bs, errp);
+ }
+ }
+}
+
static BdrvChild * GRAPH_RDLOCK
bdrv_find_child(BlockDriverState *parent_bs, const char *child_name)
{
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
index a826bf5f78..9be34b3c99 100644
--- a/include/block/block-global-state.h
+++ b/include/block/block-global-state.h
@@ -184,6 +184,9 @@ bdrv_activate(BlockDriverState *bs, Error **errp);
int coroutine_fn no_co_wrapper_bdrv_rdlock
bdrv_co_activate(BlockDriverState *bs, Error **errp);
+int no_coroutine_fn
+bdrv_inactivate(BlockDriverState *bs, Error **errp);
+
void bdrv_activate_all(Error **errp);
int bdrv_inactivate_all(void);
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 6ec603aa6f..c1af3d1f7d 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -4930,6 +4930,38 @@
{ 'command': 'blockdev-del', 'data': { 'node-name': 'str' },
'allow-preconfig': true }
+##
+# @blockdev-set-active:
+#
+# Activate or inactivate a block device. Use this to manage the handover of
+# block devices on migration with qemu-storage-daemon.
+#
+# Activating a node automatically activates all of its child nodes first.
+# Inactivating a node automatically inactivates any of its child nodes that are
+# not in use by a still active node.
+#
+# @node-name: Name of the graph node to activate or inactivate. By default, all
+# nodes are affected by the operation.
+#
+# @active: true if the nodes should be active when the command returns success,
+# false if they should be inactive.
+#
+# Since: 10.0
+#
+# .. qmp-example::
+#
+# -> { "execute": "blockdev-set-active",
+# "arguments": {
+# "node-name": "node0",
+# "active": false
+# }
+# }
+# <- { "return": {} }
+##
+{ 'command': 'blockdev-set-active',
+ 'data': { '*node-name': 'str', 'active': 'bool' },
+ 'allow-preconfig': true }
+
##
# @BlockdevCreateOptionsFile:
#
--
2.39.3

View File

@ -0,0 +1,143 @@
From 659dd2d1f7b1facbf9c548468c1b50237f7aa8e4 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Fri, 9 May 2025 15:40:21 -0500
Subject: [PATCH 04/14] block: Add new bdrv_co_is_all_zeroes() function
RH-Author: Eric Blake <eblake@redhat.com>
RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors
RH-Jira: RHEL-88435 RHEL-88437
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [4/14] 404590dbec0b1113872a7eb1bfe5af0450fe6a28 (ebblake/centos-qemu-kvm)
There are some optimizations that require knowing if an image starts
out as reading all zeroes, such as making blockdev-mirror faster by
skipping the copying of source zeroes to the destination. The
existing bdrv_co_is_zero_fast() is a good building block for answering
this question, but it tends to give an answer of 0 for a file we just
created via QMP 'blockdev-create' or similar (such as 'qemu-img create
-f raw'). Why? Because file-posix.c insists on allocating a tiny
header to any file rather than leaving it 100% sparse, due to some
filesystems that are unable to answer alignment probes on a hole. But
teaching file-posix.c to read the tiny header doesn't scale - the
problem of a small header is also visible when libvirt sets up an NBD
client to a just-created file on a migration destination host.
So, we need a wrapper function that handles a bit more complexity in a
common manner for all block devices - when the BDS is mostly a hole,
but has a small non-hole header, it is still worth the time to read
that header and check if it reads as all zeroes before giving up and
returning a pessimistic answer.
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250509204341.3553601-19-eblake@redhat.com>
(cherry picked from commit 52726096707c5c8b90597c445de897fa64d56e73)
Jira: https://issues.redhat.com/browse/RHEL-88435
Jira: https://issues.redhat.com/browse/RHEL-88437
Signed-off-by: Eric Blake <eblake@redhat.com>
---
block/io.c | 62 ++++++++++++++++++++++++++++++++++++++++
include/block/block-io.h | 2 ++
2 files changed, 64 insertions(+)
diff --git a/block/io.c b/block/io.c
index 64f4b1d22a..b6fc07e1dc 100644
--- a/block/io.c
+++ b/block/io.c
@@ -38,10 +38,14 @@
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "system/replay.h"
+#include "qemu/units.h"
/* Maximum bounce buffer for copy-on-read and write zeroes, in bytes */
#define MAX_BOUNCE_BUFFER (32768 << BDRV_SECTOR_BITS)
+/* Maximum read size for checking if data reads as zero, in bytes */
+#define MAX_ZERO_CHECK_BUFFER (128 * KiB)
+
static void coroutine_fn GRAPH_RDLOCK
bdrv_parent_cb_resize(BlockDriverState *bs);
@@ -2778,6 +2782,64 @@ int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
return 1;
}
+/*
+ * Check @bs (and its backing chain) to see if the entire image is known
+ * to read as zeroes.
+ * Return 1 if that is the case, 0 otherwise and -errno on error.
+ * This test is meant to be fast rather than accurate so returning 0
+ * does not guarantee non-zero data; however, a return of 1 is reliable,
+ * and this function can report 1 in more cases than bdrv_co_is_zero_fast.
+ */
+int coroutine_fn bdrv_co_is_all_zeroes(BlockDriverState *bs)
+{
+ int ret;
+ int64_t pnum, bytes;
+ char *buf;
+ QEMUIOVector local_qiov;
+ IO_CODE();
+
+ bytes = bdrv_co_getlength(bs);
+ if (bytes < 0) {
+ return bytes;
+ }
+
+ /* First probe - see if the entire image reads as zero */
+ ret = bdrv_co_common_block_status_above(bs, NULL, false, BDRV_WANT_ZERO,
+ 0, bytes, &pnum, NULL, NULL,
+ NULL);
+ if (ret < 0) {
+ return ret;
+ }
+ if (ret & BDRV_BLOCK_ZERO) {
+ return bdrv_co_is_zero_fast(bs, pnum, bytes - pnum);
+ }
+
+ /*
+ * Because of the way 'blockdev-create' works, raw files tend to
+ * be created with a non-sparse region at the front to make
+ * alignment probing easier. If the block starts with only a
+ * small allocated region, it is still worth the effort to see if
+ * the rest of the image is still sparse, coupled with manually
+ * reading the first region to see if it reads zero after all.
+ */
+ if (pnum > MAX_ZERO_CHECK_BUFFER) {
+ return 0;
+ }
+ ret = bdrv_co_is_zero_fast(bs, pnum, bytes - pnum);
+ if (ret <= 0) {
+ return ret;
+ }
+ /* Only the head of the image is unknown, and it's small. Read it. */
+ buf = qemu_blockalign(bs, pnum);
+ qemu_iovec_init_buf(&local_qiov, buf, pnum);
+ ret = bdrv_driver_preadv(bs, 0, pnum, &local_qiov, 0, 0);
+ if (ret >= 0) {
+ ret = buffer_is_zero(buf, pnum);
+ }
+ qemu_vfree(buf);
+ return ret;
+}
+
int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t offset,
int64_t bytes, int64_t *pnum)
{
diff --git a/include/block/block-io.h b/include/block/block-io.h
index b49e0537dd..b99cc98d26 100644
--- a/include/block/block-io.h
+++ b/include/block/block-io.h
@@ -161,6 +161,8 @@ bdrv_is_allocated_above(BlockDriverState *bs, BlockDriverState *base,
int coroutine_fn GRAPH_RDLOCK
bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset, int64_t bytes);
+int coroutine_fn GRAPH_RDLOCK
+bdrv_co_is_all_zeroes(BlockDriverState *bs);
int GRAPH_RDLOCK
bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
--
2.39.3

View File

@ -1,102 +0,0 @@
From 990a468ee87adc98bb53d859b52c8a5c7bbb8524 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 4 Feb 2025 22:13:58 +0100
Subject: [PATCH 13/22] block: Add option to create inactive nodes
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 340: QMP command for block device reactivation after migration
RH-Jira: RHEL-54670
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [13/22] 4e5d2d86502ac5ace83f2abe4a48abfba188256d (kmwolf/centos-qemu-kvm)
In QEMU, nodes are automatically created inactive while expecting an
incoming migration (i.e. RUN_STATE_INMIGRATE). In qemu-storage-daemon,
the notion of runstates doesn't exist. It also wouldn't necessarily make
sense to introduce it because a single daemon can serve multiple VMs
that can be in different states.
Therefore, allow the user to explicitly open images as inactive with a
new option. The default is as before: Nodes are usually active, except
when created during RUN_STATE_INMIGRATE.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250204211407.381505-8-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit faecd16fe5c65a25b5b55b5edbe4322cec5a9d96)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 9 +++++++++
include/block/block-common.h | 1 +
qapi/block-core.json | 6 ++++++
3 files changed, 16 insertions(+)
diff --git a/block.c b/block.c
index bedd54deaa..fd2ac177ef 100644
--- a/block.c
+++ b/block.c
@@ -1573,6 +1573,10 @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
if (qemu_opt_get_bool_del(opts, BDRV_OPT_AUTO_READ_ONLY, false)) {
*flags |= BDRV_O_AUTO_RDONLY;
}
+
+ if (!qemu_opt_get_bool_del(opts, BDRV_OPT_ACTIVE, true)) {
+ *flags |= BDRV_O_INACTIVE;
+ }
}
static void update_options_from_flags(QDict *options, int flags)
@@ -1799,6 +1803,11 @@ QemuOptsList bdrv_runtime_opts = {
.type = QEMU_OPT_BOOL,
.help = "Ignore flush requests",
},
+ {
+ .name = BDRV_OPT_ACTIVE,
+ .type = QEMU_OPT_BOOL,
+ .help = "Node is activated",
+ },
{
.name = BDRV_OPT_READ_ONLY,
.type = QEMU_OPT_BOOL,
diff --git a/include/block/block-common.h b/include/block/block-common.h
index 338fe5ff7a..7030669f04 100644
--- a/include/block/block-common.h
+++ b/include/block/block-common.h
@@ -257,6 +257,7 @@ typedef enum {
#define BDRV_OPT_AUTO_READ_ONLY "auto-read-only"
#define BDRV_OPT_DISCARD "discard"
#define BDRV_OPT_FORCE_SHARE "force-share"
+#define BDRV_OPT_ACTIVE "active"
#define BDRV_SECTOR_BITS 9
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 92af032744..6ec603aa6f 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -4668,6 +4668,11 @@
#
# @cache: cache-related options
#
+# @active: whether the block node should be activated (default: true).
+# Having inactive block nodes is useful primarily for migration because it
+# allows opening an image on the destination while the source is still
+# holding locks for it. (Since 10.0)
+#
# @read-only: whether the block device should be read-only (default:
# false). Note that some block drivers support only read-only
# access, either generally or in certain configurations. In this
@@ -4694,6 +4699,7 @@
'*node-name': 'str',
'*discard': 'BlockdevDiscardOptions',
'*cache': 'BlockdevCacheOptions',
+ '*active': 'bool',
'*read-only': 'bool',
'*auto-read-only': 'bool',
'*force-share': 'bool',
--
2.39.3

View File

@ -1,80 +0,0 @@
From 87507aae02f0b381c658a71777baad6fe3129485 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 4 Feb 2025 22:13:53 +0100
Subject: [PATCH 08/22] block: Allow inactivating already inactive nodes
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 340: QMP command for block device reactivation after migration
RH-Jira: RHEL-54670
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [8/22] 5247551bb2cc2ac51ce28f690f30b0f54c9abef5 (kmwolf/centos-qemu-kvm)
What we wanted to catch with the assertion is cases where the recursion
finds that a child was inactive before its parent. This should never
happen. But if the user tries to inactivate an image that is already
inactive, that's harmless and we don't want to fail the assertion.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250204211407.381505-3-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit a6490ec9d56b9e95a13918813585a3a9891710bc)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/block.c b/block.c
index c94d78eefd..a2aa454312 100644
--- a/block.c
+++ b/block.c
@@ -6959,7 +6959,8 @@ bdrv_has_bds_parent(BlockDriverState *bs, bool only_active)
return false;
}
-static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs)
+static int GRAPH_RDLOCK
+bdrv_inactivate_recurse(BlockDriverState *bs, bool top_level)
{
BdrvChild *child, *parent;
int ret;
@@ -6977,7 +6978,14 @@ static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs)
return 0;
}
- assert(!(bs->open_flags & BDRV_O_INACTIVE));
+ /*
+ * Inactivating an already inactive node on user request is harmless, but if
+ * a child is already inactive before its parent, that's bad.
+ */
+ if (bs->open_flags & BDRV_O_INACTIVE) {
+ assert(top_level);
+ return 0;
+ }
/* Inactivate this node */
if (bs->drv->bdrv_inactivate) {
@@ -7014,7 +7022,7 @@ static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs)
/* Recursively inactivate children */
QLIST_FOREACH(child, &bs->children, next) {
- ret = bdrv_inactivate_recurse(child->bs);
+ ret = bdrv_inactivate_recurse(child->bs, false);
if (ret < 0) {
return ret;
}
@@ -7039,7 +7047,7 @@ int bdrv_inactivate_all(void)
if (bdrv_has_bds_parent(bs, false)) {
continue;
}
- ret = bdrv_inactivate_recurse(bs);
+ ret = bdrv_inactivate_recurse(bs, true);
if (ret < 0) {
bdrv_next_cleanup(&it);
break;
--
2.39.3

View File

@ -1,46 +0,0 @@
From 85c5bd4a41fec70482b634ae2d3bb3c56631e337 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 4 Feb 2025 22:13:56 +0100
Subject: [PATCH 11/22] block: Don't attach inactive child to active node
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 340: QMP command for block device reactivation after migration
RH-Jira: RHEL-54670
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [11/22] 7148d3e16eeda8a6142aedeab245a88b879b37b8 (kmwolf/centos-qemu-kvm)
An active node makes unrestricted use of its children and would possibly
run into assertion failures when it operates on an inactive child node.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250204211407.381505-6-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 9b81361aedcc47905de5e91f68221de89c6f5467)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/block.c b/block.c
index a2aa454312..41e72e6965 100644
--- a/block.c
+++ b/block.c
@@ -3183,6 +3183,11 @@ bdrv_attach_child_noperm(BlockDriverState *parent_bs,
child_bs->node_name, child_name, parent_bs->node_name);
return NULL;
}
+ if (bdrv_is_inactive(child_bs) && !bdrv_is_inactive(parent_bs)) {
+ error_setg(errp, "Inactive '%s' can't be a %s child of active '%s'",
+ child_bs->node_name, child_name, parent_bs->node_name);
+ return NULL;
+ }
bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm);
bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL,
--
2.39.3

View File

@ -1,52 +0,0 @@
From e7fa06c5ad14fc4df863265ca4723c9b74368682 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 4 Feb 2025 22:14:02 +0100
Subject: [PATCH 17/22] block: Drain nodes before inactivating them
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 340: QMP command for block device reactivation after migration
RH-Jira: RHEL-54670
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [17/22] 64b1f9168b91793dcf3cf1df39e4799c7dc0f73c (kmwolf/centos-qemu-kvm)
So far the assumption has always been that if we try to inactivate a
node, it is already idle. This doesn't hold true any more if we allow
inactivating exported nodes because we can't know when new external
requests come in.
Drain the node around setting BDRV_O_INACTIVE so that requests can't
start operating on an active node and then in the middle it suddenly
becomes inactive. With this change, it's enough for exports to check
for new requests that they operate on an active node (or, like reads,
are allowed even on an inactive node).
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Fabiano Rosas <farosas@suse.de>
Message-ID: <20250204211407.381505-12-kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 2849092a0024405e74c96f0a5ec41bb182ec8538)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/block.c b/block.c
index 2140a5d3b7..38cb8481a8 100644
--- a/block.c
+++ b/block.c
@@ -7032,7 +7032,9 @@ bdrv_inactivate_recurse(BlockDriverState *bs, bool top_level)
return -EPERM;
}
+ bdrv_drained_begin(bs);
bs->open_flags |= BDRV_O_INACTIVE;
+ bdrv_drained_end(bs);
/*
* Update permissions, they may differ for inactive nodes.
--
2.39.3

View File

@ -0,0 +1,689 @@
From cb945ccd11d37c959f590ae5661ffe5b73f372a7 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Fri, 9 May 2025 15:40:18 -0500
Subject: [PATCH 01/14] block: Expand block status mode from bool to flags
RH-Author: Eric Blake <eblake@redhat.com>
RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors
RH-Jira: RHEL-88435 RHEL-88437
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/14] 12507ca1dbe44640e4a8baded4d5afd5fb4ed615 (ebblake/centos-qemu-kvm)
This patch is purely mechanical, changing bool want_zero into an
unsigned int for bitwise-or of flags. As of this patch, all
implementations are unchanged (the old want_zero==true is now
mode==BDRV_WANT_PRECISE which is a superset of BDRV_WANT_ZERO); but
the callers in io.c that used to pass want_zero==false are now
prepared for future driver changes that can now distinguish bewteen
BDRV_WANT_ZERO vs. BDRV_WANT_ALLOCATED. The next patch will actually
change the file-posix driver along those lines, now that we have
more-specific hints.
As for the background why this patch is useful: right now, the
file-posix driver recognizes that if allocation is being queried, the
entire image can be reported as allocated (there is no backing file to
refer to) - but this throws away information on whether the entire
image reads as zero (trivially true if lseek(SEEK_HOLE) at offset 0
returns -ENXIO, a bit more complicated to prove if the raw file was
created with 'qemu-img create' since we intentionally allocate a small
chunk of all-zero data to help with alignment probing). Later patches
will add a generic algorithm for seeing if an entire file reads as
zeroes.
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250509204341.3553601-16-eblake@redhat.com>
(cherry picked from commit c33159dec79069514f78faecfe268439226b0f5b)
Jira: https://issues.redhat.com/browse/RHEL-88435
Jira: https://issues.redhat.com/browse/RHEL-88437
Signed-off-by: Eric Blake <eblake@redhat.com>
---
block/blkdebug.c | 6 ++--
block/copy-before-write.c | 4 +--
block/coroutines.h | 4 +--
block/file-posix.c | 4 +--
block/gluster.c | 4 +--
block/io.c | 51 ++++++++++++++++----------------
block/iscsi.c | 6 ++--
block/nbd.c | 4 +--
block/null.c | 6 ++--
block/parallels.c | 6 ++--
block/qcow.c | 2 +-
block/qcow2.c | 6 ++--
block/qed.c | 6 ++--
block/quorum.c | 4 +--
block/raw-format.c | 4 +--
block/rbd.c | 6 ++--
block/snapshot-access.c | 4 +--
block/vdi.c | 4 +--
block/vmdk.c | 2 +-
block/vpc.c | 2 +-
block/vvfat.c | 6 ++--
include/block/block-common.h | 11 +++++++
include/block/block_int-common.h | 27 +++++++++--------
include/block/block_int-io.h | 4 +--
tests/unit/test-block-iothread.c | 2 +-
25 files changed, 99 insertions(+), 86 deletions(-)
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 1c1967f8e0..c54aee0c84 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -751,9 +751,9 @@ blkdebug_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
}
static int coroutine_fn GRAPH_RDLOCK
-blkdebug_co_block_status(BlockDriverState *bs, bool want_zero, int64_t offset,
- int64_t bytes, int64_t *pnum, int64_t *map,
- BlockDriverState **file)
+blkdebug_co_block_status(BlockDriverState *bs, unsigned int mode,
+ int64_t offset, int64_t bytes, int64_t *pnum,
+ int64_t *map, BlockDriverState **file)
{
int err;
diff --git a/block/copy-before-write.c b/block/copy-before-write.c
index fd470f5f92..2badb3a885 100644
--- a/block/copy-before-write.c
+++ b/block/copy-before-write.c
@@ -291,8 +291,8 @@ cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes,
}
static int coroutine_fn GRAPH_RDLOCK
-cbw_co_snapshot_block_status(BlockDriverState *bs,
- bool want_zero, int64_t offset, int64_t bytes,
+cbw_co_snapshot_block_status(BlockDriverState *bs, unsigned int mode,
+ int64_t offset, int64_t bytes,
int64_t *pnum, int64_t *map,
BlockDriverState **file)
{
diff --git a/block/coroutines.h b/block/coroutines.h
index 79e5efbf75..892646bb7a 100644
--- a/block/coroutines.h
+++ b/block/coroutines.h
@@ -47,7 +47,7 @@ int coroutine_fn GRAPH_RDLOCK
bdrv_co_common_block_status_above(BlockDriverState *bs,
BlockDriverState *base,
bool include_base,
- bool want_zero,
+ unsigned int mode,
int64_t offset,
int64_t bytes,
int64_t *pnum,
@@ -78,7 +78,7 @@ int co_wrapper_mixed_bdrv_rdlock
bdrv_common_block_status_above(BlockDriverState *bs,
BlockDriverState *base,
bool include_base,
- bool want_zero,
+ unsigned int mode,
int64_t offset,
int64_t bytes,
int64_t *pnum,
diff --git a/block/file-posix.c b/block/file-posix.c
index 0d85123d0f..0c6569742f 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -3266,7 +3266,7 @@ static int find_allocation(BlockDriverState *bs, off_t start,
* well exceed it.
*/
static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
- bool want_zero,
+ unsigned int mode,
int64_t offset,
int64_t bytes, int64_t *pnum,
int64_t *map,
@@ -3282,7 +3282,7 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
return ret;
}
- if (!want_zero) {
+ if (mode != BDRV_WANT_PRECISE) {
*pnum = bytes;
*map = offset;
*file = bs;
diff --git a/block/gluster.c b/block/gluster.c
index c6d25ae733..8197b0ecef 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -1465,7 +1465,7 @@ exit:
* (Based on raw_co_block_status() from file-posix.c.)
*/
static int coroutine_fn qemu_gluster_co_block_status(BlockDriverState *bs,
- bool want_zero,
+ unsigned int mode,
int64_t offset,
int64_t bytes,
int64_t *pnum,
@@ -1482,7 +1482,7 @@ static int coroutine_fn qemu_gluster_co_block_status(BlockDriverState *bs,
return ret;
}
- if (!want_zero) {
+ if (mode != BDRV_WANT_PRECISE) {
*pnum = bytes;
*map = offset;
*file = bs;
diff --git a/block/io.c b/block/io.c
index ccec11386b..e328402adc 100644
--- a/block/io.c
+++ b/block/io.c
@@ -2364,10 +2364,8 @@ int bdrv_flush_all(void)
* Drivers not implementing the functionality are assumed to not support
* backing files, hence all their sectors are reported as allocated.
*
- * If 'want_zero' is true, the caller is querying for mapping
- * purposes, with a focus on valid BDRV_BLOCK_OFFSET_VALID, _DATA, and
- * _ZERO where possible; otherwise, the result favors larger 'pnum',
- * with a focus on accurate BDRV_BLOCK_ALLOCATED.
+ * 'mode' serves as a hint as to which results are favored; see the
+ * BDRV_WANT_* macros for details.
*
* If 'offset' is beyond the end of the disk image the return value is
* BDRV_BLOCK_EOF and 'pnum' is set to 0.
@@ -2387,7 +2385,7 @@ int bdrv_flush_all(void)
* set to the host mapping and BDS corresponding to the guest offset.
*/
static int coroutine_fn GRAPH_RDLOCK
-bdrv_co_do_block_status(BlockDriverState *bs, bool want_zero,
+bdrv_co_do_block_status(BlockDriverState *bs, unsigned int mode,
int64_t offset, int64_t bytes,
int64_t *pnum, int64_t *map, BlockDriverState **file)
{
@@ -2476,7 +2474,7 @@ bdrv_co_do_block_status(BlockDriverState *bs, bool want_zero,
local_file = bs;
local_map = aligned_offset;
} else {
- ret = bs->drv->bdrv_co_block_status(bs, want_zero, aligned_offset,
+ ret = bs->drv->bdrv_co_block_status(bs, mode, aligned_offset,
aligned_bytes, pnum, &local_map,
&local_file);
@@ -2488,10 +2486,10 @@ bdrv_co_do_block_status(BlockDriverState *bs, bool want_zero,
* the cache requires an RCU update, so double check here to avoid
* such an update if possible.
*
- * Check want_zero, because we only want to update the cache when we
+ * Check mode, because we only want to update the cache when we
* have accurate information about what is zero and what is data.
*/
- if (want_zero &&
+ if (mode == BDRV_WANT_PRECISE &&
ret == (BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID) &&
QLIST_EMPTY(&bs->children))
{
@@ -2548,7 +2546,7 @@ bdrv_co_do_block_status(BlockDriverState *bs, bool want_zero,
if (ret & BDRV_BLOCK_RAW) {
assert(ret & BDRV_BLOCK_OFFSET_VALID && local_file);
- ret = bdrv_co_do_block_status(local_file, want_zero, local_map,
+ ret = bdrv_co_do_block_status(local_file, mode, local_map,
*pnum, pnum, &local_map, &local_file);
goto out;
}
@@ -2560,7 +2558,7 @@ bdrv_co_do_block_status(BlockDriverState *bs, bool want_zero,
if (!cow_bs) {
ret |= BDRV_BLOCK_ZERO;
- } else if (want_zero) {
+ } else if (mode == BDRV_WANT_PRECISE) {
int64_t size2 = bdrv_co_getlength(cow_bs);
if (size2 >= 0 && offset >= size2) {
@@ -2569,14 +2567,14 @@ bdrv_co_do_block_status(BlockDriverState *bs, bool want_zero,
}
}
- if (want_zero && ret & BDRV_BLOCK_RECURSE &&
+ if (mode == BDRV_WANT_PRECISE && ret & BDRV_BLOCK_RECURSE &&
local_file && local_file != bs &&
(ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) &&
(ret & BDRV_BLOCK_OFFSET_VALID)) {
int64_t file_pnum;
int ret2;
- ret2 = bdrv_co_do_block_status(local_file, want_zero, local_map,
+ ret2 = bdrv_co_do_block_status(local_file, mode, local_map,
*pnum, &file_pnum, NULL, NULL);
if (ret2 >= 0) {
/* Ignore errors. This is just providing extra information, it
@@ -2627,7 +2625,7 @@ int coroutine_fn
bdrv_co_common_block_status_above(BlockDriverState *bs,
BlockDriverState *base,
bool include_base,
- bool want_zero,
+ unsigned int mode,
int64_t offset,
int64_t bytes,
int64_t *pnum,
@@ -2654,7 +2652,7 @@ bdrv_co_common_block_status_above(BlockDriverState *bs,
return 0;
}
- ret = bdrv_co_do_block_status(bs, want_zero, offset, bytes, pnum,
+ ret = bdrv_co_do_block_status(bs, mode, offset, bytes, pnum,
map, file);
++*depth;
if (ret < 0 || *pnum == 0 || ret & BDRV_BLOCK_ALLOCATED || bs == base) {
@@ -2671,7 +2669,7 @@ bdrv_co_common_block_status_above(BlockDriverState *bs,
for (p = bdrv_filter_or_cow_bs(bs); include_base || p != base;
p = bdrv_filter_or_cow_bs(p))
{
- ret = bdrv_co_do_block_status(p, want_zero, offset, bytes, pnum,
+ ret = bdrv_co_do_block_status(p, mode, offset, bytes, pnum,
map, file);
++*depth;
if (ret < 0) {
@@ -2734,7 +2732,8 @@ int coroutine_fn bdrv_co_block_status_above(BlockDriverState *bs,
BlockDriverState **file)
{
IO_CODE();
- return bdrv_co_common_block_status_above(bs, base, false, true, offset,
+ return bdrv_co_common_block_status_above(bs, base, false,
+ BDRV_WANT_PRECISE, offset,
bytes, pnum, map, file, NULL);
}
@@ -2765,8 +2764,9 @@ int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
return 1;
}
- ret = bdrv_co_common_block_status_above(bs, NULL, false, false, offset,
- bytes, &pnum, NULL, NULL, NULL);
+ ret = bdrv_co_common_block_status_above(bs, NULL, false, BDRV_WANT_ZERO,
+ offset, bytes, &pnum, NULL, NULL,
+ NULL);
if (ret < 0) {
return ret;
@@ -2782,9 +2782,9 @@ int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t offset,
int64_t dummy;
IO_CODE();
- ret = bdrv_co_common_block_status_above(bs, bs, true, false, offset,
- bytes, pnum ? pnum : &dummy, NULL,
- NULL, NULL);
+ ret = bdrv_co_common_block_status_above(bs, bs, true, BDRV_WANT_ALLOCATED,
+ offset, bytes, pnum ? pnum : &dummy,
+ NULL, NULL, NULL);
if (ret < 0) {
return ret;
}
@@ -2817,7 +2817,8 @@ int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *bs,
int ret;
IO_CODE();
- ret = bdrv_co_common_block_status_above(bs, base, include_base, false,
+ ret = bdrv_co_common_block_status_above(bs, base, include_base,
+ BDRV_WANT_ALLOCATED,
offset, bytes, pnum, NULL, NULL,
&depth);
if (ret < 0) {
@@ -3714,8 +3715,8 @@ bdrv_co_preadv_snapshot(BdrvChild *child, int64_t offset, int64_t bytes,
}
int coroutine_fn
-bdrv_co_snapshot_block_status(BlockDriverState *bs,
- bool want_zero, int64_t offset, int64_t bytes,
+bdrv_co_snapshot_block_status(BlockDriverState *bs, unsigned int mode,
+ int64_t offset, int64_t bytes,
int64_t *pnum, int64_t *map,
BlockDriverState **file)
{
@@ -3733,7 +3734,7 @@ bdrv_co_snapshot_block_status(BlockDriverState *bs,
}
bdrv_inc_in_flight(bs);
- ret = drv->bdrv_co_snapshot_block_status(bs, want_zero, offset, bytes,
+ ret = drv->bdrv_co_snapshot_block_status(bs, mode, offset, bytes,
pnum, map, file);
bdrv_dec_in_flight(bs);
diff --git a/block/iscsi.c b/block/iscsi.c
index 2f0f4dac09..15b96ee880 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -694,9 +694,9 @@ out_unlock:
static int coroutine_fn iscsi_co_block_status(BlockDriverState *bs,
- bool want_zero, int64_t offset,
- int64_t bytes, int64_t *pnum,
- int64_t *map,
+ unsigned int mode,
+ int64_t offset, int64_t bytes,
+ int64_t *pnum, int64_t *map,
BlockDriverState **file)
{
IscsiLun *iscsilun = bs->opaque;
diff --git a/block/nbd.c b/block/nbd.c
index 887841bc81..d5a2b21c6d 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -1397,8 +1397,8 @@ nbd_client_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
}
static int coroutine_fn GRAPH_RDLOCK nbd_client_co_block_status(
- BlockDriverState *bs, bool want_zero, int64_t offset, int64_t bytes,
- int64_t *pnum, int64_t *map, BlockDriverState **file)
+ BlockDriverState *bs, unsigned int mode, int64_t offset,
+ int64_t bytes, int64_t *pnum, int64_t *map, BlockDriverState **file)
{
int ret, request_ret;
NBDExtent64 extent = { 0 };
diff --git a/block/null.c b/block/null.c
index dc0b1fdbd9..4e448d593d 100644
--- a/block/null.c
+++ b/block/null.c
@@ -227,9 +227,9 @@ static int null_reopen_prepare(BDRVReopenState *reopen_state,
}
static int coroutine_fn null_co_block_status(BlockDriverState *bs,
- bool want_zero, int64_t offset,
- int64_t bytes, int64_t *pnum,
- int64_t *map,
+ unsigned int mode,
+ int64_t offset, int64_t bytes,
+ int64_t *pnum, int64_t *map,
BlockDriverState **file)
{
BDRVNullState *s = bs->opaque;
diff --git a/block/parallels.c b/block/parallels.c
index 347ca127f3..3a375e2a8a 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -416,9 +416,9 @@ parallels_co_flush_to_os(BlockDriverState *bs)
}
static int coroutine_fn GRAPH_RDLOCK
-parallels_co_block_status(BlockDriverState *bs, bool want_zero, int64_t offset,
- int64_t bytes, int64_t *pnum, int64_t *map,
- BlockDriverState **file)
+parallels_co_block_status(BlockDriverState *bs, unsigned int mode,
+ int64_t offset, int64_t bytes, int64_t *pnum,
+ int64_t *map, BlockDriverState **file)
{
BDRVParallelsState *s = bs->opaque;
int count;
diff --git a/block/qcow.c b/block/qcow.c
index da8ad4d243..8a3e7591a9 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -530,7 +530,7 @@ get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate,
}
static int coroutine_fn GRAPH_RDLOCK
-qcow_co_block_status(BlockDriverState *bs, bool want_zero,
+qcow_co_block_status(BlockDriverState *bs, unsigned int mode,
int64_t offset, int64_t bytes, int64_t *pnum,
int64_t *map, BlockDriverState **file)
{
diff --git a/block/qcow2.c b/block/qcow2.c
index b6ade4755d..9fc96ba99a 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2147,9 +2147,9 @@ static void qcow2_join_options(QDict *options, QDict *old_options)
}
static int coroutine_fn GRAPH_RDLOCK
-qcow2_co_block_status(BlockDriverState *bs, bool want_zero, int64_t offset,
- int64_t count, int64_t *pnum, int64_t *map,
- BlockDriverState **file)
+qcow2_co_block_status(BlockDriverState *bs, unsigned int mode,
+ int64_t offset, int64_t count, int64_t *pnum,
+ int64_t *map, BlockDriverState **file)
{
BDRVQcow2State *s = bs->opaque;
uint64_t host_offset;
diff --git a/block/qed.c b/block/qed.c
index ac24449ffb..4a36fb3929 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -833,9 +833,9 @@ fail:
}
static int coroutine_fn GRAPH_RDLOCK
-bdrv_qed_co_block_status(BlockDriverState *bs, bool want_zero, int64_t pos,
- int64_t bytes, int64_t *pnum, int64_t *map,
- BlockDriverState **file)
+bdrv_qed_co_block_status(BlockDriverState *bs, unsigned int mode,
+ int64_t pos, int64_t bytes, int64_t *pnum,
+ int64_t *map, BlockDriverState **file)
{
BDRVQEDState *s = bs->opaque;
size_t len = MIN(bytes, SIZE_MAX);
diff --git a/block/quorum.c b/block/quorum.c
index 30747a6df9..ed8ce801ee 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -1226,7 +1226,7 @@ static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c,
* region contains zeroes, and BDRV_BLOCK_DATA otherwise.
*/
static int coroutine_fn GRAPH_RDLOCK
-quorum_co_block_status(BlockDriverState *bs, bool want_zero,
+quorum_co_block_status(BlockDriverState *bs, unsigned int mode,
int64_t offset, int64_t count,
int64_t *pnum, int64_t *map, BlockDriverState **file)
{
@@ -1238,7 +1238,7 @@ quorum_co_block_status(BlockDriverState *bs, bool want_zero,
for (i = 0; i < s->num_children; i++) {
int64_t bytes;
ret = bdrv_co_common_block_status_above(s->children[i]->bs, NULL, false,
- want_zero, offset, count,
+ mode, offset, count,
&bytes, NULL, NULL, NULL);
if (ret < 0) {
quorum_report_bad(QUORUM_OP_TYPE_READ, offset, count,
diff --git a/block/raw-format.c b/block/raw-format.c
index e08526e2ec..df16ac1ea2 100644
--- a/block/raw-format.c
+++ b/block/raw-format.c
@@ -283,8 +283,8 @@ fail:
}
static int coroutine_fn GRAPH_RDLOCK
-raw_co_block_status(BlockDriverState *bs, bool want_zero, int64_t offset,
- int64_t bytes, int64_t *pnum, int64_t *map,
+raw_co_block_status(BlockDriverState *bs, unsigned int mode,
+ int64_t offset, int64_t bytes, int64_t *pnum, int64_t *map,
BlockDriverState **file)
{
BDRVRawState *s = bs->opaque;
diff --git a/block/rbd.c b/block/rbd.c
index af984fb7db..4f3d42a8e7 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -1504,9 +1504,9 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, size_t len,
}
static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs,
- bool want_zero, int64_t offset,
- int64_t bytes, int64_t *pnum,
- int64_t *map,
+ unsigned int mode,
+ int64_t offset, int64_t bytes,
+ int64_t *pnum, int64_t *map,
BlockDriverState **file)
{
BDRVRBDState *s = bs->opaque;
diff --git a/block/snapshot-access.c b/block/snapshot-access.c
index 71ac83c01f..17ed2402db 100644
--- a/block/snapshot-access.c
+++ b/block/snapshot-access.c
@@ -41,11 +41,11 @@ snapshot_access_co_preadv_part(BlockDriverState *bs,
static int coroutine_fn GRAPH_RDLOCK
snapshot_access_co_block_status(BlockDriverState *bs,
- bool want_zero, int64_t offset,
+ unsigned int mode, int64_t offset,
int64_t bytes, int64_t *pnum,
int64_t *map, BlockDriverState **file)
{
- return bdrv_co_snapshot_block_status(bs->file->bs, want_zero, offset,
+ return bdrv_co_snapshot_block_status(bs->file->bs, mode, offset,
bytes, pnum, map, file);
}
diff --git a/block/vdi.c b/block/vdi.c
index a2da6ecab0..3ddc62a569 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -523,8 +523,8 @@ static int vdi_reopen_prepare(BDRVReopenState *state,
}
static int coroutine_fn GRAPH_RDLOCK
-vdi_co_block_status(BlockDriverState *bs, bool want_zero, int64_t offset,
- int64_t bytes, int64_t *pnum, int64_t *map,
+vdi_co_block_status(BlockDriverState *bs, unsigned int mode,
+ int64_t offset, int64_t bytes, int64_t *pnum, int64_t *map,
BlockDriverState **file)
{
BDRVVdiState *s = (BDRVVdiState *)bs->opaque;
diff --git a/block/vmdk.c b/block/vmdk.c
index 2adec49912..9c7ab037e1 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1777,7 +1777,7 @@ static inline uint64_t vmdk_find_offset_in_cluster(VmdkExtent *extent,
}
static int coroutine_fn GRAPH_RDLOCK
-vmdk_co_block_status(BlockDriverState *bs, bool want_zero,
+vmdk_co_block_status(BlockDriverState *bs, unsigned int mode,
int64_t offset, int64_t bytes, int64_t *pnum,
int64_t *map, BlockDriverState **file)
{
diff --git a/block/vpc.c b/block/vpc.c
index 0309e319f6..801ff5793f 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -726,7 +726,7 @@ fail:
}
static int coroutine_fn GRAPH_RDLOCK
-vpc_co_block_status(BlockDriverState *bs, bool want_zero,
+vpc_co_block_status(BlockDriverState *bs, unsigned int mode,
int64_t offset, int64_t bytes,
int64_t *pnum, int64_t *map,
BlockDriverState **file)
diff --git a/block/vvfat.c b/block/vvfat.c
index 91d69b3cc8..814796d918 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -3134,9 +3134,9 @@ vvfat_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
}
static int coroutine_fn vvfat_co_block_status(BlockDriverState *bs,
- bool want_zero, int64_t offset,
- int64_t bytes, int64_t *n,
- int64_t *map,
+ unsigned int mode,
+ int64_t offset, int64_t bytes,
+ int64_t *n, int64_t *map,
BlockDriverState **file)
{
*n = bytes;
diff --git a/include/block/block-common.h b/include/block/block-common.h
index 0b831ef87b..c8c626daea 100644
--- a/include/block/block-common.h
+++ b/include/block/block-common.h
@@ -333,6 +333,17 @@ typedef enum {
#define BDRV_BLOCK_RECURSE 0x40
#define BDRV_BLOCK_COMPRESSED 0x80
+/*
+ * Block status hints: the bitwise-or of these flags emphasize what
+ * the caller hopes to learn, and some drivers may be able to give
+ * faster answers by doing less work when the hint permits.
+ */
+#define BDRV_WANT_ZERO BDRV_BLOCK_ZERO
+#define BDRV_WANT_OFFSET_VALID BDRV_BLOCK_OFFSET_VALID
+#define BDRV_WANT_ALLOCATED BDRV_BLOCK_ALLOCATED
+#define BDRV_WANT_PRECISE (BDRV_WANT_ZERO | BDRV_WANT_OFFSET_VALID | \
+ BDRV_WANT_OFFSET_VALID)
+
typedef QTAILQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
typedef struct BDRVReopenState {
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
index ebb4e56a50..a9c0daa2a4 100644
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
@@ -608,15 +608,16 @@ struct BlockDriver {
* according to the current layer, and should only need to set
* BDRV_BLOCK_DATA, BDRV_BLOCK_ZERO, BDRV_BLOCK_OFFSET_VALID,
* and/or BDRV_BLOCK_RAW; if the current layer defers to a backing
- * layer, the result should be 0 (and not BDRV_BLOCK_ZERO). See
- * block.h for the overall meaning of the bits. As a hint, the
- * flag want_zero is true if the caller cares more about precise
- * mappings (favor accurate _OFFSET_VALID/_ZERO) or false for
- * overall allocation (favor larger *pnum, perhaps by reporting
- * _DATA instead of _ZERO). The block layer guarantees input
- * clamped to bdrv_getlength() and aligned to request_alignment,
- * as well as non-NULL pnum, map, and file; in turn, the driver
- * must return an error or set pnum to an aligned non-zero value.
+ * layer, the result should be 0 (and not BDRV_BLOCK_ZERO). The
+ * caller will synthesize BDRV_BLOCK_ALLOCATED based on the
+ * non-zero results. See block.h for the overall meaning of the
+ * bits. As a hint, the flags in @mode may include a bitwise-or
+ * of BDRV_WANT_ALLOCATED, BDRV_WANT_OFFSET_VALID, or
+ * BDRV_WANT_ZERO based on what the caller is looking for in the
+ * results. The block layer guarantees input clamped to
+ * bdrv_getlength() and aligned to request_alignment, as well as
+ * non-NULL pnum, map, and file; in turn, the driver must return
+ * an error or set pnum to an aligned non-zero value.
*
* Note that @bytes is just a hint on how big of a region the
* caller wants to inspect. It is not a limit on *pnum.
@@ -628,8 +629,8 @@ struct BlockDriver {
* to clamping *pnum for return to its caller.
*/
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_block_status)(
- BlockDriverState *bs,
- bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
+ BlockDriverState *bs, unsigned int mode,
+ int64_t offset, int64_t bytes, int64_t *pnum,
int64_t *map, BlockDriverState **file);
/*
@@ -653,8 +654,8 @@ struct BlockDriver {
QEMUIOVector *qiov, size_t qiov_offset);
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_snapshot_block_status)(
- BlockDriverState *bs, bool want_zero, int64_t offset, int64_t bytes,
- int64_t *pnum, int64_t *map, BlockDriverState **file);
+ BlockDriverState *bs, unsigned int mode, int64_t offset,
+ int64_t bytes, int64_t *pnum, int64_t *map, BlockDriverState **file);
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pdiscard_snapshot)(
BlockDriverState *bs, int64_t offset, int64_t bytes);
diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
index 4a7cf2b4fd..4f94eb3c5a 100644
--- a/include/block/block_int-io.h
+++ b/include/block/block_int-io.h
@@ -38,8 +38,8 @@
int coroutine_fn GRAPH_RDLOCK bdrv_co_preadv_snapshot(BdrvChild *child,
int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset);
int coroutine_fn GRAPH_RDLOCK bdrv_co_snapshot_block_status(
- BlockDriverState *bs, bool want_zero, int64_t offset, int64_t bytes,
- int64_t *pnum, int64_t *map, BlockDriverState **file);
+ BlockDriverState *bs, unsigned int mode, int64_t offset,
+ int64_t bytes, int64_t *pnum, int64_t *map, BlockDriverState **file);
int coroutine_fn GRAPH_RDLOCK bdrv_co_pdiscard_snapshot(BlockDriverState *bs,
int64_t offset, int64_t bytes);
diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c
index 2b358eaaa8..e26b3be593 100644
--- a/tests/unit/test-block-iothread.c
+++ b/tests/unit/test-block-iothread.c
@@ -63,7 +63,7 @@ bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
}
static int coroutine_fn bdrv_test_co_block_status(BlockDriverState *bs,
- bool want_zero,
+ unsigned int mode,
int64_t offset, int64_t count,
int64_t *pnum, int64_t *map,
BlockDriverState **file)
--
2.39.3

View File

@ -1,68 +0,0 @@
From fcf20a7c75d01009701fd960247ff76914280e1a Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 4 Feb 2025 22:13:57 +0100
Subject: [PATCH 12/22] block: Fix crash on block_resize on inactive node
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 340: QMP command for block device reactivation after migration
RH-Jira: RHEL-54670
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [12/22] 9edc182c7ac587b0eaea836203b77d94b4d9bd80 (kmwolf/centos-qemu-kvm)
In order for block_resize to fail gracefully on an inactive node instead
of crashing with an assertion failure in bdrv_co_write_req_prepare()
(called from bdrv_co_truncate()), we need to check for inactive nodes
also when they are attached as a root node and make sure that
BLK_PERM_RESIZE isn't among the permissions allowed for inactive nodes.
To this effect, don't enumerate the permissions that are incompatible
with inactive nodes any more, but allow only BLK_PERM_CONSISTENT_READ
for them.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250204211407.381505-7-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 8c2c72a33581987af8d8c484d03af3cd69b9e10a)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 7 +++++++
block/block-backend.c | 2 +-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/block.c b/block.c
index 41e72e6965..bedd54deaa 100644
--- a/block.c
+++ b/block.c
@@ -3077,6 +3077,13 @@ bdrv_attach_child_common(BlockDriverState *child_bs,
assert(child_class->get_parent_desc);
GLOBAL_STATE_CODE();
+ if (bdrv_is_inactive(child_bs) && (perm & ~BLK_PERM_CONSISTENT_READ)) {
+ g_autofree char *perm_names = bdrv_perm_names(perm);
+ error_setg(errp, "Permission '%s' unavailable on inactive node",
+ perm_names);
+ return NULL;
+ }
+
new_child = g_new(BdrvChild, 1);
*new_child = (BdrvChild) {
.bs = NULL,
diff --git a/block/block-backend.c b/block/block-backend.c
index db6f9b92a3..356db1b703 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -253,7 +253,7 @@ static bool blk_can_inactivate(BlockBackend *blk)
* guest. For block job BBs that satisfy this, we can just allow
* it. This is the case for mirror job source, which is required
* by libvirt non-shared block migration. */
- if (!(blk->perm & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED))) {
+ if (!(blk->perm & ~BLK_PERM_CONSISTENT_READ)) {
return true;
}
--
2.39.3

View File

@ -1,68 +0,0 @@
From b0b5dbd95c73a5cd4173c11d283f6144f0d78e04 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 4 Feb 2025 22:13:54 +0100
Subject: [PATCH 09/22] block: Inactivate external snapshot overlays when
necessary
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 340: QMP command for block device reactivation after migration
RH-Jira: RHEL-54670
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [9/22] 82aa17e6d5009c0a89fb884afbf408ae2f4c5478 (kmwolf/centos-qemu-kvm)
Putting an active block node on top of an inactive one is strictly
speaking an invalid configuration and the next patch will turn it into a
hard error.
However, taking a snapshot while disk images are inactive after
completing migration has an important use case: After migrating to a
file, taking an external snapshot is what is needed to take a full VM
snapshot.
In order for this to keep working after the later patches, change
creating a snapshot such that it automatically inactivates an overlay
that is added on top of an already inactive node.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250204211407.381505-4-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit e80210ffb24c4e47650344ba77ce3ed354af596c)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
blockdev.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/blockdev.c b/blockdev.c
index 835064ed03..81430122df 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1497,6 +1497,22 @@ static void external_snapshot_action(TransactionAction *action,
return;
}
+ /*
+ * Older QEMU versions have allowed adding an active parent node to an
+ * inactive child node. This is unsafe in the general case, but there is an
+ * important use case, which is taking a VM snapshot with migration to file
+ * and then adding an external snapshot while the VM is still stopped and
+ * images are inactive. Requiring the user to explicitly create the overlay
+ * as inactive would break compatibility, so just do it automatically here
+ * to keep this working.
+ */
+ if (bdrv_is_inactive(state->old_bs) && !bdrv_is_inactive(state->new_bs)) {
+ ret = bdrv_inactivate(state->new_bs, errp);
+ if (ret < 0) {
+ return;
+ }
+ }
+
ret = bdrv_append(state->new_bs, state->old_bs, errp);
if (ret < 0) {
return;
--
2.39.3

View File

@ -0,0 +1,90 @@
From e101b9872f9b3f6c5e128f29d7c3bb91faca362b Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Fri, 9 May 2025 15:40:20 -0500
Subject: [PATCH 03/14] block: Let bdrv_co_is_zero_fast consolidate adjacent
extents
RH-Author: Eric Blake <eblake@redhat.com>
RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors
RH-Jira: RHEL-88435 RHEL-88437
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [3/14] 4520f7ef5bcc5803413541e6f48bf750af3d31e0 (ebblake/centos-qemu-kvm)
Some BDS drivers have a cap on how much block status they can supply
in one query (for example, NBD talking to an older server cannot
inspect more than 4G per query; and qcow2 tends to cap its answers
rather than cross a cluster boundary of an L1 table). Although the
existing callers of bdrv_co_is_zero_fast are not passing in that large
of a 'bytes' parameter, an upcoming caller wants to query the entire
image at once, and will thus benefit from being able to treat adjacent
zero regions in a coalesced manner, rather than claiming the region is
non-zero merely because pnum was truncated and didn't match the
incoming bytes.
While refactoring this into a loop, note that there is no need to
assign pnum prior to calling bdrv_co_common_block_status_above() (it
is guaranteed to be assigned deeper in the callstack).
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250509204341.3553601-18-eblake@redhat.com>
(cherry picked from commit 31bf15d97dd1d205a3b264675f9a1b3bd1939068)
Jira: https://issues.redhat.com/browse/RHEL-88435
Jira: https://issues.redhat.com/browse/RHEL-88437
Signed-off-by: Eric Blake <eblake@redhat.com>
---
block/io.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/block/io.c b/block/io.c
index e328402adc..64f4b1d22a 100644
--- a/block/io.c
+++ b/block/io.c
@@ -2751,28 +2751,31 @@ int coroutine_fn bdrv_co_block_status(BlockDriverState *bs, int64_t offset,
* by @offset and @bytes is known to read as zeroes.
* Return 1 if that is the case, 0 otherwise and -errno on error.
* This test is meant to be fast rather than accurate so returning 0
- * does not guarantee non-zero data.
+ * does not guarantee non-zero data; but a return of 1 is reliable.
*/
int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
int64_t bytes)
{
int ret;
- int64_t pnum = bytes;
+ int64_t pnum;
IO_CODE();
- if (!bytes) {
- return 1;
- }
-
- ret = bdrv_co_common_block_status_above(bs, NULL, false, BDRV_WANT_ZERO,
- offset, bytes, &pnum, NULL, NULL,
- NULL);
+ while (bytes) {
+ ret = bdrv_co_common_block_status_above(bs, NULL, false,
+ BDRV_WANT_ZERO, offset, bytes,
+ &pnum, NULL, NULL, NULL);
- if (ret < 0) {
- return ret;
+ if (ret < 0) {
+ return ret;
+ }
+ if (!(ret & BDRV_BLOCK_ZERO)) {
+ return 0;
+ }
+ offset += pnum;
+ bytes -= pnum;
}
- return (pnum == bytes) && (ret & BDRV_BLOCK_ZERO);
+ return 1;
}
int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t offset,
--
2.39.3

View File

@ -1,66 +0,0 @@
From 1c4cdab823e271cea3bb980eb0b2714f3474c7fa Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 4 Feb 2025 22:14:00 +0100
Subject: [PATCH 15/22] block: Support inactive nodes in blk_insert_bs()
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 340: QMP command for block device reactivation after migration
RH-Jira: RHEL-54670
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [15/22] fed3cf8ea4bd443ff9bf52328650b43e3ce3150d (kmwolf/centos-qemu-kvm)
Device models have a relatively complex way to set up their block
backends, in which blk_attach_dev() sets blk->disable_perm = true.
We want to support inactive images in exports, too, so that
qemu-storage-daemon can be used with migration. Because they don't use
blk_attach_dev(), they need another way to set this flag. The most
convenient is to do this automatically when an inactive node is attached
to a BlockBackend that can be inactivated.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250204211407.381505-10-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit c1c5c7cc4ef6c45ca769c640566fd40d2cb7d5c1)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/block-backend.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index 356db1b703..4a5a1c1f6a 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -909,14 +909,24 @@ void blk_remove_bs(BlockBackend *blk)
int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
{
ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
+ uint64_t perm, shared_perm;
GLOBAL_STATE_CODE();
bdrv_ref(bs);
bdrv_graph_wrlock();
+
+ if ((bs->open_flags & BDRV_O_INACTIVE) && blk_can_inactivate(blk)) {
+ blk->disable_perm = true;
+ perm = 0;
+ shared_perm = BLK_PERM_ALL;
+ } else {
+ perm = blk->perm;
+ shared_perm = blk->shared_perm;
+ }
+
blk->root = bdrv_root_attach_child(bs, "root", &child_root,
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
- blk->perm, blk->shared_perm,
- blk, errp);
+ perm, shared_perm, blk, errp);
bdrv_graph_wrunlock();
if (blk->root == NULL) {
return -EPERM;
--
2.39.3

View File

@ -1,135 +0,0 @@
From f4e875181720552ebdb9530e533fbad96b8d01d2 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 4 Feb 2025 22:14:03 +0100
Subject: [PATCH 18/22] block/export: Add option to allow export of inactive
nodes
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 340: QMP command for block device reactivation after migration
RH-Jira: RHEL-54670
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [18/22] 0a2723f830936a67fbcc4ee1ee7e846468adc77b (kmwolf/centos-qemu-kvm)
Add an option in BlockExportOptions to allow creating an export on an
inactive node without activating the node. This mode needs to be
explicitly supported by the export type (so that it doesn't perform any
operations that are forbidden for inactive nodes), so this patch alone
doesn't allow this option to be successfully used yet.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250204211407.381505-13-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 1600ef01ab1296ca8230daa6bc41ba983751f646)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/export/export.c | 31 +++++++++++++++++++++----------
include/block/export.h | 3 +++
qapi/block-export.json | 10 +++++++++-
3 files changed, 33 insertions(+), 11 deletions(-)
diff --git a/block/export/export.c b/block/export/export.c
index 23a86efcdb..71af65b3e5 100644
--- a/block/export/export.c
+++ b/block/export/export.c
@@ -75,6 +75,7 @@ static const BlockExportDriver *blk_exp_find_driver(BlockExportType type)
BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
{
bool fixed_iothread = export->has_fixed_iothread && export->fixed_iothread;
+ bool allow_inactive = export->has_allow_inactive && export->allow_inactive;
const BlockExportDriver *drv;
BlockExport *exp = NULL;
BlockDriverState *bs;
@@ -138,17 +139,24 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
}
}
- /*
- * Block exports are used for non-shared storage migration. Make sure
- * that BDRV_O_INACTIVE is cleared and the image is ready for write
- * access since the export could be available before migration handover.
- * ctx was acquired in the caller.
- */
bdrv_graph_rdlock_main_loop();
- ret = bdrv_activate(bs, errp);
- if (ret < 0) {
- bdrv_graph_rdunlock_main_loop();
- goto fail;
+ if (allow_inactive) {
+ if (!drv->supports_inactive) {
+ error_setg(errp, "Export type does not support inactive exports");
+ bdrv_graph_rdunlock_main_loop();
+ goto fail;
+ }
+ } else {
+ /*
+ * Block exports are used for non-shared storage migration. Make sure
+ * that BDRV_O_INACTIVE is cleared and the image is ready for write
+ * access since the export could be available before migration handover.
+ */
+ ret = bdrv_activate(bs, errp);
+ if (ret < 0) {
+ bdrv_graph_rdunlock_main_loop();
+ goto fail;
+ }
}
bdrv_graph_rdunlock_main_loop();
@@ -162,6 +170,9 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
if (!fixed_iothread) {
blk_set_allow_aio_context_change(blk, true);
}
+ if (allow_inactive) {
+ blk_set_force_allow_inactivate(blk);
+ }
ret = blk_insert_bs(blk, bs, errp);
if (ret < 0) {
diff --git a/include/block/export.h b/include/block/export.h
index f2fe0f8078..4bd9531d4d 100644
--- a/include/block/export.h
+++ b/include/block/export.h
@@ -29,6 +29,9 @@ typedef struct BlockExportDriver {
*/
size_t instance_size;
+ /* True if the export type supports running on an inactive node */
+ bool supports_inactive;
+
/* Creates and starts a new block export */
int (*create)(BlockExport *, BlockExportOptions *, Error **);
diff --git a/qapi/block-export.json b/qapi/block-export.json
index ce33fe378d..117b05d13c 100644
--- a/qapi/block-export.json
+++ b/qapi/block-export.json
@@ -372,6 +372,13 @@
# cannot be moved to the iothread. The default is false.
# (since: 5.2)
#
+# @allow-inactive: If true, the export allows the exported node to be inactive.
+# If it is created for an inactive block node, the node remains inactive. If
+# the export type doesn't support running on an inactive node, an error is
+# returned. If false, inactive block nodes are automatically activated before
+# creating the export and trying to inactivate them later fails.
+# (since: 10.0; default: false)
+#
# Since: 4.2
##
{ 'union': 'BlockExportOptions',
@@ -381,7 +388,8 @@
'*iothread': 'str',
'node-name': 'str',
'*writable': 'bool',
- '*writethrough': 'bool' },
+ '*writethrough': 'bool',
+ '*allow-inactive': 'bool' },
'discriminator': 'type',
'data': {
'nbd': 'BlockExportOptionsNbd',
--
2.39.3

View File

@ -1,50 +0,0 @@
From 7e3b7fff56e0f8f16a898e7d22789ffad4166aca Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 4 Feb 2025 22:14:01 +0100
Subject: [PATCH 16/22] block/export: Don't ignore image activation error in
blk_exp_add()
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 340: QMP command for block device reactivation after migration
RH-Jira: RHEL-54670
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [16/22] 3318a1c7eb1707a8a0b01a0c6edbd69deada8ca7 (kmwolf/centos-qemu-kvm)
Currently, block exports can't handle inactive images correctly.
Incoming write requests would run into assertion failures. Make sure
that we return an error when creating an export can't activate the
image.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250204211407.381505-11-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 69f28176ca0af850db23a1c6364f0c8525b20801)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/export/export.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/block/export/export.c b/block/export/export.c
index 6d51ae8ed7..23a86efcdb 100644
--- a/block/export/export.c
+++ b/block/export/export.c
@@ -145,7 +145,11 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
* ctx was acquired in the caller.
*/
bdrv_graph_rdlock_main_loop();
- bdrv_activate(bs, NULL);
+ ret = bdrv_activate(bs, errp);
+ if (ret < 0) {
+ bdrv_graph_rdunlock_main_loop();
+ goto fail;
+ }
bdrv_graph_rdunlock_main_loop();
perm = BLK_PERM_CONSISTENT_READ;
--
2.39.3

View File

@ -0,0 +1,74 @@
From 8d520ef6e8959a017535ecfc556b067e4b118cb7 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Thu, 17 Apr 2025 11:05:28 -0400
Subject: [PATCH 2/4] block/io: skip head/tail requests on EINVAL
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 354: file-posix: probe discard alignment on Linux block devices
RH-Jira: RHEL-87642
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Commit: [2/3] 5fddeb3ba2df7c61cdb8dd709e56914f3b5c0972 (stefanha/centos-stream-qemu-kvm)
When guests send misaligned discard requests, the block layer breaks
them up into a misaligned head, an aligned main body, and a misaligned
tail.
The file-posix block driver on Linux returns -EINVAL on misaligned
discard requests. This causes bdrv_co_pdiscard() to fail and guests
configured with werror=stop will pause.
Add a special case for misaligned head/tail requests. Simply continue
when EINVAL is encountered so that the aligned main body of the request
can be completed and the guest is not paused. This is the best we can do
when guest discard limits do not match the host discard limits.
Fixes: https://issues.redhat.com/browse/RHEL-86032
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Message-ID: <20250417150528.76470-3-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 4733cb0833c4b223f92ec0136980eeb5239ecb87)
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
block/io.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/block/io.c b/block/io.c
index 1ba8d1aeea..ccec11386b 100644
--- a/block/io.c
+++ b/block/io.c
@@ -3109,11 +3109,12 @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
/* Invalidate the cached block-status data range if this discard overlaps */
bdrv_bsc_invalidate_range(bs, offset, bytes);
- /* Discard is advisory, but some devices track and coalesce
+ /*
+ * Discard is advisory, but some devices track and coalesce
* unaligned requests, so we must pass everything down rather than
- * round here. Still, most devices will just silently ignore
- * unaligned requests (by returning -ENOTSUP), so we must fragment
- * the request accordingly. */
+ * round here. Still, most devices reject unaligned requests with
+ * -EINVAL or -ENOTSUP, so we must fragment the request accordingly.
+ */
align = MAX(bs->bl.pdiscard_alignment, bs->bl.request_alignment);
assert(align % bs->bl.request_alignment == 0);
head = offset % align;
@@ -3180,7 +3181,11 @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
}
}
if (ret && ret != -ENOTSUP) {
- goto out;
+ if (ret == -EINVAL && (offset % align != 0 || num % align != 0)) {
+ /* Silently skip rejected unaligned head/tail requests */
+ } else {
+ goto out; /* bail out */
+ }
}
offset += num;
--
2.39.3

View File

@ -0,0 +1,49 @@
From 9e52d5e0ac43c31ca39c7e1ac41bf5bcb179f848 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:44 +0200
Subject: [PATCH 19/33] block: mark bdrv_child_change_aio_context()
GRAPH_RDLOCK
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [7/21] ca3294430750a4266f4f3cbe42192d3abb84c817 (kmwolf/centos-qemu-kvm)
This is a small step in preparation to mark bdrv_drained_begin() as
GRAPH_UNLOCKED. More concretely, it is in preparation to move the
drain out of bdrv_change_aio_context() and marking that function as
GRAPH_RDLOCK.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20250530151125.955508-8-f.ebner@proxmox.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 469422c45b3a816eaf36e7edc895c81e0f3d38bb)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
include/block/block-global-state.h | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
index 9be34b3c99..aad160956a 100644
--- a/include/block/block-global-state.h
+++ b/include/block/block-global-state.h
@@ -274,9 +274,10 @@ int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag);
int bdrv_debug_resume(BlockDriverState *bs, const char *tag);
bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag);
-bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
- GHashTable *visited, Transaction *tran,
- Error **errp);
+bool GRAPH_RDLOCK
+bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
+ GHashTable *visited, Transaction *tran,
+ Error **errp);
int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
BdrvChild *ignore_child, Error **errp);
--
2.39.3

View File

@ -0,0 +1,62 @@
From e002888564647162c7796075ef7bdc14c0dc29fc Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:56 +0200
Subject: [PATCH 31/33] block: mark bdrv_drained_begin() and friends as
GRAPH_UNLOCKED
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [19/21] 7dd6a447a7fabb2685bec471a28f9e3e78dbc2d1 (kmwolf/centos-qemu-kvm)
All of bdrv_drain_all_begin(), bdrv_drain_all() and
bdrv_drained_begin() poll and are not allowed to be called with the
block graph lock held. Mark the function as such.
Suggested-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20250530151125.955508-20-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit fc1d2f3eac7946658b160db0b813b81288fb1778)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
include/block/block-global-state.h | 4 ++--
include/block/block-io.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
index 91f249b5ad..84a2a4ecd5 100644
--- a/include/block/block-global-state.h
+++ b/include/block/block-global-state.h
@@ -192,10 +192,10 @@ int bdrv_inactivate_all(void);
int bdrv_flush_all(void);
void bdrv_close_all(void);
-void bdrv_drain_all_begin(void);
+void GRAPH_UNLOCKED bdrv_drain_all_begin(void);
void bdrv_drain_all_begin_nopoll(void);
void bdrv_drain_all_end(void);
-void bdrv_drain_all(void);
+void GRAPH_UNLOCKED bdrv_drain_all(void);
void bdrv_aio_cancel(BlockAIOCB *acb);
diff --git a/include/block/block-io.h b/include/block/block-io.h
index b99cc98d26..4cf83fb367 100644
--- a/include/block/block-io.h
+++ b/include/block/block-io.h
@@ -431,7 +431,7 @@ bdrv_drain_poll(BlockDriverState *bs, BdrvChild *ignore_parent,
*
* This function can be recursive.
*/
-void bdrv_drained_begin(BlockDriverState *bs);
+void GRAPH_UNLOCKED bdrv_drained_begin(BlockDriverState *bs);
/**
* bdrv_do_drained_begin_quiesce:
--
2.39.3

View File

@ -0,0 +1,49 @@
From 191a72ef2a40d7bd14c5ad3745f1dfccbbf95817 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:42 +0200
Subject: [PATCH 17/33] block: mark bdrv_parent_change_aio_context()
GRAPH_RDLOCK
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [5/21] e80d701ce609e823f85465a3433324cbf077b3b9 (kmwolf/centos-qemu-kvm)
This is a small step in preparation to mark bdrv_drained_begin() as
GRAPH_UNLOCKED. More concretely, it allows marking the
change_aio_ctx() callback GRAPH_RDLOCK_PTR, which is the next step.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20250530151125.955508-6-f.ebner@proxmox.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 3758733959af93b5eb3283659d868ad5b24152b4)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/block.c b/block.c
index e340bac177..18a6be3bd6 100644
--- a/block.c
+++ b/block.c
@@ -7575,10 +7575,10 @@ typedef struct BdrvStateSetAioContext {
BlockDriverState *bs;
} BdrvStateSetAioContext;
-static bool bdrv_parent_change_aio_context(BdrvChild *c, AioContext *ctx,
- GHashTable *visited,
- Transaction *tran,
- Error **errp)
+static bool GRAPH_RDLOCK
+bdrv_parent_change_aio_context(BdrvChild *c, AioContext *ctx,
+ GHashTable *visited, Transaction *tran,
+ Error **errp)
{
GLOBAL_STATE_CODE();
if (g_hash_table_contains(visited, c)) {
--
2.39.3

View File

@ -0,0 +1,103 @@
From 1c72dbd318b6c15d7a7cbc14a270056a5cb6b182 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:43 +0200
Subject: [PATCH 18/33] block: mark change_aio_ctx() callback and instances as
GRAPH_RDLOCK(_PTR)
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [6/21] 9b1d5045f18b3393c5a35ce854da0dfd6fc2803b (kmwolf/centos-qemu-kvm)
This is a small step in preparation to mark bdrv_drained_begin() as
GRAPH_UNLOCKED. More concretely, it is in preparation to move the
drain out of bdrv_change_aio_context() and marking that function as
GRAPH_RDLOCK.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20250530151125.955508-7-f.ebner@proxmox.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 844d550d09ac29ff2b1b49069587ae6a989df31d)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 7 ++++---
block/block-backend.c | 6 +++---
blockjob.c | 6 +++---
include/block/block_int-common.h | 6 +++---
4 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/block.c b/block.c
index 18a6be3bd6..f7b21d8f27 100644
--- a/block.c
+++ b/block.c
@@ -1226,9 +1226,10 @@ static int bdrv_child_cb_inactivate(BdrvChild *child)
return 0;
}
-static bool bdrv_child_cb_change_aio_ctx(BdrvChild *child, AioContext *ctx,
- GHashTable *visited, Transaction *tran,
- Error **errp)
+static bool GRAPH_RDLOCK
+bdrv_child_cb_change_aio_ctx(BdrvChild *child, AioContext *ctx,
+ GHashTable *visited, Transaction *tran,
+ Error **errp)
{
BlockDriverState *bs = child->opaque;
return bdrv_change_aio_context(bs, ctx, visited, tran, errp);
diff --git a/block/block-backend.c b/block/block-backend.c
index a402db13f2..6a6949edeb 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -136,9 +136,9 @@ static void blk_root_drained_end(BdrvChild *child);
static void blk_root_change_media(BdrvChild *child, bool load);
static void blk_root_resize(BdrvChild *child);
-static bool blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx,
- GHashTable *visited, Transaction *tran,
- Error **errp);
+static bool GRAPH_RDLOCK
+blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx, GHashTable *visited,
+ Transaction *tran, Error **errp);
static char *blk_root_get_parent_desc(BdrvChild *child)
{
diff --git a/blockjob.c b/blockjob.c
index 32007f31a9..34185d7715 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -144,9 +144,9 @@ static TransactionActionDrv change_child_job_context = {
.clean = g_free,
};
-static bool child_job_change_aio_ctx(BdrvChild *c, AioContext *ctx,
- GHashTable *visited, Transaction *tran,
- Error **errp)
+static bool GRAPH_RDLOCK
+child_job_change_aio_ctx(BdrvChild *c, AioContext *ctx, GHashTable *visited,
+ Transaction *tran, Error **errp)
{
BlockJob *job = c->opaque;
BdrvStateChildJobContext *s;
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
index a9c0daa2a4..307dc56ed8 100644
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
@@ -987,9 +987,9 @@ struct BdrvChildClass {
bool backing_mask_protocol,
Error **errp);
- bool (*change_aio_ctx)(BdrvChild *child, AioContext *ctx,
- GHashTable *visited, Transaction *tran,
- Error **errp);
+ bool GRAPH_RDLOCK_PTR (*change_aio_ctx)(BdrvChild *child, AioContext *ctx,
+ GHashTable *visited,
+ Transaction *tran, Error **errp);
/*
* I/O API functions. These functions are thread-safe.
--
2.39.3

View File

@ -0,0 +1,326 @@
From 62e8b3e9173ea4fb85cf52c66109832ff9d4d437 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:50 +0200
Subject: [PATCH 25/33] block: move drain outside of bdrv_attach_child()
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [13/21] c68a1e34fa991dff72ec0a6403fd9786341ab534 (kmwolf/centos-qemu-kvm)
This is part of resolving the deadlock mentioned in commit "block:
move draining out of bdrv_change_aio_context() and mark GRAPH_RDLOCK".
The function bdrv_attach_child() runs under the graph lock, so it is
not allowed to drain. It is called by:
1. replication_start()
2. quorum_add_child()
3. bdrv_open_child_common()
4. Throughout test-bdrv-graph-mod.c and test-bdrv-drain.c unit tests.
In all callers, a drained section is introduced.
The function quorum_add_child() runs under the graph lock, so it is
not actually allowed to drain. This will be addressed by the following
commit.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20250530151125.955508-14-f.ebner@proxmox.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 77f3965ba7fed5b35212171a1e41c20c05a7ef11)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 6 ++++--
block/quorum.c | 2 ++
block/replication.c | 5 +++++
tests/unit/test-bdrv-drain.c | 14 ++++++++++++++
tests/unit/test-bdrv-graph-mod.c | 10 ++++++++++
5 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/block.c b/block.c
index 536a017201..3857f42877 100644
--- a/block.c
+++ b/block.c
@@ -3269,6 +3269,8 @@ out:
*
* On failure NULL is returned, errp is set and the reference to
* child_bs is also dropped.
+ *
+ * All block nodes must be drained.
*/
BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
BlockDriverState *child_bs,
@@ -3283,7 +3285,6 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
GLOBAL_STATE_CODE();
- bdrv_drain_all_begin();
child = bdrv_attach_child_noperm(parent_bs, child_bs, child_name,
child_class, child_role, tran, errp);
if (!child) {
@@ -3298,7 +3299,6 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
out:
tran_finalize(tran, ret);
- bdrv_drain_all_end();
bdrv_schedule_unref(child_bs);
@@ -3789,10 +3789,12 @@ static BdrvChild *bdrv_open_child_common(const char *filename,
return NULL;
}
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
errp);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
return child;
}
diff --git a/block/quorum.c b/block/quorum.c
index ed8ce801ee..ea17b0ec13 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -1096,8 +1096,10 @@ quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs, Error **errp)
/* We can safely add the child now */
bdrv_ref(child_bs);
+ bdrv_drain_all_begin();
child = bdrv_attach_child(bs, child_bs, indexstr, &child_of_bds,
BDRV_CHILD_DATA, errp);
+ bdrv_drain_all_end();
if (child == NULL) {
s->next_child_index--;
return;
diff --git a/block/replication.c b/block/replication.c
index 0020f33843..02814578c6 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -541,6 +541,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
return;
}
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_ref(hidden_disk->bs);
@@ -550,6 +551,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
if (local_err) {
error_propagate(errp, local_err);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
return;
}
@@ -560,6 +562,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
if (local_err) {
error_propagate(errp, local_err);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
return;
}
@@ -572,12 +575,14 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
!check_top_bs(top_bs, bs)) {
error_setg(errp, "No top_bs or it is invalid");
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
reopen_backing_file(bs, false, NULL);
return;
}
bdrv_op_block_all(top_bs, s->blocker);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
s->backup_job = backup_job_create(
NULL, s->secondary_disk->bs, s->hidden_disk->bs,
diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c
index 4f3057844b..ac76525e5a 100644
--- a/tests/unit/test-bdrv-drain.c
+++ b/tests/unit/test-bdrv-drain.c
@@ -1049,10 +1049,12 @@ static void do_test_delete_by_drain(bool detach_instead_of_delete,
null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
&error_abort);
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds,
BDRV_CHILD_DATA, &error_abort);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
/* This child will be the one to pass to requests through to, and
* it will stall until a drain occurs */
@@ -1060,21 +1062,25 @@ static void do_test_delete_by_drain(bool detach_instead_of_delete,
&error_abort);
child_bs->total_sectors = 65536 >> BDRV_SECTOR_BITS;
/* Takes our reference to child_bs */
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
tts->wait_child = bdrv_attach_child(bs, child_bs, "wait-child",
&child_of_bds,
BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY,
&error_abort);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
/* This child is just there to be deleted
* (for detach_instead_of_delete == true) */
null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
&error_abort);
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds, BDRV_CHILD_DATA,
&error_abort);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
blk_insert_bs(blk, bs, &error_abort);
@@ -1157,6 +1163,7 @@ static void no_coroutine_fn detach_indirect_bh(void *opaque)
bdrv_dec_in_flight(data->child_b->bs);
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_unref_child(data->parent_b, data->child_b);
@@ -1165,6 +1172,7 @@ static void no_coroutine_fn detach_indirect_bh(void *opaque)
&child_of_bds, BDRV_CHILD_DATA,
&error_abort);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
}
static void coroutine_mixed_fn detach_by_parent_aio_cb(void *opaque, int ret)
@@ -1262,6 +1270,7 @@ static void TSA_NO_TSA test_detach_indirect(bool by_parent_cb)
/* Set child relationships */
bdrv_ref(b);
bdrv_ref(a);
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
child_b = bdrv_attach_child(parent_b, b, "PB-B", &child_of_bds,
BDRV_CHILD_DATA, &error_abort);
@@ -1273,6 +1282,7 @@ static void TSA_NO_TSA test_detach_indirect(bool by_parent_cb)
by_parent_cb ? &child_of_bds : &detach_by_driver_cb_class,
BDRV_CHILD_DATA, &error_abort);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
g_assert_cmpint(parent_a->refcnt, ==, 1);
g_assert_cmpint(parent_b->refcnt, ==, 1);
@@ -1685,6 +1695,7 @@ static void test_drop_intermediate_poll(void)
* Establish the chain last, so the chain links are the first
* elements in the BDS.parents lists
*/
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
for (i = 0; i < 3; i++) {
if (i) {
@@ -1694,6 +1705,7 @@ static void test_drop_intermediate_poll(void)
}
}
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
job = block_job_create("job", &test_simple_job_driver, NULL, job_node,
0, BLK_PERM_ALL, 0, 0, NULL, NULL, &error_abort);
@@ -1940,10 +1952,12 @@ static void do_test_replace_child_mid_drain(int old_drain_count,
new_child_bs->total_sectors = 1;
bdrv_ref(old_child_bs);
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_attach_child(parent_bs, old_child_bs, "child", &child_of_bds,
BDRV_CHILD_COW, &error_abort);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
parent_s->setup_completed = true;
for (i = 0; i < old_drain_count; i++) {
diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c
index d743abb4bb..7b03ebe4b0 100644
--- a/tests/unit/test-bdrv-graph-mod.c
+++ b/tests/unit/test-bdrv-graph-mod.c
@@ -137,10 +137,12 @@ static void test_update_perm_tree(void)
blk_insert_bs(root, bs, &error_abort);
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_attach_child(filter, bs, "child", &child_of_bds,
BDRV_CHILD_DATA, &error_abort);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
ret = bdrv_append(filter, bs, NULL);
g_assert_cmpint(ret, <, 0);
@@ -204,11 +206,13 @@ static void test_should_update_child(void)
bdrv_set_backing_hd(target, bs, &error_abort);
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
g_assert(target->backing->bs == bs);
bdrv_attach_child(filter, target, "target", &child_of_bds,
BDRV_CHILD_DATA, &error_abort);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
bdrv_append(filter, bs, &error_abort);
bdrv_graph_rdlock_main_loop();
@@ -244,6 +248,7 @@ static void test_parallel_exclusive_write(void)
bdrv_ref(base);
bdrv_ref(fl1);
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_attach_child(top, fl1, "backing", &child_of_bds,
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
@@ -257,6 +262,7 @@ static void test_parallel_exclusive_write(void)
bdrv_replace_node(fl1, fl2, &error_abort);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
bdrv_drained_end(fl2);
bdrv_drained_end(fl1);
@@ -363,6 +369,7 @@ static void test_parallel_perm_update(void)
*/
bdrv_ref(base);
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_attach_child(top, ws, "file", &child_of_bds, BDRV_CHILD_DATA,
&error_abort);
@@ -377,6 +384,7 @@ static void test_parallel_perm_update(void)
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
&error_abort);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
/* Select fl1 as first child to be active */
s->selected = c_fl1;
@@ -430,11 +438,13 @@ static void test_append_greedy_filter(void)
BlockDriverState *base = no_perm_node("base");
BlockDriverState *fl = exclusive_writer_node("fl1");
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_attach_child(top, base, "backing", &child_of_bds,
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
&error_abort);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
bdrv_append(fl, base, &error_abort);
bdrv_unref(fl);
--
2.39.3

View File

@ -0,0 +1,260 @@
From faa96d060a393458e2e1f9ba77c53adf7d52bc85 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:47 +0200
Subject: [PATCH 22/33] block: move drain outside of
bdrv_attach_child_common(_abort)()
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [10/21] 0b8f078c657c094dbd6f967eaaccafd8112a9bda (kmwolf/centos-qemu-kvm)
This is part of resolving the deadlock mentioned in commit "block:
move draining out of bdrv_change_aio_context() and mark GRAPH_RDLOCK".
The function bdrv_attach_child_common_abort() is used only as the
abort callback in bdrv_attach_child_common_drv transactions, so the
tran_finalize() calls of such transactions need to be in drained
sections too.
All code paths are covered:
The bdrv_attach_child_common_drv transactions are only used in
bdrv_attach_child_common(), so it is enough to check callers of
bdrv_attach_child_common() following the transactions.
bdrv_attach_child_common() is called by:
1. bdrv_attach_child_noperm(), which does not finalize the
transaction yet.
2. bdrv_root_attach_child(), where a drained section is introduced.
bdrv_attach_child_noperm() is called by:
1. bdrv_attach_child(), where a drained section is introduced.
2. bdrv_set_file_or_backing_noperm(), which does not finalize the
transaction yet.
3. bdrv_append(), where a drained section is introduced.
bdrv_set_file_or_backing_noperm() is called by:
1. bdrv_set_backing_hd_drained(), where a drained section is
introduced.
2. bdrv_reopen_parse_file_or_backing(), which does not finalize the
transaction yet. Draining the old child bs currently happens under
the graph lock there. This is replaced with an assertion, because
the drain will be moved further up to the caller.
bdrv_reopen_parse_file_or_backing() is called by:
1. bdrv_reopen_prepare(), which does not finalize the transaction yet.
bdrv_reopen_prepare() is called by:
1. bdrv_reopen_multiple(), which does finalize the transaction. It is
called after bdrv_reopen_queue(), which starts a drained section.
The drained section ends, when bdrv_reopen_queue_free() is called
at the end of bdrv_reopen_multiple().
This resolves all code paths.
The functions bdrv_set_backing_hd_drained(), bdrv_attach_child() and
bdrv_root_attach_child() run under the graph lock, so they are not
actually allowed to drain. This will be addressed in the following
commits.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20250530151125.955508-11-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 2b833595aa21679145cfe67ba720113b165c19ef)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 40 ++++++++++++++++++++++++----------------
1 file changed, 24 insertions(+), 16 deletions(-)
diff --git a/block.c b/block.c
index 3c2e8c5592..2c18e0a4fa 100644
--- a/block.c
+++ b/block.c
@@ -3028,10 +3028,8 @@ static void GRAPH_WRLOCK bdrv_attach_child_common_abort(void *opaque)
bdrv_replace_child_noperm(s->child, NULL);
if (bdrv_get_aio_context(bs) != s->old_child_ctx) {
- bdrv_drain_all_begin();
bdrv_try_change_aio_context_locked(bs, s->old_child_ctx, NULL,
&error_abort);
- bdrv_drain_all_end();
}
if (bdrv_child_get_parent_aio_context(s->child) != s->old_parent_ctx) {
@@ -3043,10 +3041,8 @@ static void GRAPH_WRLOCK bdrv_attach_child_common_abort(void *opaque)
/* No need to visit `child`, because it has been detached already */
visited = g_hash_table_new(NULL, NULL);
- bdrv_drain_all_begin();
ret = s->child->klass->change_aio_ctx(s->child, s->old_parent_ctx,
visited, tran, &error_abort);
- bdrv_drain_all_end();
g_hash_table_destroy(visited);
/* transaction is supposed to always succeed */
@@ -3075,6 +3071,9 @@ static TransactionActionDrv bdrv_attach_child_common_drv = {
*
* Both @parent_bs and @child_bs can move to a different AioContext in this
* function.
+ *
+ * All block nodes must be drained before this function is called until after
+ * the transaction is finalized.
*/
static BdrvChild * GRAPH_WRLOCK
bdrv_attach_child_common(BlockDriverState *child_bs,
@@ -3118,10 +3117,8 @@ bdrv_attach_child_common(BlockDriverState *child_bs,
parent_ctx = bdrv_child_get_parent_aio_context(new_child);
if (child_ctx != parent_ctx) {
Error *local_err = NULL;
- bdrv_drain_all_begin();
int ret = bdrv_try_change_aio_context_locked(child_bs, parent_ctx, NULL,
&local_err);
- bdrv_drain_all_end();
if (ret < 0 && child_class->change_aio_ctx) {
Transaction *aio_ctx_tran = tran_new();
@@ -3129,11 +3126,9 @@ bdrv_attach_child_common(BlockDriverState *child_bs,
bool ret_child;
g_hash_table_add(visited, new_child);
- bdrv_drain_all_begin();
ret_child = child_class->change_aio_ctx(new_child, child_ctx,
visited, aio_ctx_tran,
NULL);
- bdrv_drain_all_end();
if (ret_child == true) {
error_free(local_err);
ret = 0;
@@ -3189,6 +3184,9 @@ bdrv_attach_child_common(BlockDriverState *child_bs,
*
* After calling this function, the transaction @tran may only be completed
* while holding a writer lock for the graph.
+ *
+ * All block nodes must be drained before this function is called until after
+ * the transaction is finalized.
*/
static BdrvChild * GRAPH_WRLOCK
bdrv_attach_child_noperm(BlockDriverState *parent_bs,
@@ -3244,6 +3242,7 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
GLOBAL_STATE_CODE();
+ bdrv_drain_all_begin();
child = bdrv_attach_child_common(child_bs, child_name, child_class,
child_role, perm, shared_perm, opaque,
tran, errp);
@@ -3256,6 +3255,7 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
out:
tran_finalize(tran, ret);
+ bdrv_drain_all_end();
bdrv_schedule_unref(child_bs);
@@ -3283,6 +3283,7 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
GLOBAL_STATE_CODE();
+ bdrv_drain_all_begin();
child = bdrv_attach_child_noperm(parent_bs, child_bs, child_name,
child_class, child_role, tran, errp);
if (!child) {
@@ -3297,6 +3298,7 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
out:
tran_finalize(tran, ret);
+ bdrv_drain_all_end();
bdrv_schedule_unref(child_bs);
@@ -3465,6 +3467,9 @@ static BdrvChildRole bdrv_backing_role(BlockDriverState *bs)
*
* After calling this function, the transaction @tran may only be completed
* while holding a writer lock for the graph.
+ *
+ * All block nodes must be drained before this function is called until after
+ * the transaction is finalized.
*/
static int GRAPH_WRLOCK
bdrv_set_file_or_backing_noperm(BlockDriverState *parent_bs,
@@ -3573,6 +3578,7 @@ int bdrv_set_backing_hd_drained(BlockDriverState *bs,
assert(bs->backing->bs->quiesce_counter > 0);
}
+ bdrv_drain_all_begin();
ret = bdrv_set_file_or_backing_noperm(bs, backing_hd, true, tran, errp);
if (ret < 0) {
goto out;
@@ -3581,6 +3587,7 @@ int bdrv_set_backing_hd_drained(BlockDriverState *bs,
ret = bdrv_refresh_perms(bs, tran, errp);
out:
tran_finalize(tran, ret);
+ bdrv_drain_all_end();
return ret;
}
@@ -4721,6 +4728,9 @@ int bdrv_reopen_set_read_only(BlockDriverState *bs, bool read_only,
* Return 0 on success, otherwise return < 0 and set @errp.
*
* @reopen_state->bs can move to a different AioContext in this function.
+ *
+ * All block nodes must be drained before this function is called until after
+ * the transaction is finalized.
*/
static int GRAPH_UNLOCKED
bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
@@ -4814,7 +4824,7 @@ bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
if (old_child_bs) {
bdrv_ref(old_child_bs);
- bdrv_drained_begin(old_child_bs);
+ assert(old_child_bs->quiesce_counter > 0);
}
bdrv_graph_rdunlock_main_loop();
@@ -4826,7 +4836,6 @@ bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
bdrv_graph_wrunlock();
if (old_child_bs) {
- bdrv_drained_end(old_child_bs);
bdrv_unref(old_child_bs);
}
@@ -4855,6 +4864,9 @@ out_rdlock:
*
* After calling this function, the transaction @change_child_tran may only be
* completed while holding a writer lock for the graph.
+ *
+ * All block nodes must be drained before this function is called until after
+ * the transaction is finalized.
*/
static int GRAPH_UNLOCKED
bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
@@ -5501,9 +5513,7 @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
assert(!bs_new->backing);
bdrv_graph_rdunlock_main_loop();
- bdrv_drained_begin(bs_top);
- bdrv_drained_begin(bs_new);
-
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
child = bdrv_attach_child_noperm(bs_new, bs_top, "backing",
@@ -5525,9 +5535,7 @@ out:
bdrv_refresh_limits(bs_top, NULL, NULL);
bdrv_graph_wrunlock();
-
- bdrv_drained_end(bs_top);
- bdrv_drained_end(bs_new);
+ bdrv_drain_all_end();
return ret;
}
--
2.39.3

View File

@ -0,0 +1,269 @@
From c5b0d95edea3d1e2ef47804e0c6fe19ade4dcaed Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:45 +0200
Subject: [PATCH 20/33] block: move drain outside of bdrv_change_aio_context()
and mark GRAPH_RDLOCK
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [8/21] 26dc90de9b684044752ba2ad3831bd786e40fe72 (kmwolf/centos-qemu-kvm)
This is in preparation to mark bdrv_drained_begin() as GRAPH_UNLOCKED.
Note that even if bdrv_drained_begin() were already marked as
GRAPH_UNLOCKED, TSA would not complain about the instance in
bdrv_change_aio_context() before this change, because it is preceded
by a bdrv_graph_rdunlock_main_loop() call. It is not correct to
release the lock here, and in case the caller holds a write lock, it
wouldn't actually release the lock.
In combination with block-stream, there is a deadlock that can happen
because of this [0]. In particular, it can happen that
main thread IO thread
1. acquires write lock
in blk_co_do_preadv_part():
2. have non-zero blk->in_flight
3. try to acquire read lock
4. begin drain
Steps 3 and 4 might be switched. Draining will poll and get stuck,
because it will see the non-zero in_flight counter. But the IO thread
will not make any progress either, because it cannot acquire the read
lock.
After this change, all paths to bdrv_change_aio_context() drain:
bdrv_change_aio_context() is called by:
1. bdrv_child_cb_change_aio_ctx() which is only called via the
change_aio_ctx() callback, see below.
2. bdrv_child_change_aio_context(), see below.
3. bdrv_try_change_aio_context(), where a drained section is
introduced.
The change_aio_ctx() callback is called by:
1. bdrv_attach_child_common_abort(), where a drained section is
introduced.
2. bdrv_attach_child_common(), where a drained section is introduced.
3. bdrv_parent_change_aio_context(), see below.
bdrv_child_change_aio_context() is called by:
1. bdrv_change_aio_context(), i.e. recursive, so being in a drained
section is invariant.
2. child_job_change_aio_ctx(), which is only called via the
change_aio_ctx() callback, see above.
bdrv_parent_change_aio_context() is called by:
1. bdrv_change_aio_context(), i.e. recursive, so being in a drained
section is invariant.
This resolves all code paths. Note that bdrv_attach_child_common()
and bdrv_attach_child_common_abort() hold the graph write lock and
callers of bdrv_try_change_aio_context() might too, so they are not
actually allowed to drain either. This will be addressed in the
following commits.
More granular draining is not trivially possible, because
bdrv_change_aio_context() can recursively call itself e.g. via
bdrv_child_change_aio_context().
[0]: https://lore.kernel.org/qemu-devel/73839c04-7616-407e-b057-80ca69e63f51@virtuozzo.com/
Reported-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20250530151125.955508-9-f.ebner@proxmox.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 91ba0e1c382bd4a4b9c6a200f8a175d6ff30ab99)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 57 +++++++++++++++++++++++---------
include/block/block_int-common.h | 12 +++++++
2 files changed, 53 insertions(+), 16 deletions(-)
diff --git a/block.c b/block.c
index f7b21d8f27..af438ae7ff 100644
--- a/block.c
+++ b/block.c
@@ -106,9 +106,9 @@ static void bdrv_reopen_abort(BDRVReopenState *reopen_state);
static bool bdrv_backing_overridden(BlockDriverState *bs);
-static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
- GHashTable *visited, Transaction *tran,
- Error **errp);
+static bool GRAPH_RDLOCK
+bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
+ GHashTable *visited, Transaction *tran, Error **errp);
/* If non-zero, use only whitelisted block drivers */
static int use_bdrv_whitelist;
@@ -3040,8 +3040,10 @@ static void GRAPH_WRLOCK bdrv_attach_child_common_abort(void *opaque)
/* No need to visit `child`, because it has been detached already */
visited = g_hash_table_new(NULL, NULL);
+ bdrv_drain_all_begin();
ret = s->child->klass->change_aio_ctx(s->child, s->old_parent_ctx,
visited, tran, &error_abort);
+ bdrv_drain_all_end();
g_hash_table_destroy(visited);
/* transaction is supposed to always succeed */
@@ -3122,9 +3124,11 @@ bdrv_attach_child_common(BlockDriverState *child_bs,
bool ret_child;
g_hash_table_add(visited, new_child);
+ bdrv_drain_all_begin();
ret_child = child_class->change_aio_ctx(new_child, child_ctx,
visited, aio_ctx_tran,
NULL);
+ bdrv_drain_all_end();
if (ret_child == true) {
error_free(local_err);
ret = 0;
@@ -7576,6 +7580,17 @@ typedef struct BdrvStateSetAioContext {
BlockDriverState *bs;
} BdrvStateSetAioContext;
+/*
+ * Changes the AioContext of @child to @ctx and recursively for the associated
+ * block nodes and all their children and parents. Returns true if the change is
+ * possible and the transaction @tran can be continued. Returns false and sets
+ * @errp if not and the transaction must be aborted.
+ *
+ * @visited will accumulate all visited BdrvChild objects. The caller is
+ * responsible for freeing the list afterwards.
+ *
+ * Must be called with the affected block nodes drained.
+ */
static bool GRAPH_RDLOCK
bdrv_parent_change_aio_context(BdrvChild *c, AioContext *ctx,
GHashTable *visited, Transaction *tran,
@@ -7604,6 +7619,17 @@ bdrv_parent_change_aio_context(BdrvChild *c, AioContext *ctx,
return true;
}
+/*
+ * Changes the AioContext of @c->bs to @ctx and recursively for all its children
+ * and parents. Returns true if the change is possible and the transaction @tran
+ * can be continued. Returns false and sets @errp if not and the transaction
+ * must be aborted.
+ *
+ * @visited will accumulate all visited BdrvChild objects. The caller is
+ * responsible for freeing the list afterwards.
+ *
+ * Must be called with the affected block nodes drained.
+ */
bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
GHashTable *visited, Transaction *tran,
Error **errp)
@@ -7619,10 +7645,6 @@ bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
static void bdrv_set_aio_context_clean(void *opaque)
{
BdrvStateSetAioContext *state = (BdrvStateSetAioContext *) opaque;
- BlockDriverState *bs = (BlockDriverState *) state->bs;
-
- /* Paired with bdrv_drained_begin in bdrv_change_aio_context() */
- bdrv_drained_end(bs);
g_free(state);
}
@@ -7650,10 +7672,12 @@ static TransactionActionDrv set_aio_context = {
*
* @visited will accumulate all visited BdrvChild objects. The caller is
* responsible for freeing the list afterwards.
+ *
+ * @bs must be drained.
*/
-static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
- GHashTable *visited, Transaction *tran,
- Error **errp)
+static bool GRAPH_RDLOCK
+bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
+ GHashTable *visited, Transaction *tran, Error **errp)
{
BdrvChild *c;
BdrvStateSetAioContext *state;
@@ -7664,21 +7688,17 @@ static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
return true;
}
- bdrv_graph_rdlock_main_loop();
QLIST_FOREACH(c, &bs->parents, next_parent) {
if (!bdrv_parent_change_aio_context(c, ctx, visited, tran, errp)) {
- bdrv_graph_rdunlock_main_loop();
return false;
}
}
QLIST_FOREACH(c, &bs->children, next) {
if (!bdrv_child_change_aio_context(c, ctx, visited, tran, errp)) {
- bdrv_graph_rdunlock_main_loop();
return false;
}
}
- bdrv_graph_rdunlock_main_loop();
state = g_new(BdrvStateSetAioContext, 1);
*state = (BdrvStateSetAioContext) {
@@ -7686,8 +7706,7 @@ static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
.bs = bs,
};
- /* Paired with bdrv_drained_end in bdrv_set_aio_context_clean() */
- bdrv_drained_begin(bs);
+ assert(bs->quiesce_counter > 0);
tran_add(tran, &set_aio_context, state);
@@ -7720,6 +7739,8 @@ int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
if (ignore_child) {
g_hash_table_add(visited, ignore_child);
}
+ bdrv_drain_all_begin();
+ bdrv_graph_rdlock_main_loop();
ret = bdrv_change_aio_context(bs, ctx, visited, tran, errp);
g_hash_table_destroy(visited);
@@ -7733,10 +7754,14 @@ int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
if (!ret) {
/* Just run clean() callbacks. No AioContext changed. */
tran_abort(tran);
+ bdrv_graph_rdunlock_main_loop();
+ bdrv_drain_all_end();
return -EPERM;
}
tran_commit(tran);
+ bdrv_graph_rdunlock_main_loop();
+ bdrv_drain_all_end();
return 0;
}
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
index 307dc56ed8..5d34e6a510 100644
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
@@ -987,6 +987,18 @@ struct BdrvChildClass {
bool backing_mask_protocol,
Error **errp);
+ /*
+ * Notifies the parent that the child is trying to change its AioContext.
+ * The parent may in turn change the AioContext of other nodes in the same
+ * transaction. Returns true if the change is possible and the transaction
+ * can be continued. Returns false and sets @errp if not and the transaction
+ * must be aborted.
+ *
+ * @visited will accumulate all visited BdrvChild objects. The caller is
+ * responsible for freeing the list afterwards.
+ *
+ * Must be called with the affected block nodes drained.
+ */
bool GRAPH_RDLOCK_PTR (*change_aio_ctx)(BdrvChild *child, AioContext *ctx,
GHashTable *visited,
Transaction *tran, Error **errp);
--
2.39.3

View File

@ -0,0 +1,283 @@
From 4629f2201a220c7775df5a305f22d51ba7a34641 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:49 +0200
Subject: [PATCH 24/33] block: move drain outside of bdrv_root_attach_child()
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [12/21] fa142303dc37b7dc3555900f6e86d5d8241cb36b (kmwolf/centos-qemu-kvm)
This is part of resolving the deadlock mentioned in commit "block:
move draining out of bdrv_change_aio_context() and mark GRAPH_RDLOCK".
The function bdrv_root_attach_child() runs under the graph lock, so it
is not allowed to drain. It is called by:
1. blk_insert_bs(), where a drained section is introduced.
2. block_job_add_bdrv(), which holds the graph lock itself.
block_job_add_bdrv() is called by:
1. mirror_start_job()
2. stream_start()
3. commit_start()
4. backup_job_create()
5. block_job_create()
6. In the test_blockjob_common_drain_node() unit test
In all callers, a drained section is introduced.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20250530151125.955508-13-f.ebner@proxmox.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit ffdcd081f52544f065020c780a6c522dace6b0af)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 4 ++--
block/backup.c | 2 ++
block/block-backend.c | 2 ++
block/commit.c | 4 ++++
block/mirror.c | 5 +++++
block/stream.c | 4 ++++
blockjob.c | 4 ++++
include/block/blockjob.h | 2 ++
tests/unit/test-bdrv-drain.c | 2 ++
9 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/block.c b/block.c
index d84b8ae49e..536a017201 100644
--- a/block.c
+++ b/block.c
@@ -3228,6 +3228,8 @@ bdrv_attach_child_noperm(BlockDriverState *parent_bs,
*
* On failure NULL is returned, errp is set and the reference to
* child_bs is also dropped.
+ *
+ * All block nodes must be drained.
*/
BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
const char *child_name,
@@ -3242,7 +3244,6 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
GLOBAL_STATE_CODE();
- bdrv_drain_all_begin();
child = bdrv_attach_child_common(child_bs, child_name, child_class,
child_role, perm, shared_perm, opaque,
tran, errp);
@@ -3255,7 +3256,6 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
out:
tran_finalize(tran, ret);
- bdrv_drain_all_end();
bdrv_schedule_unref(child_bs);
diff --git a/block/backup.c b/block/backup.c
index 79652bf57b..9d55e55b79 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -497,10 +497,12 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
block_copy_set_speed(bcs, speed);
/* Required permissions are taken by copy-before-write filter target */
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
&error_abort);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
return &job->common;
diff --git a/block/block-backend.c b/block/block-backend.c
index 6a6949edeb..24cae3cb55 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -904,6 +904,7 @@ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
GLOBAL_STATE_CODE();
bdrv_ref(bs);
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
if ((bs->open_flags & BDRV_O_INACTIVE) && blk_can_inactivate(blk)) {
@@ -919,6 +920,7 @@ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
perm, shared_perm, blk, errp);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
if (blk->root == NULL) {
return -EPERM;
}
diff --git a/block/commit.c b/block/commit.c
index 5df3d05346..6c06b894ff 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -342,6 +342,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
* this is the responsibility of the interface (i.e. whoever calls
* commit_start()).
*/
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
s->base_overlay = bdrv_find_overlay(top, base);
assert(s->base_overlay);
@@ -374,18 +375,21 @@ void commit_start(const char *job_id, BlockDriverState *bs,
iter_shared_perms, errp);
if (ret < 0) {
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
goto fail;
}
}
if (bdrv_freeze_backing_chain(commit_top_bs, base, errp) < 0) {
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
goto fail;
}
s->chain_frozen = true;
ret = block_job_add_bdrv(&s->common, "base", base, 0, BLK_PERM_ALL, errp);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
if (ret < 0) {
goto fail;
diff --git a/block/mirror.c b/block/mirror.c
index c2c5099c95..6e8caf4b49 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -2014,6 +2014,7 @@ static BlockJob *mirror_start_job(
*/
bdrv_disable_dirty_bitmap(s->dirty_bitmap);
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
ret = block_job_add_bdrv(&s->common, "source", bs, 0,
BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE |
@@ -2021,6 +2022,7 @@ static BlockJob *mirror_start_job(
errp);
if (ret < 0) {
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
goto fail;
}
@@ -2066,16 +2068,19 @@ static BlockJob *mirror_start_job(
iter_shared_perms, errp);
if (ret < 0) {
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
goto fail;
}
}
if (bdrv_freeze_backing_chain(mirror_top_bs, target, errp) < 0) {
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
goto fail;
}
}
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
QTAILQ_INIT(&s->ops_in_flight);
diff --git a/block/stream.c b/block/stream.c
index 6ba49cffd3..f5441f27f4 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -371,10 +371,12 @@ void stream_start(const char *job_id, BlockDriverState *bs,
* already have our own plans. Also don't allow resize as the image size is
* queried only at the job start and then cached.
*/
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
if (block_job_add_bdrv(&s->common, "active node", bs, 0,
basic_flags | BLK_PERM_WRITE, errp)) {
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
goto fail;
}
@@ -395,10 +397,12 @@ void stream_start(const char *job_id, BlockDriverState *bs,
basic_flags, errp);
if (ret < 0) {
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
goto fail;
}
}
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
s->base_overlay = base_overlay;
s->above_base = above_base;
diff --git a/blockjob.c b/blockjob.c
index 34185d7715..44991e3ff7 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -496,6 +496,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
int ret;
GLOBAL_STATE_CODE();
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
if (job_id == NULL && !(flags & JOB_INTERNAL)) {
@@ -506,6 +507,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
flags, cb, opaque, errp);
if (job == NULL) {
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
return NULL;
}
@@ -544,10 +546,12 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
}
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
return job;
fail:
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
job_early_fail(&job->job);
return NULL;
}
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index 7061ab7201..990f3e179a 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -137,6 +137,8 @@ BlockJob *block_job_get_locked(const char *id);
* Add @bs to the list of BlockDriverState that are involved in
* @job. This means that all operations will be blocked on @bs while
* @job exists.
+ *
+ * All block nodes must be drained.
*/
int GRAPH_WRLOCK
block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c
index 3185f3f429..4f3057844b 100644
--- a/tests/unit/test-bdrv-drain.c
+++ b/tests/unit/test-bdrv-drain.c
@@ -772,9 +772,11 @@ static void test_blockjob_common_drain_node(enum drain_type drain_type,
tjob->bs = src;
job = &tjob->common;
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
block_job_add_bdrv(job, "target", target, 0, BLK_PERM_ALL, &error_abort);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
switch (result) {
case TEST_JOB_SUCCESS:
--
2.39.3

View File

@ -0,0 +1,405 @@
From 1ad00825750a515baf5bd9185bbc31549a61568b Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:52 +0200
Subject: [PATCH 27/33] block: move drain outside of bdrv_root_unref_child()
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [15/21] 05cc374ad5ce3f3ae4b3e5d4024c67141acf2cc2 (kmwolf/centos-qemu-kvm)
This is part of resolving the deadlock mentioned in commit "block:
move draining out of bdrv_change_aio_context() and mark GRAPH_RDLOCK".
bdrv_root_unref_child() is called by:
1. blk_remove_bs(), where a drained section is introduced.
2. bdrv_unref_child(), which runs under the graph lock, so the drain
will be moved further up to its callers.
3. block_job_remove_all_bdrv(), where a drained section is introduced.
For all callers of bdrv_unref_child() and its generated
bdrv_co_unref_child() coroutine variant, a drained section is
introduced, they are not explicilty listed here. The caller
quorum_del_child() holds the graph lock, so it is not actually allowed
to drain. This will be addressed in the next commit.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20250530151125.955508-16-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit b13f54654546cbc0661d3fe9d25f7543535c2bee)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 18 ++++++++++++++----
block/blklogwrites.c | 4 ++++
block/blkverify.c | 2 ++
block/block-backend.c | 2 ++
block/qcow2.c | 4 ++++
block/quorum.c | 6 ++++++
block/replication.c | 2 ++
block/snapshot.c | 2 ++
block/vmdk.c | 10 ++++++++++
blockjob.c | 2 ++
tests/unit/test-bdrv-drain.c | 4 ++++
11 files changed, 52 insertions(+), 4 deletions(-)
diff --git a/block.c b/block.c
index d7425ff971..51bc084b1e 100644
--- a/block.c
+++ b/block.c
@@ -1721,12 +1721,14 @@ bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv, const char *node_name,
open_failed:
bs->drv = NULL;
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
if (bs->file != NULL) {
bdrv_unref_child(bs, bs->file);
assert(!bs->file);
}
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
g_free(bs->opaque);
bs->opaque = NULL;
@@ -3305,7 +3307,11 @@ out:
return ret < 0 ? NULL : child;
}
-/* Callers must ensure that child->frozen is false. */
+/*
+ * Callers must ensure that child->frozen is false.
+ *
+ * All block nodes must be drained.
+ */
void bdrv_root_unref_child(BdrvChild *child)
{
BlockDriverState *child_bs = child->bs;
@@ -3326,10 +3332,8 @@ void bdrv_root_unref_child(BdrvChild *child)
* When the parent requiring a non-default AioContext is removed, the
* node moves back to the main AioContext
*/
- bdrv_drain_all_begin();
bdrv_try_change_aio_context_locked(child_bs, qemu_get_aio_context(),
NULL, NULL);
- bdrv_drain_all_end();
}
bdrv_schedule_unref(child_bs);
@@ -3402,7 +3406,11 @@ bdrv_unset_inherits_from(BlockDriverState *root, BdrvChild *child,
}
}
-/* Callers must ensure that child->frozen is false. */
+/*
+ * Callers must ensure that child->frozen is false.
+ *
+ * All block nodes must be drained.
+ */
void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child)
{
GLOBAL_STATE_CODE();
@@ -5172,6 +5180,7 @@ static void bdrv_close(BlockDriverState *bs)
bs->drv = NULL;
}
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
QLIST_FOREACH_SAFE(child, &bs->children, next, next) {
bdrv_unref_child(bs, child);
@@ -5180,6 +5189,7 @@ static void bdrv_close(BlockDriverState *bs)
assert(!bs->backing);
assert(!bs->file);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
g_free(bs->opaque);
bs->opaque = NULL;
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
index b0f78c4bc7..70ac76f401 100644
--- a/block/blklogwrites.c
+++ b/block/blklogwrites.c
@@ -281,9 +281,11 @@ static int blk_log_writes_open(BlockDriverState *bs, QDict *options, int flags,
ret = 0;
fail_log:
if (ret < 0) {
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_unref_child(bs, s->log_file);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
s->log_file = NULL;
qemu_mutex_destroy(&s->mutex);
}
@@ -296,10 +298,12 @@ static void blk_log_writes_close(BlockDriverState *bs)
{
BDRVBlkLogWritesState *s = bs->opaque;
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_unref_child(bs, s->log_file);
s->log_file = NULL;
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
qemu_mutex_destroy(&s->mutex);
}
diff --git a/block/blkverify.c b/block/blkverify.c
index db79a36681..3a71f7498c 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -151,10 +151,12 @@ static void blkverify_close(BlockDriverState *bs)
{
BDRVBlkverifyState *s = bs->opaque;
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_unref_child(bs, s->test_file);
s->test_file = NULL;
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
}
static int64_t coroutine_fn GRAPH_RDLOCK
diff --git a/block/block-backend.c b/block/block-backend.c
index 24cae3cb55..68209bb2f7 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -889,9 +889,11 @@ void blk_remove_bs(BlockBackend *blk)
root = blk->root;
blk->root = NULL;
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_root_unref_child(root);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
}
/*
diff --git a/block/qcow2.c b/block/qcow2.c
index 9fc96ba99a..9480598b6d 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1901,7 +1901,9 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
g_free(s->image_data_file);
if (open_data_file && has_data_file(bs)) {
bdrv_graph_co_rdunlock();
+ bdrv_drain_all_begin();
bdrv_co_unref_child(bs, s->data_file);
+ bdrv_drain_all_end();
bdrv_graph_co_rdlock();
s->data_file = NULL;
}
@@ -2827,9 +2829,11 @@ qcow2_do_close(BlockDriverState *bs, bool close_data_file)
if (close_data_file && has_data_file(bs)) {
GLOBAL_STATE_CODE();
bdrv_graph_rdunlock_main_loop();
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_unref_child(bs, s->data_file);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
s->data_file = NULL;
bdrv_graph_rdlock_main_loop();
}
diff --git a/block/quorum.c b/block/quorum.c
index ed8ce801ee..81407a38ee 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -1037,6 +1037,7 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
close_exit:
/* cleanup on error */
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
for (i = 0; i < s->num_children; i++) {
if (!opened[i]) {
@@ -1045,6 +1046,7 @@ close_exit:
bdrv_unref_child(bs, s->children[i]);
}
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
g_free(s->children);
g_free(opened);
exit:
@@ -1057,11 +1059,13 @@ static void quorum_close(BlockDriverState *bs)
BDRVQuorumState *s = bs->opaque;
int i;
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
for (i = 0; i < s->num_children; i++) {
bdrv_unref_child(bs, s->children[i]);
}
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
g_free(s->children);
}
@@ -1143,7 +1147,9 @@ quorum_del_child(BlockDriverState *bs, BdrvChild *child, Error **errp)
(s->num_children - i - 1) * sizeof(BdrvChild *));
s->children = g_renew(BdrvChild *, s->children, --s->num_children);
+ bdrv_drain_all_begin();
bdrv_unref_child(bs, child);
+ bdrv_drain_all_end();
quorum_refresh_flags(bs);
}
diff --git a/block/replication.c b/block/replication.c
index 02814578c6..92eb432b1b 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -655,12 +655,14 @@ static void replication_done(void *opaque, int ret)
if (ret == 0) {
s->stage = BLOCK_REPLICATION_DONE;
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_unref_child(bs, s->secondary_disk);
s->secondary_disk = NULL;
bdrv_unref_child(bs, s->hidden_disk);
s->hidden_disk = NULL;
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
s->error = 0;
} else {
diff --git a/block/snapshot.c b/block/snapshot.c
index 9f300a78bd..28c9c43621 100644
--- a/block/snapshot.c
+++ b/block/snapshot.c
@@ -291,9 +291,11 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
}
/* .bdrv_open() will re-attach it */
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_unref_child(bs, fallback);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
ret = bdrv_snapshot_goto(fallback_bs, snapshot_id, errp);
memset(bs->opaque, 0, drv->instance_size);
diff --git a/block/vmdk.c b/block/vmdk.c
index 9c7ab037e1..89a7250120 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -271,6 +271,7 @@ static void vmdk_free_extents(BlockDriverState *bs)
BDRVVmdkState *s = bs->opaque;
VmdkExtent *e;
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
for (i = 0; i < s->num_extents; i++) {
e = &s->extents[i];
@@ -283,6 +284,7 @@ static void vmdk_free_extents(BlockDriverState *bs)
}
}
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
g_free(s->extents);
}
@@ -1247,9 +1249,11 @@ vmdk_parse_extents(const char *desc, BlockDriverState *bs, QDict *options,
0, 0, 0, 0, 0, &extent, errp);
if (ret < 0) {
bdrv_graph_rdunlock_main_loop();
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
bdrv_graph_rdlock_main_loop();
goto out;
}
@@ -1266,9 +1270,11 @@ vmdk_parse_extents(const char *desc, BlockDriverState *bs, QDict *options,
g_free(buf);
if (ret) {
bdrv_graph_rdunlock_main_loop();
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
bdrv_graph_rdlock_main_loop();
goto out;
}
@@ -1277,9 +1283,11 @@ vmdk_parse_extents(const char *desc, BlockDriverState *bs, QDict *options,
ret = vmdk_open_se_sparse(bs, extent_file, bs->open_flags, errp);
if (ret) {
bdrv_graph_rdunlock_main_loop();
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
bdrv_graph_rdlock_main_loop();
goto out;
}
@@ -1287,9 +1295,11 @@ vmdk_parse_extents(const char *desc, BlockDriverState *bs, QDict *options,
} else {
error_setg(errp, "Unsupported extent type '%s'", type);
bdrv_graph_rdunlock_main_loop();
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
bdrv_unref_child(bs, extent_file);
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
bdrv_graph_rdlock_main_loop();
ret = -ENOTSUP;
goto out;
diff --git a/blockjob.c b/blockjob.c
index 44991e3ff7..e68181a35b 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -198,6 +198,7 @@ void block_job_remove_all_bdrv(BlockJob *job)
* one to make sure that such a concurrent access does not attempt
* to process an already freed BdrvChild.
*/
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
while (job->nodes) {
GSList *l = job->nodes;
@@ -211,6 +212,7 @@ void block_job_remove_all_bdrv(BlockJob *job)
g_slist_free_1(l);
}
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
}
bool block_job_has_bdrv(BlockJob *job, BlockDriverState *bs)
diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c
index ac76525e5a..59c2793725 100644
--- a/tests/unit/test-bdrv-drain.c
+++ b/tests/unit/test-bdrv-drain.c
@@ -955,11 +955,13 @@ static void bdrv_test_top_close(BlockDriverState *bs)
{
BdrvChild *c, *next_c;
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) {
bdrv_unref_child(bs, c);
}
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
}
static int coroutine_fn GRAPH_RDLOCK
@@ -1016,7 +1018,9 @@ static void coroutine_fn test_co_delete_by_drain(void *opaque)
bdrv_graph_co_rdlock();
QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) {
bdrv_graph_co_rdunlock();
+ bdrv_drain_all_begin();
bdrv_co_unref_child(bs, c);
+ bdrv_drain_all_end();
bdrv_graph_co_rdlock();
}
bdrv_graph_co_rdunlock();
--
2.39.3

View File

@ -0,0 +1,123 @@
From e3a722681805290fced1cde3d4ac991f8278f158 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:48 +0200
Subject: [PATCH 23/33] block: move drain outside of
bdrv_set_backing_hd_drained()
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [11/21] ab1d93ce55b51312e3aac1867e8826286c5d49de (kmwolf/centos-qemu-kvm)
This is part of resolving the deadlock mentioned in commit "block:
move draining out of bdrv_change_aio_context() and mark GRAPH_RDLOCK".
The function bdrv_set_backing_hd_drained() holds the graph lock, so it
is not allowed to drain. It is called by:
1. bdrv_set_backing_hd(), where a drained section is introduced,
replacing the previously present bs-specific drains.
2. stream_prepare(), where a drained section is introduced replacing
the previously present bs-specific drains.
The drain_bs variable in bdrv_set_backing_hd_drained() is now
superfluous and thus dropped.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20250530151125.955508-12-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit e66dbda11eab2b4a091d470f3508a4d6ca60eaf5)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 16 +++-------------
block/stream.c | 6 ++----
2 files changed, 5 insertions(+), 17 deletions(-)
diff --git a/block.c b/block.c
index 2c18e0a4fa..d84b8ae49e 100644
--- a/block.c
+++ b/block.c
@@ -3562,8 +3562,7 @@ out:
* Both @bs and @backing_hd can move to a different AioContext in this
* function.
*
- * If a backing child is already present (i.e. we're detaching a node), that
- * child node must be drained.
+ * All block nodes must be drained.
*/
int bdrv_set_backing_hd_drained(BlockDriverState *bs,
BlockDriverState *backing_hd,
@@ -3578,7 +3577,6 @@ int bdrv_set_backing_hd_drained(BlockDriverState *bs,
assert(bs->backing->bs->quiesce_counter > 0);
}
- bdrv_drain_all_begin();
ret = bdrv_set_file_or_backing_noperm(bs, backing_hd, true, tran, errp);
if (ret < 0) {
goto out;
@@ -3587,28 +3585,20 @@ int bdrv_set_backing_hd_drained(BlockDriverState *bs,
ret = bdrv_refresh_perms(bs, tran, errp);
out:
tran_finalize(tran, ret);
- bdrv_drain_all_end();
return ret;
}
int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
Error **errp)
{
- BlockDriverState *drain_bs;
int ret;
GLOBAL_STATE_CODE();
- bdrv_graph_rdlock_main_loop();
- drain_bs = bs->backing ? bs->backing->bs : bs;
- bdrv_graph_rdunlock_main_loop();
-
- bdrv_ref(drain_bs);
- bdrv_drained_begin(drain_bs);
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
ret = bdrv_set_backing_hd_drained(bs, backing_hd, errp);
bdrv_graph_wrunlock();
- bdrv_drained_end(drain_bs);
- bdrv_unref(drain_bs);
+ bdrv_drain_all_end();
return ret;
}
diff --git a/block/stream.c b/block/stream.c
index 999d9e56d4..6ba49cffd3 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -80,11 +80,10 @@ static int stream_prepare(Job *job)
* may end up working with the wrong base node (or it might even have gone
* away by the time we want to use it).
*/
- bdrv_drained_begin(unfiltered_bs);
if (unfiltered_bs_cow) {
bdrv_ref(unfiltered_bs_cow);
- bdrv_drained_begin(unfiltered_bs_cow);
}
+ bdrv_drain_all_begin();
bdrv_graph_rdlock_main_loop();
base = bdrv_filter_or_cow_bs(s->above_base);
@@ -123,11 +122,10 @@ static int stream_prepare(Job *job)
}
out:
+ bdrv_drain_all_end();
if (unfiltered_bs_cow) {
- bdrv_drained_end(unfiltered_bs_cow);
bdrv_unref(unfiltered_bs_cow);
}
- bdrv_drained_end(unfiltered_bs);
return ret;
}
--
2.39.3

View File

@ -0,0 +1,257 @@
From 0fc67b52f8d95a10d0bbc1d49eaf2f93c603d967 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:46 +0200
Subject: [PATCH 21/33] block: move drain outside of
bdrv_try_change_aio_context()
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [9/21] 9e421c675137364d37f9694b7df6ed5c434f20c6 (kmwolf/centos-qemu-kvm)
This is part of resolving the deadlock mentioned in commit "block:
move draining out of bdrv_change_aio_context() and mark GRAPH_RDLOCK".
Convert the function to a _locked() version that has to be called with
the graph lock held and add a convenience wrapper that has to be
called with the graph unlocked, which drains and takes the lock
itself. Since bdrv_try_change_aio_context() is global state code, the
wrapper is too.
Callers are adapted to use the appropriate variant, depending on
whether the caller already holds the lock. In the
test_set_aio_context() unit test, prior drains can be removed, because
draining already happens inside the new wrapper.
Note that bdrv_attach_child_common_abort(), bdrv_attach_child_common()
and bdrv_root_unref_child() hold the graph lock and are not actually
allowed to drain either. This will be addressed in the following
commits.
Functions like qmp_blockdev_mirror() query the nodes to act on before
draining and locking. In theory, draining could invalidate those nodes.
This kind of issue is not addressed by these commits.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20250530151125.955508-10-f.ebner@proxmox.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit a1ea8eb5912256c0b2be16fae5d3786aebc80cb1)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 58 ++++++++++++++++++++++--------
blockdev.c | 15 +++++---
include/block/block-global-state.h | 8 +++--
tests/unit/test-bdrv-drain.c | 4 ---
4 files changed, 59 insertions(+), 26 deletions(-)
diff --git a/block.c b/block.c
index af438ae7ff..3c2e8c5592 100644
--- a/block.c
+++ b/block.c
@@ -3028,7 +3028,10 @@ static void GRAPH_WRLOCK bdrv_attach_child_common_abort(void *opaque)
bdrv_replace_child_noperm(s->child, NULL);
if (bdrv_get_aio_context(bs) != s->old_child_ctx) {
- bdrv_try_change_aio_context(bs, s->old_child_ctx, NULL, &error_abort);
+ bdrv_drain_all_begin();
+ bdrv_try_change_aio_context_locked(bs, s->old_child_ctx, NULL,
+ &error_abort);
+ bdrv_drain_all_end();
}
if (bdrv_child_get_parent_aio_context(s->child) != s->old_parent_ctx) {
@@ -3115,8 +3118,10 @@ bdrv_attach_child_common(BlockDriverState *child_bs,
parent_ctx = bdrv_child_get_parent_aio_context(new_child);
if (child_ctx != parent_ctx) {
Error *local_err = NULL;
- int ret = bdrv_try_change_aio_context(child_bs, parent_ctx, NULL,
- &local_err);
+ bdrv_drain_all_begin();
+ int ret = bdrv_try_change_aio_context_locked(child_bs, parent_ctx, NULL,
+ &local_err);
+ bdrv_drain_all_end();
if (ret < 0 && child_class->change_aio_ctx) {
Transaction *aio_ctx_tran = tran_new();
@@ -3319,8 +3324,10 @@ void bdrv_root_unref_child(BdrvChild *child)
* When the parent requiring a non-default AioContext is removed, the
* node moves back to the main AioContext
*/
- bdrv_try_change_aio_context(child_bs, qemu_get_aio_context(), NULL,
- NULL);
+ bdrv_drain_all_begin();
+ bdrv_try_change_aio_context_locked(child_bs, qemu_get_aio_context(),
+ NULL, NULL);
+ bdrv_drain_all_end();
}
bdrv_schedule_unref(child_bs);
@@ -7719,9 +7726,13 @@ bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
*
* If ignore_child is not NULL, that child (and its subgraph) will not
* be touched.
+ *
+ * Called with the graph lock held.
+ *
+ * Called while all bs are drained.
*/
-int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
- BdrvChild *ignore_child, Error **errp)
+int bdrv_try_change_aio_context_locked(BlockDriverState *bs, AioContext *ctx,
+ BdrvChild *ignore_child, Error **errp)
{
Transaction *tran;
GHashTable *visited;
@@ -7730,17 +7741,15 @@ int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
/*
* Recursion phase: go through all nodes of the graph.
- * Take care of checking that all nodes support changing AioContext
- * and drain them, building a linear list of callbacks to run if everything
- * is successful (the transaction itself).
+ * Take care of checking that all nodes support changing AioContext,
+ * building a linear list of callbacks to run if everything is successful
+ * (the transaction itself).
*/
tran = tran_new();
visited = g_hash_table_new(NULL, NULL);
if (ignore_child) {
g_hash_table_add(visited, ignore_child);
}
- bdrv_drain_all_begin();
- bdrv_graph_rdlock_main_loop();
ret = bdrv_change_aio_context(bs, ctx, visited, tran, errp);
g_hash_table_destroy(visited);
@@ -7754,15 +7763,34 @@ int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
if (!ret) {
/* Just run clean() callbacks. No AioContext changed. */
tran_abort(tran);
- bdrv_graph_rdunlock_main_loop();
- bdrv_drain_all_end();
return -EPERM;
}
tran_commit(tran);
+ return 0;
+}
+
+/*
+ * Change bs's and recursively all of its parents' and children's AioContext
+ * to the given new context, returning an error if that isn't possible.
+ *
+ * If ignore_child is not NULL, that child (and its subgraph) will not
+ * be touched.
+ */
+int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
+ BdrvChild *ignore_child, Error **errp)
+{
+ int ret;
+
+ GLOBAL_STATE_CODE();
+
+ bdrv_drain_all_begin();
+ bdrv_graph_rdlock_main_loop();
+ ret = bdrv_try_change_aio_context_locked(bs, ctx, ignore_child, errp);
bdrv_graph_rdunlock_main_loop();
bdrv_drain_all_end();
- return 0;
+
+ return ret;
}
void bdrv_add_aio_context_notifier(BlockDriverState *bs,
diff --git a/blockdev.c b/blockdev.c
index efa7d1d0b2..41b6481c9a 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3595,12 +3595,13 @@ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
AioContext *new_context;
BlockDriverState *bs;
- GRAPH_RDLOCK_GUARD_MAINLOOP();
+ bdrv_drain_all_begin();
+ bdrv_graph_rdlock_main_loop();
bs = bdrv_find_node(node_name);
if (!bs) {
error_setg(errp, "Failed to find node with node-name='%s'", node_name);
- return;
+ goto out;
}
/* Protects against accidents. */
@@ -3608,14 +3609,14 @@ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
error_setg(errp, "Node %s is associated with a BlockBackend and could "
"be in use (use force=true to override this check)",
node_name);
- return;
+ goto out;
}
if (iothread->type == QTYPE_QSTRING) {
IOThread *obj = iothread_by_id(iothread->u.s);
if (!obj) {
error_setg(errp, "Cannot find iothread %s", iothread->u.s);
- return;
+ goto out;
}
new_context = iothread_get_aio_context(obj);
@@ -3623,7 +3624,11 @@ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
new_context = qemu_get_aio_context();
}
- bdrv_try_change_aio_context(bs, new_context, NULL, errp);
+ bdrv_try_change_aio_context_locked(bs, new_context, NULL, errp);
+
+out:
+ bdrv_graph_rdunlock_main_loop();
+ bdrv_drain_all_end();
}
QemuOptsList qemu_common_drive_opts = {
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
index aad160956a..91f249b5ad 100644
--- a/include/block/block-global-state.h
+++ b/include/block/block-global-state.h
@@ -278,8 +278,12 @@ bool GRAPH_RDLOCK
bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
GHashTable *visited, Transaction *tran,
Error **errp);
-int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
- BdrvChild *ignore_child, Error **errp);
+int GRAPH_UNLOCKED
+bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
+ BdrvChild *ignore_child, Error **errp);
+int GRAPH_RDLOCK
+bdrv_try_change_aio_context_locked(BlockDriverState *bs, AioContext *ctx,
+ BdrvChild *ignore_child, Error **errp);
int GRAPH_RDLOCK bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz);
int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo);
diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c
index 290cd2a70e..3185f3f429 100644
--- a/tests/unit/test-bdrv-drain.c
+++ b/tests/unit/test-bdrv-drain.c
@@ -1396,14 +1396,10 @@ static void test_set_aio_context(void)
bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
&error_abort);
- bdrv_drained_begin(bs);
bdrv_try_change_aio_context(bs, ctx_a, NULL, &error_abort);
- bdrv_drained_end(bs);
- bdrv_drained_begin(bs);
bdrv_try_change_aio_context(bs, ctx_b, NULL, &error_abort);
bdrv_try_change_aio_context(bs, qemu_get_aio_context(), NULL, &error_abort);
- bdrv_drained_end(bs);
bdrv_unref(bs);
iothread_join(a);
--
2.39.3

View File

@ -0,0 +1,120 @@
From af295ac08ffca4efd6f10a2d1a38eaa8d09d8e6f Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:51 +0200
Subject: [PATCH 26/33] block: move drain outside of quorum_add_child()
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [14/21] 1079c7996e39d09d021d210d974522fba2e5515d (kmwolf/centos-qemu-kvm)
This is part of resolving the deadlock mentioned in commit "block:
move draining out of bdrv_change_aio_context() and mark GRAPH_RDLOCK".
The quorum_add_child() callback runs under the graph lock, so it is
not allowed to drain. It is only called as the .bdrv_add_child()
callback, which is only called in the bdrv_add_child() function, which
also runs under the graph lock.
The bdrv_add_child() function is called by qmp_x_blockdev_change(),
where a drained section is introduced.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20250530151125.955508-15-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 0414930d3adfa89299eaea5ce92accab15d9fba5)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 10 ++++++++--
block/quorum.c | 2 --
blockdev.c | 2 ++
include/block/block_int-common.h | 7 +++++++
4 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/block.c b/block.c
index 3857f42877..d7425ff971 100644
--- a/block.c
+++ b/block.c
@@ -8220,8 +8220,10 @@ char *bdrv_dirname(BlockDriverState *bs, Error **errp)
}
/*
- * Hot add/remove a BDS's child. So the user can take a child offline when
- * it is broken and take a new child online
+ * Hot add a BDS's child. Used in combination with bdrv_del_child, so the user
+ * can take a child offline when it is broken and take a new child online.
+ *
+ * All block nodes must be drained.
*/
void bdrv_add_child(BlockDriverState *parent_bs, BlockDriverState *child_bs,
Error **errp)
@@ -8261,6 +8263,10 @@ void bdrv_add_child(BlockDriverState *parent_bs, BlockDriverState *child_bs,
parent_bs->drv->bdrv_add_child(parent_bs, child_bs, errp);
}
+/*
+ * Hot remove a BDS's child. Used in combination with bdrv_add_child, so the
+ * user can take a child offline when it is broken and take a new child online.
+ */
void bdrv_del_child(BlockDriverState *parent_bs, BdrvChild *child, Error **errp)
{
BdrvChild *tmp;
diff --git a/block/quorum.c b/block/quorum.c
index ea17b0ec13..ed8ce801ee 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -1096,10 +1096,8 @@ quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs, Error **errp)
/* We can safely add the child now */
bdrv_ref(child_bs);
- bdrv_drain_all_begin();
child = bdrv_attach_child(bs, child_bs, indexstr, &child_of_bds,
BDRV_CHILD_DATA, errp);
- bdrv_drain_all_end();
if (child == NULL) {
s->next_child_index--;
return;
diff --git a/blockdev.c b/blockdev.c
index 41b6481c9a..8edd3e7bba 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3525,6 +3525,7 @@ void qmp_x_blockdev_change(const char *parent, const char *child,
BlockDriverState *parent_bs, *new_bs = NULL;
BdrvChild *p_child;
+ bdrv_drain_all_begin();
bdrv_graph_wrlock();
parent_bs = bdrv_lookup_bs(parent, parent, errp);
@@ -3562,6 +3563,7 @@ void qmp_x_blockdev_change(const char *parent, const char *child,
out:
bdrv_graph_wrunlock();
+ bdrv_drain_all_end();
}
BlockJobInfoList *qmp_query_block_jobs(Error **errp)
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
index 5d34e6a510..8d76b37c03 100644
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
@@ -396,6 +396,13 @@ struct BlockDriver {
int GRAPH_RDLOCK_PTR (*bdrv_probe_geometry)(
BlockDriverState *bs, HDGeometry *geo);
+ /**
+ * Hot add a BDS's child. Used in combination with bdrv_del_child, so the
+ * user can take a child offline when it is broken and take a new child
+ * online.
+ *
+ * All block nodes must be drained.
+ */
void GRAPH_WRLOCK_PTR (*bdrv_add_child)(
BlockDriverState *parent, BlockDriverState *child, Error **errp);
--
2.39.3

View File

@ -0,0 +1,85 @@
From de70d5b485006ecd92e860242634a3166b709fa8 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:53 +0200
Subject: [PATCH 28/33] block: move drain outside of quorum_del_child()
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [16/21] abceebd102dde266fa880f2c40ef83de25a87ed6 (kmwolf/centos-qemu-kvm)
The quorum_del_child() callback runs under the graph lock, so it is
not allowed to drain. It is only called as the .bdrv_del_child()
callback, which is only called in the bdrv_del_child() function, which
also runs under the graph lock.
The bdrv_del_child() function is called by qmp_x_blockdev_change().
A drained section was already introduced there by commit "block: move
drain out of quorum_add_child()".
This finally finishes moving out the drain to places that are not
under the graph lock started in "block: move draining out of
bdrv_change_aio_context() and mark GRAPH_RDLOCK".
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20250530151125.955508-17-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit d75f8ed1d7fc27cf1643e549cd006a68d3bf6ef1)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 2 ++
block/quorum.c | 2 --
include/block/block_int-common.h | 7 +++++++
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/block.c b/block.c
index 51bc084b1e..309ef1349a 100644
--- a/block.c
+++ b/block.c
@@ -8276,6 +8276,8 @@ void bdrv_add_child(BlockDriverState *parent_bs, BlockDriverState *child_bs,
/*
* Hot remove a BDS's child. Used in combination with bdrv_add_child, so the
* user can take a child offline when it is broken and take a new child online.
+ *
+ * All block nodes must be drained.
*/
void bdrv_del_child(BlockDriverState *parent_bs, BdrvChild *child, Error **errp)
{
diff --git a/block/quorum.c b/block/quorum.c
index 81407a38ee..cc3bc5f4e7 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -1147,9 +1147,7 @@ quorum_del_child(BlockDriverState *bs, BdrvChild *child, Error **errp)
(s->num_children - i - 1) * sizeof(BdrvChild *));
s->children = g_renew(BdrvChild *, s->children, --s->num_children);
- bdrv_drain_all_begin();
bdrv_unref_child(bs, child);
- bdrv_drain_all_end();
quorum_refresh_flags(bs);
}
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
index 8d76b37c03..f33695ab74 100644
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
@@ -406,6 +406,13 @@ struct BlockDriver {
void GRAPH_WRLOCK_PTR (*bdrv_add_child)(
BlockDriverState *parent, BlockDriverState *child, Error **errp);
+ /**
+ * Hot remove a BDS's child. Used in combination with bdrv_add_child, so the
+ * user can take a child offline when it is broken and take a new child
+ * online.
+ *
+ * All block nodes must be drained.
+ */
void GRAPH_WRLOCK_PTR (*bdrv_del_child)(
BlockDriverState *parent, BdrvChild *child, Error **errp);
--
2.39.3

View File

@ -0,0 +1,106 @@
From a4f11515016abb663e37c9796ef4655d5e7e831b Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:41 +0200
Subject: [PATCH 16/33] block: move drain outside of read-locked
bdrv_inactivate_recurse()
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [4/21] 56ced7ba208c22d5998ab27c70ec6a027dc2469e (kmwolf/centos-qemu-kvm)
This is in preparation to mark bdrv_drained_begin() as GRAPH_UNLOCKED.
More granular draining is not trivially possible, because
bdrv_inactivate_recurse() can recursively call itself.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20250530151125.955508-5-f.ebner@proxmox.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 841998e08650f5b4476fa2d1eb84a592ab405f51)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/block.c b/block.c
index 85efdf9c1b..e340bac177 100644
--- a/block.c
+++ b/block.c
@@ -6989,6 +6989,8 @@ bdrv_inactivate_recurse(BlockDriverState *bs, bool top_level)
GLOBAL_STATE_CODE();
+ assert(bs->quiesce_counter > 0);
+
if (!bs->drv) {
return -ENOMEDIUM;
}
@@ -7032,9 +7034,7 @@ bdrv_inactivate_recurse(BlockDriverState *bs, bool top_level)
return -EPERM;
}
- bdrv_drained_begin(bs);
bs->open_flags |= BDRV_O_INACTIVE;
- bdrv_drained_end(bs);
/*
* Update permissions, they may differ for inactive nodes.
@@ -7059,20 +7059,26 @@ int bdrv_inactivate(BlockDriverState *bs, Error **errp)
int ret;
GLOBAL_STATE_CODE();
- GRAPH_RDLOCK_GUARD_MAINLOOP();
+
+ bdrv_drain_all_begin();
+ bdrv_graph_rdlock_main_loop();
if (bdrv_has_bds_parent(bs, true)) {
error_setg(errp, "Node has active parent node");
- return -EPERM;
+ ret = -EPERM;
+ goto out;
}
ret = bdrv_inactivate_recurse(bs, true);
if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to inactivate node");
- return ret;
+ goto out;
}
- return 0;
+out:
+ bdrv_graph_rdunlock_main_loop();
+ bdrv_drain_all_end();
+ return ret;
}
int bdrv_inactivate_all(void)
@@ -7082,7 +7088,9 @@ int bdrv_inactivate_all(void)
int ret = 0;
GLOBAL_STATE_CODE();
- GRAPH_RDLOCK_GUARD_MAINLOOP();
+
+ bdrv_drain_all_begin();
+ bdrv_graph_rdlock_main_loop();
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
/* Nodes with BDS parents are covered by recursion from the last
@@ -7098,6 +7106,9 @@ int bdrv_inactivate_all(void)
}
}
+ bdrv_graph_rdunlock_main_loop();
+ bdrv_drain_all_end();
+
return ret;
}
--
2.39.3

View File

@ -0,0 +1,87 @@
From c5eb44ccd03e327f15977acccfeaf23a047e0dc6 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:39 +0200
Subject: [PATCH 14/33] block: move drain outside of read-locked
bdrv_reopen_queue_child()
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [2/21] 726503557f318087c2142ee95a8193f22d7df5b2 (kmwolf/centos-qemu-kvm)
This is in preparation to mark bdrv_drained_begin() as GRAPH_UNLOCKED.
More granular draining is not trivially possible, because
bdrv_reopen_queue_child() can recursively call itself.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20250530151125.955508-3-f.ebner@proxmox.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit e1d681b3e1d8256047dbfc6d2c796028b9694eaf)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/block.c b/block.c
index 9346486ac6..85efdf9c1b 100644
--- a/block.c
+++ b/block.c
@@ -4358,7 +4358,7 @@ bdrv_recurse_has_child(BlockDriverState *bs, BlockDriverState *child)
* returns a pointer to bs_queue, which is either the newly allocated
* bs_queue, or the existing bs_queue being used.
*
- * bs is drained here and undrained by bdrv_reopen_queue_free().
+ * bs must be drained.
*/
static BlockReopenQueue * GRAPH_RDLOCK
bdrv_reopen_queue_child(BlockReopenQueue *bs_queue, BlockDriverState *bs,
@@ -4377,12 +4377,7 @@ bdrv_reopen_queue_child(BlockReopenQueue *bs_queue, BlockDriverState *bs,
GLOBAL_STATE_CODE();
- /*
- * Strictly speaking, draining is illegal under GRAPH_RDLOCK. We know that
- * we've been called with bdrv_graph_rdlock_main_loop(), though, so it's ok
- * in practice.
- */
- bdrv_drained_begin(bs);
+ assert(bs->quiesce_counter > 0);
if (bs_queue == NULL) {
bs_queue = g_new0(BlockReopenQueue, 1);
@@ -4522,6 +4517,12 @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
QDict *options, bool keep_old_opts)
{
GLOBAL_STATE_CODE();
+
+ if (bs_queue == NULL) {
+ /* Paired with bdrv_drain_all_end() in bdrv_reopen_queue_free(). */
+ bdrv_drain_all_begin();
+ }
+
GRAPH_RDLOCK_GUARD_MAINLOOP();
return bdrv_reopen_queue_child(bs_queue, bs, options, NULL, 0, false,
@@ -4534,12 +4535,14 @@ void bdrv_reopen_queue_free(BlockReopenQueue *bs_queue)
if (bs_queue) {
BlockReopenQueueEntry *bs_entry, *next;
QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
- bdrv_drained_end(bs_entry->state.bs);
qobject_unref(bs_entry->state.explicit_options);
qobject_unref(bs_entry->state.options);
g_free(bs_entry);
}
g_free(bs_queue);
+
+ /* Paired with bdrv_drain_all_begin() in bdrv_reopen_queue(). */
+ bdrv_drain_all_end();
}
}
--
2.39.3

View File

@ -0,0 +1,61 @@
From 055168058f614c9f3b8be6c0692794a6299420ab Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:38 +0200
Subject: [PATCH 13/33] block: remove outdated comments about AioContext
locking
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [1/21] 607caf7954ab7d1cd4616335fba031cdbfa30324 (kmwolf/centos-qemu-kvm)
AioContext locking was removed in commit b49f4755c7 ("block: remove
AioContext locking").
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20250530151125.955508-2-f.ebner@proxmox.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit f1bf3be14bd5d6e6a2cfbbe64cdd4d58a8595d68)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/block.c b/block.c
index 0ece805e41..9346486ac6 100644
--- a/block.c
+++ b/block.c
@@ -4359,8 +4359,6 @@ bdrv_recurse_has_child(BlockDriverState *bs, BlockDriverState *child)
* bs_queue, or the existing bs_queue being used.
*
* bs is drained here and undrained by bdrv_reopen_queue_free().
- *
- * To be called with bs->aio_context locked.
*/
static BlockReopenQueue * GRAPH_RDLOCK
bdrv_reopen_queue_child(BlockReopenQueue *bs_queue, BlockDriverState *bs,
@@ -4519,7 +4517,6 @@ bdrv_reopen_queue_child(BlockReopenQueue *bs_queue, BlockDriverState *bs,
return bs_queue;
}
-/* To be called with bs->aio_context locked */
BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
BlockDriverState *bs,
QDict *options, bool keep_old_opts)
@@ -7278,10 +7275,6 @@ bool bdrv_op_blocker_is_empty(BlockDriverState *bs)
return true;
}
-/*
- * Must not be called while holding the lock of an AioContext other than the
- * current one.
- */
void bdrv_img_create(const char *filename, const char *fmt,
const char *base_filename, const char *base_fmt,
char *options, uint64_t img_size, int flags, bool quiet,
--
2.39.3

View File

@ -1,17 +1,17 @@
From 635637c7e38b031965ab81a40ae11dd639f57006 Mon Sep 17 00:00:00 2001
From 116f42add040dfa1eaf25087db1038f8c4198bf7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 10 Jun 2025 13:36:41 +0100
Subject: [PATCH 04/31] block: skip automatic zero-init of large array in
Subject: [PATCH 11/43] block: skip automatic zero-init of large array in
ioq_submit
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 460: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-99889
RH-MergeRequest: 381: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-95479
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [3/30] 9d240d5fcc6f24a18303f3f51f5cfaf6735d3f6c
RH-Commit: [3/31] 3d4c81fcc56f1c7a4d1d3819214bd6296edc2a1e (stefanha/centos-stream-qemu-kvm)
The 'ioq_submit' method has a struct array that is 8k in size.
Skip the automatic zero-init of this array to eliminate the
@ -31,7 +31,7 @@ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/linux-aio.c b/block/linux-aio.c
index e3b5ec9aba..26d9f086d2 100644
index 407369f5c9..c200e7ad20 100644
--- a/block/linux-aio.c
+++ b/block/linux-aio.c
@@ -291,7 +291,7 @@ static void ioq_submit(LinuxAioState *s)

View File

@ -0,0 +1,231 @@
From 5c8408a7d6b0f7a66de2bfa31ef228b1817200ec Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:40 +0200
Subject: [PATCH 15/33] block/snapshot: move drain outside of read-locked
bdrv_snapshot_delete()
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [3/21] 4263420635ed51a5df458d079f60618c53120d87 (kmwolf/centos-qemu-kvm)
This is in preparation to mark bdrv_drained_begin() as GRAPH_UNLOCKED.
More granular draining is not trivially possible, because
bdrv_snapshot_delete() can recursively call itself.
The return value of bdrv_all_delete_snapshot() changes from -1 to
-errno propagated from failed sub-calls. This is fine for the existing
callers of bdrv_all_delete_snapshot().
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20250530151125.955508-4-f.ebner@proxmox.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit d4c5f8c980f1073356d2f18d51dc68d42bebb59d)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/snapshot.c | 26 +++++++++++++++-----------
blockdev.c | 25 +++++++++++++++++--------
qemu-img.c | 2 ++
3 files changed, 34 insertions(+), 19 deletions(-)
diff --git a/block/snapshot.c b/block/snapshot.c
index 22567f1fb9..9f300a78bd 100644
--- a/block/snapshot.c
+++ b/block/snapshot.c
@@ -327,7 +327,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
/**
* Delete an internal snapshot by @snapshot_id and @name.
- * @bs: block device used in the operation
+ * @bs: block device used in the operation, must be drained
* @snapshot_id: unique snapshot ID, or NULL
* @name: snapshot name, or NULL
* @errp: location to store error
@@ -358,6 +358,8 @@ int bdrv_snapshot_delete(BlockDriverState *bs,
GLOBAL_STATE_CODE();
+ assert(bs->quiesce_counter > 0);
+
if (!drv) {
error_setg(errp, "Device '%s' has no medium",
bdrv_get_device_name(bs));
@@ -368,9 +370,6 @@ int bdrv_snapshot_delete(BlockDriverState *bs,
return -EINVAL;
}
- /* drain all pending i/o before deleting snapshot */
- bdrv_drained_begin(bs);
-
if (drv->bdrv_snapshot_delete) {
ret = drv->bdrv_snapshot_delete(bs, snapshot_id, name, errp);
} else if (fallback_bs) {
@@ -382,7 +381,6 @@ int bdrv_snapshot_delete(BlockDriverState *bs,
ret = -ENOTSUP;
}
- bdrv_drained_end(bs);
return ret;
}
@@ -571,19 +569,22 @@ int bdrv_all_delete_snapshot(const char *name,
ERRP_GUARD();
g_autoptr(GList) bdrvs = NULL;
GList *iterbdrvs;
+ int ret = 0;
GLOBAL_STATE_CODE();
- GRAPH_RDLOCK_GUARD_MAINLOOP();
- if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
- return -1;
+ bdrv_drain_all_begin();
+ bdrv_graph_rdlock_main_loop();
+
+ ret = bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp);
+ if (ret < 0) {
+ goto out;
}
iterbdrvs = bdrvs;
while (iterbdrvs) {
BlockDriverState *bs = iterbdrvs->data;
QEMUSnapshotInfo sn1, *snapshot = &sn1;
- int ret = 0;
if ((devices || bdrv_all_snapshots_includes_bs(bs)) &&
bdrv_snapshot_find(bs, snapshot, name) >= 0)
@@ -594,13 +595,16 @@ int bdrv_all_delete_snapshot(const char *name,
if (ret < 0) {
error_prepend(errp, "Could not delete snapshot '%s' on '%s': ",
name, bdrv_get_device_or_node_name(bs));
- return -1;
+ goto out;
}
iterbdrvs = iterbdrvs->next;
}
- return 0;
+out:
+ bdrv_graph_rdunlock_main_loop();
+ bdrv_drain_all_end();
+ return ret;
}
diff --git a/blockdev.c b/blockdev.c
index 0fa8813efe..efa7d1d0b2 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1132,39 +1132,41 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
int ret;
GLOBAL_STATE_CODE();
- GRAPH_RDLOCK_GUARD_MAINLOOP();
+
+ bdrv_drain_all_begin();
+ bdrv_graph_rdlock_main_loop();
bs = qmp_get_root_bs(device, errp);
if (!bs) {
- return NULL;
+ goto error;
}
if (!id && !name) {
error_setg(errp, "Name or id must be provided");
- return NULL;
+ goto error;
}
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE, errp)) {
- return NULL;
+ goto error;
}
ret = bdrv_snapshot_find_by_id_and_name(bs, id, name, &sn, &local_err);
if (local_err) {
error_propagate(errp, local_err);
- return NULL;
+ goto error;
}
if (!ret) {
error_setg(errp,
"Snapshot with id '%s' and name '%s' does not exist on "
"device '%s'",
STR_OR_NULL(id), STR_OR_NULL(name), device);
- return NULL;
+ goto error;
}
bdrv_snapshot_delete(bs, id, name, &local_err);
if (local_err) {
error_propagate(errp, local_err);
- return NULL;
+ goto error;
}
info = g_new0(SnapshotInfo, 1);
@@ -1180,6 +1182,9 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
info->has_icount = true;
}
+error:
+ bdrv_graph_rdunlock_main_loop();
+ bdrv_drain_all_end();
return info;
}
@@ -1295,12 +1300,14 @@ static void internal_snapshot_abort(void *opaque)
Error *local_error = NULL;
GLOBAL_STATE_CODE();
- GRAPH_RDLOCK_GUARD_MAINLOOP();
if (!state->created) {
return;
}
+ bdrv_drain_all_begin();
+ bdrv_graph_rdlock_main_loop();
+
if (bdrv_snapshot_delete(bs, sn->id_str, sn->name, &local_error) < 0) {
error_reportf_err(local_error,
"Failed to delete snapshot with id '%s' and "
@@ -1308,6 +1315,8 @@ static void internal_snapshot_abort(void *opaque)
sn->id_str, sn->name,
bdrv_get_device_name(bs));
}
+ bdrv_graph_rdunlock_main_loop();
+ bdrv_drain_all_end();
}
static void internal_snapshot_clean(void *opaque)
diff --git a/qemu-img.c b/qemu-img.c
index 2044c22a4c..ba8412f66e 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3505,6 +3505,7 @@ static int img_snapshot(int argc, char **argv)
break;
case SNAPSHOT_DELETE:
+ bdrv_drain_all_begin();
bdrv_graph_rdlock_main_loop();
ret = bdrv_snapshot_find(bs, &sn, snapshot_name);
if (ret < 0) {
@@ -3520,6 +3521,7 @@ static int img_snapshot(int argc, char **argv)
}
}
bdrv_graph_rdunlock_main_loop();
+ bdrv_drain_all_end();
break;
}
--
2.39.3

View File

@ -0,0 +1,70 @@
From 96407f6d729312c373e9b2ccbf97918d453c7a52 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:55 +0200
Subject: [PATCH 30/33] blockdev: drain while unlocked in
external_snapshot_action()
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [18/21] b651de913db70b4897f0085af696cdaf925f5f81 (kmwolf/centos-qemu-kvm)
This is in preparation to mark bdrv_drained_begin() as GRAPH_UNLOCKED.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20250530151125.955508-19-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 195a8a946a8681dfe7e8aa8d49db415693db5311)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
blockdev.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/blockdev.c b/blockdev.c
index 2560a11a53..998dbe38a5 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1377,9 +1377,10 @@ static void external_snapshot_action(TransactionAction *action,
const char *new_image_file;
ExternalSnapshotState *state = g_new0(ExternalSnapshotState, 1);
uint64_t perm, shared;
+ BlockDriverState *check_bs;
/* TODO We'll eventually have to take a writer lock in this function */
- GRAPH_RDLOCK_GUARD_MAINLOOP();
+ bdrv_graph_rdlock_main_loop();
tran_add(tran, &external_snapshot_drv, state);
@@ -1412,11 +1413,25 @@ static void external_snapshot_action(TransactionAction *action,
state->old_bs = bdrv_lookup_bs(device, node_name, errp);
if (!state->old_bs) {
+ bdrv_graph_rdunlock_main_loop();
return;
}
+ /* Need to drain while unlocked. */
+ bdrv_graph_rdunlock_main_loop();
/* Paired with .clean() */
bdrv_drained_begin(state->old_bs);
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
+
+ /* Make sure the associated bs did not change with the drain. */
+ check_bs = bdrv_lookup_bs(device, node_name, errp);
+ if (state->old_bs != check_bs) {
+ if (check_bs) {
+ error_setg(errp, "Block node of device '%s' unexpectedly changed",
+ device);
+ } /* else errp is already set */
+ return;
+ }
if (!bdrv_is_inserted(state->old_bs)) {
error_setg(errp, "Device '%s' has no medium",
--
2.39.3

View File

@ -0,0 +1,80 @@
From a2b28210cbcbb8e66815d9b38484fde3122a3ab9 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Fri, 30 May 2025 17:10:54 +0200
Subject: [PATCH 29/33] blockdev: drain while unlocked in
internal_snapshot_action()
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 393: block: do not drain while holding the graph lock
RH-Jira: RHEL-88561
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [17/21] 8379ac5e6ec0ecf71b540d2631cf42394d985f16 (kmwolf/centos-qemu-kvm)
This is in preparation to mark bdrv_drained_begin() as GRAPH_UNLOCKED.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20250530151125.955508-18-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 6f101614f95c889399352b8301917c0ac7919ae7)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
blockdev.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index 8edd3e7bba..2560a11a53 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1208,7 +1208,7 @@ static void internal_snapshot_action(BlockdevSnapshotInternal *internal,
Error *local_err = NULL;
const char *device;
const char *name;
- BlockDriverState *bs;
+ BlockDriverState *bs, *check_bs;
QEMUSnapshotInfo old_sn, *sn;
bool ret;
int64_t rt;
@@ -1216,7 +1216,7 @@ static void internal_snapshot_action(BlockdevSnapshotInternal *internal,
int ret1;
GLOBAL_STATE_CODE();
- GRAPH_RDLOCK_GUARD_MAINLOOP();
+ bdrv_graph_rdlock_main_loop();
tran_add(tran, &internal_snapshot_drv, state);
@@ -1225,14 +1225,29 @@ static void internal_snapshot_action(BlockdevSnapshotInternal *internal,
bs = qmp_get_root_bs(device, errp);
if (!bs) {
+ bdrv_graph_rdunlock_main_loop();
return;
}
state->bs = bs;
+ /* Need to drain while unlocked. */
+ bdrv_graph_rdunlock_main_loop();
/* Paired with .clean() */
bdrv_drained_begin(bs);
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
+
+ /* Make sure the root bs did not change with the drain. */
+ check_bs = qmp_get_root_bs(device, errp);
+ if (bs != check_bs) {
+ if (check_bs) {
+ error_setg(errp, "Block node of device '%s' unexpectedly changed",
+ device);
+ } /* else errp is already set */
+ return;
+ }
+
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, errp)) {
return;
}
--
2.39.3

View File

@ -1,17 +1,17 @@
From e789160acd34f9493696cf5f20eccd3ed4271ae5 Mon Sep 17 00:00:00 2001
From c7114f381bfa2663bdaa368b7b0dca764e28a07e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 10 Jun 2025 13:36:42 +0100
Subject: [PATCH 05/31] chardev/char-fd: skip automatic zero-init of large
Subject: [PATCH 12/43] chardev/char-fd: skip automatic zero-init of large
array
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 460: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-99889
RH-MergeRequest: 381: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-95479
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [4/30] 9745f9fa7d74d0a66de2826b93eea5f74b614de1
RH-Commit: [4/31] b26dc4c1b9677adb1332c778e6c9ec452952f4c1 (stefanha/centos-stream-qemu-kvm)
The 'fd_chr_read' method has a 4k byte array used for copying
data between the socket and device. Skip the automatic zero-init

View File

@ -1,17 +1,17 @@
From ed3fefc5bcaf3d0843eabca60d0630678740bd9b Mon Sep 17 00:00:00 2001
From dfe44e34228c242f539f61383c431b6b9acd86f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 10 Jun 2025 13:36:43 +0100
Subject: [PATCH 06/31] chardev/char-pty: skip automatic zero-init of large
Subject: [PATCH 13/43] chardev/char-pty: skip automatic zero-init of large
array
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 460: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-99889
RH-MergeRequest: 381: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-95479
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [5/30] 9555824c46d6a12316ea57a73042e69ee7d8d033
RH-Commit: [5/31] e41c3503091674e90cc7c17f202e5d4ae1f417cd (stefanha/centos-stream-qemu-kvm)
The 'pty_chr_read' method has a 4k byte array used for copying
data between the PTY and device. Skip the automatic zero-init
@ -32,10 +32,10 @@ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index cc2f7617fe..3319ad215d 100644
index 6a2c1dc13a..f484aac78d 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -152,7 +152,7 @@ static gboolean pty_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
@@ -154,7 +154,7 @@ static gboolean pty_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
Chardev *chr = CHARDEV(opaque);
PtyChardev *s = PTY_CHARDEV(opaque);
gsize len;

View File

@ -1,17 +1,17 @@
From 60383e9e167883840c5cbea4b279622ef29a0107 Mon Sep 17 00:00:00 2001
From 1dbdcc30075e480b1d6da9ef19a8bd38e1762ac9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 10 Jun 2025 13:36:44 +0100
Subject: [PATCH 07/31] chardev/char-socket: skip automatic zero-init of large
Subject: [PATCH 14/43] chardev/char-socket: skip automatic zero-init of large
array
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 460: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-99889
RH-MergeRequest: 381: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-95479
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [6/30] 5e2bb9ad5a8422682ca2e6a8e5abc8b7eebc84d2
RH-Commit: [6/31] 97ec8420f5a8cc37d5ece5721d409e9d94f8b11f (stefanha/centos-stream-qemu-kvm)
The 'tcp_chr_read' method has a 4k byte array used for copying
data between the socket and device. Skip the automatic zero-init
@ -32,7 +32,7 @@ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 1ca9441b1b..99d644e89f 100644
index 2f842f9f88..22c87d0885 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -497,7 +497,7 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)

View File

@ -0,0 +1,40 @@
From 234f0ccebe9c52b774e85083c0df9dcb3367dcfc Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 18 Jul 2025 18:03:48 +0200
Subject: [PATCH 056/100] cpu: Don't set vcpu_dirty when guest_state_protected
QEMU calls kvm_arch_put_registers() when vcpu_dirty is true in
kvm_vcpu_exec(). However, for confidential guest, like TDX, putting
registers is disallowed due to guest state is protected.
Only set vcpu_dirty to true with guest state is not protected when
creating the vcpu.
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Link: https://lore.kernel.org/r/20250508150002.689633-43-xiaoyao.li@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit b4b7fb5a773e1d2215c2aaa99789eca51914b78f)
Signed-off-by: Paolo Bonzini <pbonzini@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 696abf2cea..e59d98c22f 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -466,7 +466,9 @@ int kvm_create_vcpu(CPUState *cpu)
cpu->kvm_fd = kvm_fd;
cpu->kvm_state = s;
- cpu->vcpu_dirty = true;
+ if (!s->guest_state_protected) {
+ cpu->vcpu_dirty = true;
+ }
cpu->dirty_pages = 0;
cpu->throttle_us_per_full = 0;
--
2.47.3

View File

@ -0,0 +1,214 @@
From 5120234d30c9e5193961831e659daf7c923a3d79 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 18 Jul 2025 18:03:48 +0200
Subject: [PATCH 069/100] docs: Add TDX documentation
Add docs/system/i386/tdx.rst for TDX support, and add tdx in
confidential-guest-support.rst
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Link: https://lore.kernel.org/r/20250508150002.689633-56-xiaoyao.li@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit dc1424319311f86449c6825ceec2364ee645a363)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
docs/system/confidential-guest-support.rst | 1 +
docs/system/i386/tdx.rst | 161 +++++++++++++++++++++
docs/system/target-i386.rst | 1 +
3 files changed, 163 insertions(+)
create mode 100644 docs/system/i386/tdx.rst
diff --git a/docs/system/confidential-guest-support.rst b/docs/system/confidential-guest-support.rst
index 0c490dbda2..66129fbab6 100644
--- a/docs/system/confidential-guest-support.rst
+++ b/docs/system/confidential-guest-support.rst
@@ -38,6 +38,7 @@ Supported mechanisms
Currently supported confidential guest mechanisms are:
* AMD Secure Encrypted Virtualization (SEV) (see :doc:`i386/amd-memory-encryption`)
+* Intel Trust Domain Extension (TDX) (see :doc:`i386/tdx`)
* POWER Protected Execution Facility (PEF) (see :ref:`power-papr-protected-execution-facility-pef`)
* s390x Protected Virtualization (PV) (see :doc:`s390x/protvirt`)
diff --git a/docs/system/i386/tdx.rst b/docs/system/i386/tdx.rst
new file mode 100644
index 0000000000..8131750b64
--- /dev/null
+++ b/docs/system/i386/tdx.rst
@@ -0,0 +1,161 @@
+Intel Trusted Domain eXtension (TDX)
+====================================
+
+Intel Trusted Domain eXtensions (TDX) refers to an Intel technology that extends
+Virtual Machine Extensions (VMX) and Multi-Key Total Memory Encryption (MKTME)
+with a new kind of virtual machine guest called a Trust Domain (TD). A TD runs
+in a CPU mode that is designed to protect the confidentiality of its memory
+contents and its CPU state from any other software, including the hosting
+Virtual Machine Monitor (VMM), unless explicitly shared by the TD itself.
+
+Prerequisites
+-------------
+
+To run TD, the physical machine needs to have TDX module loaded and initialized
+while KVM hypervisor has TDX support and has TDX enabled. If those requirements
+are met, the ``KVM_CAP_VM_TYPES`` will report the support of ``KVM_X86_TDX_VM``.
+
+Trust Domain Virtual Firmware (TDVF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Trust Domain Virtual Firmware (TDVF) is required to provide TD services to boot
+TD Guest OS. TDVF needs to be copied to guest private memory and measured before
+the TD boots.
+
+KVM vcpu ioctl ``KVM_TDX_INIT_MEM_REGION`` can be used to populate the TDVF
+content into its private memory.
+
+Since TDX doesn't support readonly memslot, TDVF cannot be mapped as pflash
+device and it actually works as RAM. "-bios" option is chosen to load TDVF.
+
+OVMF is the opensource firmware that implements the TDVF support. Thus the
+command line to specify and load TDVF is ``-bios OVMF.fd``
+
+Feature Configuration
+---------------------
+
+Unlike non-TDX VM, the CPU features (enumerated by CPU or MSR) of a TD are not
+under full control of VMM. VMM can only configure part of features of a TD on
+``KVM_TDX_INIT_VM`` command of VM scope ``MEMORY_ENCRYPT_OP`` ioctl.
+
+The configurable features have three types:
+
+- Attributes:
+ - PKS (bit 30) controls whether Supervisor Protection Keys is exposed to TD,
+ which determines related CPUID bit and CR4 bit;
+ - PERFMON (bit 63) controls whether PMU is exposed to TD.
+
+- XSAVE related features (XFAM):
+ XFAM is a 64b mask, which has the same format as XCR0 or IA32_XSS MSR. It
+ determines the set of extended features available for use by the guest TD.
+
+- CPUID features:
+ Only some bits of some CPUID leaves are directly configurable by VMM.
+
+What features can be configured is reported via TDX capabilities.
+
+TDX capabilities
+~~~~~~~~~~~~~~~~
+
+The VM scope ``MEMORY_ENCRYPT_OP`` ioctl provides command ``KVM_TDX_CAPABILITIES``
+to get the TDX capabilities from KVM. It returns a data structure of
+``struct kvm_tdx_capabilities``, which tells the supported configuration of
+attributes, XFAM and CPUIDs.
+
+TD attributes
+~~~~~~~~~~~~~
+
+QEMU supports configuring raw 64-bit TD attributes directly via "attributes"
+property of "tdx-guest" object. Note, it's users' responsibility to provide a
+valid value because some bits may not supported by current QEMU or KVM yet.
+
+QEMU also supports the configuration of individual attribute bits that are
+supported by it, via properties of "tdx-guest" object.
+E.g., "sept-ve-disable" (bit 28).
+
+MSR based features
+~~~~~~~~~~~~~~~~~~
+
+Current KVM doesn't support MSR based feature (e.g., MSR_IA32_ARCH_CAPABILITIES)
+configuration for TDX, and it's a future work to enable it in QEMU when KVM adds
+support of it.
+
+Feature check
+~~~~~~~~~~~~~
+
+QEMU checks if the final (CPU) features, determined by given cpu model and
+explicit feature adjustment of "+featureA/-featureB", can be supported or not.
+It can produce feature not supported warning like
+
+ "warning: host doesn't support requested feature: CPUID.07H:EBX.intel-pt [bit 25]"
+
+It can also produce warning like
+
+ "warning: TDX forcibly sets the feature: CPUID.80000007H:EDX.invtsc [bit 8]"
+
+if the fixed-1 feature is requested to be disabled explicitly. This is newly
+added to QEMU for TDX because TDX has fixed-1 features that are forcibly enabled
+by TDX module and VMM cannot disable them.
+
+Launching a TD (TDX VM)
+-----------------------
+
+To launch a TD, the necessary command line options are tdx-guest object and
+split kernel-irqchip, as below:
+
+.. parsed-literal::
+
+ |qemu_system_x86| \\
+ -accel kvm \\
+ -cpu host \\
+ -object tdx-guest,id=tdx0 \\
+ -machine ...,confidential-guest-support=tdx0 \\
+ -bios OVMF.fd \\
+
+Restrictions
+------------
+
+ - kernel-irqchip must be split;
+
+ This is set by default for TDX guest if kernel-irqchip is left on its default
+ 'auto' setting.
+
+ - No readonly support for private memory;
+
+ - No SMM support: SMM support requires manipulating the guest register states
+ which is not allowed;
+
+Debugging
+---------
+
+Bit 0 of TD attributes, is DEBUG bit, which decides if the TD runs in off-TD
+debug mode. When in off-TD debug mode, TD's VCPU state and private memory are
+accessible via given SEAMCALLs. This requires KVM to expose APIs to invoke those
+SEAMCALLs and corresonponding QEMU change.
+
+It's targeted as future work.
+
+TD attestation
+--------------
+
+In TD guest, the attestation process is used to verify the TDX guest
+trustworthiness to other entities before provisioning secrets to the guest.
+
+TD attestation is initiated first by calling TDG.MR.REPORT inside TD to get the
+REPORT. Then the REPORT data needs to be converted into a remotely verifiable
+Quote by SGX Quoting Enclave (QE).
+
+It's a future work in QEMU to add support of TD attestation since it lacks
+support in current KVM.
+
+Live Migration
+--------------
+
+Future work.
+
+References
+----------
+
+- `TDX Homepage <https://www.intel.com/content/www/us/en/developer/articles/technical/intel-trust-domain-extensions.html>`__
+
+- `SGX QE <https://github.com/intel/SGXDataCenterAttestationPrimitives/tree/master/QuoteGeneration>`__
diff --git a/docs/system/target-i386.rst b/docs/system/target-i386.rst
index ab7af1a75d..43b09c79d6 100644
--- a/docs/system/target-i386.rst
+++ b/docs/system/target-i386.rst
@@ -31,6 +31,7 @@ Architectural features
i386/kvm-pv
i386/sgx
i386/amd-memory-encryption
+ i386/tdx
OS requirements
~~~~~~~~~~~~~~~
--
2.47.3

View File

@ -0,0 +1,71 @@
From c73cd0b322ad22a4ba47035ba87a0e83ff851b6a Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Thu, 1 May 2025 10:31:26 +0100
Subject: [PATCH] docs: Don't define duplicate label in
qemu-block-drivers.rst.inc
Sphinx requires that labels within documents are unique across the
whole manual. This is because the "create a hyperlink" directive
specifies only the name of the label, not a filename+label. Some
Sphinx versions will warn about duplicate labels, but even if there
is no warning there is still an ambiguity and no guarantee that the
hyperlink will be created to the right target.
For QEMU this is awkward, because we have various .rst.inc fragments
which we include into multiple .rst files. If you define a label in
the .rst.inc file then it will be a duplicate label. We have mostly
worked around this by not putting labels into those .rst.inc files,
or by adding "insert a label" functionality into the hxtool extension
(see commit 1eeb432a953b0 "doc/sphinx/hxtool.py: add optional label
argument to SRST directive").
Unfortunately in commit 7f6314427e78 ("docs/devel: add a codebase
section") we accidentally added a duplicate label, because not all
Sphinx versions warn about the mistake.
In this case the link was only from the developer docs codebase
summary, so as the simplest fix for the stable branch, we drop
the link entirely.
Cc: qemu-stable@nongnu.org
Fixes: 1eeb432a953b0 "doc/sphinx/hxtool.py: add optional label argument to SRST directive"
Reported-by: Dario Faggioli <dfaggioli@suse.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Acked-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Message-id: 20250501093126.716667-1-peter.maydell@linaro.org
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
docs/devel/codebase.rst | 2 +-
docs/system/qemu-block-drivers.rst.inc | 2 --
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/docs/devel/codebase.rst b/docs/devel/codebase.rst
index ef98578296..085da10a22 100644
--- a/docs/devel/codebase.rst
+++ b/docs/devel/codebase.rst
@@ -116,7 +116,7 @@ yet, so sometimes the source code is all you have.
* `monitor <https://gitlab.com/qemu-project/qemu/-/tree/master/monitor>`_:
`Monitor <QEMU monitor>` implementation (HMP & QMP).
* `nbd <https://gitlab.com/qemu-project/qemu/-/tree/master/nbd>`_:
- QEMU `NBD (Network Block Device) <nbd>` server.
+ QEMU NBD (Network Block Device) server.
* `net <https://gitlab.com/qemu-project/qemu/-/tree/master/net>`_:
Network (host) support.
* `pc-bios <https://gitlab.com/qemu-project/qemu/-/tree/master/pc-bios>`_:
diff --git a/docs/system/qemu-block-drivers.rst.inc b/docs/system/qemu-block-drivers.rst.inc
index cfe1acb78a..384e95ba76 100644
--- a/docs/system/qemu-block-drivers.rst.inc
+++ b/docs/system/qemu-block-drivers.rst.inc
@@ -500,8 +500,6 @@ What you should *never* do:
- expect it to work when loadvm'ing
- write to the FAT directory on the host system while accessing it with the guest system
-.. _nbd:
-
NBD access
~~~~~~~~~~
--
2.39.3

View File

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

View File

@ -1,41 +0,0 @@
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

View File

@ -1,61 +0,0 @@
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

View File

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

View File

@ -0,0 +1,42 @@
From 42fc4705817fc4d16f2ba785fd29777ed2b7355a Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 29 Apr 2025 17:05:41 +0200
Subject: [PATCH 1/9] file-posix: Define DM_MPATH_PROBE_PATHS
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 370: file-posix: Fix multipath failover with SCSI passthrough
RH-Jira: RHEL-65852
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [1/2] 6680f4a3f15a768b1ca51aafea452c3d0886f12e (kmwolf/centos-qemu-kvm)
While the kernel side isn't merged yet and we're still using old kernel
headers, just define DM_MPATH_PROBE_PATHS manually.
This is a downstream-only patch that can be removed after the next minor
release.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/file-posix.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/block/file-posix.c b/block/file-posix.c
index dea7b09b6c..52cc25db84 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -134,6 +134,11 @@
#define RAW_LOCK_PERM_BASE 100
#define RAW_LOCK_SHARED_BASE 200
+/* TODO Remove this when the kernel side is merged */
+#if !defined(DM_MPATH_PROBE_PATHS) && defined(DM_GET_TARGET_VERSION)
+#define DM_MPATH_PROBE_PATHS _IO(DM_IOCTL, DM_GET_TARGET_VERSION_CMD + 1)
+#endif
+
typedef struct BDRVRawState {
int fd;
bool use_lock;
--
2.39.3

View File

@ -0,0 +1,106 @@
From 53711e6aad8a6e40426ccef25e911d3cad93220a Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Wed, 25 Jun 2025 10:50:19 +0200
Subject: [PATCH 12/33] file-posix: Fix aio=threads performance regression
after enablign FUA
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 392: file-posix: Fix aio=threads performance regression after enabling FUA
RH-Jira: RHEL-96854
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Commit: [1/1] e523c0305e3072d59ad6454afc690cabfcfb86b2 (kmwolf/centos-qemu-kvm)
For aio=threads, we're currently not implementing REQ_FUA in any useful
way, but just do a separate raw_co_flush_to_disk() call. This changes
behaviour compared to the old state, which used bdrv_co_flush() with its
optimisations. As a quick fix, call bdrv_co_flush() again like before.
Eventually, we can use pwritev2() to make use of RWF_DSYNC if available,
but we'll still have to keep this code path as a fallback, so this fix
is required either way.
While the fix itself is a one-liner, some new graph locking annotations
are needed to convince TSA that the locking is correct.
Cc: qemu-stable@nongnu.org
Fixes: 984a32f17e8d ("file-posix: Support FUA writes")
Buglink: https://issues.redhat.com/browse/RHEL-96854
Reported-by: Tingting Mao <timao@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20250625085019.27735-1-kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit d402da1360c2240e81f0e5fc80ddbfc6238e0da8)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/file-posix.c | 29 +++++++++++++++--------------
1 file changed, 15 insertions(+), 14 deletions(-)
diff --git a/block/file-posix.c b/block/file-posix.c
index 77a35d9ae9..d3c7dcc7e4 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -2573,9 +2573,9 @@ static inline bool raw_check_linux_aio(BDRVRawState *s)
}
#endif
-static int coroutine_fn raw_co_prw(BlockDriverState *bs, int64_t *offset_ptr,
- uint64_t bytes, QEMUIOVector *qiov, int type,
- int flags)
+static int coroutine_fn GRAPH_RDLOCK
+raw_co_prw(BlockDriverState *bs, int64_t *offset_ptr, uint64_t bytes,
+ QEMUIOVector *qiov, int type, int flags)
{
BDRVRawState *s = bs->opaque;
RawPosixAIOData acb;
@@ -2634,7 +2634,7 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, int64_t *offset_ptr,
ret = raw_thread_pool_submit(handle_aiocb_rw, &acb);
if (ret == 0 && (flags & BDRV_REQ_FUA)) {
/* TODO Use pwritev2() instead if it's available */
- ret = raw_co_flush_to_disk(bs);
+ ret = bdrv_co_flush(bs);
}
goto out; /* Avoid the compiler err of unused label */
@@ -2669,16 +2669,16 @@ out:
return ret;
}
-static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset,
- int64_t bytes, QEMUIOVector *qiov,
- BdrvRequestFlags flags)
+static int coroutine_fn GRAPH_RDLOCK
+raw_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
{
return raw_co_prw(bs, &offset, bytes, qiov, QEMU_AIO_READ, flags);
}
-static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, int64_t offset,
- int64_t bytes, QEMUIOVector *qiov,
- BdrvRequestFlags flags)
+static int coroutine_fn GRAPH_RDLOCK
+raw_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
{
return raw_co_prw(bs, &offset, bytes, qiov, QEMU_AIO_WRITE, flags);
}
@@ -3615,10 +3615,11 @@ static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
#endif
#if defined(CONFIG_BLKZONED)
-static int coroutine_fn raw_co_zone_append(BlockDriverState *bs,
- int64_t *offset,
- QEMUIOVector *qiov,
- BdrvRequestFlags flags) {
+static int coroutine_fn GRAPH_RDLOCK
+raw_co_zone_append(BlockDriverState *bs,
+ int64_t *offset,
+ QEMUIOVector *qiov,
+ BdrvRequestFlags flags) {
assert(flags == 0);
int64_t zone_size_mask = bs->bl.zone_size - 1;
int64_t iov_len = 0;
--
2.39.3

View File

@ -0,0 +1,46 @@
From 4d575970f12462a054a207b593438aff0d40881a Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 29 Apr 2025 17:56:54 +0200
Subject: [PATCH 3/4] file-posix: Fix crash on discard_granularity == 0
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 354: file-posix: probe discard alignment on Linux block devices
RH-Jira: RHEL-87642
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Commit: [3/3] dbe73aef453e77263d30ebebc690ab21145f6bab (stefanha/centos-stream-qemu-kvm)
Block devices that don't support discard have a discard_granularity of
0. Currently, this results in a division by zero when we try to make
sure that it's a multiple of request_alignment. Only try to update
bs->bl.pdiscard_alignment when we got a non-zero discard_granularity
from sysfs.
Fixes: f605796aae4 ('file-posix: probe discard alignment on Linux block devices')
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-ID: <20250429155654.102735-1-kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 71a30d54e6ab1d5c102a8bee2c263414697402ea)
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
block/file-posix.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/file-posix.c b/block/file-posix.c
index 0d6e12f880..0d85123d0f 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1573,7 +1573,7 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
int ret;
ret = hdev_get_pdiscard_alignment(&st, &dalign);
- if (ret == 0) {
+ if (ret == 0 && dalign != 0) {
uint32_t ralign = bs->bl.request_alignment;
/* Probably never happens, but handle it just in case */
--
2.39.3

View File

@ -0,0 +1,215 @@
From 35a2470f67cb38c52246974a853d843dbb80b84d Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Thu, 22 May 2025 15:08:03 +0200
Subject: [PATCH 2/9] file-posix: Probe paths and retry SG_IO on potential path
errors
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 370: file-posix: Fix multipath failover with SCSI passthrough
RH-Jira: RHEL-65852
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [2/2] bbaa1d4de0675a2c67dafed74eacc0d1103aab18 (kmwolf/centos-qemu-kvm)
When scsi-block is used on a host multipath device, it runs into the
problem that the kernel dm-mpath doesn't know anything about SCSI or
SG_IO and therefore can't decide if a SG_IO request returned an error
and needs to be retried on a different path. Instead of getting working
failover, an error is returned to scsi-block and handled according to
the configured error policy. Obviously, this is not what users want,
they want working failover.
QEMU can parse the SG_IO result and determine whether this could have
been a path error, but just retrying the same request could just send it
to the same failing path again and result in the same error.
With a kernel that supports the DM_MPATH_PROBE_PATHS ioctl on dm-mpath
block devices (queued in the device mapper tree for Linux 6.16), we can
tell the kernel to probe all paths and tell us if any usable paths
remained. If so, we can now retry the SG_IO ioctl and expect it to be
sent to a working path.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20250522130803.34738-1-kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit bf627788ef17721955bfcfba84209a07ae5f54ea)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/file-posix.c | 115 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 114 insertions(+), 1 deletion(-)
diff --git a/block/file-posix.c b/block/file-posix.c
index 52cc25db84..77a35d9ae9 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -41,6 +41,7 @@
#include "scsi/pr-manager.h"
#include "scsi/constants.h"
+#include "scsi/utils.h"
#if defined(__APPLE__) && (__MACH__)
#include <sys/ioctl.h>
@@ -72,6 +73,7 @@
#include <linux/blkzoned.h>
#endif
#include <linux/cdrom.h>
+#include <linux/dm-ioctl.h>
#include <linux/fd.h>
#include <linux/fs.h>
#include <linux/hdreg.h>
@@ -139,6 +141,22 @@
#define DM_MPATH_PROBE_PATHS _IO(DM_IOCTL, DM_GET_TARGET_VERSION_CMD + 1)
#endif
+/*
+ * Multiple retries are mostly meant for two separate scenarios:
+ *
+ * - DM_MPATH_PROBE_PATHS returns success, but before SG_IO completes, another
+ * path goes down.
+ *
+ * - DM_MPATH_PROBE_PATHS failed all paths in the current path group, so we have
+ * to send another SG_IO to switch to another path group to probe the paths in
+ * it.
+ *
+ * Even if each path is in a separate path group (path_grouping_policy set to
+ * failover), it's rare to have more than eight path groups - and even then
+ * pretty unlikely that only bad path groups would be chosen in eight retries.
+ */
+#define SG_IO_MAX_RETRIES 8
+
typedef struct BDRVRawState {
int fd;
bool use_lock;
@@ -166,6 +184,7 @@ typedef struct BDRVRawState {
bool use_linux_aio:1;
bool has_laio_fdsync:1;
bool use_linux_io_uring:1;
+ bool use_mpath:1;
int page_cache_inconsistent; /* errno from fdatasync failure */
bool has_fallocate;
bool needs_alignment;
@@ -4262,15 +4281,105 @@ hdev_open_Mac_error:
/* Since this does ioctl the device must be already opened */
bs->sg = hdev_is_sg(bs);
+ /* sg devices aren't even block devices and can't use dm-mpath */
+ s->use_mpath = !bs->sg;
+
return ret;
}
#if defined(__linux__)
+#if defined(DM_MPATH_PROBE_PATHS)
+static bool coroutine_fn sgio_path_error(int ret, sg_io_hdr_t *io_hdr)
+{
+ if (ret < 0) {
+ switch (ret) {
+ case -ENODEV:
+ return true;
+ case -EAGAIN:
+ /*
+ * The device is probably suspended. This happens while the dm table
+ * is reloaded, e.g. because a path is added or removed. This is an
+ * operation that should complete within 1ms, so just wait a bit and
+ * retry.
+ *
+ * If the device was suspended for another reason, we'll wait and
+ * retry SG_IO_MAX_RETRIES times. This is a tolerable delay before
+ * we return an error and potentially stop the VM.
+ */
+ qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ if (io_hdr->host_status != SCSI_HOST_OK) {
+ return true;
+ }
+
+ switch (io_hdr->status) {
+ case GOOD:
+ case CONDITION_GOOD:
+ case INTERMEDIATE_GOOD:
+ case INTERMEDIATE_C_GOOD:
+ case RESERVATION_CONFLICT:
+ case COMMAND_TERMINATED:
+ return false;
+ case CHECK_CONDITION:
+ return !scsi_sense_buf_is_guest_recoverable(io_hdr->sbp,
+ io_hdr->mx_sb_len);
+ default:
+ return true;
+ }
+}
+
+static bool coroutine_fn hdev_co_ioctl_sgio_retry(RawPosixAIOData *acb, int ret)
+{
+ BDRVRawState *s = acb->bs->opaque;
+ RawPosixAIOData probe_acb;
+
+ if (!s->use_mpath) {
+ return false;
+ }
+
+ if (!sgio_path_error(ret, acb->ioctl.buf)) {
+ return false;
+ }
+
+ probe_acb = (RawPosixAIOData) {
+ .bs = acb->bs,
+ .aio_type = QEMU_AIO_IOCTL,
+ .aio_fildes = s->fd,
+ .aio_offset = 0,
+ .ioctl = {
+ .buf = NULL,
+ .cmd = DM_MPATH_PROBE_PATHS,
+ },
+ };
+
+ ret = raw_thread_pool_submit(handle_aiocb_ioctl, &probe_acb);
+ if (ret == -ENOTTY) {
+ s->use_mpath = false;
+ } else if (ret == -EAGAIN) {
+ /* The device might be suspended for a table reload, worth retrying */
+ return true;
+ }
+
+ return ret == 0;
+}
+#else
+static bool coroutine_fn hdev_co_ioctl_sgio_retry(RawPosixAIOData *acb, int ret)
+{
+ return false;
+}
+#endif /* DM_MPATH_PROBE_PATHS */
+
static int coroutine_fn
hdev_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
{
BDRVRawState *s = bs->opaque;
RawPosixAIOData acb;
+ int retries = SG_IO_MAX_RETRIES;
int ret;
ret = fd_open(bs);
@@ -4298,7 +4407,11 @@ hdev_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
},
};
- return raw_thread_pool_submit(handle_aiocb_ioctl, &acb);
+ do {
+ ret = raw_thread_pool_submit(handle_aiocb_ioctl, &acb);
+ } while (req == SG_IO && retries-- && hdev_co_ioctl_sgio_retry(&acb, ret));
+
+ return ret;
}
#endif /* linux */
--
2.39.3

View File

@ -0,0 +1,64 @@
From f8d89f67817fa362a3b8ed0721775e353dac8f18 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Fri, 9 May 2025 15:40:19 -0500
Subject: [PATCH 02/14] file-posix, gluster: Handle zero block status hint
better
RH-Author: Eric Blake <eblake@redhat.com>
RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors
RH-Jira: RHEL-88435 RHEL-88437
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/14] c40cd3f8cda2ea1646d90fd174b5f0dbd3e1a50b (ebblake/centos-qemu-kvm)
Although the previous patch to change 'bool want_zero' into a bitmask
made no semantic change, it is now time to differentiate. When the
caller specifically wants to know what parts of the file read as zero,
we need to use lseek and actually reporting holes, rather than
short-circuiting and advertising full allocation.
This change will be utilized in later patches to let mirroring
optimize for the case when the destination already reads as zeroes.
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250509204341.3553601-17-eblake@redhat.com>
(cherry picked from commit a6a0a7fb0e327d17594c971b4a39de14e025b415)
Jira: https://issues.redhat.com/browse/RHEL-88435
Jira: https://issues.redhat.com/browse/RHEL-88437
Signed-off-by: Eric Blake <eblake@redhat.com>
---
block/file-posix.c | 3 ++-
block/gluster.c | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/block/file-posix.c b/block/file-posix.c
index 0c6569742f..dea7b09b6c 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -3282,7 +3282,8 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
return ret;
}
- if (mode != BDRV_WANT_PRECISE) {
+ if (!(mode & BDRV_WANT_ZERO)) {
+ /* There is no backing file - all bytes are allocated in this file. */
*pnum = bytes;
*map = offset;
*file = bs;
diff --git a/block/gluster.c b/block/gluster.c
index 8197b0ecef..e702666cbc 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -1482,7 +1482,7 @@ static int coroutine_fn qemu_gluster_co_block_status(BlockDriverState *bs,
return ret;
}
- if (mode != BDRV_WANT_PRECISE) {
+ if (!(mode & BDRV_WANT_ZERO)) {
*pnum = bytes;
*map = offset;
*file = bs;
--
2.39.3

View File

@ -0,0 +1,131 @@
From 2baedec75a8a0daf9e93228795d1e6f2974f4825 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Thu, 17 Apr 2025 11:05:27 -0400
Subject: [PATCH 1/4] file-posix: probe discard alignment on Linux block
devices
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 354: file-posix: probe discard alignment on Linux block devices
RH-Jira: RHEL-87642
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Commit: [1/3] 84de24191bfa47e94cd475e78dcafd38a50a5888 (stefanha/centos-stream-qemu-kvm)
Populate the pdiscard_alignment block limit so the block layer is able
align discard requests correctly.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20250417150528.76470-2-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit f605796aae42885034400c83ed6a9b07cd6d6481)
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
block/file-posix.c | 67 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 66 insertions(+), 1 deletion(-)
diff --git a/block/file-posix.c b/block/file-posix.c
index 56d1972d15..0d6e12f880 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1276,10 +1276,10 @@ static int get_sysfs_zoned_model(struct stat *st, BlockZoneModel *zoned)
}
#endif /* defined(CONFIG_BLKZONED) */
+#ifdef CONFIG_LINUX
/*
* Get a sysfs attribute value as a long integer.
*/
-#ifdef CONFIG_LINUX
static long get_sysfs_long_val(struct stat *st, const char *attribute)
{
g_autofree char *str = NULL;
@@ -1299,6 +1299,30 @@ static long get_sysfs_long_val(struct stat *st, const char *attribute)
}
return ret;
}
+
+/*
+ * Get a sysfs attribute value as a uint32_t.
+ */
+static int get_sysfs_u32_val(struct stat *st, const char *attribute,
+ uint32_t *u32)
+{
+ g_autofree char *str = NULL;
+ const char *end;
+ unsigned int val;
+ int ret;
+
+ ret = get_sysfs_str_val(st, attribute, &str);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* The file is ended with '\n', pass 'end' to accept that. */
+ ret = qemu_strtoui(str, &end, 10, &val);
+ if (ret == 0 && end && *end == '\0') {
+ *u32 = val;
+ }
+ return ret;
+}
#endif
static int hdev_get_max_segments(int fd, struct stat *st)
@@ -1318,6 +1342,23 @@ static int hdev_get_max_segments(int fd, struct stat *st)
#endif
}
+/*
+ * Fills in *dalign with the discard alignment and returns 0 on success,
+ * -errno otherwise.
+ */
+static int hdev_get_pdiscard_alignment(struct stat *st, uint32_t *dalign)
+{
+#ifdef CONFIG_LINUX
+ /*
+ * Note that Linux "discard_granularity" is QEMU "discard_alignment". Linux
+ * "discard_alignment" is something else.
+ */
+ return get_sysfs_u32_val(st, "discard_granularity", dalign);
+#else
+ return -ENOTSUP;
+#endif
+}
+
#if defined(CONFIG_BLKZONED)
/*
* If the reset_all flag is true, then the wps of zone whose state is
@@ -1527,6 +1568,30 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
}
}
+ if (S_ISBLK(st.st_mode)) {
+ uint32_t dalign = 0;
+ int ret;
+
+ ret = hdev_get_pdiscard_alignment(&st, &dalign);
+ if (ret == 0) {
+ uint32_t ralign = bs->bl.request_alignment;
+
+ /* Probably never happens, but handle it just in case */
+ if (dalign < ralign && (ralign % dalign == 0)) {
+ dalign = ralign;
+ }
+
+ /* The block layer requires a multiple of request_alignment */
+ if (dalign % ralign != 0) {
+ error_setg(errp, "Invalid pdiscard_alignment limit %u is not a "
+ "multiple of request_alignment %u", dalign, ralign);
+ return;
+ }
+
+ bs->bl.pdiscard_alignment = dalign;
+ }
+ }
+
raw_refresh_zoned_limits(bs, &st, errp);
}
--
2.39.3

View File

@ -0,0 +1,225 @@
From 8cd2c71be827e01f1bcc6e0e7ad7de2268835265 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 18 Jul 2025 18:03:46 +0200
Subject: [PATCH 036/100] headers: Add definitions from UEFI spec for volumes,
resources, etc...
Add UEFI definitions for literals, enums, structs, GUIDs, etc... that
will be used by TDX to build the UEFI Hand-Off Block (HOB) that is passed
to the Trusted Domain Virtual Firmware (TDVF).
All values come from the UEFI specification [1], PI spec [2] and TDVF
design guide[3].
[1] UEFI Specification v2.1.0 https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf
[2] UEFI PI spec v1.8 https://uefi.org/sites/default/files/resources/UEFI_PI_Spec_1_8_March3.pdf
[3] https://software.intel.com/content/dam/develop/external/us/en/documents/tdx-virtual-firmware-design-guide-rev-1.pdf
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Link: https://lore.kernel.org/r/20250508150002.689633-23-xiaoyao.li@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 88aa6576e4ab40b538f543852128cb17fce37f87)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/standard-headers/uefi/uefi.h | 187 +++++++++++++++++++++++++++
1 file changed, 187 insertions(+)
create mode 100644 include/standard-headers/uefi/uefi.h
diff --git a/include/standard-headers/uefi/uefi.h b/include/standard-headers/uefi/uefi.h
new file mode 100644
index 0000000000..5256349ec0
--- /dev/null
+++ b/include/standard-headers/uefi/uefi.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2025 Intel Corporation
+ *
+ * Author: Isaku Yamahata <isaku.yamahata at gmail.com>
+ * <isaku.yamahata at intel.com>
+ * Xiaoyao Li <xiaoyao.li@intel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_I386_UEFI_H
+#define HW_I386_UEFI_H
+
+/***************************************************************************/
+/*
+ * basic EFI definitions
+ * supplemented with UEFI Specification Version 2.8 (Errata A)
+ * released February 2020
+ */
+/* UEFI integer is little endian */
+
+typedef struct {
+ uint32_t Data1;
+ uint16_t Data2;
+ uint16_t Data3;
+ uint8_t Data4[8];
+} EFI_GUID;
+
+typedef enum {
+ EfiReservedMemoryType,
+ EfiLoaderCode,
+ EfiLoaderData,
+ EfiBootServicesCode,
+ EfiBootServicesData,
+ EfiRuntimeServicesCode,
+ EfiRuntimeServicesData,
+ EfiConventionalMemory,
+ EfiUnusableMemory,
+ EfiACPIReclaimMemory,
+ EfiACPIMemoryNVS,
+ EfiMemoryMappedIO,
+ EfiMemoryMappedIOPortSpace,
+ EfiPalCode,
+ EfiPersistentMemory,
+ EfiUnacceptedMemoryType,
+ EfiMaxMemoryType
+} EFI_MEMORY_TYPE;
+
+#define EFI_HOB_HANDOFF_TABLE_VERSION 0x0009
+
+#define EFI_HOB_TYPE_HANDOFF 0x0001
+#define EFI_HOB_TYPE_MEMORY_ALLOCATION 0x0002
+#define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR 0x0003
+#define EFI_HOB_TYPE_GUID_EXTENSION 0x0004
+#define EFI_HOB_TYPE_FV 0x0005
+#define EFI_HOB_TYPE_CPU 0x0006
+#define EFI_HOB_TYPE_MEMORY_POOL 0x0007
+#define EFI_HOB_TYPE_FV2 0x0009
+#define EFI_HOB_TYPE_LOAD_PEIM_UNUSED 0x000A
+#define EFI_HOB_TYPE_UEFI_CAPSULE 0x000B
+#define EFI_HOB_TYPE_FV3 0x000C
+#define EFI_HOB_TYPE_UNUSED 0xFFFE
+#define EFI_HOB_TYPE_END_OF_HOB_LIST 0xFFFF
+
+typedef struct {
+ uint16_t HobType;
+ uint16_t HobLength;
+ uint32_t Reserved;
+} EFI_HOB_GENERIC_HEADER;
+
+typedef uint64_t EFI_PHYSICAL_ADDRESS;
+typedef uint32_t EFI_BOOT_MODE;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+ uint32_t Version;
+ EFI_BOOT_MODE BootMode;
+ EFI_PHYSICAL_ADDRESS EfiMemoryTop;
+ EFI_PHYSICAL_ADDRESS EfiMemoryBottom;
+ EFI_PHYSICAL_ADDRESS EfiFreeMemoryTop;
+ EFI_PHYSICAL_ADDRESS EfiFreeMemoryBottom;
+ EFI_PHYSICAL_ADDRESS EfiEndOfHobList;
+} EFI_HOB_HANDOFF_INFO_TABLE;
+
+#define EFI_RESOURCE_SYSTEM_MEMORY 0x00000000
+#define EFI_RESOURCE_MEMORY_MAPPED_IO 0x00000001
+#define EFI_RESOURCE_IO 0x00000002
+#define EFI_RESOURCE_FIRMWARE_DEVICE 0x00000003
+#define EFI_RESOURCE_MEMORY_MAPPED_IO_PORT 0x00000004
+#define EFI_RESOURCE_MEMORY_RESERVED 0x00000005
+#define EFI_RESOURCE_IO_RESERVED 0x00000006
+#define EFI_RESOURCE_MEMORY_UNACCEPTED 0x00000007
+#define EFI_RESOURCE_MAX_MEMORY_TYPE 0x00000008
+
+#define EFI_RESOURCE_ATTRIBUTE_PRESENT 0x00000001
+#define EFI_RESOURCE_ATTRIBUTE_INITIALIZED 0x00000002
+#define EFI_RESOURCE_ATTRIBUTE_TESTED 0x00000004
+#define EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC 0x00000008
+#define EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC 0x00000010
+#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 0x00000020
+#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 0x00000040
+#define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED 0x00000080
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED 0x00000100
+#define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED 0x00000200
+#define EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE 0x00000400
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE 0x00000800
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE 0x00001000
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE 0x00002000
+#define EFI_RESOURCE_ATTRIBUTE_16_BIT_IO 0x00004000
+#define EFI_RESOURCE_ATTRIBUTE_32_BIT_IO 0x00008000
+#define EFI_RESOURCE_ATTRIBUTE_64_BIT_IO 0x00010000
+#define EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED 0x00020000
+#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED 0x00040000
+#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE 0x00080000
+#define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE 0x00100000
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE 0x00200000
+#define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE 0x00400000
+#define EFI_RESOURCE_ATTRIBUTE_PERSISTENT 0x00800000
+#define EFI_RESOURCE_ATTRIBUTE_PERSISTABLE 0x01000000
+#define EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE 0x02000000
+
+typedef uint32_t EFI_RESOURCE_TYPE;
+typedef uint32_t EFI_RESOURCE_ATTRIBUTE_TYPE;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+ EFI_GUID Owner;
+ EFI_RESOURCE_TYPE ResourceType;
+ EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute;
+ EFI_PHYSICAL_ADDRESS PhysicalStart;
+ uint64_t ResourceLength;
+} EFI_HOB_RESOURCE_DESCRIPTOR;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+ EFI_GUID Name;
+
+ /* guid specific data follows */
+} EFI_HOB_GUID_TYPE;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ uint64_t Length;
+} EFI_HOB_FIRMWARE_VOLUME;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ uint64_t Length;
+ EFI_GUID FvName;
+ EFI_GUID FileName;
+} EFI_HOB_FIRMWARE_VOLUME2;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ uint64_t Length;
+ uint32_t AuthenticationStatus;
+ bool ExtractedFv;
+ EFI_GUID FvName;
+ EFI_GUID FileName;
+} EFI_HOB_FIRMWARE_VOLUME3;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+ uint8_t SizeOfMemorySpace;
+ uint8_t SizeOfIoSpace;
+ uint8_t Reserved[6];
+} EFI_HOB_CPU;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+} EFI_HOB_MEMORY_POOL;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ uint64_t Length;
+} EFI_HOB_UEFI_CAPSULE;
+
+#define EFI_HOB_OWNER_ZERO \
+ ((EFI_GUID){ 0x00000000, 0x0000, 0x0000, \
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } })
+
+#endif
--
2.47.3

View File

@ -1,61 +0,0 @@
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

View File

@ -1,217 +0,0 @@
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

View File

@ -1,16 +1,16 @@
From ebdb9f250c30dec885894b6b9e249c1744d36b2d Mon Sep 17 00:00:00 2001
From 662b91cbf6bebfa4f38fe2d1b1868d316bfe8838 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 10 Jun 2025 13:36:45 +0100
Subject: [PATCH 08/31] hw/audio/ac97: skip automatic zero-init of large arrays
Subject: [PATCH 15/43] hw/audio/ac97: skip automatic zero-init of large arrays
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 460: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-99889
RH-MergeRequest: 381: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-95479
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [7/30] f5ecbd20c7b3a4c77eb5d3230e589115a333737f
RH-Commit: [7/31] 5c4f1eea2eab9ef363ac7f0076725fc5767ee51f (stefanha/centos-stream-qemu-kvm)
The 'read_audio' & 'write_audio' methods have a 4k byte array used
for copying data between the audio backend and device. Skip the
@ -31,7 +31,7 @@ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c
index 3f0053f94d..681b5752a1 100644
index 05c573776e..2b290cb2b1 100644
--- a/hw/audio/ac97.c
+++ b/hw/audio/ac97.c
@@ -886,7 +886,7 @@ static void nabm_writel(void *opaque, uint32_t addr, uint32_t val)

View File

@ -1,17 +1,17 @@
From 29e5d6acc630a604451c109ca260066e077badb5 Mon Sep 17 00:00:00 2001
From 301bc6085046756e7ae0b5c2d4a95fa8cc88be0d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 10 Jun 2025 13:36:46 +0100
Subject: [PATCH 09/31] hw/audio/cs4231a: skip automatic zero-init of large
Subject: [PATCH 16/43] hw/audio/cs4231a: skip automatic zero-init of large
arrays
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 460: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-99889
RH-MergeRequest: 381: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-95479
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [8/30] b6d953f19b9b6d6ed2dc9e81fd028faae1d34154
RH-Commit: [8/31] 8633c398b929f3c4e0c1d7d5874b2fead4496a7d (stefanha/centos-stream-qemu-kvm)
The 'cs_write_audio' method has a pair of byte arrays, one 4k in size
and one 8k, which are used in converting audio samples. Skip the
@ -33,7 +33,7 @@ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c
index 9ef57f042d..5c312642cc 100644
index 5a9be80ba3..eb916035ec 100644
--- a/hw/audio/cs4231a.c
+++ b/hw/audio/cs4231a.c
@@ -528,7 +528,7 @@ static int cs_write_audio (CSState *s, int nchan, int dma_pos,

View File

@ -1,17 +1,17 @@
From a8adc00e27b3c649522dfb2db29cc6d7fd9cb17b Mon Sep 17 00:00:00 2001
From 084ce8fa1c5db2eb9c5567fbcd0568e3e2cd37a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 10 Jun 2025 13:36:47 +0100
Subject: [PATCH 10/31] hw/audio/es1370: skip automatic zero-init of large
Subject: [PATCH 17/43] hw/audio/es1370: skip automatic zero-init of large
array
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 460: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-99889
RH-MergeRequest: 381: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-95479
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [9/30] 735b9d5225ffc8b3a51344b3ffbfb18a5ef66cc3
RH-Commit: [9/31] 3d8c0165ee60c4027302706abc9d6c55461c884b (stefanha/centos-stream-qemu-kvm)
The 'es1370_transfer_audio' method has a 4k byte array used for
copying data between the audio backend and device. Skip the automatic
@ -32,7 +32,7 @@ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c
index 4ab61d3b9d..6aea934f54 100644
index 75f71e5d78..d0ed0052db 100644
--- a/hw/audio/es1370.c
+++ b/hw/audio/es1370.c
@@ -604,7 +604,7 @@ static uint64_t es1370_read(void *opaque, hwaddr addr, unsigned size)

View File

@ -1,16 +1,16 @@
From 7e7dcd9e3a9a021629aa2013135153b1619cc16a Mon Sep 17 00:00:00 2001
From 7c889953afbf830cb4522ec259221a9319c0f42a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 10 Jun 2025 13:36:48 +0100
Subject: [PATCH 11/31] hw/audio/gus: skip automatic zero-init of large array
Subject: [PATCH 18/43] hw/audio/gus: skip automatic zero-init of large array
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 460: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-99889
RH-MergeRequest: 381: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-95479
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [10/30] 4ae3651d4f6a78a8484cd96c752c6a8b4cd1c7c3
RH-Commit: [10/31] a580b7fae56231c7bf1e2b797a4037eeb45f817a (stefanha/centos-stream-qemu-kvm)
The 'GUS_read_DMA' method has a 4k byte array used for copying
data between the audio backend and device. Skip the automatic
@ -31,7 +31,7 @@ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/audio/gus.c b/hw/audio/gus.c
index 4beb3fd74e..e8b0b85d44 100644
index e718c1183e..bd242e19a3 100644
--- a/hw/audio/gus.c
+++ b/hw/audio/gus.c
@@ -183,7 +183,7 @@ static int GUS_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)

View File

@ -1,17 +1,17 @@
From 9196c381e0137d5f7c82342d9c200b477bbbcebb Mon Sep 17 00:00:00 2001
From ef07fc569ae2a50f54f8bf29f09555cb0e8b08db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 10 Jun 2025 13:36:49 +0100
Subject: [PATCH 12/31] hw/audio/marvell_88w8618: skip automatic zero-init of
Subject: [PATCH 19/43] hw/audio/marvell_88w8618: skip automatic zero-init of
large array
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 460: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-99889
RH-MergeRequest: 381: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-95479
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [11/30] fdb3782a308d6d5026bbf15f34ef3ad35e0e9723
RH-Commit: [11/31] c45c78043e51ac3195e76aaf0b745dd41c8d8345 (stefanha/centos-stream-qemu-kvm)
The 'mv88w8618_audio_callback' method has a 4k byte array used for
copying data between the audio backend and device. Skip the automatic
@ -33,7 +33,7 @@ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/audio/marvell_88w8618.c b/hw/audio/marvell_88w8618.c
index cc285444bc..b7b4b27272 100644
index 28f9af320d..31a73f53b9 100644
--- a/hw/audio/marvell_88w8618.c
+++ b/hw/audio/marvell_88w8618.c
@@ -66,7 +66,7 @@ static void mv88w8618_audio_callback(void *opaque, int free_out, int free_in)

View File

@ -1,16 +1,16 @@
From 5174f114117bd69f39c2c422c281e0623ce478d0 Mon Sep 17 00:00:00 2001
From 5b5db5d5901a9d8106cf594f7f7ebf9c9152a53f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 10 Jun 2025 13:36:50 +0100
Subject: [PATCH 13/31] hw/audio/sb16: skip automatic zero-init of large array
Subject: [PATCH 20/43] hw/audio/sb16: skip automatic zero-init of large array
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 460: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-99889
RH-MergeRequest: 381: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-95479
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [12/30] 84f5d96cd3352f645098b38e47b364140a343997
RH-Commit: [12/31] 2f715c640897101a96a6f397d574f248fc1a7fce (stefanha/centos-stream-qemu-kvm)
The 'write_audio' method has a 4k byte array used for copying data
between the audio backend and device. Skip the automatic zero-init
@ -31,7 +31,7 @@ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c
index fd76e78d18..04c818ed3d 100644
index 0c661b4947..afee59d798 100644
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -1181,7 +1181,7 @@ static int write_audio (SB16State *s, int nchan, int dma_pos,

View File

@ -1,17 +1,17 @@
From bb7babfc547e0339fcb27da41f5f407578865a8c Mon Sep 17 00:00:00 2001
From dc08736e78d641eaab2f6df35218fb2b0f88ee50 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 10 Jun 2025 13:36:51 +0100
Subject: [PATCH 14/31] hw/audio/via-ac97: skip automatic zero-init of large
Subject: [PATCH 21/43] hw/audio/via-ac97: skip automatic zero-init of large
array
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 460: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-99889
RH-MergeRequest: 381: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED
RH-Jira: RHEL-95479
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [13/30] 46ade09cbd7bf00f3b3b24b2c32cb187d0d8d087
RH-Commit: [13/31] 8afade9e5ac67ec271f3318473c04b6fb9947f8d (stefanha/centos-stream-qemu-kvm)
The 'out_cb' method has a 4k byte array used for copying data
between the audio backend and device. Skip the automatic zero-init
@ -32,7 +32,7 @@ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/audio/via-ac97.c b/hw/audio/via-ac97.c
index 4c127a1def..e8fcf44e5d 100644
index 4e115e011e..08e6762597 100644
--- a/hw/audio/via-ac97.c
+++ b/hw/audio/via-ac97.c
@@ -175,7 +175,7 @@ static void out_cb(void *opaque, int avail)

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