diff --git a/.gitignore b/.gitignore index 2a5c31c..e715b64 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -qemu-9.1.0.tar.xz +qemu-10.0.0.tar.xz diff --git a/0004-Initial-redhat-build.patch b/0004-Initial-redhat-build.patch index fa0e5f7..853276c 100644 --- a/0004-Initial-redhat-build.patch +++ b/0004-Initial-redhat-build.patch @@ -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 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 --- -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 @@ diff --git a/0005-Enable-disable-devices-for-RHEL.patch b/0005-Enable-disable-devices-for-RHEL.patch index 459ce3b..e470db7 100644 --- a/0005-Enable-disable-devices-for-RHEL.patch +++ b/0005-Enable-disable-devices-for-RHEL.patch @@ -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 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 --- -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 }"); diff --git a/0006-Machine-type-related-general-changes.patch b/0006-Machine-type-related-general-changes.patch index f7832d0..005d537 100644 --- a/0006-Machine-type-related-general-changes.patch +++ b/0006-Machine-type-related-general-changes.patch @@ -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 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 --- -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 { diff --git a/0007-meson-temporarily-disable-Wunused-function.patch b/0007-meson-temporarily-disable-Wunused-function.patch index ce7c17c..c87b164 100644 --- a/0007-meson-temporarily-disable-Wunused-function.patch +++ b/0007-meson-temporarily-disable-Wunused-function.patch @@ -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?= 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Ă© -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', diff --git a/0008-Remove-upstream-machine-types-for-aarch64-s390x-and-.patch b/0008-Remove-upstream-machine-types-for-aarch64-s390x-and-.patch index 335b53f..59cdaa0 100644 --- a/0008-Remove-upstream-machine-types-for-aarch64-s390x-and-.patch +++ b/0008-Remove-upstream-machine-types-for-aarch64-s390x-and-.patch @@ -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 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Ă© Signed-off-by: Miroslav Rezanina -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 */ diff --git a/0009-Adapt-versioned-machine-type-macros-for-RHEL.patch b/0009-Adapt-versioned-machine-type-macros-for-RHEL.patch index 40f753a..fea50ed 100644 --- a/0009-Adapt-versioned-machine-type-macros-for-RHEL.patch +++ b/0009-Adapt-versioned-machine-type-macros-for-RHEL.patch @@ -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?= 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 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 diff --git a/0010-Increase-deletion-schedule-to-4-releases.patch b/0010-Increase-deletion-schedule-to-4-releases.patch index ac7e4eb..047cf63 100644 --- a/0010-Increase-deletion-schedule-to-4-releases.patch +++ b/0010-Increase-deletion-schedule-to-4-releases.patch @@ -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?= 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Ă© -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. */ diff --git a/0011-Add-downstream-aarch64-versioned-virt-machine-types.patch b/0011-Add-downstream-aarch64-versioned-virt-machine-types.patch index 97b2fb1..d6469f6 100644 --- a/0011-Add-downstream-aarch64-versioned-virt-machine-types.patch +++ b/0011-Add-downstream-aarch64-versioned-virt-machine-types.patch @@ -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?= 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 --- -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 diff --git a/0012-Add-downstream-s390x-versioned-s390-ccw-virtio-machi.patch b/0012-Add-downstream-s390x-versioned-s390-ccw-virtio-machi.patch index a684e80..cf21b6b 100644 --- a/0012-Add-downstream-s390x-versioned-s390-ccw-virtio-machi.patch +++ b/0012-Add-downstream-s390x-versioned-s390-ccw-virtio-machi.patch @@ -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?= 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 -- -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)); diff --git a/0013-Add-downstream-x86_64-versioned-pc-q35-machine-types.patch b/0013-Add-downstream-x86_64-versioned-pc-q35-machine-types.patch index 18058b2..9697d1c 100644 --- a/0013-Add-downstream-x86_64-versioned-pc-q35-machine-types.patch +++ b/0013-Add-downstream-x86_64-versioned-pc-q35-machine-types.patch @@ -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?= 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 --- -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 #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) diff --git a/0014-Revert-meson-temporarily-disable-Wunused-function.patch b/0014-Revert-meson-temporarily-disable-Wunused-function.patch index 426e39f..87b2a80 100644 --- a/0014-Revert-meson-temporarily-disable-Wunused-function.patch +++ b/0014-Revert-meson-temporarily-disable-Wunused-function.patch @@ -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?= 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Ă© 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', diff --git a/0015-Enable-make-check.patch b/0015-Enable-make-check.patch index 5c5ebc1..de71366 100644 --- a/0015-Enable-make-check.patch +++ b/0015-Enable-make-check.patch @@ -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 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 --- -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 " \ diff --git a/0016-vfio-cap-number-of-devices-that-can-be-assigned.patch b/0016-vfio-cap-number-of-devices-that-can-be-assigned.patch index a492875..adac2b6 100644 --- a/0016-vfio-cap-number-of-devices-that-can-be-assigned.patch +++ b/0016-vfio-cap-number-of-devices-that-can-be-assigned.patch @@ -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 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 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 { diff --git a/0017-Add-support-statement-to-help-output.patch b/0017-Add-support-statement-to-help-output.patch index 1d3cd3f..862cb9e 100644 --- a/0017-Add-support-statement-to-help-output.patch +++ b/0017-Add-support-statement-to-help-output.patch @@ -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 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 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"); diff --git a/0018-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch b/0018-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch index 8226ee1..7c483d1 100644 --- a/0018-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch +++ b/0018-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch @@ -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 Date: Wed, 8 Jul 2020 08:35:50 +0200 Subject: Use qemu-kvm in documentation instead of qemu-system- @@ -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 :: diff --git a/0019-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch b/0019-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch index ef84e7d..128998f 100644 --- a/0019-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch +++ b/0019-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch @@ -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 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 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, diff --git a/0021-Add-upstream-compatibility-bits.patch b/0021-Add-upstream-compatibility-bits.patch deleted file mode 100644 index 8f0de48..0000000 --- a/0021-Add-upstream-compatibility-bits.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 03502faf7012e20fb7c4f1efee7e429ad3727fd1 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -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 - diff --git a/0022-redhat-Add-QEMU-9.1-compat-handling-to-the-s390x-mac.patch b/0022-redhat-Add-QEMU-9.1-compat-handling-to-the-s390x-mac.patch deleted file mode 100644 index 2353cc5..0000000 --- a/0022-redhat-Add-QEMU-9.1-compat-handling-to-the-s390x-mac.patch +++ /dev/null @@ -1,37 +0,0 @@ -From d27437e5baba347cb3392280399d402414dcb21c Mon Sep 17 00:00:00 2001 -From: Thomas Huth -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 ---- - 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 - diff --git a/0023-redhat-Add-rhel9.6.0-and-rhel10.0.0-machine-types.patch b/0023-redhat-Add-rhel9.6.0-and-rhel10.0.0-machine-types.patch deleted file mode 100644 index 33b6f77..0000000 --- a/0023-redhat-Add-rhel9.6.0-and-rhel10.0.0-machine-types.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 926a9d0ca2437b4c4270062f707ed24284ad469f Mon Sep 17 00:00:00 2001 -From: Thomas Huth -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 ---- - 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 - diff --git a/0024-x86-ensure-compatibility-of-pc-q35-rhel9.patch b/0024-x86-ensure-compatibility-of-pc-q35-rhel9.patch deleted file mode 100644 index b1e23de..0000000 --- a/0024-x86-ensure-compatibility-of-pc-q35-rhel9.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 6be70c681bf7a1b9666ed5896b5be8be7df2bf50 Mon Sep 17 00:00:00 2001 -From: Sebastian Ott -Date: Wed, 4 Sep 2024 15:46:53 +0200 -Subject: x86: ensure compatibility of pc-q35-rhel9* - -Signed-off-by: Sebastian Ott ---- - 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 - diff --git a/0025-arm-ensure-compatibility-of-virt-rhel9.patch b/0025-arm-ensure-compatibility-of-virt-rhel9.patch deleted file mode 100644 index 2b95ffe..0000000 --- a/0025-arm-ensure-compatibility-of-virt-rhel9.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 17c3bccf2f2804772ab60bf4f04d7437f13ed48a Mon Sep 17 00:00:00 2001 -From: Sebastian Ott -Date: Wed, 4 Sep 2024 15:52:00 +0200 -Subject: arm: ensure compatibility of virt-rhel9* - -Signed-off-by: Sebastian Ott ---- - 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 - diff --git a/2001-Add-ppc64-support.patch b/2001-Add-ppc64-support.patch index 539f024..f4f3bbf 100644 --- a/2001-Add-ppc64-support.patch +++ b/2001-Add-ppc64-support.patch @@ -1,19 +1,20 @@ -From eb742e8a7c75e3be5c158cb19185d9cf6ae4862c Mon Sep 17 00:00:00 2001 +From 9928955dc717c10f4c1084ef1ba71308fef68376 Mon Sep 17 00:00:00 2001 From: eabdullin 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) diff --git a/2002-Enable-QXL-device-build.patch b/2002-Enable-QXL-device-build.patch index 862fc46..14eaf1f 100644 --- a/2002-Enable-QXL-device-build.patch +++ b/2002-Enable-QXL-device-build.patch @@ -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 - diff --git a/kvm-Declare-rtl8139-as-deprecated.patch b/kvm-Declare-rtl8139-as-deprecated.patch new file mode 100644 index 0000000..71df389 --- /dev/null +++ b/kvm-Declare-rtl8139-as-deprecated.patch @@ -0,0 +1,56 @@ +From e4a324ce1f4ffca214b6d5b5681b9eca630707bf Mon Sep 17 00:00:00 2001 +From: Laurent Vivier +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 +RH-MergeRequest: 396: Declare rtl8139 as deprecated +RH-Jira: RHEL-45624 +RH-Acked-by: Eugenio PĂ©rez +RH-Acked-by: Thomas Huth +RH-Acked-by: Cindy Lu +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 +--- + 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 + diff --git a/kvm-Disable-virtio-net-pci-romfile-loading-on-riscv64.patch b/kvm-Disable-virtio-net-pci-romfile-loading-on-riscv64.patch new file mode 100644 index 0000000..8cd2641 --- /dev/null +++ b/kvm-Disable-virtio-net-pci-romfile-loading-on-riscv64.patch @@ -0,0 +1,54 @@ +From 12720b4c0434d9549f0e41ed5951890fdd9aedd4 Mon Sep 17 00:00:00 2001 +From: Andrea Bolognani +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 +RH-MergeRequest: 373: Various small fixes +RH-Jira: RHEL-96057 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [4/4] b490ef3c3ab6a47f90c67016f685e19a65d97100 (abologna/centos-stream-qemu-kvm) + +Same motivation for disabling it as on aarch64. + +Signed-off-by: Andrea Bolognani +--- + 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 + diff --git a/kvm-Enable-amd-iommu-device.patch b/kvm-Enable-amd-iommu-device.patch new file mode 100644 index 0000000..67f6bbc --- /dev/null +++ b/kvm-Enable-amd-iommu-device.patch @@ -0,0 +1,38 @@ +From 7b15a63367901d3d3fad7cd17c3960662f2f88f0 Mon Sep 17 00:00:00 2001 +From: John Allen +Date: Wed, 11 Jun 2025 15:41:14 -0500 +Subject: [PATCH 42/43] Enable amd-iommu device + +RH-Author: John Allen +RH-MergeRequest: 383: Add ability to manually specify the AMDVI-PCI device +RH-Jira: RHEL-85649 +RH-Acked-by: Miroslav Rezanina +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 +--- + 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 + diff --git a/kvm-Enable-uefi-variable-service-for-edk2.patch b/kvm-Enable-uefi-variable-service-for-edk2.patch new file mode 100644 index 0000000..74884cb --- /dev/null +++ b/kvm-Enable-uefi-variable-service-for-edk2.patch @@ -0,0 +1,45 @@ +From 058b99a669b3cdd55a8c0c685d2fbfae0935d79e Mon Sep 17 00:00:00 2001 +From: Shaoqin Huang +Date: Wed, 6 Aug 2025 22:31:50 -0400 +Subject: [PATCH] Enable uefi variable service for edk2 + +RH-Author: Shaoqin Huang +RH-MergeRequest: 398: Enable uefi variable service for edk2 +RH-Jira: RHEL-102325 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Eric Auger +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 +--- + 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 + diff --git a/kvm-Enable-vhost-user-gpu-pci-for-RHIVOS.patch b/kvm-Enable-vhost-user-gpu-pci-for-RHIVOS.patch new file mode 100644 index 0000000..659e692 --- /dev/null +++ b/kvm-Enable-vhost-user-gpu-pci-for-RHIVOS.patch @@ -0,0 +1,39 @@ +From 86f52a84c158f7b31455596c9700124977696314 Mon Sep 17 00:00:00 2001 +From: Miroslav Rezanina +Date: Tue, 29 Apr 2025 09:09:51 -0400 +Subject: [PATCH 4/4] Enable vhost-user-gpu-pci for RHIVOS + +RH-Author: Miroslav Rezanina +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 +--- + 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 + diff --git a/kvm-KVM-Define-KVM_MEMSLOTS_NUM_MAX_DEFAULT.patch b/kvm-KVM-Define-KVM_MEMSLOTS_NUM_MAX_DEFAULT.patch deleted file mode 100644 index 14bd08c..0000000 --- a/kvm-KVM-Define-KVM_MEMSLOTS_NUM_MAX_DEFAULT.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 111d70a5bdc3ee0dde0a6def9e0c75ed20b4f093 Mon Sep 17 00:00:00 2001 -From: Peter Xu -Date: Tue, 17 Sep 2024 12:38:33 -0400 -Subject: [PATCH 6/9] KVM: Define KVM_MEMSLOTS_NUM_MAX_DEFAULT - -RH-Author: Peter Xu -RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array -RH-Jira: RHEL-57685 -RH-Acked-by: Juraj Marcin -RH-Acked-by: Miroslav Rezanina -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 -Signed-off-by: Peter Xu -Link: https://lore.kernel.org/r/20240917163835.194664-3-peterx@redhat.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit b34a908c8f24eedb0a8e5ff486b059b58fd793f4) -Signed-off-by: Peter Xu ---- - 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 - diff --git a/kvm-KVM-Dynamic-sized-kvm-memslots-array.patch b/kvm-KVM-Dynamic-sized-kvm-memslots-array.patch deleted file mode 100644 index 8fc648d..0000000 --- a/kvm-KVM-Dynamic-sized-kvm-memslots-array.patch +++ /dev/null @@ -1,251 +0,0 @@ -From c77a30265b8d0db43174b040ea82103f8fdb9911 Mon Sep 17 00:00:00 2001 -From: Peter Xu -Date: Tue, 17 Sep 2024 12:38:32 -0400 -Subject: [PATCH 5/9] KVM: Dynamic sized kvm memslots array - -RH-Author: Peter Xu -RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array -RH-Jira: RHEL-57685 -RH-Acked-by: Juraj Marcin -RH-Acked-by: Miroslav Rezanina -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 -Reported-by: Zhiyi Guo -Tested-by: Zhiyi Guo -Signed-off-by: Peter Xu -Acked-by: David Hildenbrand -Reviewed-by: Fabiano Rosas -Link: https://lore.kernel.org/r/20240917163835.194664-2-peterx@redhat.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit 5504a8126115d173687b37e657312a8ffe29fc0c) -Signed-off-by: Peter Xu ---- - 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 - diff --git a/kvm-KVM-Rename-KVMMemoryListener.nr_used_slots-to-nr_slo.patch b/kvm-KVM-Rename-KVMMemoryListener.nr_used_slots-to-nr_slo.patch deleted file mode 100644 index 544247a..0000000 --- a/kvm-KVM-Rename-KVMMemoryListener.nr_used_slots-to-nr_slo.patch +++ /dev/null @@ -1,73 +0,0 @@ -From b1d082cfad79245ac0ffed45f723092388d1cf45 Mon Sep 17 00:00:00 2001 -From: Peter Xu -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 -RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array -RH-Jira: RHEL-57685 -RH-Acked-by: Juraj Marcin -RH-Acked-by: Miroslav Rezanina -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 -Signed-off-by: Peter Xu -Link: https://lore.kernel.org/r/20240917163835.194664-4-peterx@redhat.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit dbdc00ba5b136bba80d850f61cc79a9cafaae1cd) -Signed-off-by: Peter Xu ---- - 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 - diff --git a/kvm-KVM-Rename-KVMState-nr_slots-to-nr_slots_max.patch b/kvm-KVM-Rename-KVMState-nr_slots-to-nr_slots_max.patch deleted file mode 100644 index 92b46cc..0000000 --- a/kvm-KVM-Rename-KVMState-nr_slots-to-nr_slots_max.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 891fb13363d168760cd21d0c57368e1a413cad27 Mon Sep 17 00:00:00 2001 -From: Peter Xu -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 -RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array -RH-Jira: RHEL-57685 -RH-Acked-by: Juraj Marcin -RH-Acked-by: Miroslav Rezanina -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 -Signed-off-by: Peter Xu -Link: https://lore.kernel.org/r/20240917163835.194664-5-peterx@redhat.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit 943c742868c739c0b14fd996bad3adf744156fec) -Signed-off-by: Peter Xu ---- - 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 - diff --git a/kvm-RH-Author-Shaoqin-Huang-shahuang-redhat.com.patch b/kvm-RH-Author-Shaoqin-Huang-shahuang-redhat.com.patch deleted file mode 100644 index f1ddc9b..0000000 --- a/kvm-RH-Author-Shaoqin-Huang-shahuang-redhat.com.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 5110e137294163ae43a61376485a7f610bf496f3 Mon Sep 17 00:00:00 2001 -From: Shaoqin Huang -Date: Wed, 22 May 2024 03:23:28 -0400 -Subject: [PATCH 8/9] RH-Author: Shaoqin Huang - RH-MergeRequest: 271: hw/arm/virt: Fix Manufacturer and Product Name in - emulated SMBIOS mode RH-Jira: RHEL-38374 RH-Acked-by: Cornelia Huck - RH-Acked-by: Miroslav Rezanina - RH-Acked-by: Eric Auger 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 - diff --git a/kvm-accel-kvm-check-for-KVM_CAP_READONLY_MEM-on-VM.patch b/kvm-accel-kvm-check-for-KVM_CAP_READONLY_MEM-on-VM.patch deleted file mode 100644 index 6724ead..0000000 --- a/kvm-accel-kvm-check-for-KVM_CAP_READONLY_MEM-on-VM.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 2b4558ec338adde1b9735128bb8d2f81db303a93 Mon Sep 17 00:00:00 2001 -From: Avadhut Naik -Date: Wed, 23 Oct 2024 12:25:28 -0500 -Subject: [PATCH 01/38] accel/kvm: check for KVM_CAP_READONLY_MEM on VM - -RH-Author: avnaik1 -RH-MergeRequest: 276: accel/kvm: check for KVM_CAP_READONLY_MEM on VM -RH-Jira: RHEL-58928 -RH-Acked-by: Paolo Bonzini -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [1/1] 1d392a9e47e68bb71dc44635c494d161585a885c (avnaik1/avnaik-qemu-kvm-fork) - -JIRA: https://issues.redhat.com/browse/RHEL-58928 - -commit 64e0e63ea16aa0122dc0c41a0679da0ae4616208 -Author: Tom Dohrmann -Date: Tue Sep 3 06:29:53 2024 +0000 - - accel/kvm: check for KVM_CAP_READONLY_MEM on VM - - KVM_CAP_READONLY_MEM used to be a global capability, but with the - introduction of AMD SEV-SNP confidential VMs, this extension is not - always available on all VM types [1,2]. - - Query the extension on the VM level instead of on the KVM level. - - [1] https://patchwork.kernel.org/project/kvm/patch/20240809190319.1710470-2-seanjc@google.com/ - [2] https://patchwork.kernel.org/project/kvm/patch/20240902144219.3716974-1-erbse.13@gmx.de/ - - Cc: Paolo Bonzini - Signed-off-by: Tom Dohrmann - Link: https://lore.kernel.org/r/20240903062953.3926498-1-erbse.13@gmx.de - Cc: qemu-stable@nongnu.org - Signed-off-by: Paolo Bonzini - -Signed-off-by: Avadhut Naik ---- - accel/kvm/kvm-all.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 75d11a07b2..acc23092e7 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2603,7 +2603,7 @@ static int kvm_init(MachineState *ms) - } - - kvm_readonly_mem_allowed = -- (kvm_check_extension(s, KVM_CAP_READONLY_MEM) > 0); -+ (kvm_vm_check_extension(s, KVM_CAP_READONLY_MEM) > 0); - - kvm_resamplefds_allowed = - (kvm_check_extension(s, KVM_CAP_IRQFD_RESAMPLE) > 0); --- -2.39.3 - diff --git a/kvm-accel-kvm-refactor-dirty-ring-setup.patch b/kvm-accel-kvm-refactor-dirty-ring-setup.patch deleted file mode 100644 index eb6eb23..0000000 --- a/kvm-accel-kvm-refactor-dirty-ring-setup.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 00a2dbf483a077bb31b1c9f70cced36319d22628 Mon Sep 17 00:00:00 2001 -From: Ani Sinha -Date: Thu, 12 Sep 2024 11:48:38 +0530 -Subject: [PATCH 4/9] accel/kvm: refactor dirty ring setup - -RH-Author: Peter Xu -RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array -RH-Jira: RHEL-57685 -RH-Acked-by: Juraj Marcin -RH-Acked-by: Miroslav Rezanina -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 -Link: https://lore.kernel.org/r/20240912061838.4501-1-anisinha@redhat.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit 28ed7f9761eb273e7dedcfdc0507d158106d0451) -Signed-off-by: Peter Xu ---- - 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 - diff --git a/kvm-arm-create-new-virt-machine-type-for-rhel-9.6.patch b/kvm-arm-create-new-virt-machine-type-for-rhel-9.6.patch deleted file mode 100644 index f32bd03..0000000 --- a/kvm-arm-create-new-virt-machine-type-for-rhel-9.6.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 60d59db99f0527eaf0ce8d3a18d8333aa77a03f2 Mon Sep 17 00:00:00 2001 -From: Sebastian Ott -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 -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 -RH-Acked-by: Cornelia Huck -RH-Acked-by: Eric Auger -RH-Commit: [2/7] 0179f5a7a177f53b58ff9b82bd09217e183f258b (seott1/cos-qemu-kvm) - -Signed-off-by: Sebastian Ott ---- - 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 - diff --git a/kvm-arm-create-virt-machine-type-for-rhel10.patch b/kvm-arm-create-virt-machine-type-for-rhel10.patch deleted file mode 100644 index 422f99a..0000000 --- a/kvm-arm-create-virt-machine-type-for-rhel10.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 704596b05f7dcdfa98857b71fed295d0005d4acc Mon Sep 17 00:00:00 2001 -From: Sebastian Ott -Date: Thu, 22 Aug 2024 17:08:26 +0200 -Subject: [PATCH 5/9] arm: create virt machine type for rhel10 - -RH-Author: Sebastian Ott -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 -RH-Acked-by: Cornelia Huck -RH-Acked-by: Eric Auger -RH-Commit: [5/7] cd8f31de4cd189cd1de69e68c84d823e43473e8c (seott1/cos-qemu-kvm) - -Create a new default virt machine type for rhel 10. - -Signed-off-by: Sebastian Ott ---- - 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 - diff --git a/kvm-arm-disable-pauth-for-virt-rhel9-in-RHEL10.patch b/kvm-arm-disable-pauth-for-virt-rhel9-in-RHEL10.patch deleted file mode 100644 index 0e08a43..0000000 --- a/kvm-arm-disable-pauth-for-virt-rhel9-in-RHEL10.patch +++ /dev/null @@ -1,60 +0,0 @@ -From d36ac428991e700dd5cec62dfa16f1d414a9dda8 Mon Sep 17 00:00:00 2001 -From: Sebastian Ott -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 -RH-MergeRequest: 327: arm: disable pauth for virt-rhel9* in RHEL10 -RH-Jira: RHEL-71761 -RH-Acked-by: Cornelia Huck -RH-Acked-by: Eric Auger -RH-Acked-by: Kashyap Chamarthy -RH-Acked-by: Gavin Shan -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 -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 - diff --git a/kvm-block-Add-active-field-to-BlockDeviceInfo.patch b/kvm-block-Add-active-field-to-BlockDeviceInfo.patch deleted file mode 100644 index 107dc6f..0000000 --- a/kvm-block-Add-active-field-to-BlockDeviceInfo.patch +++ /dev/null @@ -1,317 +0,0 @@ -From 01973563401bf804505e36fecf0c229fd548eda4 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Tue, 4 Feb 2025 22:13:52 +0100 -Subject: [PATCH 07/22] block: Add 'active' field to BlockDeviceInfo - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -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 -Acked-by: Fabiano Rosas -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Message-ID: <20250204211407.381505-2-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit aec81049c2daa8a97b89e59f03733b21ae0f8c2d) -Signed-off-by: Kevin Wolf ---- - 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 - diff --git a/kvm-block-Add-blockdev-set-active-QMP-command.patch b/kvm-block-Add-blockdev-set-active-QMP-command.patch deleted file mode 100644 index 0a25c9f..0000000 --- a/kvm-block-Add-blockdev-set-active-QMP-command.patch +++ /dev/null @@ -1,187 +0,0 @@ -From d2cb8b847b6f88b4cbabea12a0b62f323d9000ff Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Tue, 4 Feb 2025 22:13:59 +0100 -Subject: [PATCH 14/22] block: Add blockdev-set-active QMP command - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -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 -Acked-by: Fabiano Rosas -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Message-ID: <20250204211407.381505-9-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit 8cd37207f8a90c5f995283ecf95f1cb5f7518a77) -Signed-off-by: Kevin Wolf ---- - 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 - diff --git a/kvm-block-Add-new-bdrv_co_is_all_zeroes-function.patch b/kvm-block-Add-new-bdrv_co_is_all_zeroes-function.patch new file mode 100644 index 0000000..456b034 --- /dev/null +++ b/kvm-block-Add-new-bdrv_co_is_all_zeroes-function.patch @@ -0,0 +1,143 @@ +From 659dd2d1f7b1facbf9c548468c1b50237f7aa8e4 Mon Sep 17 00:00:00 2001 +From: Eric Blake +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 +RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors +RH-Jira: RHEL-88435 RHEL-88437 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Stefan Hajnoczi +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 +--- + 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 + diff --git a/kvm-block-Add-option-to-create-inactive-nodes.patch b/kvm-block-Add-option-to-create-inactive-nodes.patch deleted file mode 100644 index 6b42315..0000000 --- a/kvm-block-Add-option-to-create-inactive-nodes.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 990a468ee87adc98bb53d859b52c8a5c7bbb8524 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Tue, 4 Feb 2025 22:13:58 +0100 -Subject: [PATCH 13/22] block: Add option to create inactive nodes - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -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 -Acked-by: Fabiano Rosas -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Message-ID: <20250204211407.381505-8-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit faecd16fe5c65a25b5b55b5edbe4322cec5a9d96) -Signed-off-by: Kevin Wolf ---- - 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 - diff --git a/kvm-block-Allow-inactivating-already-inactive-nodes.patch b/kvm-block-Allow-inactivating-already-inactive-nodes.patch deleted file mode 100644 index a31520b..0000000 --- a/kvm-block-Allow-inactivating-already-inactive-nodes.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 87507aae02f0b381c658a71777baad6fe3129485 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Tue, 4 Feb 2025 22:13:53 +0100 -Subject: [PATCH 08/22] block: Allow inactivating already inactive nodes - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -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 -Acked-by: Fabiano Rosas -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Message-ID: <20250204211407.381505-3-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit a6490ec9d56b9e95a13918813585a3a9891710bc) -Signed-off-by: Kevin Wolf ---- - 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 - diff --git a/kvm-block-Don-t-attach-inactive-child-to-active-node.patch b/kvm-block-Don-t-attach-inactive-child-to-active-node.patch deleted file mode 100644 index 32bcd1d..0000000 --- a/kvm-block-Don-t-attach-inactive-child-to-active-node.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 85c5bd4a41fec70482b634ae2d3bb3c56631e337 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -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 -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -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 -Acked-by: Fabiano Rosas -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Message-ID: <20250204211407.381505-6-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit 9b81361aedcc47905de5e91f68221de89c6f5467) -Signed-off-by: Kevin Wolf ---- - 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 - diff --git a/kvm-block-Drain-nodes-before-inactivating-them.patch b/kvm-block-Drain-nodes-before-inactivating-them.patch deleted file mode 100644 index f931c50..0000000 --- a/kvm-block-Drain-nodes-before-inactivating-them.patch +++ /dev/null @@ -1,52 +0,0 @@ -From e7fa06c5ad14fc4df863265ca4723c9b74368682 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Tue, 4 Feb 2025 22:14:02 +0100 -Subject: [PATCH 17/22] block: Drain nodes before inactivating them - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -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 -Acked-by: Fabiano Rosas -Message-ID: <20250204211407.381505-12-kwolf@redhat.com> -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Signed-off-by: Kevin Wolf -(cherry picked from commit 2849092a0024405e74c96f0a5ec41bb182ec8538) -Signed-off-by: Kevin Wolf ---- - 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 - diff --git a/kvm-block-Expand-block-status-mode-from-bool-to-flags.patch b/kvm-block-Expand-block-status-mode-from-bool-to-flags.patch new file mode 100644 index 0000000..b159e0f --- /dev/null +++ b/kvm-block-Expand-block-status-mode-from-bool-to-flags.patch @@ -0,0 +1,689 @@ +From cb945ccd11d37c959f590ae5661ffe5b73f372a7 Mon Sep 17 00:00:00 2001 +From: Eric Blake +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 +RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors +RH-Jira: RHEL-88435 RHEL-88437 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Stefan Hajnoczi +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 +--- + 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 + diff --git a/kvm-block-Fix-crash-on-block_resize-on-inactive-node.patch b/kvm-block-Fix-crash-on-block_resize-on-inactive-node.patch deleted file mode 100644 index 3f5a967..0000000 --- a/kvm-block-Fix-crash-on-block_resize-on-inactive-node.patch +++ /dev/null @@ -1,68 +0,0 @@ -From fcf20a7c75d01009701fd960247ff76914280e1a Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -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 -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -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 -Acked-by: Fabiano Rosas -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Message-ID: <20250204211407.381505-7-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit 8c2c72a33581987af8d8c484d03af3cd69b9e10a) -Signed-off-by: Kevin Wolf ---- - 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 - diff --git a/kvm-block-Inactivate-external-snapshot-overlays-when-nec.patch b/kvm-block-Inactivate-external-snapshot-overlays-when-nec.patch deleted file mode 100644 index cbd4d87..0000000 --- a/kvm-block-Inactivate-external-snapshot-overlays-when-nec.patch +++ /dev/null @@ -1,68 +0,0 @@ -From b0b5dbd95c73a5cd4173c11d283f6144f0d78e04 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Tue, 4 Feb 2025 22:13:54 +0100 -Subject: [PATCH 09/22] block: Inactivate external snapshot overlays when - necessary - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -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 -Acked-by: Fabiano Rosas -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Message-ID: <20250204211407.381505-4-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit e80210ffb24c4e47650344ba77ce3ed354af596c) -Signed-off-by: Kevin Wolf ---- - 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 - diff --git a/kvm-block-Let-bdrv_co_is_zero_fast-consolidate-adjacent-.patch b/kvm-block-Let-bdrv_co_is_zero_fast-consolidate-adjacent-.patch new file mode 100644 index 0000000..f0a2749 --- /dev/null +++ b/kvm-block-Let-bdrv_co_is_zero_fast-consolidate-adjacent-.patch @@ -0,0 +1,90 @@ +From e101b9872f9b3f6c5e128f29d7c3bb91faca362b Mon Sep 17 00:00:00 2001 +From: Eric Blake +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 +RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors +RH-Jira: RHEL-88435 RHEL-88437 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Stefan Hajnoczi +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 +--- + 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 + diff --git a/kvm-block-Support-inactive-nodes-in-blk_insert_bs.patch b/kvm-block-Support-inactive-nodes-in-blk_insert_bs.patch deleted file mode 100644 index 97d6651..0000000 --- a/kvm-block-Support-inactive-nodes-in-blk_insert_bs.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 1c4cdab823e271cea3bb980eb0b2714f3474c7fa Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -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 -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -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 -Acked-by: Fabiano Rosas -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Message-ID: <20250204211407.381505-10-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit c1c5c7cc4ef6c45ca769c640566fd40d2cb7d5c1) -Signed-off-by: Kevin Wolf ---- - 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 - diff --git a/kvm-block-export-Add-option-to-allow-export-of-inactive-.patch b/kvm-block-export-Add-option-to-allow-export-of-inactive-.patch deleted file mode 100644 index b775673..0000000 --- a/kvm-block-export-Add-option-to-allow-export-of-inactive-.patch +++ /dev/null @@ -1,135 +0,0 @@ -From f4e875181720552ebdb9530e533fbad96b8d01d2 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -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 -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -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 -Acked-by: Fabiano Rosas -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Message-ID: <20250204211407.381505-13-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit 1600ef01ab1296ca8230daa6bc41ba983751f646) -Signed-off-by: Kevin Wolf ---- - 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 - diff --git a/kvm-block-export-Don-t-ignore-image-activation-error-in-.patch b/kvm-block-export-Don-t-ignore-image-activation-error-in-.patch deleted file mode 100644 index 8e57ff7..0000000 --- a/kvm-block-export-Don-t-ignore-image-activation-error-in-.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 7e3b7fff56e0f8f16a898e7d22789ffad4166aca Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -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 -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -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 -Acked-by: Fabiano Rosas -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Message-ID: <20250204211407.381505-11-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit 69f28176ca0af850db23a1c6364f0c8525b20801) -Signed-off-by: Kevin Wolf ---- - 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 - diff --git a/kvm-block-io-skip-head-tail-requests-on-EINVAL.patch b/kvm-block-io-skip-head-tail-requests-on-EINVAL.patch new file mode 100644 index 0000000..9650c04 --- /dev/null +++ b/kvm-block-io-skip-head-tail-requests-on-EINVAL.patch @@ -0,0 +1,74 @@ +From 8d520ef6e8959a017535ecfc556b067e4b118cb7 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +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 +RH-MergeRequest: 354: file-posix: probe discard alignment on Linux block devices +RH-Jira: RHEL-87642 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Eric Blake +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 +Reviewed-by: Hanna Czenczek +Message-ID: <20250417150528.76470-3-stefanha@redhat.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit 4733cb0833c4b223f92ec0136980eeb5239ecb87) +Signed-off-by: Stefan Hajnoczi +--- + 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 + diff --git a/kvm-block-mark-bdrv_child_change_aio_context-GRAPH_RDLOC.patch b/kvm-block-mark-bdrv_child_change_aio_context-GRAPH_RDLOC.patch new file mode 100644 index 0000000..a39df88 --- /dev/null +++ b/kvm-block-mark-bdrv_child_change_aio_context-GRAPH_RDLOC.patch @@ -0,0 +1,49 @@ +From 9e52d5e0ac43c31ca39c7e1ac41bf5bcb179f848 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Reviewed-by: Kevin Wolf +Message-ID: <20250530151125.955508-8-f.ebner@proxmox.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit 469422c45b3a816eaf36e7edc895c81e0f3d38bb) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-mark-bdrv_drained_begin-and-friends-as-GRAPH_U.patch b/kvm-block-mark-bdrv_drained_begin-and-friends-as-GRAPH_U.patch new file mode 100644 index 0000000..f1bad96 --- /dev/null +++ b/kvm-block-mark-bdrv_drained_begin-and-friends-as-GRAPH_U.patch @@ -0,0 +1,62 @@ +From e002888564647162c7796075ef7bdc14c0dc29fc Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Signed-off-by: Fiona Ebner +Message-ID: <20250530151125.955508-20-f.ebner@proxmox.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit fc1d2f3eac7946658b160db0b813b81288fb1778) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-mark-bdrv_parent_change_aio_context-GRAPH_RDLO.patch b/kvm-block-mark-bdrv_parent_change_aio_context-GRAPH_RDLO.patch new file mode 100644 index 0000000..1524fb9 --- /dev/null +++ b/kvm-block-mark-bdrv_parent_change_aio_context-GRAPH_RDLO.patch @@ -0,0 +1,49 @@ +From 191a72ef2a40d7bd14c5ad3745f1dfccbbf95817 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Reviewed-by: Kevin Wolf +Message-ID: <20250530151125.955508-6-f.ebner@proxmox.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit 3758733959af93b5eb3283659d868ad5b24152b4) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-mark-change_aio_ctx-callback-and-instances-as-.patch b/kvm-block-mark-change_aio_ctx-callback-and-instances-as-.patch new file mode 100644 index 0000000..ac0fbd7 --- /dev/null +++ b/kvm-block-mark-change_aio_ctx-callback-and-instances-as-.patch @@ -0,0 +1,103 @@ +From 1c72dbd318b6c15d7a7cbc14a270056a5cb6b182 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Reviewed-by: Kevin Wolf +Message-ID: <20250530151125.955508-7-f.ebner@proxmox.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit 844d550d09ac29ff2b1b49069587ae6a989df31d) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-move-drain-outside-of-bdrv_attach_child.patch b/kvm-block-move-drain-outside-of-bdrv_attach_child.patch new file mode 100644 index 0000000..43037d0 --- /dev/null +++ b/kvm-block-move-drain-outside-of-bdrv_attach_child.patch @@ -0,0 +1,326 @@ +From 62e8b3e9173ea4fb85cf52c66109832ff9d4d437 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Reviewed-by: Kevin Wolf +Message-ID: <20250530151125.955508-14-f.ebner@proxmox.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit 77f3965ba7fed5b35212171a1e41c20c05a7ef11) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-move-drain-outside-of-bdrv_attach_child_common.patch b/kvm-block-move-drain-outside-of-bdrv_attach_child_common.patch new file mode 100644 index 0000000..3cecf05 --- /dev/null +++ b/kvm-block-move-drain-outside-of-bdrv_attach_child_common.patch @@ -0,0 +1,260 @@ +From faa96d060a393458e2e1f9ba77c53adf7d52bc85 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Message-ID: <20250530151125.955508-11-f.ebner@proxmox.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit 2b833595aa21679145cfe67ba720113b165c19ef) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-move-drain-outside-of-bdrv_change_aio_context-.patch b/kvm-block-move-drain-outside-of-bdrv_change_aio_context-.patch new file mode 100644 index 0000000..14cd101 --- /dev/null +++ b/kvm-block-move-drain-outside-of-bdrv_change_aio_context-.patch @@ -0,0 +1,269 @@ +From c5b0d95edea3d1e2ef47804e0c6fe19ade4dcaed Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Signed-off-by: Fiona Ebner +Reviewed-by: Kevin Wolf +Message-ID: <20250530151125.955508-9-f.ebner@proxmox.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit 91ba0e1c382bd4a4b9c6a200f8a175d6ff30ab99) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-move-drain-outside-of-bdrv_root_attach_child.patch b/kvm-block-move-drain-outside-of-bdrv_root_attach_child.patch new file mode 100644 index 0000000..3cb6ca8 --- /dev/null +++ b/kvm-block-move-drain-outside-of-bdrv_root_attach_child.patch @@ -0,0 +1,283 @@ +From 4629f2201a220c7775df5a305f22d51ba7a34641 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Reviewed-by: Kevin Wolf +Message-ID: <20250530151125.955508-13-f.ebner@proxmox.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit ffdcd081f52544f065020c780a6c522dace6b0af) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-move-drain-outside-of-bdrv_root_unref_child.patch b/kvm-block-move-drain-outside-of-bdrv_root_unref_child.patch new file mode 100644 index 0000000..bafe83f --- /dev/null +++ b/kvm-block-move-drain-outside-of-bdrv_root_unref_child.patch @@ -0,0 +1,405 @@ +From 1ad00825750a515baf5bd9185bbc31549a61568b Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Message-ID: <20250530151125.955508-16-f.ebner@proxmox.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit b13f54654546cbc0661d3fe9d25f7543535c2bee) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-move-drain-outside-of-bdrv_set_backing_hd_drai.patch b/kvm-block-move-drain-outside-of-bdrv_set_backing_hd_drai.patch new file mode 100644 index 0000000..e64b8e9 --- /dev/null +++ b/kvm-block-move-drain-outside-of-bdrv_set_backing_hd_drai.patch @@ -0,0 +1,123 @@ +From e3a722681805290fced1cde3d4ac991f8278f158 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Message-ID: <20250530151125.955508-12-f.ebner@proxmox.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit e66dbda11eab2b4a091d470f3508a4d6ca60eaf5) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-move-drain-outside-of-bdrv_try_change_aio_cont.patch b/kvm-block-move-drain-outside-of-bdrv_try_change_aio_cont.patch new file mode 100644 index 0000000..8861e99 --- /dev/null +++ b/kvm-block-move-drain-outside-of-bdrv_try_change_aio_cont.patch @@ -0,0 +1,257 @@ +From 0fc67b52f8d95a10d0bbc1d49eaf2f93c603d967 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Reviewed-by: Kevin Wolf +Message-ID: <20250530151125.955508-10-f.ebner@proxmox.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit a1ea8eb5912256c0b2be16fae5d3786aebc80cb1) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-move-drain-outside-of-quorum_add_child.patch b/kvm-block-move-drain-outside-of-quorum_add_child.patch new file mode 100644 index 0000000..a4edd01 --- /dev/null +++ b/kvm-block-move-drain-outside-of-quorum_add_child.patch @@ -0,0 +1,120 @@ +From af295ac08ffca4efd6f10a2d1a38eaa8d09d8e6f Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Message-ID: <20250530151125.955508-15-f.ebner@proxmox.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit 0414930d3adfa89299eaea5ce92accab15d9fba5) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-move-drain-outside-of-quorum_del_child.patch b/kvm-block-move-drain-outside-of-quorum_del_child.patch new file mode 100644 index 0000000..c06c556 --- /dev/null +++ b/kvm-block-move-drain-outside-of-quorum_del_child.patch @@ -0,0 +1,85 @@ +From de70d5b485006ecd92e860242634a3166b709fa8 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Message-ID: <20250530151125.955508-17-f.ebner@proxmox.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit d75f8ed1d7fc27cf1643e549cd006a68d3bf6ef1) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-move-drain-outside-of-read-locked-bdrv_inactiv.patch b/kvm-block-move-drain-outside-of-read-locked-bdrv_inactiv.patch new file mode 100644 index 0000000..5504b27 --- /dev/null +++ b/kvm-block-move-drain-outside-of-read-locked-bdrv_inactiv.patch @@ -0,0 +1,106 @@ +From a4f11515016abb663e37c9796ef4655d5e7e831b Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Reviewed-by: Kevin Wolf +Message-ID: <20250530151125.955508-5-f.ebner@proxmox.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit 841998e08650f5b4476fa2d1eb84a592ab405f51) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-move-drain-outside-of-read-locked-bdrv_reopen_.patch b/kvm-block-move-drain-outside-of-read-locked-bdrv_reopen_.patch new file mode 100644 index 0000000..03d8bbc --- /dev/null +++ b/kvm-block-move-drain-outside-of-read-locked-bdrv_reopen_.patch @@ -0,0 +1,87 @@ +From c5eb44ccd03e327f15977acccfeaf23a047e0dc6 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Reviewed-by: Kevin Wolf +Message-ID: <20250530151125.955508-3-f.ebner@proxmox.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit e1d681b3e1d8256047dbfc6d2c796028b9694eaf) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-remove-outdated-comments-about-AioContext-lock.patch b/kvm-block-remove-outdated-comments-about-AioContext-lock.patch new file mode 100644 index 0000000..9d1219b --- /dev/null +++ b/kvm-block-remove-outdated-comments-about-AioContext-lock.patch @@ -0,0 +1,61 @@ +From 055168058f614c9f3b8be6c0692794a6299420ab Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +Date: Fri, 30 May 2025 17:10:38 +0200 +Subject: [PATCH 13/33] block: remove outdated comments about AioContext + locking + +RH-Author: Kevin Wolf +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Reviewed-by: Kevin Wolf +Message-ID: <20250530151125.955508-2-f.ebner@proxmox.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit f1bf3be14bd5d6e6a2cfbbe64cdd4d58a8595d68) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-block-skip-automatic-zero-init-of-large-array-in-ioq.patch b/kvm-block-skip-automatic-zero-init-of-large-array-in-ioq.patch index 996b93d..65204cf 100644 --- a/kvm-block-skip-automatic-zero-init-of-large-array-in-ioq.patch +++ b/kvm-block-skip-automatic-zero-init-of-large-array-in-ioq.patch @@ -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?= 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 -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 -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 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) diff --git a/kvm-block-snapshot-move-drain-outside-of-read-locked-bdr.patch b/kvm-block-snapshot-move-drain-outside-of-read-locked-bdr.patch new file mode 100644 index 0000000..3f4f810 --- /dev/null +++ b/kvm-block-snapshot-move-drain-outside-of-read-locked-bdr.patch @@ -0,0 +1,231 @@ +From 5c8408a7d6b0f7a66de2bfa31ef228b1817200ec Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Reviewed-by: Kevin Wolf +Message-ID: <20250530151125.955508-4-f.ebner@proxmox.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit d4c5f8c980f1073356d2f18d51dc68d42bebb59d) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-blockdev-drain-while-unlocked-in-external_snapshot_a.patch b/kvm-blockdev-drain-while-unlocked-in-external_snapshot_a.patch new file mode 100644 index 0000000..bf2907b --- /dev/null +++ b/kvm-blockdev-drain-while-unlocked-in-external_snapshot_a.patch @@ -0,0 +1,70 @@ +From 96407f6d729312c373e9b2ccbf97918d453c7a52 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Message-ID: <20250530151125.955508-19-f.ebner@proxmox.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit 195a8a946a8681dfe7e8aa8d49db415693db5311) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-blockdev-drain-while-unlocked-in-internal_snapshot_a.patch b/kvm-blockdev-drain-while-unlocked-in-internal_snapshot_a.patch new file mode 100644 index 0000000..db9f08a --- /dev/null +++ b/kvm-blockdev-drain-while-unlocked-in-internal_snapshot_a.patch @@ -0,0 +1,80 @@ +From a2b28210cbcbb8e66815d9b38484fde3122a3ab9 Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +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 +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Message-ID: <20250530151125.955508-18-f.ebner@proxmox.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit 6f101614f95c889399352b8301917c0ac7919ae7) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-chardev-char-fd-skip-automatic-zero-init-of-large-ar.patch b/kvm-chardev-char-fd-skip-automatic-zero-init-of-large-ar.patch index f40515a..e073d38 100644 --- a/kvm-chardev-char-fd-skip-automatic-zero-init-of-large-ar.patch +++ b/kvm-chardev-char-fd-skip-automatic-zero-init-of-large-ar.patch @@ -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?= 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 -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 -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 diff --git a/kvm-chardev-char-pty-skip-automatic-zero-init-of-large-a.patch b/kvm-chardev-char-pty-skip-automatic-zero-init-of-large-a.patch index 98d7524..c1b20a2 100644 --- a/kvm-chardev-char-pty-skip-automatic-zero-init-of-large-a.patch +++ b/kvm-chardev-char-pty-skip-automatic-zero-init-of-large-a.patch @@ -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?= 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 -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 -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 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; diff --git a/kvm-chardev-char-socket-skip-automatic-zero-init-of-larg.patch b/kvm-chardev-char-socket-skip-automatic-zero-init-of-larg.patch index ea2b146..c9a6650 100644 --- a/kvm-chardev-char-socket-skip-automatic-zero-init-of-larg.patch +++ b/kvm-chardev-char-socket-skip-automatic-zero-init-of-larg.patch @@ -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?= 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 -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 -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 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) diff --git a/kvm-cpu-Don-t-set-vcpu_dirty-when-guest_state_protected.patch b/kvm-cpu-Don-t-set-vcpu_dirty-when-guest_state_protected.patch new file mode 100644 index 0000000..10269a7 --- /dev/null +++ b/kvm-cpu-Don-t-set-vcpu_dirty-when-guest_state_protected.patch @@ -0,0 +1,40 @@ +From 234f0ccebe9c52b774e85083c0df9dcb3367dcfc Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +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 +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-43-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit b4b7fb5a773e1d2215c2aaa99789eca51914b78f) +Signed-off-by: Paolo Bonzini +--- + 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 + diff --git a/kvm-docs-Add-TDX-documentation.patch b/kvm-docs-Add-TDX-documentation.patch new file mode 100644 index 0000000..d49be6c --- /dev/null +++ b/kvm-docs-Add-TDX-documentation.patch @@ -0,0 +1,214 @@ +From 5120234d30c9e5193961831e659daf7c923a3d79 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +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 +Link: https://lore.kernel.org/r/20250508150002.689633-56-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit dc1424319311f86449c6825ceec2364ee645a363) +Signed-off-by: Paolo Bonzini +--- + 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 `__ ++ ++- `SGX QE `__ +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 + diff --git a/kvm-docs-Don-t-define-duplicate-label-in-qemu-block-driv.patch b/kvm-docs-Don-t-define-duplicate-label-in-qemu-block-driv.patch new file mode 100644 index 0000000..b6628e6 --- /dev/null +++ b/kvm-docs-Don-t-define-duplicate-label-in-qemu-block-driv.patch @@ -0,0 +1,71 @@ +From c73cd0b322ad22a4ba47035ba87a0e83ff851b6a Mon Sep 17 00:00:00 2001 +From: Peter Maydell +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 +Signed-off-by: Peter Maydell +Acked-by: Eric Blake +Reviewed-by: Pierrick Bouvier +Message-id: 20250501093126.716667-1-peter.maydell@linaro.org +Signed-off-by: Miroslav Rezanina +--- + 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 `_: + `Monitor ` implementation (HMP & QMP). + * `nbd `_: +- QEMU `NBD (Network Block Device) ` server. ++ QEMU NBD (Network Block Device) server. + * `net `_: + Network (host) support. + * `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 + diff --git a/kvm-docs-system-Update-documentation-for-s390x-IPL.patch b/kvm-docs-system-Update-documentation-for-s390x-IPL.patch deleted file mode 100644 index f0060a6..0000000 --- a/kvm-docs-system-Update-documentation-for-s390x-IPL.patch +++ /dev/null @@ -1,76 +0,0 @@ -From f1359f43bbc61f31c292ca1770688b6db6b959af Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:52 -0400 -Subject: [PATCH 20/38] docs/system: Update documentation for s390x IPL -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [19/23] 8dfc0357ec42e9baac741670f6e7da3127de0e50 (thuth/qemu-kvm-cs9) - -Update docs to show that s390x PC BIOS can support more than one boot device. - -Signed-off-by: Jared Rossi -Reviewed-by: Thomas Huth -Message-ID: <20241020012953.1380075-19-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 0bd107138ff0b171e3cd314dbc200950bcab2b05) ---- - docs/system/bootindex.rst | 7 ++++--- - docs/system/s390x/bootdevices.rst | 9 ++++++--- - 2 files changed, 10 insertions(+), 6 deletions(-) - -diff --git a/docs/system/bootindex.rst b/docs/system/bootindex.rst -index 8b057f812f..988f7b3beb 100644 ---- a/docs/system/bootindex.rst -+++ b/docs/system/bootindex.rst -@@ -49,10 +49,11 @@ Limitations - ----------- - - Some firmware has limitations on which devices can be considered for --booting. For instance, the PC BIOS boot specification allows only one --disk to be bootable. If boot from disk fails for some reason, the BIOS -+booting. For instance, the x86 PC BIOS boot specification allows only one -+disk to be bootable. If boot from disk fails for some reason, the x86 BIOS - won't retry booting from other disk. It can still try to boot from --floppy or net, though. -+floppy or net, though. In the case of s390x BIOS, the BIOS will try up to -+8 total devices, any number of which may be disks. - - Sometimes, firmware cannot map the device path QEMU wants firmware to - boot from to a boot method. It doesn't happen for devices the firmware -diff --git a/docs/system/s390x/bootdevices.rst b/docs/system/s390x/bootdevices.rst -index c97efb8fc0..1a1a764c1c 100644 ---- a/docs/system/s390x/bootdevices.rst -+++ b/docs/system/s390x/bootdevices.rst -@@ -6,9 +6,7 @@ Booting with bootindex parameter - - For classical mainframe guests (i.e. LPAR or z/VM installations), you always - have to explicitly specify the disk where you want to boot from (or "IPL" from, --in s390x-speak -- IPL means "Initial Program Load"). In particular, there can --also be only one boot device according to the architecture specification, thus --specifying multiple boot devices is not possible (yet). -+in s390x-speak -- IPL means "Initial Program Load"). - - So for booting an s390x guest in QEMU, you should always mark the - device where you want to boot from with the ``bootindex`` property, for -@@ -17,6 +15,11 @@ example:: - qemu-system-s390x -drive if=none,id=dr1,file=guest.qcow2 \ - -device virtio-blk,drive=dr1,bootindex=1 - -+Multiple devices may have a bootindex. The lowest bootindex is assigned to the -+device to IPL first. If the IPL fails for the first, the device with the second -+lowest bootindex will be tried and so on until IPL is successful or there are no -+remaining boot devices to try. -+ - For booting from a CD-ROM ISO image (which needs to include El-Torito boot - information in order to be bootable), it is recommended to specify a ``scsi-cd`` - device, for example like this:: --- -2.39.3 - diff --git a/kvm-docs-system-bootindex-Make-it-clear-that-s390x-can-a.patch b/kvm-docs-system-bootindex-Make-it-clear-that-s390x-can-a.patch deleted file mode 100644 index 0aff652..0000000 --- a/kvm-docs-system-bootindex-Make-it-clear-that-s390x-can-a.patch +++ /dev/null @@ -1,41 +0,0 @@ -From ba9b7c8375aac784fbe23beaeb91484ddd8e6829 Mon Sep 17 00:00:00 2001 -From: Thomas Huth -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 -RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature -RH-Jira: RHEL-68444 -RH-Acked-by: Miroslav Rezanina -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 -Message-ID: <20241111105506.264640-1-thuth@redhat.com> -Reviewed-by: Prasad Pandit -Reviewed-by: Boris Fiuczynski -Signed-off-by: Thomas Huth -(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 - diff --git a/kvm-docs-system-s390x-bootdevices-Update-loadparm-docume.patch b/kvm-docs-system-s390x-bootdevices-Update-loadparm-docume.patch deleted file mode 100644 index 2ab3221..0000000 --- a/kvm-docs-system-s390x-bootdevices-Update-loadparm-docume.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 3c57b3a6d48d7ddad44b67fdf9ccaebc40e5c125 Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Thu, 14 Nov 2024 19:27:42 -0500 -Subject: [PATCH 2/9] docs/system/s390x/bootdevices: Update loadparm - documentation - -RH-Author: Thomas Huth -RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature -RH-Jira: RHEL-68444 -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/8] bd74a0794bf0f2872061850ca410bab819c6a0d6 (thuth/qemu-kvm-cs9) - -Update documentation to include per-device loadparm support. - -Signed-off-by: Jared Rossi -Reviewed-by: Thomas Huth -Message-ID: <20241115002742.3576842-1-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(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 - diff --git a/kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch b/kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch deleted file mode 100644 index 808cd33..0000000 --- a/kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch +++ /dev/null @@ -1,66 +0,0 @@ -From c8e615cf130743ee95a61d7e21bb4b753eb082fb Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:40 -0400 -Subject: [PATCH 08/38] docs/system/s390x/bootdevices: Update the documentation - about network booting -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [7/23] 52d357df45400b983e17cc6b1eeac691131bf5e5 (thuth/qemu-kvm-cs9) - -Remove the information about the separate s390-netboot.img from -the documentation. - -Co-authored by: Thomas Huth -Signed-off-by: Jared Rossi -Message-ID: <20241020012953.1380075-7-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit ab2691b6c7ff360875e0af86ff463278f17786f5) ---- - docs/system/s390x/bootdevices.rst | 20 +++++++------------- - 1 file changed, 7 insertions(+), 13 deletions(-) - -diff --git a/docs/system/s390x/bootdevices.rst b/docs/system/s390x/bootdevices.rst -index 1a7a18b43b..c97efb8fc0 100644 ---- a/docs/system/s390x/bootdevices.rst -+++ b/docs/system/s390x/bootdevices.rst -@@ -82,23 +82,17 @@ Note that ``0`` can be used to boot the default entry. - Booting from a network device - ----------------------------- - --Beside the normal guest firmware (which is loaded from the file ``s390-ccw.img`` --in the data directory of QEMU, or via the ``-bios`` option), QEMU ships with --a small TFTP network bootloader firmware for virtio-net-ccw devices, too. This --firmware is loaded from a file called ``s390-netboot.img`` in the QEMU data --directory. In case you want to load it from a different filename instead, --you can specify it via the ``-global s390-ipl.netboot_fw=filename`` --command line option. -- --The ``bootindex`` property is especially important for booting via the network. --If you don't specify the ``bootindex`` property here, the network bootloader --firmware code won't get loaded into the guest memory so that the network boot --will fail. For a successful network boot, try something like this:: -+The firmware that ships with QEMU includes a small TFTP network bootloader -+for virtio-net-ccw devices. The ``bootindex`` property is especially -+important for booting via the network. If you don't specify the ``bootindex`` -+property here, the network bootloader won't be taken into consideration and -+the network boot will fail. For a successful network boot, try something -+like this:: - - qemu-system-s390x -netdev user,id=n1,tftp=...,bootfile=... \ - -device virtio-net-ccw,netdev=n1,bootindex=1 - --The network bootloader firmware also has basic support for pxelinux.cfg-style -+The network bootloader also has basic support for pxelinux.cfg-style - configuration files. See the `PXELINUX Configuration page - `__ - for details how to set up the configuration file on your TFTP server. --- -2.39.3 - diff --git a/kvm-file-posix-Define-DM_MPATH_PROBE_PATHS.patch b/kvm-file-posix-Define-DM_MPATH_PROBE_PATHS.patch new file mode 100644 index 0000000..3cfb6a7 --- /dev/null +++ b/kvm-file-posix-Define-DM_MPATH_PROBE_PATHS.patch @@ -0,0 +1,42 @@ +From 42fc4705817fc4d16f2ba785fd29777ed2b7355a Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 29 Apr 2025 17:05:41 +0200 +Subject: [PATCH 1/9] file-posix: Define DM_MPATH_PROBE_PATHS + +RH-Author: Kevin Wolf +RH-MergeRequest: 370: file-posix: Fix multipath failover with SCSI passthrough +RH-Jira: RHEL-65852 +RH-Acked-by: Hanna Czenczek +RH-Acked-by: Stefan Hajnoczi +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 +--- + 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 + diff --git a/kvm-file-posix-Fix-aio-threads-performance-regression-af.patch b/kvm-file-posix-Fix-aio-threads-performance-regression-af.patch new file mode 100644 index 0000000..a077f4f --- /dev/null +++ b/kvm-file-posix-Fix-aio-threads-performance-regression-af.patch @@ -0,0 +1,106 @@ +From 53711e6aad8a6e40426ccef25e911d3cad93220a Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +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 +RH-MergeRequest: 392: file-posix: Fix aio=threads performance regression after enabling FUA +RH-Jira: RHEL-96854 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +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 +Signed-off-by: Kevin Wolf +Message-ID: <20250625085019.27735-1-kwolf@redhat.com> +Reviewed-by: Eric Blake +Signed-off-by: Kevin Wolf +(cherry picked from commit d402da1360c2240e81f0e5fc80ddbfc6238e0da8) +Signed-off-by: Kevin Wolf +--- + 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 + diff --git a/kvm-file-posix-Fix-crash-on-discard_granularity-0.patch b/kvm-file-posix-Fix-crash-on-discard_granularity-0.patch new file mode 100644 index 0000000..d7145e3 --- /dev/null +++ b/kvm-file-posix-Fix-crash-on-discard_granularity-0.patch @@ -0,0 +1,46 @@ +From 4d575970f12462a054a207b593438aff0d40881a Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +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 +RH-MergeRequest: 354: file-posix: probe discard alignment on Linux block devices +RH-Jira: RHEL-87642 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Eric Blake +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 +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Eric Blake +Message-ID: <20250429155654.102735-1-kwolf@redhat.com> +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 71a30d54e6ab1d5c102a8bee2c263414697402ea) +Signed-off-by: Stefan Hajnoczi +--- + 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 + diff --git a/kvm-file-posix-Probe-paths-and-retry-SG_IO-on-potential-.patch b/kvm-file-posix-Probe-paths-and-retry-SG_IO-on-potential-.patch new file mode 100644 index 0000000..23a25f7 --- /dev/null +++ b/kvm-file-posix-Probe-paths-and-retry-SG_IO-on-potential-.patch @@ -0,0 +1,215 @@ +From 35a2470f67cb38c52246974a853d843dbb80b84d Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +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 +RH-MergeRequest: 370: file-posix: Fix multipath failover with SCSI passthrough +RH-Jira: RHEL-65852 +RH-Acked-by: Hanna Czenczek +RH-Acked-by: Stefan Hajnoczi +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 +Message-ID: <20250522130803.34738-1-kwolf@redhat.com> +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Hanna Czenczek +Signed-off-by: Kevin Wolf +(cherry picked from commit bf627788ef17721955bfcfba84209a07ae5f54ea) +Signed-off-by: Kevin Wolf +--- + 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 +@@ -72,6 +73,7 @@ + #include + #endif + #include ++#include + #include + #include + #include +@@ -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 + diff --git a/kvm-file-posix-gluster-Handle-zero-block-status-hint-bet.patch b/kvm-file-posix-gluster-Handle-zero-block-status-hint-bet.patch new file mode 100644 index 0000000..1405719 --- /dev/null +++ b/kvm-file-posix-gluster-Handle-zero-block-status-hint-bet.patch @@ -0,0 +1,64 @@ +From f8d89f67817fa362a3b8ed0721775e353dac8f18 Mon Sep 17 00:00:00 2001 +From: Eric Blake +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 +RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors +RH-Jira: RHEL-88435 RHEL-88437 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +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 +Reviewed-by: Stefan Hajnoczi +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 +--- + 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 + diff --git a/kvm-file-posix-probe-discard-alignment-on-Linux-block-de.patch b/kvm-file-posix-probe-discard-alignment-on-Linux-block-de.patch new file mode 100644 index 0000000..cd24d41 --- /dev/null +++ b/kvm-file-posix-probe-discard-alignment-on-Linux-block-de.patch @@ -0,0 +1,131 @@ +From 2baedec75a8a0daf9e93228795d1e6f2974f4825 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +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 +RH-MergeRequest: 354: file-posix: probe discard alignment on Linux block devices +RH-Jira: RHEL-87642 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Eric Blake +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 +Message-ID: <20250417150528.76470-2-stefanha@redhat.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit f605796aae42885034400c83ed6a9b07cd6d6481) +Signed-off-by: Stefan Hajnoczi +--- + 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 + diff --git a/kvm-headers-Add-definitions-from-UEFI-spec-for-volumes-r.patch b/kvm-headers-Add-definitions-from-UEFI-spec-for-volumes-r.patch new file mode 100644 index 0000000..f0901bd --- /dev/null +++ b/kvm-headers-Add-definitions-from-UEFI-spec-for-volumes-r.patch @@ -0,0 +1,225 @@ +From 8cd2c71be827e01f1bcc6e0e7ad7de2268835265 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +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 +Acked-by: Gerd Hoffmann +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-23-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 88aa6576e4ab40b538f543852128cb17fce37f87) +Signed-off-by: Paolo Bonzini +--- + 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 ++ * ++ * Xiaoyao Li ++ * ++ * 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 + diff --git a/kvm-hostmem-Apply-merge-property-after-the-memory-region.patch b/kvm-hostmem-Apply-merge-property-after-the-memory-region.patch deleted file mode 100644 index 1f6c8ed..0000000 --- a/kvm-hostmem-Apply-merge-property-after-the-memory-region.patch +++ /dev/null @@ -1,61 +0,0 @@ -From d0163127a47250170e01e39f48250a2725f531c0 Mon Sep 17 00:00:00 2001 -From: Gavin Shan -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 -RH-MergeRequest: 272: hostmem: Apply merge property after the memory region is initialized -RH-Jira: RHEL-58936 -RH-Acked-by: Cornelia Huck -RH-Acked-by: Eric Auger -RH-Acked-by: David Hildenbrand -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 -Tested-by: Zhenyu Zhang -Signed-off-by: Gavin Shan -Signed-off-by: David Hildenbrand -(cherry picked from commit 78c8f780d3f0d6d17aa93d6f99ff72960080fdd7) -Signed-off-by: Gavin Shan ---- - 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 - diff --git a/kvm-hw-Add-loadparm-property-to-scsi-disk-devices-for-bo.patch b/kvm-hw-Add-loadparm-property-to-scsi-disk-devices-for-bo.patch deleted file mode 100644 index 0e7d032..0000000 --- a/kvm-hw-Add-loadparm-property-to-scsi-disk-devices-for-bo.patch +++ /dev/null @@ -1,217 +0,0 @@ -From 4c90ff4c0b48df312c10defba45c9f182b535524 Mon Sep 17 00:00:00 2001 -From: Thomas Huth -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 -RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature -RH-Jira: RHEL-68444 -RH-Acked-by: Miroslav Rezanina -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 -Signed-off-by: Thomas Huth -(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 - diff --git a/kvm-hw-audio-ac97-skip-automatic-zero-init-of-large-arra.patch b/kvm-hw-audio-ac97-skip-automatic-zero-init-of-large-arra.patch index 7fa9b40..848b9c2 100644 --- a/kvm-hw-audio-ac97-skip-automatic-zero-init-of-large-arra.patch +++ b/kvm-hw-audio-ac97-skip-automatic-zero-init-of-large-arra.patch @@ -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?= 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 -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 -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 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) diff --git a/kvm-hw-audio-cs4231a-skip-automatic-zero-init-of-large-a.patch b/kvm-hw-audio-cs4231a-skip-automatic-zero-init-of-large-a.patch index 59e1c54..9baed12 100644 --- a/kvm-hw-audio-cs4231a-skip-automatic-zero-init-of-large-a.patch +++ b/kvm-hw-audio-cs4231a-skip-automatic-zero-init-of-large-a.patch @@ -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?= 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 -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 -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 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, diff --git a/kvm-hw-audio-es1370-skip-automatic-zero-init-of-large-ar.patch b/kvm-hw-audio-es1370-skip-automatic-zero-init-of-large-ar.patch index 8719eff..f3cab17 100644 --- a/kvm-hw-audio-es1370-skip-automatic-zero-init-of-large-ar.patch +++ b/kvm-hw-audio-es1370-skip-automatic-zero-init-of-large-ar.patch @@ -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?= 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 -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 -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 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) diff --git a/kvm-hw-audio-gus-skip-automatic-zero-init-of-large-array.patch b/kvm-hw-audio-gus-skip-automatic-zero-init-of-large-array.patch index 356b2a1..7530880 100644 --- a/kvm-hw-audio-gus-skip-automatic-zero-init-of-large-array.patch +++ b/kvm-hw-audio-gus-skip-automatic-zero-init-of-large-array.patch @@ -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?= 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 -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 -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 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) diff --git a/kvm-hw-audio-marvell_88w8618-skip-automatic-zero-init-of.patch b/kvm-hw-audio-marvell_88w8618-skip-automatic-zero-init-of.patch index ac0ec9d..7d596bc 100644 --- a/kvm-hw-audio-marvell_88w8618-skip-automatic-zero-init-of.patch +++ b/kvm-hw-audio-marvell_88w8618-skip-automatic-zero-init-of.patch @@ -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?= 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 -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 -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 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) diff --git a/kvm-hw-audio-sb16-skip-automatic-zero-init-of-large-arra.patch b/kvm-hw-audio-sb16-skip-automatic-zero-init-of-large-arra.patch index 1a2c736..f550b32 100644 --- a/kvm-hw-audio-sb16-skip-automatic-zero-init-of-large-arra.patch +++ b/kvm-hw-audio-sb16-skip-automatic-zero-init-of-large-arra.patch @@ -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?= 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 -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 -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 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, diff --git a/kvm-hw-audio-via-ac97-skip-automatic-zero-init-of-large-.patch b/kvm-hw-audio-via-ac97-skip-automatic-zero-init-of-large-.patch index 2c7aeaf..dea7ff7 100644 --- a/kvm-hw-audio-via-ac97-skip-automatic-zero-init-of-large-.patch +++ b/kvm-hw-audio-via-ac97-skip-automatic-zero-init-of-large-.patch @@ -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?= 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 -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 -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 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) diff --git a/kvm-hw-char-pl011-Use-correct-masks-for-IBRD-and-FBRD.patch b/kvm-hw-char-pl011-Use-correct-masks-for-IBRD-and-FBRD.patch deleted file mode 100644 index 22d55ce..0000000 --- a/kvm-hw-char-pl011-Use-correct-masks-for-IBRD-and-FBRD.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 133805a36691de83f0ca29165a2312d5ad4f0757 Mon Sep 17 00:00:00 2001 -From: Peter Maydell -Date: Mon, 14 Oct 2024 17:05:53 +0100 -Subject: [PATCH 18/18] hw/char/pl011: Use correct masks for IBRD and FBRD -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: sansshar -RH-MergeRequest: 311: hw/char/pl011: Use correct masks for IBRD and FBRD -RH-Jira: RHEL-67108 -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/1] e615ca34db8ee95533eba8cd671d620112e80cfb (sansshar/qemu-kvm-centos) - -JIRA: RHEL-67108 -Brew build id: 5099404 - -In commit b88cfee90268cad we defined masks for the IBRD and FBRD -integer and fractional baud rate divider registers, to prevent the -guest from writing invalid values which could cause division-by-zero. -Unfortunately we got the mask values the wrong way around: the FBRD -register is six bits and the IBRD register is 16 bits, not -vice-versa. - -You would only run into this bug if you programmed the UART to a baud -rate of less than 9600, because for 9600 baud and above the IBRD -value will fit into 6 bits, as per the table in - https://developer.arm.com/documentation/ddi0183/g/programmers-model/register-descriptions/fractional-baud-rate-register--uartfbrd - -The only visible effects would be that the value read back from -the register by the guest would be truncated, and we would -print an incorrect baud rate in the debug logs. - -Cc: qemu-stable@nongnu.org -Fixes: b88cfee90268 ("hw/char/pl011: Avoid division-by-zero in pl011_get_baudrate()") -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2610 -Signed-off-by: Peter Maydell -Reviewed-by: Alex BennĂ©e -Reviewed-by: Philippe Mathieu-DaudĂ© -Reviewed-by: Gavin Shan -Message-id: 20241007144732.2491331-1-peter.maydell@linaro.org -(cherry picked from commit cd247eae16ab1b9ce97fd34c000c1b883feeda45) -Signed-off-by: Sana Sharma ---- - hw/char/pl011.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/char/pl011.c b/hw/char/pl011.c -index f8078aa216..949e9d0e0d 100644 ---- a/hw/char/pl011.c -+++ b/hw/char/pl011.c -@@ -88,10 +88,10 @@ DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr) - #define CR_LBE (1 << 7) - - /* Integer Baud Rate Divider, UARTIBRD */ --#define IBRD_MASK 0x3f -+#define IBRD_MASK 0xffff - - /* Fractional Baud Rate Divider, UARTFBRD */ --#define FBRD_MASK 0xffff -+#define FBRD_MASK 0x3f - - static const unsigned char pl011_id_arm[8] = - { 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 }; --- -2.39.3 - diff --git a/kvm-hw-char-sclpconsole-lm-skip-automatic-zero-init-of-l.patch b/kvm-hw-char-sclpconsole-lm-skip-automatic-zero-init-of-l.patch index 17e8c0e..77a2ee1 100644 --- a/kvm-hw-char-sclpconsole-lm-skip-automatic-zero-init-of-l.patch +++ b/kvm-hw-char-sclpconsole-lm-skip-automatic-zero-init-of-l.patch @@ -1,17 +1,17 @@ -From 85744cd6690bcdb5538365f6a8e714264b3a9fb1 Mon Sep 17 00:00:00 2001 +From d7f96f00428f759f4323364ca1688988b34c17b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:36:52 +0100 -Subject: [PATCH 15/31] hw/char/sclpconsole-lm: skip automatic zero-init of +Subject: [PATCH 22/43] hw/char/sclpconsole-lm: 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 -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 -RH-Commit: [14/30] e3ba47e29e34cba5727bbea1dae0b1e8eba24203 +RH-Commit: [14/31] 17140f6dae4e1f23ae5d2ba5e320dd8335233a5c (stefanha/centos-stream-qemu-kvm) The 'process_mdb' method has a 4k byte array used for copying data between the guest and the chardev backend. Skip the automatic zero-init @@ -32,7 +32,7 @@ Signed-off-by: Stefan Hajnoczi 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c -index 7719f438f6..19e64b92f6 100644 +index ddb9a726d5..5084531b7b 100644 --- a/hw/char/sclpconsole-lm.c +++ b/hw/char/sclpconsole-lm.c @@ -214,7 +214,7 @@ static int process_mdb(SCLPEvent *event, MDBO *mdbo) diff --git a/kvm-hw-display-vmware_vga-skip-automatic-zero-init-of-la.patch b/kvm-hw-display-vmware_vga-skip-automatic-zero-init-of-la.patch index 08d8782..9f3d30c 100644 --- a/kvm-hw-display-vmware_vga-skip-automatic-zero-init-of-la.patch +++ b/kvm-hw-display-vmware_vga-skip-automatic-zero-init-of-la.patch @@ -1,17 +1,17 @@ -From 2434701b73853adde56d50ab6ccfb4218fb59d3c Mon Sep 17 00:00:00 2001 +From 886a2ce3ff5c05087dc667578d59a37bfedaee19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:36:54 +0100 -Subject: [PATCH 17/31] hw/display/vmware_vga: skip automatic zero-init of +Subject: [PATCH 24/43] hw/display/vmware_vga: skip automatic zero-init of large struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RH-Author: Stefan Hajnoczi -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 -RH-Commit: [16/30] 2c6e05cefbe90cf58d9383d9c0e66ba1c5c5d220 +RH-Commit: [16/31] 201c9ceb2782d17dc9ca800b2d924a8ee3a8eb98 (stefanha/centos-stream-qemu-kvm) The 'vmsvga_fifo_run' method has a struct which is a little over 20k in size, used for holding image data for cursor changes. Skip the @@ -32,7 +32,7 @@ Signed-off-by: Stefan Hajnoczi 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c -index 3db3ff98f7..69afe98a2f 100644 +index 2dd661e3c1..fae10068cb 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -618,7 +618,7 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s) diff --git a/kvm-hw-dma-xlnx_csu_dma-skip-automatic-zero-init-of-larg.patch b/kvm-hw-dma-xlnx_csu_dma-skip-automatic-zero-init-of-larg.patch index dfec547..8bd1537 100644 --- a/kvm-hw-dma-xlnx_csu_dma-skip-automatic-zero-init-of-larg.patch +++ b/kvm-hw-dma-xlnx_csu_dma-skip-automatic-zero-init-of-larg.patch @@ -1,17 +1,17 @@ -From 89410205460c56e7f1dba0cc1106c12ad07aea4e Mon Sep 17 00:00:00 2001 +From 277dbec12b1a109aca6cfe65046f2b4d6b41ee43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:36:53 +0100 -Subject: [PATCH 16/31] hw/dma/xlnx_csu_dma: skip automatic zero-init of large +Subject: [PATCH 23/43] hw/dma/xlnx_csu_dma: 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 -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 -RH-Commit: [15/30] 159936c3a88e61bfe2ceb641ffe330f9e4f31705 +RH-Commit: [15/31] 8832791cb87b342e3b9882893891a824d31b687a (stefanha/centos-stream-qemu-kvm) The 'xlnx_csu_dma_src_notify' method has a 4k byte array used for copying DMA data. Skip the automatic zero-init of this array to @@ -30,7 +30,7 @@ Signed-off-by: Stefan Hajnoczi 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c -index ae307482f2..9d1cccc5ca 100644 +index 1afaa0bf51..8091a785cc 100644 --- a/hw/dma/xlnx_csu_dma.c +++ b/hw/dma/xlnx_csu_dma.c @@ -287,7 +287,7 @@ static uint32_t xlnx_csu_dma_advance(XlnxCSUDMA *s, uint32_t len) diff --git a/kvm-hw-hyperv-syndbg-skip-automatic-zero-init-of-large-a.patch b/kvm-hw-hyperv-syndbg-skip-automatic-zero-init-of-large-a.patch index 0934d47..352c72d 100644 --- a/kvm-hw-hyperv-syndbg-skip-automatic-zero-init-of-large-a.patch +++ b/kvm-hw-hyperv-syndbg-skip-automatic-zero-init-of-large-a.patch @@ -1,17 +1,17 @@ -From 57be097713e549150f57daec1661bd324bd3cb52 Mon Sep 17 00:00:00 2001 +From 6ae70910d16ef313e4addefea33c00083cc5665c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:36:55 +0100 -Subject: [PATCH 18/31] hw/hyperv/syndbg: skip automatic zero-init of large +Subject: [PATCH 25/43] hw/hyperv/syndbg: 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 -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 -RH-Commit: [17/30] f4c7f618f3918f5c24bc9f9ac7963e239227ddf9 +RH-Commit: [17/31] 2c7e0765ddb0fe5880403b234c299931da6daabf (stefanha/centos-stream-qemu-kvm) The 'handle_recv_msg' method has a 4k byte array used for copying data between the network socket and guest memory. Skip the automatic @@ -39,7 +39,7 @@ Conflicts: 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/hyperv/syndbg.c b/hw/hyperv/syndbg.c -index 065e12fb1e..c7c43c8009 100644 +index d3e3917077..16ed1ab66b 100644 --- a/hw/hyperv/syndbg.c +++ b/hw/hyperv/syndbg.c @@ -188,7 +188,7 @@ static uint16_t handle_recv_msg(HvSynDbg *syndbg, uint64_t outgpa, diff --git a/kvm-hw-i386-Fix-machine-type-compatibility.patch b/kvm-hw-i386-Fix-machine-type-compatibility.patch deleted file mode 100644 index 8dd4c0d..0000000 --- a/kvm-hw-i386-Fix-machine-type-compatibility.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0b9f4431e9b7959044fac25f49bc92943737760f Mon Sep 17 00:00:00 2001 -From: Sebastian Ott -Date: Fri, 16 May 2025 13:01:06 +0200 -Subject: [PATCH] hw/i386: Fix machine type compatibility - -RH-Author: Sebastian Ott -RH-MergeRequest: 453: hw/i386: Fix machine type compatibility -RH-Jira: RHEL-92430 -RH-Acked-by: Cornelia Huck -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/1] f41bb758603453ef6e03b57f144b998b83b5fe04 - -Upstream Status: RHEL only - -Ensure compatibility of rhel specific pc-q35-rhel9.4.0 machine type. -Pick up missing bits from pc_compat_9_0 upstream. - -Signed-off-by: Sebastian Ott ---- - hw/i386/pc.c | 10 ++++++++++ - hw/i386/pc_q35.c | 2 ++ - include/hw/i386/pc.h | 3 +++ - 3 files changed, 15 insertions(+) - -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index 7af762065f..3447e44b97 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -298,6 +298,16 @@ GlobalProperty pc_rhel_compat[] = { - }; - const size_t pc_rhel_compat_len = G_N_ELEMENTS(pc_rhel_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" }, -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index b2b8124225..4a326f2f99 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -714,6 +714,8 @@ static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m) - - compat_props_add(m->compat_props, hw_compat_rhel_10_0, - hw_compat_rhel_10_0_len); -+ compat_props_add(m->compat_props, pc_rhel_10_0_compat, -+ pc_rhel_10_0_compat_len); - compat_props_add(m->compat_props, hw_compat_rhel_9_5, - hw_compat_rhel_9_5_len); - } -diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index 61609027d0..2befb4453a 100644 ---- a/include/hw/i386/pc.h -+++ b/include/hw/i386/pc.h -@@ -305,6 +305,9 @@ extern const size_t pc_compat_2_3_len; - extern GlobalProperty pc_rhel_compat[]; - extern const size_t pc_rhel_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; - --- -2.39.3 - diff --git a/kvm-hw-i386-amd_iommu-Allow-migration-when-explicitly-cr.patch b/kvm-hw-i386-amd_iommu-Allow-migration-when-explicitly-cr.patch new file mode 100644 index 0000000..34a65b6 --- /dev/null +++ b/kvm-hw-i386-amd_iommu-Allow-migration-when-explicitly-cr.patch @@ -0,0 +1,117 @@ +From c295cfa98a464eba271e75846275913a0ed6435a Mon Sep 17 00:00:00 2001 +From: Suravee Suthikulpanit +Date: Sun, 4 May 2025 17:04:05 +0000 +Subject: [PATCH 41/43] hw/i386/amd_iommu: Allow migration when explicitly + create the AMDVI-PCI device + +RH-Author: John Allen +RH-MergeRequest: 383: Add ability to manually specify the AMDVI-PCI device +RH-Jira: RHEL-85649 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [2/3] ee1cdd746a3b7051dc1e7c5748876384320a3f28 (johnalle/qemu-kvm-fork) + +Add migration support for AMD IOMMU model by saving necessary AMDVIState +parameters for MMIO registers, device table, command buffer, and event +buffers. + +Also change devtab_len type from size_t to uint64_t to avoid 32-bit build +issue. + +Signed-off-by: Suravee Suthikulpanit +Message-Id: <20250504170405.12623-3-suravee.suthikulpanit@amd.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 28931c2e1591deb4bfaaf744fdc8813e96c230f1) + +JIRA: https://issues.redhat.com/browse/RHEL-85649 + +Signed-off-by: John Allen +--- + hw/i386/amd_iommu.c | 48 +++++++++++++++++++++++++++++++++++++++++++++ + hw/i386/amd_iommu.h | 2 +- + 2 files changed, 49 insertions(+), 1 deletion(-) + +diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c +index da5313f3d2..fbe0be440e 100644 +--- a/hw/i386/amd_iommu.c ++++ b/hw/i386/amd_iommu.c +@@ -1611,8 +1611,55 @@ static void amdvi_sysbus_reset(DeviceState *dev) + amdvi_init(s); + } + ++static const VMStateDescription vmstate_amdvi_sysbus_migratable = { ++ .name = "amd-iommu", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .priority = MIG_PRI_IOMMU, ++ .fields = (VMStateField[]) { ++ /* Updated in amdvi_handle_control_write() */ ++ VMSTATE_BOOL(enabled, AMDVIState), ++ VMSTATE_BOOL(ga_enabled, AMDVIState), ++ VMSTATE_BOOL(ats_enabled, AMDVIState), ++ VMSTATE_BOOL(cmdbuf_enabled, AMDVIState), ++ VMSTATE_BOOL(completion_wait_intr, AMDVIState), ++ VMSTATE_BOOL(evtlog_enabled, AMDVIState), ++ VMSTATE_BOOL(evtlog_intr, AMDVIState), ++ /* Updated in amdvi_handle_devtab_write() */ ++ VMSTATE_UINT64(devtab, AMDVIState), ++ VMSTATE_UINT64(devtab_len, AMDVIState), ++ /* Updated in amdvi_handle_cmdbase_write() */ ++ VMSTATE_UINT64(cmdbuf, AMDVIState), ++ VMSTATE_UINT64(cmdbuf_len, AMDVIState), ++ /* Updated in amdvi_handle_cmdhead_write() */ ++ VMSTATE_UINT32(cmdbuf_head, AMDVIState), ++ /* Updated in amdvi_handle_cmdtail_write() */ ++ VMSTATE_UINT32(cmdbuf_tail, AMDVIState), ++ /* Updated in amdvi_handle_evtbase_write() */ ++ VMSTATE_UINT64(evtlog, AMDVIState), ++ VMSTATE_UINT32(evtlog_len, AMDVIState), ++ /* Updated in amdvi_handle_evthead_write() */ ++ VMSTATE_UINT32(evtlog_head, AMDVIState), ++ /* Updated in amdvi_handle_evttail_write() */ ++ VMSTATE_UINT32(evtlog_tail, AMDVIState), ++ /* Updated in amdvi_handle_pprbase_write() */ ++ VMSTATE_UINT64(ppr_log, AMDVIState), ++ VMSTATE_UINT32(pprlog_len, AMDVIState), ++ /* Updated in amdvi_handle_pprhead_write() */ ++ VMSTATE_UINT32(pprlog_head, AMDVIState), ++ /* Updated in amdvi_handle_tailhead_write() */ ++ VMSTATE_UINT32(pprlog_tail, AMDVIState), ++ /* MMIO registers */ ++ VMSTATE_UINT8_ARRAY(mmior, AMDVIState, AMDVI_MMIO_SIZE), ++ VMSTATE_UINT8_ARRAY(romask, AMDVIState, AMDVI_MMIO_SIZE), ++ VMSTATE_UINT8_ARRAY(w1cmask, AMDVIState, AMDVI_MMIO_SIZE), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ + static void amdvi_sysbus_realize(DeviceState *dev, Error **errp) + { ++ DeviceClass *dc = (DeviceClass *) object_get_class(OBJECT(dev)); + AMDVIState *s = AMD_IOMMU_DEVICE(dev); + MachineState *ms = MACHINE(qdev_get_machine()); + PCMachineState *pcms = PC_MACHINE(ms); +@@ -1634,6 +1681,7 @@ static void amdvi_sysbus_realize(DeviceState *dev, Error **errp) + } + + s->pci = AMD_IOMMU_PCI(pdev); ++ dc->vmsd = &vmstate_amdvi_sysbus_migratable; + } else { + s->pci = AMD_IOMMU_PCI(object_new(TYPE_AMD_IOMMU_PCI)); + /* This device should take care of IOMMU PCI properties */ +diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h +index 7a28181d9c..5672bdef89 100644 +--- a/hw/i386/amd_iommu.h ++++ b/hw/i386/amd_iommu.h +@@ -329,7 +329,7 @@ struct AMDVIState { + bool excl_enabled; + + hwaddr devtab; /* base address device table */ +- size_t devtab_len; /* device table length */ ++ uint64_t devtab_len; /* device table length */ + + hwaddr cmdbuf; /* command buffer base address */ + uint64_t cmdbuf_len; /* command buffer length */ +-- +2.39.3 + diff --git a/kvm-hw-i386-amd_iommu-Isolate-AMDVI-PCI-from-amd-iommu-d.patch b/kvm-hw-i386-amd_iommu-Isolate-AMDVI-PCI-from-amd-iommu-d.patch new file mode 100644 index 0000000..d23e2f9 --- /dev/null +++ b/kvm-hw-i386-amd_iommu-Isolate-AMDVI-PCI-from-amd-iommu-d.patch @@ -0,0 +1,267 @@ +From 1922ff43d7eafaad767496de00d4a1af766728e6 Mon Sep 17 00:00:00 2001 +From: Suravee Suthikulpanit +Date: Sun, 4 May 2025 17:04:04 +0000 +Subject: [PATCH 40/43] hw/i386/amd_iommu: Isolate AMDVI-PCI from amd-iommu + device to allow full control over the PCI device creation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: John Allen +RH-MergeRequest: 383: Add ability to manually specify the AMDVI-PCI device +RH-Jira: RHEL-85649 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/3] 3468e169fa46bca1d0a5941dfe652254b830e9c6 (johnalle/qemu-kvm-fork) + +Current amd-iommu model internally creates an AMDVI-PCI device. Here is +a snippet from info qtree: + + bus: main-system-bus + type System + dev: amd-iommu, id "" + xtsup = false + pci-id = "" + intremap = "on" + device-iotlb = false + pt = true + ... + dev: q35-pcihost, id "" + MCFG = -1 (0xffffffffffffffff) + pci-hole64-size = 34359738368 (32 GiB) + below-4g-mem-size = 134217728 (128 MiB) + above-4g-mem-size = 0 (0 B) + smm-ranges = true + x-pci-hole64-fix = true + x-config-reg-migration-enabled = true + bypass-iommu = false + bus: pcie.0 + type PCIE + dev: AMDVI-PCI, id "" + addr = 01.0 + romfile = "" + romsize = 4294967295 (0xffffffff) + rombar = -1 (0xffffffffffffffff) + multifunction = false + x-pcie-lnksta-dllla = true + x-pcie-extcap-init = true + failover_pair_id = "" + acpi-index = 0 (0x0) + x-pcie-err-unc-mask = true + x-pcie-ari-nextfn-1 = false + x-max-bounce-buffer-size = 4096 (4 KiB) + x-pcie-ext-tag = true + busnr = 0 (0x0) + class Class 0806, addr 00:01.0, pci id 1022:0000 (sub 1af4:1100) + ... + +This prohibits users from specifying the PCI topology for the amd-iommu device, +which becomes a problem when trying to support VM migration since it does not +guarantee the same enumeration of AMD IOMMU device. + +Therefore, allow the 'AMDVI-PCI' device to optionally be pre-created and +associated with a 'amd-iommu' device via a new 'pci-id' parameter on the +latter. + +For example: + -device AMDVI-PCI,id=iommupci0,bus=pcie.0,addr=0x05 \ + -device amd-iommu,intremap=on,pt=on,xtsup=on,pci-id=iommupci0 \ + +For backward-compatibility, internally create the AMDVI-PCI device if not +specified on the CLI. + +Co-developed-by: Daniel P. BerrangĂ© +Reviewed-by: Daniel P. BerrangĂ© +Signed-off-by: Suravee Suthikulpanit +Message-Id: <20250504170405.12623-2-suravee.suthikulpanit@amd.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit f864a3235ea1d1d714b3cde2d9a810ea6344a7b5) + +JIRA: https://issues.redhat.com/browse/RHEL-85649 + +Signed-off-by: John Allen +--- + hw/i386/acpi-build.c | 8 +++---- + hw/i386/amd_iommu.c | 53 ++++++++++++++++++++++++++------------------ + hw/i386/amd_iommu.h | 3 ++- + 3 files changed, 38 insertions(+), 26 deletions(-) + +diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c +index 3fffa4a332..f4b65701a4 100644 +--- a/hw/i386/acpi-build.c ++++ b/hw/i386/acpi-build.c +@@ -2333,10 +2333,10 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id, + build_append_int_noprefix(table_data, ivhd_blob->len + 24, 2); + /* DeviceID */ + build_append_int_noprefix(table_data, +- object_property_get_int(OBJECT(&s->pci), "addr", ++ object_property_get_int(OBJECT(s->pci), "addr", + &error_abort), 2); + /* Capability offset */ +- build_append_int_noprefix(table_data, s->pci.capab_offset, 2); ++ build_append_int_noprefix(table_data, s->pci->capab_offset, 2); + /* IOMMU base address */ + build_append_int_noprefix(table_data, s->mr_mmio.addr, 8); + /* PCI Segment Group */ +@@ -2368,10 +2368,10 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id, + build_append_int_noprefix(table_data, ivhd_blob->len + 40, 2); + /* DeviceID */ + build_append_int_noprefix(table_data, +- object_property_get_int(OBJECT(&s->pci), "addr", ++ object_property_get_int(OBJECT(s->pci), "addr", + &error_abort), 2); + /* Capability offset */ +- build_append_int_noprefix(table_data, s->pci.capab_offset, 2); ++ build_append_int_noprefix(table_data, s->pci->capab_offset, 2); + /* IOMMU base address */ + build_append_int_noprefix(table_data, s->mr_mmio.addr, 8); + /* PCI Segment Group */ +diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c +index 5f9b952799..da5313f3d2 100644 +--- a/hw/i386/amd_iommu.c ++++ b/hw/i386/amd_iommu.c +@@ -167,11 +167,11 @@ static void amdvi_generate_msi_interrupt(AMDVIState *s) + { + MSIMessage msg = {}; + MemTxAttrs attrs = { +- .requester_id = pci_requester_id(&s->pci.dev) ++ .requester_id = pci_requester_id(&s->pci->dev) + }; + +- if (msi_enabled(&s->pci.dev)) { +- msg = msi_get_message(&s->pci.dev, 0); ++ if (msi_enabled(&s->pci->dev)) { ++ msg = msi_get_message(&s->pci->dev, 0); + address_space_stl_le(&address_space_memory, msg.address, msg.data, + attrs, NULL); + } +@@ -239,7 +239,7 @@ static void amdvi_page_fault(AMDVIState *s, uint16_t devid, + info |= AMDVI_EVENT_IOPF_I | AMDVI_EVENT_IOPF; + amdvi_encode_event(evt, devid, addr, info); + amdvi_log_event(s, evt); +- pci_word_test_and_set_mask(s->pci.dev.config + PCI_STATUS, ++ pci_word_test_and_set_mask(s->pci->dev.config + PCI_STATUS, + PCI_STATUS_SIG_TARGET_ABORT); + } + /* +@@ -256,7 +256,7 @@ static void amdvi_log_devtab_error(AMDVIState *s, uint16_t devid, + + amdvi_encode_event(evt, devid, devtab, info); + amdvi_log_event(s, evt); +- pci_word_test_and_set_mask(s->pci.dev.config + PCI_STATUS, ++ pci_word_test_and_set_mask(s->pci->dev.config + PCI_STATUS, + PCI_STATUS_SIG_TARGET_ABORT); + } + /* log an event trying to access command buffer +@@ -269,7 +269,7 @@ static void amdvi_log_command_error(AMDVIState *s, hwaddr addr) + + amdvi_encode_event(evt, 0, addr, info); + amdvi_log_event(s, evt); +- pci_word_test_and_set_mask(s->pci.dev.config + PCI_STATUS, ++ pci_word_test_and_set_mask(s->pci->dev.config + PCI_STATUS, + PCI_STATUS_SIG_TARGET_ABORT); + } + /* log an illegal command event +@@ -310,7 +310,7 @@ static void amdvi_log_pagetab_error(AMDVIState *s, uint16_t devid, + info |= AMDVI_EVENT_PAGE_TAB_HW_ERROR; + amdvi_encode_event(evt, devid, addr, info); + amdvi_log_event(s, evt); +- pci_word_test_and_set_mask(s->pci.dev.config + PCI_STATUS, ++ pci_word_test_and_set_mask(s->pci->dev.config + PCI_STATUS, + PCI_STATUS_SIG_TARGET_ABORT); + } + +@@ -1607,7 +1607,7 @@ static void amdvi_sysbus_reset(DeviceState *dev) + { + AMDVIState *s = AMD_IOMMU_DEVICE(dev); + +- msi_reset(&s->pci.dev); ++ msi_reset(&s->pci->dev); + amdvi_init(s); + } + +@@ -1619,14 +1619,32 @@ static void amdvi_sysbus_realize(DeviceState *dev, Error **errp) + X86MachineState *x86ms = X86_MACHINE(ms); + PCIBus *bus = pcms->pcibus; + +- s->iotlb = g_hash_table_new_full(amdvi_uint64_hash, +- amdvi_uint64_equal, g_free, g_free); ++ if (s->pci_id) { ++ PCIDevice *pdev = NULL; ++ int ret = pci_qdev_find_device(s->pci_id, &pdev); + +- /* This device should take care of IOMMU PCI properties */ +- if (!qdev_realize(DEVICE(&s->pci), &bus->qbus, errp)) { +- return; ++ if (ret) { ++ error_report("Cannot find PCI device '%s'", s->pci_id); ++ return; ++ } ++ ++ if (!object_dynamic_cast(OBJECT(pdev), TYPE_AMD_IOMMU_PCI)) { ++ error_report("Device '%s' must be an AMDVI-PCI device type", s->pci_id); ++ return; ++ } ++ ++ s->pci = AMD_IOMMU_PCI(pdev); ++ } else { ++ s->pci = AMD_IOMMU_PCI(object_new(TYPE_AMD_IOMMU_PCI)); ++ /* This device should take care of IOMMU PCI properties */ ++ if (!qdev_realize(DEVICE(s->pci), &bus->qbus, errp)) { ++ return; ++ } + } + ++ s->iotlb = g_hash_table_new_full(amdvi_uint64_hash, ++ amdvi_uint64_equal, g_free, g_free); ++ + /* Pseudo address space under root PCI bus. */ + x86ms->ioapic_as = amdvi_host_dma_iommu(bus, s, AMDVI_IOAPIC_SB_DEVID); + +@@ -1663,6 +1681,7 @@ static void amdvi_sysbus_realize(DeviceState *dev, Error **errp) + + static const Property amdvi_properties[] = { + DEFINE_PROP_BOOL("xtsup", AMDVIState, xtsup, false), ++ DEFINE_PROP_STRING("pci-id", AMDVIState, pci_id), + }; + + static const VMStateDescription vmstate_amdvi_sysbus = { +@@ -1670,13 +1689,6 @@ static const VMStateDescription vmstate_amdvi_sysbus = { + .unmigratable = 1 + }; + +-static void amdvi_sysbus_instance_init(Object *klass) +-{ +- AMDVIState *s = AMD_IOMMU_DEVICE(klass); +- +- object_initialize(&s->pci, sizeof(s->pci), TYPE_AMD_IOMMU_PCI); +-} +- + static void amdvi_sysbus_class_init(ObjectClass *klass, void *data) + { + DeviceClass *dc = DEVICE_CLASS(klass); +@@ -1696,7 +1708,6 @@ static const TypeInfo amdvi_sysbus = { + .name = TYPE_AMD_IOMMU_DEVICE, + .parent = TYPE_X86_IOMMU_DEVICE, + .instance_size = sizeof(AMDVIState), +- .instance_init = amdvi_sysbus_instance_init, + .class_init = amdvi_sysbus_class_init + }; + +diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h +index 28125130c6..7a28181d9c 100644 +--- a/hw/i386/amd_iommu.h ++++ b/hw/i386/amd_iommu.h +@@ -315,7 +315,8 @@ struct AMDVIPCIState { + + struct AMDVIState { + X86IOMMUState iommu; /* IOMMU bus device */ +- AMDVIPCIState pci; /* IOMMU PCI device */ ++ AMDVIPCIState *pci; /* IOMMU PCI device */ ++ char *pci_id; /* ID of AMDVI-PCI device, if user created */ + + uint32_t version; + +-- +2.39.3 + diff --git a/kvm-hw-misc-aspeed_hace-skip-automatic-zero-init-of-larg.patch b/kvm-hw-misc-aspeed_hace-skip-automatic-zero-init-of-larg.patch index 631277a..87b163c 100644 --- a/kvm-hw-misc-aspeed_hace-skip-automatic-zero-init-of-larg.patch +++ b/kvm-hw-misc-aspeed_hace-skip-automatic-zero-init-of-larg.patch @@ -1,17 +1,17 @@ -From 788153c8baea4f04b33e1114b4d2c8fc2e5015f8 Mon Sep 17 00:00:00 2001 +From 2bfd29936ae867af81ac7aad36a615e5f478d0ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:36:56 +0100 -Subject: [PATCH 19/31] hw/misc/aspeed_hace: skip automatic zero-init of large +Subject: [PATCH 26/43] hw/misc/aspeed_hace: 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 -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 -RH-Commit: [18/30] a38166115c3eecf654fd1e04357200970684f513 +RH-Commit: [18/31] 300760bfe80f17dd429ddbf8bb969a741e596421 (stefanha/centos-stream-qemu-kvm) The 'do_hash_operation' method has a 256 element iovec array used for holding pointers to data that is to be hashed. Skip the automatic @@ -40,18 +40,18 @@ Conflicts: 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c -index c06c04ddc6..d2118f1864 100644 +index d75da33353..9273aac9c1 100644 --- a/hw/misc/aspeed_hace.c +++ b/hw/misc/aspeed_hace.c -@@ -188,7 +188,7 @@ static int gen_acc_mode_iov(AspeedHACEState *s, struct iovec *iov, int id, +@@ -164,7 +164,7 @@ static int reconstruct_iov(AspeedHACEState *s, struct iovec *iov, int id, static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode, bool acc_mode) { - struct iovec iov[ASPEED_HACE_MAX_SG]; + QEMU_UNINITIALIZED struct iovec iov[ASPEED_HACE_MAX_SG]; + uint32_t total_msg_len; + uint32_t pad_offset; g_autofree uint8_t *digest_buf = NULL; - size_t digest_len = 0; - int niov = 0; -- 2.39.3 diff --git a/kvm-hw-net-rtl8139-skip-automatic-zero-init-of-large-arr.patch b/kvm-hw-net-rtl8139-skip-automatic-zero-init-of-large-arr.patch index 65bade2..68af4bf 100644 --- a/kvm-hw-net-rtl8139-skip-automatic-zero-init-of-large-arr.patch +++ b/kvm-hw-net-rtl8139-skip-automatic-zero-init-of-large-arr.patch @@ -1,16 +1,16 @@ -From b92fc59a551abc4912688b56fdd13c1f0f37cd2c Mon Sep 17 00:00:00 2001 +From 2aa9f26afe4f3c5d69771b71b0e69e123ac5d893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:36:57 +0100 -Subject: [PATCH 20/31] hw/net/rtl8139: skip automatic zero-init of large array +Subject: [PATCH 27/43] hw/net/rtl8139: 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 -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 -RH-Commit: [19/30] ace21ca18ce8c21e731401779dbf4fb31f1e3a85 +RH-Commit: [19/31] 489f599053f7f36dbf382a99697e89309e1273de (stefanha/centos-stream-qemu-kvm) The 'rtl8139_transmit_one' method has a 8k byte array used for copying data between guest and host. Skip the automatic zero-init @@ -31,10 +31,10 @@ Signed-off-by: Stefan Hajnoczi 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c -index f2fe057535..a2732bf1c1 100644 +index 6c57a8985b..31a6956252 100644 --- a/hw/net/rtl8139.c +++ b/hw/net/rtl8139.c -@@ -1818,7 +1818,7 @@ static int rtl8139_transmit_one(RTL8139State *s, int descriptor) +@@ -1816,7 +1816,7 @@ static int rtl8139_transmit_one(RTL8139State *s, int descriptor) PCIDevice *d = PCI_DEVICE(s); int txsize = s->TxStatus[descriptor] & 0x1fff; diff --git a/kvm-hw-net-tulip-skip-automatic-zero-init-of-large-array.patch b/kvm-hw-net-tulip-skip-automatic-zero-init-of-large-array.patch index ffcd432..0b3cbca 100644 --- a/kvm-hw-net-tulip-skip-automatic-zero-init-of-large-array.patch +++ b/kvm-hw-net-tulip-skip-automatic-zero-init-of-large-array.patch @@ -1,16 +1,16 @@ -From 180f8a9f8e3ed06905fda019be92342531eff5e1 Mon Sep 17 00:00:00 2001 +From 3164836816fb41146e617c769c3cc82f30fa2f38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:36:58 +0100 -Subject: [PATCH 21/31] hw/net/tulip: skip automatic zero-init of large array +Subject: [PATCH 28/43] hw/net/tulip: 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 -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 -RH-Commit: [20/30] afd02f3bfd53f653c9babde27ec8fd6858371bd1 +RH-Commit: [20/31] 289701647a64bf8bbadfd32a4592ffc70d11dba9 (stefanha/centos-stream-qemu-kvm) The 'tulip_setup_frame' method has a 4k byte array used for copynig DMA data from the device. Skip the automatic zero-init of this array @@ -30,7 +30,7 @@ Signed-off-by: Stefan Hajnoczi 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/tulip.c b/hw/net/tulip.c -index 1f2ef20977..5cf2b96fbd 100644 +index a0646bb84c..97bffe4643 100644 --- a/hw/net/tulip.c +++ b/hw/net/tulip.c @@ -629,7 +629,7 @@ static void tulip_setup_filter_addr(TULIPState *s, uint8_t *buf, int n) diff --git a/kvm-hw-net-virtio-net-skip-automatic-zero-init-of-large-.patch b/kvm-hw-net-virtio-net-skip-automatic-zero-init-of-large-.patch index a33fc04..3d6a35f 100644 --- a/kvm-hw-net-virtio-net-skip-automatic-zero-init-of-large-.patch +++ b/kvm-hw-net-virtio-net-skip-automatic-zero-init-of-large-.patch @@ -1,17 +1,17 @@ -From 054501bf9876c933d7e745fcec9ff27eaf8351a6 Mon Sep 17 00:00:00 2001 +From 9f9c5b4e9f0c230e81167f937d9d875a67e4558b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:36:59 +0100 -Subject: [PATCH 22/31] hw/net/virtio-net: skip automatic zero-init of large +Subject: [PATCH 29/43] hw/net/virtio-net: 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 -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 -RH-Commit: [21/30] ea6f1bde3855278be9fb0cfb52a65d5a29333cfb +RH-Commit: [21/31] 87ec97d9e701b7ee27f4b728f0622f5b730e1c03 (stefanha/centos-stream-qemu-kvm) The 'virtio_net_receive_rcu' method has three arrays with VIRTQUEUE_MAX_SIZE elements, which are apprixmately 32k in @@ -33,12 +33,12 @@ Signed-off-by: Stefan Hajnoczi 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 3d2b2460ad..086ea20ea0 100644 +index bd37651dab..aaa024d70c 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c -@@ -1895,9 +1895,9 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, +@@ -1910,9 +1910,9 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, VirtIONet *n = qemu_get_nic_opaque(nc); - VirtIONetQueue *q = virtio_net_get_subqueue(nc); + VirtIONetQueue *q; VirtIODevice *vdev = VIRTIO_DEVICE(n); - VirtQueueElement *elems[VIRTQUEUE_MAX_SIZE]; - size_t lens[VIRTQUEUE_MAX_SIZE]; diff --git a/kvm-hw-net-xgamc-skip-automatic-zero-init-of-large-array.patch b/kvm-hw-net-xgamc-skip-automatic-zero-init-of-large-array.patch index a50af96..3a554e5 100644 --- a/kvm-hw-net-xgamc-skip-automatic-zero-init-of-large-array.patch +++ b/kvm-hw-net-xgamc-skip-automatic-zero-init-of-large-array.patch @@ -1,16 +1,16 @@ -From 20bbffe0e677431d0535920fdfe82a4ecc83e563 Mon Sep 17 00:00:00 2001 +From 9df074f93f69dcb7f3a61bcdb05c8e2ece7b6698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:37:00 +0100 -Subject: [PATCH 23/31] hw/net/xgamc: skip automatic zero-init of large array +Subject: [PATCH 30/43] hw/net/xgamc: 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 -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 -RH-Commit: [22/30] 11dde61ef5be6ec87c7ae054ee755a149b0cb0fe +RH-Commit: [22/31] 252d607753e42558049b0516924dad3ca08092c0 (stefanha/centos-stream-qemu-kvm) The 'xgmac_enet_send' method has a 8k byte array used for copying data between guest and host. Skip the automatic zero-init of this @@ -30,7 +30,7 @@ Signed-off-by: Stefan Hajnoczi 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c -index ffe3fc8dbe..eff8022aca 100644 +index e3cc4c60eb..14225eb27a 100644 --- a/hw/net/xgmac.c +++ b/hw/net/xgmac.c @@ -207,7 +207,7 @@ static void xgmac_enet_send(XgmacState *s) diff --git a/kvm-hw-nvme-ctrl-skip-automatic-zero-init-of-large-array.patch b/kvm-hw-nvme-ctrl-skip-automatic-zero-init-of-large-array.patch index 883a93f..cb185e8 100644 --- a/kvm-hw-nvme-ctrl-skip-automatic-zero-init-of-large-array.patch +++ b/kvm-hw-nvme-ctrl-skip-automatic-zero-init-of-large-array.patch @@ -1,16 +1,16 @@ -From 949020434ce0692feb8cb9378fb0806ea081a92a Mon Sep 17 00:00:00 2001 +From a39a353ec7656ef7a805391270cec24dfa815b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:37:01 +0100 -Subject: [PATCH 24/31] hw/nvme/ctrl: skip automatic zero-init of large arrays +Subject: [PATCH 31/43] hw/nvme/ctrl: 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 -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 -RH-Commit: [23/30] 4c0fecafad4034214f5e62595f282e87cacfc8ad +RH-Commit: [23/31] 926fb489c480ad10c8560efa934b8a7fb3e7a8a3 (stefanha/centos-stream-qemu-kvm) The 'nvme_map_sgl' method has a 256 element array used for copying data from the device. Skip the automatic zero-init of this array @@ -37,10 +37,10 @@ Signed-off-by: Stefan Hajnoczi 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c -index 9f277b81d8..f000e2246f 100644 +index d6b77d4fbc..ad6b264933 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c -@@ -1047,7 +1047,8 @@ static uint16_t nvme_map_sgl(NvmeCtrl *n, NvmeSg *sg, NvmeSglDescriptor sgl, +@@ -1057,7 +1057,8 @@ static uint16_t nvme_map_sgl(NvmeCtrl *n, NvmeSg *sg, NvmeSglDescriptor sgl, */ #define SEG_CHUNK_SIZE 256 @@ -50,7 +50,7 @@ index 9f277b81d8..f000e2246f 100644 uint64_t nsgld; uint32_t seg_len; uint16_t status; -@@ -5029,7 +5030,7 @@ static uint16_t nvme_error_info(NvmeCtrl *n, uint8_t rae, uint32_t buf_len, +@@ -5128,7 +5129,7 @@ static uint16_t nvme_error_info(NvmeCtrl *n, uint8_t rae, uint32_t buf_len, static uint16_t nvme_changed_nslist(NvmeCtrl *n, uint8_t rae, uint32_t buf_len, uint64_t off, NvmeRequest *req) { @@ -59,7 +59,7 @@ index 9f277b81d8..f000e2246f 100644 uint32_t trans_len; int i = 0; uint32_t nsid; -@@ -5039,7 +5040,6 @@ static uint16_t nvme_changed_nslist(NvmeCtrl *n, uint8_t rae, uint32_t buf_len, +@@ -5138,7 +5139,6 @@ static uint16_t nvme_changed_nslist(NvmeCtrl *n, uint8_t rae, uint32_t buf_len, return NVME_INVALID_FIELD | NVME_DNR; } diff --git a/kvm-hw-ppc-pnv_occ-skip-automatic-zero-init-of-large-str.patch b/kvm-hw-ppc-pnv_occ-skip-automatic-zero-init-of-large-str.patch new file mode 100644 index 0000000..b03d925 --- /dev/null +++ b/kvm-hw-ppc-pnv_occ-skip-automatic-zero-init-of-large-str.patch @@ -0,0 +1,50 @@ +From 71d1656aa3a7ea9b0bb7749212246f3dc8382534 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Tue, 10 Jun 2025 13:37:02 +0100 +Subject: [PATCH 32/43] hw/ppc/pnv_occ: skip automatic zero-init of large + struct +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Stefan Hajnoczi +RH-MergeRequest: 381: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-95479 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [24/31] c6db01eff71723d490feafb993764d76aa13e3da (stefanha/centos-stream-qemu-kvm) + +The 'occ_model_tick' method has a 12k struct used for copying +data between guest and host. Skip the automatic zero-init of this +struct to eliminate the performance overhead in the I/O hot path. + +The 'dynamic_data' buffer will be fully initialized when reading +data from the guest. + +Signed-off-by: Daniel P. BerrangĂ© +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Klaus Jensen +Reviewed-by: Harsh Prateek Bora +Message-id: 20250610123709.835102-25-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 3438eabaf4f8ae58b6c47f1727938d1d7dac4823) +Signed-off-by: Stefan Hajnoczi +--- + hw/ppc/pnv_occ.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c +index 177c5e514b..577af71d43 100644 +--- a/hw/ppc/pnv_occ.c ++++ b/hw/ppc/pnv_occ.c +@@ -790,7 +790,7 @@ static bool occ_opal_process_command(PnvOCC *occ, + + static bool occ_model_tick(PnvOCC *occ) + { +- struct occ_dynamic_data dynamic_data; ++ QEMU_UNINITIALIZED struct occ_dynamic_data dynamic_data; + + if (!occ_read_dynamic_data(occ, &dynamic_data, NULL)) { + /* Can't move OCC state field to safe because we can't map it! */ +-- +2.39.3 + diff --git a/kvm-hw-ppc-spapr_tpm_proxy-skip-automatic-zero-init-of-l.patch b/kvm-hw-ppc-spapr_tpm_proxy-skip-automatic-zero-init-of-l.patch index 3ffe10a..468e38c 100644 --- a/kvm-hw-ppc-spapr_tpm_proxy-skip-automatic-zero-init-of-l.patch +++ b/kvm-hw-ppc-spapr_tpm_proxy-skip-automatic-zero-init-of-l.patch @@ -1,17 +1,17 @@ -From c5d08a9aae7010ada9ed76785b3b22c20f490768 Mon Sep 17 00:00:00 2001 +From 3fafd694cf5df4fa7a9f4f48aad86748d18bd15a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:37:03 +0100 -Subject: [PATCH 25/31] hw/ppc/spapr_tpm_proxy: skip automatic zero-init of +Subject: [PATCH 33/43] hw/ppc/spapr_tpm_proxy: 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 -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 -RH-Commit: [24/30] 848a40837aec29084f37eb0e20a584c280209ab4 +RH-Commit: [25/31] fe7e91a1f74a696e03336cf3429042681c77c4c7 (stefanha/centos-stream-qemu-kvm) The 'tpm_execute' method has a pair of 4k arrays used for copying data between guest and host. Skip the automatic zero-init of these @@ -33,7 +33,7 @@ Signed-off-by: Stefan Hajnoczi 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr_tpm_proxy.c b/hw/ppc/spapr_tpm_proxy.c -index e10af35a18..88833d9e2e 100644 +index ceaa0acaa1..7472ff8709 100644 --- a/hw/ppc/spapr_tpm_proxy.c +++ b/hw/ppc/spapr_tpm_proxy.c @@ -41,8 +41,8 @@ static ssize_t tpm_execute(SpaprTpmProxy *tpm_proxy, target_ulong *args) diff --git a/kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch b/kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch deleted file mode 100644 index dafdddc..0000000 --- a/kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch +++ /dev/null @@ -1,270 +0,0 @@ -From 416ee0a87ee4bfedf07bc37d328066375b36fdc1 Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:49 -0400 -Subject: [PATCH 17/38] hw/s390x: Build an IPLB for each boot device -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [16/23] 40a579b400cebd1470bb632869ad4a5581e3c41f (thuth/qemu-kvm-cs9) - -Build an IPLB for any device with a bootindex (up to a maximum of 8 devices). - -The IPLB chain is placed immediately before the BIOS in memory. Because this -is not a fixed address, the location of the next IPLB and number of remaining -boot devices is stored in the QIPL global variable for possible later access by -the guest during IPL. - -Signed-off-by: Jared Rossi -Reviewed-by: Thomas Huth -Message-ID: <20241020012953.1380075-16-jrossi@linux.ibm.com> -[thuth: Fix endianness problem when accessing the qipl structure] -Signed-off-by: Thomas Huth -(cherry picked from commit 0927875e704e93ace03bb7533c0877bf97e4bda9) ---- - hw/s390x/ipl.c | 129 ++++++++++++++++++++++++++++-------- - hw/s390x/ipl.h | 1 + - include/hw/s390x/ipl/qipl.h | 4 +- - 3 files changed, 105 insertions(+), 29 deletions(-) - -diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c -index d83832d975..f4576f8822 100644 ---- a/hw/s390x/ipl.c -+++ b/hw/s390x/ipl.c -@@ -56,6 +56,13 @@ static bool iplb_extended_needed(void *opaque) - return ipl->iplbext_migration; - } - -+/* Place the IPLB chain immediately before the BIOS in memory */ -+static uint64_t find_iplb_chain_addr(uint64_t bios_addr, uint16_t count) -+{ -+ return (bios_addr & TARGET_PAGE_MASK) -+ - (count * sizeof(IplParameterBlock)); -+} -+ - static const VMStateDescription vmstate_iplb_extended = { - .name = "ipl/iplb_extended", - .version_id = 0, -@@ -398,6 +405,17 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st, int *devtype) - return ccw_dev; - } - -+static uint64_t s390_ipl_map_iplb_chain(IplParameterBlock *iplb_chain) -+{ -+ S390IPLState *ipl = get_ipl_device(); -+ uint16_t count = be16_to_cpu(ipl->qipl.chain_len); -+ uint64_t len = sizeof(IplParameterBlock) * count; -+ uint64_t chain_addr = find_iplb_chain_addr(ipl->bios_start_addr, count); -+ -+ cpu_physical_memory_write(chain_addr, iplb_chain, len); -+ return chain_addr; -+} -+ - void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp) - { - int i; -@@ -428,54 +446,51 @@ void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp) - } - } - --static bool s390_gen_initial_iplb(S390IPLState *ipl) -+static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb) - { -- DeviceState *dev_st; -+ S390IPLState *ipl = get_ipl_device(); - CcwDevice *ccw_dev = NULL; - SCSIDevice *sd; - int devtype; - uint8_t *lp; - -- dev_st = get_boot_device(0); -- if (dev_st) { -- ccw_dev = s390_get_ccw_device(dev_st, &devtype); -- } -- - /* - * Currently allow IPL only from CCW devices. - */ -+ ccw_dev = s390_get_ccw_device(dev_st, &devtype); - if (ccw_dev) { - lp = ccw_dev->loadparm; - - switch (devtype) { - case CCW_DEVTYPE_SCSI: - sd = SCSI_DEVICE(dev_st); -- ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN); -- ipl->iplb.blk0_len = -+ iplb->len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN); -+ iplb->blk0_len = - cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - S390_IPLB_HEADER_LEN); -- ipl->iplb.pbt = S390_IPL_TYPE_QEMU_SCSI; -- ipl->iplb.scsi.lun = cpu_to_be32(sd->lun); -- ipl->iplb.scsi.target = cpu_to_be16(sd->id); -- ipl->iplb.scsi.channel = cpu_to_be16(sd->channel); -- ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno); -- ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3; -+ iplb->pbt = S390_IPL_TYPE_QEMU_SCSI; -+ iplb->scsi.lun = cpu_to_be32(sd->lun); -+ iplb->scsi.target = cpu_to_be16(sd->id); -+ iplb->scsi.channel = cpu_to_be16(sd->channel); -+ iplb->scsi.devno = cpu_to_be16(ccw_dev->sch->devno); -+ iplb->scsi.ssid = ccw_dev->sch->ssid & 3; - break; - case CCW_DEVTYPE_VFIO: -- ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); -- ipl->iplb.pbt = S390_IPL_TYPE_CCW; -- ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno); -- ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3; -+ iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); -+ iplb->pbt = S390_IPL_TYPE_CCW; -+ iplb->ccw.devno = cpu_to_be16(ccw_dev->sch->devno); -+ iplb->ccw.ssid = ccw_dev->sch->ssid & 3; - break; - case CCW_DEVTYPE_VIRTIO_NET: -+ /* The S390IPLState netboot is true if ANY IPLB may use netboot */ - ipl->netboot = true; - /* Fall through to CCW_DEVTYPE_VIRTIO case */ - case CCW_DEVTYPE_VIRTIO: -- ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); -- ipl->iplb.blk0_len = -+ iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); -+ iplb->blk0_len = - cpu_to_be32(S390_IPLB_MIN_CCW_LEN - S390_IPLB_HEADER_LEN); -- ipl->iplb.pbt = S390_IPL_TYPE_CCW; -- ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno); -- ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3; -+ iplb->pbt = S390_IPL_TYPE_CCW; -+ iplb->ccw.devno = cpu_to_be16(ccw_dev->sch->devno); -+ iplb->ccw.ssid = ccw_dev->sch->ssid & 3; - break; - } - -@@ -484,8 +499,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl) - lp = S390_CCW_MACHINE(qdev_get_machine())->loadparm; - } - -- s390_ipl_convert_loadparm((char *)lp, ipl->iplb.loadparm); -- ipl->iplb.flags |= DIAG308_FLAGS_LP_VALID; -+ s390_ipl_convert_loadparm((char *)lp, iplb->loadparm); -+ iplb->flags |= DIAG308_FLAGS_LP_VALID; - - return true; - } -@@ -493,6 +508,62 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl) - return false; - } - -+static bool s390_init_all_iplbs(S390IPLState *ipl) -+{ -+ int iplb_num = 0; -+ IplParameterBlock iplb_chain[7]; -+ DeviceState *dev_st = get_boot_device(0); -+ Object *machine = qdev_get_machine(); -+ -+ /* -+ * Parse the boot devices. Generate an IPLB for only the first boot device -+ * which will later be set with DIAG308. -+ */ -+ if (!dev_st) { -+ ipl->qipl.chain_len = 0; -+ return false; -+ } -+ -+ /* If no machine loadparm was defined fill it with spaces */ -+ if (memcmp(S390_CCW_MACHINE(machine)->loadparm, NO_LOADPARM, 8) == 0) { -+ object_property_set_str(machine, "loadparm", " ", NULL); -+ } -+ -+ iplb_num = 1; -+ s390_build_iplb(dev_st, &ipl->iplb); -+ -+ /* Index any fallback boot devices */ -+ while (get_boot_device(iplb_num)) { -+ iplb_num++; -+ } -+ -+ if (iplb_num > MAX_BOOT_DEVS) { -+ warn_report("Excess boot devices defined! %d boot devices found, " -+ "but only the first %d will be considered.", -+ iplb_num, MAX_BOOT_DEVS); -+ -+ iplb_num = MAX_BOOT_DEVS; -+ } -+ -+ ipl->qipl.chain_len = cpu_to_be16(iplb_num - 1); -+ -+ /* -+ * Build fallback IPLBs for any boot devices above index 0, up to a -+ * maximum amount as defined in ipl.h -+ */ -+ if (iplb_num > 1) { -+ /* Start at 1 because the IPLB for boot index 0 is not chained */ -+ for (int i = 1; i < iplb_num; i++) { -+ dev_st = get_boot_device(i); -+ s390_build_iplb(dev_st, &iplb_chain[i - 1]); -+ } -+ -+ ipl->qipl.next_iplb = cpu_to_be64(s390_ipl_map_iplb_chain(iplb_chain)); -+ } -+ -+ return iplb_num; -+} -+ - static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb, - int virtio_id) - { -@@ -620,7 +691,7 @@ void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type) - * this is the original boot device's SCSI - * so restore IPL parameter info from it - */ -- ipl->iplb_valid = s390_gen_initial_iplb(ipl); -+ ipl->iplb_valid = s390_build_iplb(get_boot_device(0), &ipl->iplb); - } - } - if (reset_type == S390_RESET_MODIFIED_CLEAR || -@@ -714,7 +785,9 @@ void s390_ipl_prepare_cpu(S390CPU *cpu) - if (!ipl->kernel || ipl->iplb_valid) { - cpu->env.psw.addr = ipl->bios_start_addr; - if (!ipl->iplb_valid) { -- ipl->iplb_valid = s390_gen_initial_iplb(ipl); -+ ipl->iplb_valid = s390_init_all_iplbs(ipl); -+ } else { -+ ipl->qipl.chain_len = 0; - } - } - s390_ipl_set_boot_menu(ipl); -diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h -index b670bad551..54eb48fd6e 100644 ---- a/hw/s390x/ipl.h -+++ b/hw/s390x/ipl.h -@@ -20,6 +20,7 @@ - #include "qom/object.h" - - #define DIAG308_FLAGS_LP_VALID 0x80 -+#define MAX_BOOT_DEVS 8 /* Max number of devices that may have a bootindex */ - - void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp); - void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp); -diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h -index b67d2ae061..1da4f75aa8 100644 ---- a/include/hw/s390x/ipl/qipl.h -+++ b/include/hw/s390x/ipl/qipl.h -@@ -32,7 +32,9 @@ struct QemuIplParameters { - uint8_t reserved1[3]; - uint64_t reserved2; - uint32_t boot_menu_timeout; -- uint8_t reserved3[12]; -+ uint8_t reserved3[2]; -+ uint16_t chain_len; -+ uint64_t next_iplb; - } QEMU_PACKED; - typedef struct QemuIplParameters QemuIplParameters; - --- -2.39.3 - diff --git a/kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch b/kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch deleted file mode 100644 index 6329706..0000000 --- a/kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch +++ /dev/null @@ -1,201 +0,0 @@ -From 36f64f38b39f2a2e0f0682f62f669d5e23074875 Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Thu, 20 Jun 2024 16:59:28 +0200 -Subject: [PATCH 06/38] hw/s390x: Remove the possibility to load the - s390-netboot.img binary -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [5/23] ff245b81b45ddd3a78343d1a8cfdd725a8255d87 (thuth/qemu-kvm-cs9) - -Since the netboot code has now been merged into the main s390-ccw.img -binary, we don't need the separate s390-netboot.img anymore. Remove -it and the code that was responsible for loading it. - -Message-Id: <20240621082422.136217-6-thuth@redhat.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 188e255bf8ed68fa64bcb63577cb100eeb326254) ---- - hw/s390x/ipl.c | 55 -------------------------------------- - hw/s390x/ipl.h | 12 +++------ - hw/s390x/s390-virtio-ccw.c | 10 ++----- - pc-bios/meson.build | 1 - - 4 files changed, 6 insertions(+), 72 deletions(-) - -diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c -index 9362de0b6f..8a0a3e6961 100644 ---- a/hw/s390x/ipl.c -+++ b/hw/s390x/ipl.c -@@ -288,7 +288,6 @@ static Property s390_ipl_properties[] = { - DEFINE_PROP_STRING("initrd", S390IPLState, initrd), - DEFINE_PROP_STRING("cmdline", S390IPLState, cmdline), - DEFINE_PROP_STRING("firmware", S390IPLState, firmware), -- DEFINE_PROP_STRING("netboot_fw", S390IPLState, netboot_fw), - DEFINE_PROP_BOOL("enforce_bios", S390IPLState, enforce_bios, false), - DEFINE_PROP_BOOL("iplbext_migration", S390IPLState, iplbext_migration, - true), -@@ -480,56 +479,6 @@ int s390_ipl_set_loadparm(uint8_t *loadparm) - return -1; - } - --static int load_netboot_image(Error **errp) --{ -- MachineState *ms = MACHINE(qdev_get_machine()); -- S390IPLState *ipl = get_ipl_device(); -- char *netboot_filename; -- MemoryRegion *sysmem = get_system_memory(); -- MemoryRegion *mr = NULL; -- void *ram_ptr = NULL; -- int img_size = -1; -- -- mr = memory_region_find(sysmem, 0, 1).mr; -- if (!mr) { -- error_setg(errp, "Failed to find memory region at address 0"); -- return -1; -- } -- -- ram_ptr = memory_region_get_ram_ptr(mr); -- if (!ram_ptr) { -- error_setg(errp, "No RAM found"); -- goto unref_mr; -- } -- -- netboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, ipl->netboot_fw); -- if (netboot_filename == NULL) { -- error_setg(errp, "Could not find network bootloader '%s'", -- ipl->netboot_fw); -- goto unref_mr; -- } -- -- img_size = load_elf_ram(netboot_filename, NULL, NULL, NULL, -- &ipl->start_addr, -- NULL, NULL, NULL, 1, EM_S390, 0, 0, NULL, -- false); -- -- if (img_size < 0) { -- img_size = load_image_size(netboot_filename, ram_ptr, ms->ram_size); -- ipl->start_addr = KERN_IMAGE_START; -- } -- -- if (img_size < 0) { -- error_setg(errp, "Failed to load network bootloader"); -- } -- -- g_free(netboot_filename); -- --unref_mr: -- memory_region_unref(mr); -- return img_size; --} -- - static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb, - int virtio_id) - { -@@ -754,10 +703,6 @@ void s390_ipl_prepare_cpu(S390CPU *cpu) - ipl->iplb_valid = s390_gen_initial_iplb(ipl); - } - } -- if (ipl->netboot) { -- load_netboot_image(&error_fatal); -- ipl->qipl.netboot_start_addr = cpu_to_be64(ipl->start_addr); -- } - s390_ipl_set_boot_menu(ipl); - s390_ipl_prepare_qipl(cpu); - } -diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h -index 57cd125769..b2105b616a 100644 ---- a/hw/s390x/ipl.h -+++ b/hw/s390x/ipl.h -@@ -134,11 +134,8 @@ void s390_ipl_clear_reset_request(void); - /* - * The QEMU IPL Parameters will be stored at absolute address - * 204 (0xcc) which means it is 32-bit word aligned but not -- * double-word aligned. -- * Placement of data fields in this area must account for -- * their alignment needs. E.g., netboot_start_address must -- * have an offset of 4 + n * 8 bytes within the struct in order -- * to keep it double-word aligned. -+ * double-word aligned. Placement of 64-bit data fields in this -+ * area must account for their alignment needs. - * The total size of the struct must never exceed 28 bytes. - * This definition must be kept in sync with the definition - * in pc-bios/s390-ccw/iplb.h. -@@ -146,9 +143,9 @@ void s390_ipl_clear_reset_request(void); - struct QemuIplParameters { - uint8_t qipl_flags; - uint8_t reserved1[3]; -- uint64_t netboot_start_addr; -+ uint64_t reserved2; - uint32_t boot_menu_timeout; -- uint8_t reserved2[12]; -+ uint8_t reserved3[12]; - } QEMU_PACKED; - typedef struct QemuIplParameters QemuIplParameters; - -@@ -178,7 +175,6 @@ struct S390IPLState { - char *initrd; - char *cmdline; - char *firmware; -- char *netboot_fw; - uint8_t cssid; - uint8_t ssid; - uint16_t devno; -diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c -index b61392bac1..29a89a0c31 100644 ---- a/hw/s390x/s390-virtio-ccw.c -+++ b/hw/s390x/s390-virtio-ccw.c -@@ -197,11 +197,10 @@ static void s390_memory_init(MemoryRegion *ram) - static void s390_init_ipl_dev(const char *kernel_filename, - const char *kernel_cmdline, - const char *initrd_filename, const char *firmware, -- const char *netboot_fw, bool enforce_bios) -+ bool enforce_bios) - { - Object *new = object_new(TYPE_S390_IPL); - DeviceState *dev = DEVICE(new); -- char *netboot_fw_prop; - - if (kernel_filename) { - qdev_prop_set_string(dev, "kernel", kernel_filename); -@@ -212,11 +211,6 @@ static void s390_init_ipl_dev(const char *kernel_filename, - qdev_prop_set_string(dev, "cmdline", kernel_cmdline); - qdev_prop_set_string(dev, "firmware", firmware); - qdev_prop_set_bit(dev, "enforce_bios", enforce_bios); -- netboot_fw_prop = object_property_get_str(new, "netboot_fw", &error_abort); -- if (!strlen(netboot_fw_prop)) { -- qdev_prop_set_string(dev, "netboot_fw", netboot_fw); -- } -- g_free(netboot_fw_prop); - object_property_add_child(qdev_get_machine(), TYPE_S390_IPL, - new); - object_unref(new); -@@ -284,7 +278,7 @@ static void ccw_init(MachineState *machine) - s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline, - machine->initrd_filename, - machine->firmware ?: "s390-ccw.img", -- "s390-netboot.img", true); -+ true); - - dev = qdev_new(TYPE_S390_PCI_HOST_BRIDGE); - object_property_add_child(qdev_get_machine(), TYPE_S390_PCI_HOST_BRIDGE, -diff --git a/pc-bios/meson.build b/pc-bios/meson.build -index 8602b45b9b..ea85c54c86 100644 ---- a/pc-bios/meson.build -+++ b/pc-bios/meson.build -@@ -66,7 +66,6 @@ blobs = [ - 'kvmvapic.bin', - 'pvh.bin', - 's390-ccw.img', -- 's390-netboot.img', - 'slof.bin', - 'skiboot.lid', - 'palcode-clipper', --- -2.39.3 - diff --git a/kvm-hw-s390x-Restrict-loadparm-property-to-devices-that-.patch b/kvm-hw-s390x-Restrict-loadparm-property-to-devices-that-.patch deleted file mode 100644 index 3df6be5..0000000 --- a/kvm-hw-s390x-Restrict-loadparm-property-to-devices-that-.patch +++ /dev/null @@ -1,112 +0,0 @@ -From b9950c32c2845c9592650df49183c431a4190e7f Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Wed, 13 Nov 2024 12:47:41 +0100 -Subject: [PATCH 4/9] hw/s390x: Restrict "loadparm" property to devices that - can be used for booting -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature -RH-Jira: RHEL-68444 -RH-Acked-by: Miroslav Rezanina -RH-Commit: [3/8] 7b0fee6a1508649d66b913e6ebf23b4af29628dd (thuth/qemu-kvm-cs9) - -Commit bb185de423 ("s390x: Add individual loadparm assignment to -CCW device") added a "loadparm" property to all CCW devices. This -was a little bit unfortunate, since this property is only useful -for devices that can be used for booting, but certainly it is not -useful for devices like virtio-gpu or virtio-tablet. - -Thus let's restrict the property to CCW devices that we can boot from -(i.e. virtio-block, virtio-net and vfio-ccw devices). - -Message-ID: <20241113114741.681096-1-thuth@redhat.com> -Reviewed-by: Philippe Mathieu-DaudĂ© -Reviewed-by: Jared Rossi -Signed-off-by: Thomas Huth -(cherry picked from commit 6e7c96ae61e0542e97d385084f1f2281a0331054) ---- - hw/s390x/ccw-device.c | 4 +--- - hw/s390x/ccw-device.h | 5 +++++ - hw/s390x/virtio-ccw-blk.c | 1 + - hw/s390x/virtio-ccw-net.c | 1 + - hw/vfio/ccw.c | 1 + - 5 files changed, 9 insertions(+), 3 deletions(-) - -diff --git a/hw/s390x/ccw-device.c b/hw/s390x/ccw-device.c -index 4e54f34b1c..d7bb364579 100644 ---- a/hw/s390x/ccw-device.c -+++ b/hw/s390x/ccw-device.c -@@ -73,7 +73,7 @@ static void ccw_device_set_loadparm(Object *obj, Visitor *v, - s390_ipl_fmt_loadparm(dev->loadparm, val, errp); - } - --static const PropertyInfo ccw_loadparm = { -+const PropertyInfo ccw_loadparm = { - .name = "ccw_loadparm", - .description = "Up to 8 chars in set of [A-Za-z0-9. ] to pass" - " to the guest loader/kernel", -@@ -85,8 +85,6 @@ static Property ccw_device_properties[] = { - DEFINE_PROP_CSS_DEV_ID("devno", CcwDevice, devno), - DEFINE_PROP_CSS_DEV_ID_RO("dev_id", CcwDevice, dev_id), - DEFINE_PROP_CSS_DEV_ID_RO("subch_id", CcwDevice, subch_id), -- DEFINE_PROP("loadparm", CcwDevice, loadparm, ccw_loadparm, -- typeof(uint8_t[8])), - DEFINE_PROP_END_OF_LIST(), - }; - -diff --git a/hw/s390x/ccw-device.h b/hw/s390x/ccw-device.h -index 1e1737c0f3..4439feb140 100644 ---- a/hw/s390x/ccw-device.h -+++ b/hw/s390x/ccw-device.h -@@ -51,4 +51,9 @@ static inline CcwDevice *to_ccw_dev_fast(DeviceState *d) - - OBJECT_DECLARE_TYPE(CcwDevice, CCWDeviceClass, CCW_DEVICE) - -+extern const PropertyInfo ccw_loadparm; -+ -+#define DEFINE_PROP_CCW_LOADPARM(_n, _s, _f) \ -+ DEFINE_PROP(_n, _s, _f, ccw_loadparm, typeof(uint8_t[8])) -+ - #endif -diff --git a/hw/s390x/virtio-ccw-blk.c b/hw/s390x/virtio-ccw-blk.c -index 8e0e58b77d..2364432c6e 100644 ---- a/hw/s390x/virtio-ccw-blk.c -+++ b/hw/s390x/virtio-ccw-blk.c -@@ -48,6 +48,7 @@ static Property virtio_ccw_blk_properties[] = { - VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), - DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, - VIRTIO_CCW_MAX_REV), -+ DEFINE_PROP_CCW_LOADPARM("loadparm", CcwDevice, loadparm), - DEFINE_PROP_END_OF_LIST(), - }; - -diff --git a/hw/s390x/virtio-ccw-net.c b/hw/s390x/virtio-ccw-net.c -index 484e617659..a4a3f65c7e 100644 ---- a/hw/s390x/virtio-ccw-net.c -+++ b/hw/s390x/virtio-ccw-net.c -@@ -51,6 +51,7 @@ static Property virtio_ccw_net_properties[] = { - VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), - DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, - VIRTIO_CCW_MAX_REV), -+ DEFINE_PROP_CCW_LOADPARM("loadparm", CcwDevice, loadparm), - DEFINE_PROP_END_OF_LIST(), - }; - -diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c -index 115862f430..99f16614ad 100644 ---- a/hw/vfio/ccw.c -+++ b/hw/vfio/ccw.c -@@ -662,6 +662,7 @@ static Property vfio_ccw_properties[] = { - DEFINE_PROP_LINK("iommufd", VFIOCCWDevice, vdev.iommufd, - TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *), - #endif -+ DEFINE_PROP_CCW_LOADPARM("loadparm", CcwDevice, loadparm), - DEFINE_PROP_END_OF_LIST(), - }; - --- -2.39.3 - diff --git a/kvm-hw-s390x-ccw-device-Fix-memory-leak-in-loadparm-sett.patch b/kvm-hw-s390x-ccw-device-Fix-memory-leak-in-loadparm-sett.patch new file mode 100644 index 0000000..10fc8c4 --- /dev/null +++ b/kvm-hw-s390x-ccw-device-Fix-memory-leak-in-loadparm-sett.patch @@ -0,0 +1,47 @@ +From fee9f1ed047043035ce91284fe0f0feffb27d3af Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 25 Jun 2025 10:27:51 +0200 +Subject: [PATCH 02/43] hw/s390x/ccw-device: Fix memory leak in loadparm setter +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 386: s390x: Fix memory leaks related to loadparm [rhel-10] +RH-Jira: RHEL-98555 +RH-Acked-by: CĂ©dric Le Goater +RH-Acked-by: Kevin Wolf +RH-Commit: [2/2] f238e2b4819d7e5daf53df3f2eed8744cf534c02 (thuth/qemu-kvm-cs) + +Commit bdf12f2a fixed the setter for the "loadparm" machine property, +which gets a string from a visitor, passes it to s390_ipl_fmt_loadparm() +and then forgot to free it. It left another instance of the same problem +unfixed in the "loadparm" device property. Fix it. + +Signed-off-by: Kevin Wolf +Message-ID: <20250625082751.24896-1-kwolf@redhat.com> +Reviewed-by: Eric Farman +Reviewed-by: Halil Pasic +Tested-by: Thomas Huth +Signed-off-by: Thomas Huth +(cherry picked from commit 78e3781541209b3dcd6f4bb66adf3a3e504b88a4) +--- + hw/s390x/ccw-device.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/s390x/ccw-device.c b/hw/s390x/ccw-device.c +index 1ea9934f6c..a5ee9dc84d 100644 +--- a/hw/s390x/ccw-device.c ++++ b/hw/s390x/ccw-device.c +@@ -57,7 +57,7 @@ static void ccw_device_set_loadparm(Object *obj, Visitor *v, + Error **errp) + { + CcwDevice *dev = CCW_DEVICE(obj); +- char *val; ++ g_autofree char *val = NULL; + int index; + + index = object_property_get_int(obj, "bootindex", NULL); +-- +2.39.3 + diff --git a/kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch b/kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch deleted file mode 100644 index cea6973..0000000 --- a/kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch +++ /dev/null @@ -1,61 +0,0 @@ -From ce0d8bc163952ce177c37ea431cacf60889017f2 Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Fri, 21 Jun 2024 10:24:17 +0200 -Subject: [PATCH 02/38] hw/s390x/ipl: Provide more memory to the s390-ccw.img - firmware -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/23] c33a2769b041e62285eb7840f8a7c05ac32aca7b (thuth/qemu-kvm-cs9) - -We are going to link the SLOF libc into the s390-ccw.img, and this -libc needs more memory for providing space for malloc() and friends. -Thus bump the memory size that we reserve for the bios to 3 MiB -instead of only 2 MiB. While we're at it, add a proper check that -there is really enough memory assigned to the machine before blindly -using it. - -Message-ID: <20240621082422.136217-3-thuth@redhat.com> -Signed-off-by: Thomas Huth -(cherry picked from commit abaabb2e601adfe296a64471746a997eabcc607f) ---- - hw/s390x/ipl.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c -index e934bf89d1..9362de0b6f 100644 ---- a/hw/s390x/ipl.c -+++ b/hw/s390x/ipl.c -@@ -45,6 +45,7 @@ - #define INITRD_PARM_START 0x010408UL - #define PARMFILE_START 0x001000UL - #define ZIPL_IMAGE_START 0x009000UL -+#define BIOS_MAX_SIZE 0x300000UL - #define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64) - - static bool iplb_extended_needed(void *opaque) -@@ -144,7 +145,14 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp) - * even if an external kernel has been defined. - */ - if (!ipl->kernel || ipl->enforce_bios) { -- uint64_t fwbase = (MIN(ms->ram_size, 0x80000000U) - 0x200000) & ~0xffffUL; -+ uint64_t fwbase; -+ -+ if (ms->ram_size < BIOS_MAX_SIZE) { -+ error_setg(errp, "not enough RAM to load the BIOS file"); -+ return; -+ } -+ -+ fwbase = (MIN(ms->ram_size, 0x80000000U) - BIOS_MAX_SIZE) & ~0xffffUL; - - bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, ipl->firmware); - if (bios_filename == NULL) { --- -2.39.3 - diff --git a/kvm-hw-scsi-lsi53c895a-skip-automatic-zero-init-of-large.patch b/kvm-hw-scsi-lsi53c895a-skip-automatic-zero-init-of-large.patch index b7b66be..38b1bc2 100644 --- a/kvm-hw-scsi-lsi53c895a-skip-automatic-zero-init-of-large.patch +++ b/kvm-hw-scsi-lsi53c895a-skip-automatic-zero-init-of-large.patch @@ -1,17 +1,17 @@ -From 671138b8df11c3e663778b811d75686b6685e8ab Mon Sep 17 00:00:00 2001 +From 6a11d5845b62f4f1a1c481b9be33aae9acded335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:37:05 +0100 -Subject: [PATCH 27/31] hw/scsi/lsi53c895a: skip automatic zero-init of large +Subject: [PATCH 35/43] hw/scsi/lsi53c895a: 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 -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 -RH-Commit: [26/30] d49841c853484c14ea6bce2543ab1344b6e0d4a8 +RH-Commit: [27/31] d54767678b4bd133b69cc7461220121eee04c9bb (stefanha/centos-stream-qemu-kvm) The 'lsi_memcpy' method has a 4k byte array used for copying data to/from the device. Skip the automatic zero-init of this array to @@ -32,7 +32,7 @@ Signed-off-by: Stefan Hajnoczi 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c -index f1935e5328..f165705f8a 100644 +index 6689ebba25..bacc6593f6 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -1112,7 +1112,7 @@ bad: diff --git a/kvm-hw-scsi-megasas-skip-automatic-zero-init-of-large-ar.patch b/kvm-hw-scsi-megasas-skip-automatic-zero-init-of-large-ar.patch index f1c36d6..98ca107 100644 --- a/kvm-hw-scsi-megasas-skip-automatic-zero-init-of-large-ar.patch +++ b/kvm-hw-scsi-megasas-skip-automatic-zero-init-of-large-ar.patch @@ -1,17 +1,17 @@ -From 1ec76ce3a18f5f181e28fe3c6e8af8b37e46a0a3 Mon Sep 17 00:00:00 2001 +From e1ca896e3388b7a92e3f65c37c7d0f7a9b4679a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:37:06 +0100 -Subject: [PATCH 28/31] hw/scsi/megasas: skip automatic zero-init of large +Subject: [PATCH 36/43] hw/scsi/megasas: 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 -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 -RH-Commit: [27/30] a57fd72cba0aa33d99a19b6c39a4ef600303a590 +RH-Commit: [28/31] 2123323efa4331a9899c62af9edeeac388f09fc4 (stefanha/centos-stream-qemu-kvm) The 'megasas_dcmd_pd_get_list' and 'megasas_dcmd_get_properties' methods have 4k structs used for copying data from the device. @@ -37,7 +37,7 @@ Signed-off-by: Stefan Hajnoczi 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c -index 2d0c607177..91b65accbc 100644 +index 9f3b30e6ce..79b0fdcfe3 100644 --- a/hw/scsi/megasas.c +++ b/hw/scsi/megasas.c @@ -981,13 +981,11 @@ static int megasas_event_wait(MegasasState *s, MegasasCmd *cmd) diff --git a/kvm-hw-uefi-check-access-for-first-variable.patch b/kvm-hw-uefi-check-access-for-first-variable.patch new file mode 100644 index 0000000..84adfde --- /dev/null +++ b/kvm-hw-uefi-check-access-for-first-variable.patch @@ -0,0 +1,43 @@ +From 84a96bdbeb9df47665f12489c35de191f289a74b Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Mon, 11 Aug 2025 15:01:09 +0200 +Subject: [PATCH 3/3] hw/uefi: check access for first variable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Gerd Hoffmann +RH-MergeRequest: 481: hw/uefi: clear uefi-vars buffer in uefi_vars_write callback +RH-Jira: RHEL-108614 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [3/3] 64dc149a5c1c3869f66ff54fa5bd1d40eef52471 + +When listing variables (via get-next-variable-name) only the names of +variables which can be accessed will be returned. That check was +missing for the first variable though. Add it. + +Reviewed-by: Philippe Mathieu-DaudĂ© +Signed-off-by: Gerd Hoffmann +Message-ID: <20250811130110.820958-3-kraxel@redhat.com> +(cherry picked from commit fc8ee8fe58ad410f27fca64e4ad212c5a3eabe00) +--- + hw/uefi/var-service-vars.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/hw/uefi/var-service-vars.c b/hw/uefi/var-service-vars.c +index 58ae560d6e..e382fb2813 100644 +--- a/hw/uefi/var-service-vars.c ++++ b/hw/uefi/var-service-vars.c +@@ -357,6 +357,9 @@ uefi_vars_mm_get_next_variable(uefi_vars_state *uv, mm_header *mhdr, + if (uefi_strlen(name, nv->name_size) == 0) { + /* empty string -> first */ + var = QTAILQ_FIRST(&uv->variables); ++ while (var && !check_access(uv, var)) { ++ var = QTAILQ_NEXT(var, next); ++ } + if (!var) { + return uefi_vars_mm_error(mhdr, mvar, EFI_NOT_FOUND); + } +-- +2.47.3 + diff --git a/kvm-hw-uefi-clear-uefi-vars-buffer-in-uefi_vars_write-ca.patch b/kvm-hw-uefi-clear-uefi-vars-buffer-in-uefi_vars_write-ca.patch new file mode 100644 index 0000000..2f502f2 --- /dev/null +++ b/kvm-hw-uefi-clear-uefi-vars-buffer-in-uefi_vars_write-ca.patch @@ -0,0 +1,51 @@ +From b84753eee88ce06e0c652f0a5d5ac64d2937e3ea Mon Sep 17 00:00:00 2001 +From: Mauro Matteo Cascella +Date: Mon, 11 Aug 2025 12:11:24 +0200 +Subject: [PATCH 1/3] hw/uefi: clear uefi-vars buffer in uefi_vars_write + callback + +RH-Author: Gerd Hoffmann +RH-MergeRequest: 481: hw/uefi: clear uefi-vars buffer in uefi_vars_write callback +RH-Jira: RHEL-108614 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/3] 4087bb66a3f8c5f8c4a50a19d76a153a547da155 + +When the guest writes to register UEFI_VARS_REG_BUFFER_SIZE, the .write +callback `uefi_vars_write` is invoked. The function allocates a +heap buffer without zeroing the memory, leaving the buffer filled with +residual data from prior allocations. When the guest later reads from +register UEFI_VARS_REG_PIO_BUFFER_TRANSFER, the .read callback +`uefi_vars_read` returns leftover metadata or other sensitive process +memory from the previously allocated buffer, leading to an information +disclosure vulnerability. + +Fixes: CVE-2025-8860 +Fixes: 90ca4e03c27d ("hw/uefi: add var-service-core.c") +Reported-by: ZDI +Suggested-by: Gerd Hoffmann +Signed-off-by: Mauro Matteo Cascella +Message-ID: <20250811101128.17661-1-mcascell@redhat.com> +Signed-off-by: Gerd Hoffmann +(cherry picked from commit f757d9d90d19b914d4023663bfc4da73bbbf007e) +--- + hw/uefi/var-service-core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/uefi/var-service-core.c b/hw/uefi/var-service-core.c +index 4836a0cb81..92fc121fe7 100644 +--- a/hw/uefi/var-service-core.c ++++ b/hw/uefi/var-service-core.c +@@ -259,8 +259,8 @@ static void uefi_vars_write(void *opaque, hwaddr addr, uint64_t val, unsigned si + uv->buf_size = val; + g_free(uv->buffer); + g_free(uv->pio_xfer_buffer); +- uv->buffer = g_malloc(uv->buf_size); +- uv->pio_xfer_buffer = g_malloc(uv->buf_size); ++ uv->buffer = g_malloc0(uv->buf_size); ++ uv->pio_xfer_buffer = g_malloc0(uv->buf_size); + break; + case UEFI_VARS_REG_DMA_BUFFER_ADDR_LO: + uv->buf_addr_lo = val; +-- +2.47.3 + diff --git a/kvm-hw-uefi-return-success-for-notifications.patch b/kvm-hw-uefi-return-success-for-notifications.patch new file mode 100644 index 0000000..575d3a4 --- /dev/null +++ b/kvm-hw-uefi-return-success-for-notifications.patch @@ -0,0 +1,47 @@ +From 8de5fa7675b189119e95cf0c82d6fe41a17f1fcd Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Mon, 11 Aug 2025 15:01:08 +0200 +Subject: [PATCH 2/3] hw/uefi: return success for notifications +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Gerd Hoffmann +RH-MergeRequest: 481: hw/uefi: clear uefi-vars buffer in uefi_vars_write callback +RH-Jira: RHEL-108614 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [2/3] 22174635fd787fa1cbd67bd8baa2550ad5009dba + +Set status to SUCCESS for ready-to-boot and exit-boot-services +notification calls. + +Reviewed-by: Philippe Mathieu-DaudĂ© +Signed-off-by: Gerd Hoffmann +Message-ID: <20250811130110.820958-2-kraxel@redhat.com> +(cherry picked from commit 88e5a28d5aabb57f44c1805fbba0a458023f5106) +--- + hw/uefi/var-service-vars.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/hw/uefi/var-service-vars.c b/hw/uefi/var-service-vars.c +index 7f98d77a38..58ae560d6e 100644 +--- a/hw/uefi/var-service-vars.c ++++ b/hw/uefi/var-service-vars.c +@@ -702,12 +702,14 @@ uint32_t uefi_vars_mm_vars_proto(uefi_vars_state *uv) + case SMM_VARIABLE_FUNCTION_READY_TO_BOOT: + trace_uefi_event("ready-to-boot"); + uv->ready_to_boot = true; ++ mvar->status = EFI_SUCCESS; + length = 0; + break; + + case SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE: + trace_uefi_event("exit-boot-service"); + uv->exit_boot_service = true; ++ mvar->status = EFI_SUCCESS; + length = 0; + break; + +-- +2.47.3 + diff --git a/kvm-hw-ufs-lu-skip-automatic-zero-init-of-large-array.patch b/kvm-hw-ufs-lu-skip-automatic-zero-init-of-large-array.patch index 2f80b7a..430b484 100644 --- a/kvm-hw-ufs-lu-skip-automatic-zero-init-of-large-array.patch +++ b/kvm-hw-ufs-lu-skip-automatic-zero-init-of-large-array.patch @@ -1,16 +1,16 @@ -From 31235ee1ebeb34c16f2673b9c86a585031344bca Mon Sep 17 00:00:00 2001 +From b6904ecdbd09b38339963465dd9bd81c25acf5cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:37:07 +0100 -Subject: [PATCH 29/31] hw/ufs/lu: skip automatic zero-init of large array +Subject: [PATCH 37/43] hw/ufs/lu: 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 -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 -RH-Commit: [28/30] 2a9adaeaed2689cb9915cbd9f4dc9a310a63b25c +RH-Commit: [29/31] 9b4da8039e1856614cd65981c2ec0a4b59c4e379 (stefanha/centos-stream-qemu-kvm) The 'ufs_emulate_scsi_cmd' method has a 4k byte array used for copying data from the device. Skip the automatic zero-init of @@ -33,7 +33,7 @@ Signed-off-by: Stefan Hajnoczi 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ufs/lu.c b/hw/ufs/lu.c -index 81bfff9b4e..caad82dcc4 100644 +index 1c3794b2d4..63e482bf83 100644 --- a/hw/ufs/lu.c +++ b/hw/ufs/lu.c @@ -194,7 +194,7 @@ static int ufs_emulate_wlun_inquiry(UfsRequest *req, uint8_t *outbuf, diff --git a/kvm-hw-usb-hcd-ohci-skip-automatic-zero-init-of-large-ar.patch b/kvm-hw-usb-hcd-ohci-skip-automatic-zero-init-of-large-ar.patch index 4e1d56e..4d09fdf 100644 --- a/kvm-hw-usb-hcd-ohci-skip-automatic-zero-init-of-large-ar.patch +++ b/kvm-hw-usb-hcd-ohci-skip-automatic-zero-init-of-large-ar.patch @@ -1,17 +1,17 @@ -From 1fec74f62de4a34351d4f315b5f6372498b1a56a Mon Sep 17 00:00:00 2001 +From d906c6d5ce5b69083890f4ceea4136e736704aab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:37:04 +0100 -Subject: [PATCH 26/31] hw/usb/hcd-ohci: skip automatic zero-init of large +Subject: [PATCH 34/43] hw/usb/hcd-ohci: 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 -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 -RH-Commit: [25/30] bb77133a42314bfdc52dc7d97602ffe6f102a40c +RH-Commit: [26/31] 4a8000f1c5065bfc95318615952c62f7070500d9 (stefanha/centos-stream-qemu-kvm) The 'ohci_service_iso_td' method has a 8k byte array used for copying data between guest and host. Skip the automatic zero-init of this diff --git a/kvm-hw-virtio-fix-crash-in-processing-balloon-stats.patch b/kvm-hw-virtio-fix-crash-in-processing-balloon-stats.patch deleted file mode 100644 index 31bbbbe..0000000 --- a/kvm-hw-virtio-fix-crash-in-processing-balloon-stats.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 58ad1bbfe399cecf0f05ebc70d2d3189fb78851d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= -Date: Fri, 29 Nov 2024 13:55:05 +0000 -Subject: [PATCH 2/4] hw/virtio: fix crash in processing balloon stats -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 322: hw/virtio: fix crash in processing balloon stats -RH-Jira: RHEL-73835 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Daniel P. BerrangĂ© -RH-Commit: [1/1] 7a0f9b816b1ce5f82ae6d0f4686fbb2ca0632e00 (thuth/qemu-kvm-cs9) - -balloon_stats_get_all will iterate over guest stats upto the max -VIRTIO_BALLOON_S_NR value, calling visit_type_uint64 to populate -the QObject dict. The dict keys are obtained from the static -array balloon_stat_names which is VIRTIO_BALLOON_S_NR in size. - -Unfortunately the way that array is declared results in any -unassigned stats getting a NULL name, which will then cause -visit_type_uint64 to trigger an assert in qobject_output_add_obj. - -The balloon_stat_names array was fortunately fully populated with -names until recently: - - commit 0d2eeef77a33315187df8519491a900bde4a3d83 - Author: Bibo Mao - Date: Mon Oct 28 10:38:09 2024 +0800 - - linux-headers: Update to Linux v6.12-rc5 - -pulled a change to include/standard-headers/linux/virtio_balloon.h -which increased VIRTIO_BALLOON_S_NR by 6, and failed to add the new -names to balloon_stat_names. - -This commit fills in the missing names, and uses a static assert to -guarantee that any future changes to VIRTIO_BALLOON_S_NR will cause -a build failure until balloon_stat_names is updated. - -This problem was detected by the Cockpit Project's automated -integration tests on QEMU 9.2.0-rc1. - -Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2329448 -Fixes: 0d2eeef77a3 ("linux-headers: Update to Linux v6.12-rc5") -Reported-by: Martin Pitt -Reviewed-by: Richard W.M. Jones -Signed-off-by: Daniel P. BerrangĂ© -Reviewed-by: David Hildenbrand -Reviewed-by: Michael Tokarev -Acked-by: Michael S. Tsirkin -Message-ID: <20241129135507.699030-2-berrange@redhat.com> -Signed-off-by: Philippe Mathieu-DaudĂ© -(cherry picked from commit bff1050a5630ce5da6f43ed002725d52140bb9e6) -Signed-off-by: Thomas Huth ---- - hw/virtio/virtio-balloon.c | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) - -diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c -index 609e39a821..afd2ad6dd6 100644 ---- a/hw/virtio/virtio-balloon.c -+++ b/hw/virtio/virtio-balloon.c -@@ -167,19 +167,33 @@ static void balloon_deflate_page(VirtIOBalloon *balloon, - } - } - -+/* -+ * All stats upto VIRTIO_BALLOON_S_NR /must/ have a -+ * non-NULL name declared here, since these are used -+ * as keys for populating the QDict with stats -+ */ - static const char *balloon_stat_names[] = { - [VIRTIO_BALLOON_S_SWAP_IN] = "stat-swap-in", - [VIRTIO_BALLOON_S_SWAP_OUT] = "stat-swap-out", - [VIRTIO_BALLOON_S_MAJFLT] = "stat-major-faults", - [VIRTIO_BALLOON_S_MINFLT] = "stat-minor-faults", - [VIRTIO_BALLOON_S_MEMFREE] = "stat-free-memory", -+ - [VIRTIO_BALLOON_S_MEMTOT] = "stat-total-memory", - [VIRTIO_BALLOON_S_AVAIL] = "stat-available-memory", - [VIRTIO_BALLOON_S_CACHES] = "stat-disk-caches", - [VIRTIO_BALLOON_S_HTLB_PGALLOC] = "stat-htlb-pgalloc", - [VIRTIO_BALLOON_S_HTLB_PGFAIL] = "stat-htlb-pgfail", -- [VIRTIO_BALLOON_S_NR] = NULL -+ -+ [VIRTIO_BALLOON_S_OOM_KILL] = "stat-oom-kills", -+ [VIRTIO_BALLOON_S_ALLOC_STALL] = "stat-alloc-stalls", -+ [VIRTIO_BALLOON_S_ASYNC_SCAN] = "stat-async-scans", -+ [VIRTIO_BALLOON_S_DIRECT_SCAN] = "stat-direct-scans", -+ [VIRTIO_BALLOON_S_ASYNC_RECLAIM] = "stat-async-reclaims", -+ -+ [VIRTIO_BALLOON_S_DIRECT_RECLAIM] = "stat-direct-reclaims", - }; -+G_STATIC_ASSERT(G_N_ELEMENTS(balloon_stat_names) == VIRTIO_BALLOON_S_NR); - - /* - * reset_stats - Mark all items in the stats array as unset --- -2.39.3 - diff --git a/kvm-hw-virtio-virtio-avoid-cost-of-ftrivial-auto-var-ini.patch b/kvm-hw-virtio-virtio-avoid-cost-of-ftrivial-auto-var-ini.patch index 3682b8e..85fb74b 100644 --- a/kvm-hw-virtio-virtio-avoid-cost-of-ftrivial-auto-var-ini.patch +++ b/kvm-hw-virtio-virtio-avoid-cost-of-ftrivial-auto-var-ini.patch @@ -1,17 +1,17 @@ -From 2089707620066ae567466918fdb733db23e4f87a Mon Sep 17 00:00:00 2001 +From 6063d3fedb2767f1a4d668828f49ef8505fa54f3 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Tue, 10 Jun 2025 13:36:40 +0100 -Subject: [PATCH 03/31] hw/virtio/virtio: avoid cost of -ftrivial-auto-var-init +Subject: [PATCH 10/43] hw/virtio/virtio: avoid cost of -ftrivial-auto-var-init in hot path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RH-Author: Stefan Hajnoczi -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 -RH-Commit: [2/30] 0d56c3259da6f71f03be563622ce58714fe5bde8 +RH-Commit: [2/31] 12f251ba363203812e46f268a6f46ccfdbf21b41 (stefanha/centos-stream-qemu-kvm) Since commit 7ff9ff039380 ("meson: mitigate against use of uninitialize stack for exploits") the -ftrivial-auto-var-init=zero compiler option is @@ -43,7 +43,7 @@ Signed-off-by: Stefan Hajnoczi 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index 10f24a58dd..7f7b178a50 100644 +index 85110bce37..f41a418da3 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -1680,8 +1680,8 @@ static void *virtqueue_split_pop(VirtQueue *vq, size_t sz) diff --git a/kvm-i386-Introduce-tdx-guest-object.patch b/kvm-i386-Introduce-tdx-guest-object.patch new file mode 100644 index 0000000..f575bea --- /dev/null +++ b/kvm-i386-Introduce-tdx-guest-object.patch @@ -0,0 +1,206 @@ +From 1718cfaf922e867eb361bed009b43ea1c4a8f479 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:45 +0200 +Subject: [PATCH 016/100] i386: Introduce tdx-guest object +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduce tdx-guest object which inherits X86_CONFIDENTIAL_GUEST, +and will be used to create TDX VMs (TDs) by + + qemu -machine ...,confidential-guest-support=tdx0 \ + -object tdx-guest,id=tdx0 + +It has one QAPI member 'attributes' defined, which allows user to set +TD's attributes directly. + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Acked-by: Markus Armbruster +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-3-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 756e12e791771034ac105a5d2c9887bbbb6b7c73) +Signed-off-by: Paolo Bonzini + +Conflict: class_init's second argument is not const +--- + configs/devices/i386-softmmu/default.mak | 1 + + hw/i386/Kconfig | 5 +++ + qapi/qom.json | 15 +++++++++ + target/i386/kvm/meson.build | 2 ++ + target/i386/kvm/tdx.c | 43 ++++++++++++++++++++++++ + target/i386/kvm/tdx.h | 21 ++++++++++++ + 6 files changed, 87 insertions(+) + create mode 100644 target/i386/kvm/tdx.c + create mode 100644 target/i386/kvm/tdx.h + +diff --git a/configs/devices/i386-softmmu/default.mak b/configs/devices/i386-softmmu/default.mak +index 4faf2f0315..bc0479a7e0 100644 +--- a/configs/devices/i386-softmmu/default.mak ++++ b/configs/devices/i386-softmmu/default.mak +@@ -18,6 +18,7 @@ + #CONFIG_QXL=n + #CONFIG_SEV=n + #CONFIG_SGA=n ++#CONFIG_TDX=n + #CONFIG_TEST_DEVICES=n + #CONFIG_TPM_CRB=n + #CONFIG_TPM_TIS_ISA=n +diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig +index d34ce07b21..cce9521ba9 100644 +--- a/hw/i386/Kconfig ++++ b/hw/i386/Kconfig +@@ -10,6 +10,10 @@ config SGX + bool + depends on KVM + ++config TDX ++ bool ++ depends on KVM ++ + config PC + bool + imply APPLESMC +@@ -26,6 +30,7 @@ config PC + imply QXL + imply SEV + imply SGX ++ imply TDX + imply TEST_DEVICES + imply TPM_CRB + imply TPM_TIS_ISA +diff --git a/qapi/qom.json b/qapi/qom.json +index 28ce24cd8d..c0b61df964 100644 +--- a/qapi/qom.json ++++ b/qapi/qom.json +@@ -1047,6 +1047,19 @@ + '*host-data': 'str', + '*vcek-disabled': 'bool' } } + ++## ++# @TdxGuestProperties: ++# ++# Properties for tdx-guest objects. ++# ++# @attributes: The 'attributes' of a TD guest that is passed to ++# KVM_TDX_INIT_VM ++# ++# Since: 10.1 ++## ++{ 'struct': 'TdxGuestProperties', ++ 'data': { '*attributes': 'uint64' } } ++ + ## + # @ThreadContextProperties: + # +@@ -1132,6 +1145,7 @@ + 'sev-snp-guest', + 'thread-context', + 's390-pv-guest', ++ 'tdx-guest', + 'throttle-group', + 'tls-creds-anon', + 'tls-creds-psk', +@@ -1204,6 +1218,7 @@ + 'if': 'CONFIG_SECRET_KEYRING' }, + 'sev-guest': 'SevGuestProperties', + 'sev-snp-guest': 'SevSnpGuestProperties', ++ 'tdx-guest': 'TdxGuestProperties', + 'thread-context': 'ThreadContextProperties', + 'throttle-group': 'ThrottleGroupProperties', + 'tls-creds-anon': 'TlsCredsAnonProperties', +diff --git a/target/i386/kvm/meson.build b/target/i386/kvm/meson.build +index 3996cafaf2..466bccb9cb 100644 +--- a/target/i386/kvm/meson.build ++++ b/target/i386/kvm/meson.build +@@ -8,6 +8,8 @@ i386_kvm_ss.add(files( + + i386_kvm_ss.add(when: 'CONFIG_XEN_EMU', if_true: files('xen-emu.c')) + ++i386_kvm_ss.add(when: 'CONFIG_TDX', if_true: files('tdx.c')) ++ + i386_system_ss.add(when: 'CONFIG_HYPERV', if_true: files('hyperv.c'), if_false: files('hyperv-stub.c')) + + i386_system_ss.add_all(when: 'CONFIG_KVM', if_true: i386_kvm_ss) +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +new file mode 100644 +index 0000000000..ec84ae2947 +--- /dev/null ++++ b/target/i386/kvm/tdx.c +@@ -0,0 +1,43 @@ ++/* ++ * QEMU TDX support ++ * ++ * Copyright (c) 2025 Intel Corporation ++ * ++ * Author: ++ * Xiaoyao Li ++ * ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ */ ++ ++#include "qemu/osdep.h" ++#include "qom/object_interfaces.h" ++ ++#include "tdx.h" ++ ++/* tdx guest */ ++OBJECT_DEFINE_TYPE_WITH_INTERFACES(TdxGuest, ++ tdx_guest, ++ TDX_GUEST, ++ X86_CONFIDENTIAL_GUEST, ++ { TYPE_USER_CREATABLE }, ++ { NULL }) ++ ++static void tdx_guest_init(Object *obj) ++{ ++ ConfidentialGuestSupport *cgs = CONFIDENTIAL_GUEST_SUPPORT(obj); ++ TdxGuest *tdx = TDX_GUEST(obj); ++ ++ cgs->require_guest_memfd = true; ++ tdx->attributes = 0; ++ ++ object_property_add_uint64_ptr(obj, "attributes", &tdx->attributes, ++ OBJ_PROP_FLAG_READWRITE); ++} ++ ++static void tdx_guest_finalize(Object *obj) ++{ ++} ++ ++static void tdx_guest_class_init(ObjectClass *oc, void *data) ++{ ++} +diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h +new file mode 100644 +index 0000000000..f3b7253361 +--- /dev/null ++++ b/target/i386/kvm/tdx.h +@@ -0,0 +1,21 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#ifndef QEMU_I386_TDX_H ++#define QEMU_I386_TDX_H ++ ++#include "confidential-guest.h" ++ ++#define TYPE_TDX_GUEST "tdx-guest" ++#define TDX_GUEST(obj) OBJECT_CHECK(TdxGuest, (obj), TYPE_TDX_GUEST) ++ ++typedef struct TdxGuestClass { ++ X86ConfidentialGuestClass parent_class; ++} TdxGuestClass; ++ ++typedef struct TdxGuest { ++ X86ConfidentialGuest parent_obj; ++ ++ uint64_t attributes; /* TD attributes */ ++} TdxGuest; ++ ++#endif /* QEMU_I386_TDX_H */ +-- +2.47.3 + diff --git a/kvm-i386-Remove-unused-parameter-uint32_t-bit-in-feature.patch b/kvm-i386-Remove-unused-parameter-uint32_t-bit-in-feature.patch new file mode 100644 index 0000000..760a382 --- /dev/null +++ b/kvm-i386-Remove-unused-parameter-uint32_t-bit-in-feature.patch @@ -0,0 +1,54 @@ +From 596e05c6bbb27e9d4783464c5fd49ef1f20fde1e Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:44 +0200 +Subject: [PATCH 001/100] i386: Remove unused parameter "uint32_t bit" in + feature_word_description() + +Parameter "uint32_t bit" is not used in function feature_word_description(), +so remove it. + +Signed-off-by: Lei Wang +Reviewed-by: Igor Mammedov +Reviewed-by: Xiaoyao Li +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Message-ID: <20241217123932.948789-2-xiaoyao.li@intel.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit bab32b8b4bf9da5d13386c8faa5a9389e63244b7) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 3e31999d19..86a7dd1c77 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -6184,7 +6184,7 @@ static const TypeInfo max_x86_cpu_type_info = { + .class_init = max_x86_cpu_class_init, + }; + +-static char *feature_word_description(FeatureWordInfo *f, uint32_t bit) ++static char *feature_word_description(FeatureWordInfo *f) + { + assert(f->type == CPUID_FEATURE_WORD || f->type == MSR_FEATURE_WORD); + +@@ -6223,6 +6223,7 @@ static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint64_t mask, + CPUX86State *env = &cpu->env; + FeatureWordInfo *f = &feature_word_info[w]; + int i; ++ g_autofree char *feat_word_str = feature_word_description(f); + + if (!cpu->force_features) { + env->features[w] &= ~mask; +@@ -6235,7 +6236,6 @@ static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint64_t mask, + + for (i = 0; i < 64; ++i) { + if ((1ULL << i) & mask) { +- g_autofree char *feat_word_str = feature_word_description(f, i); + warn_report("%s: %s%s%s [bit %d]", + verbose_prefix, + feat_word_str, +-- +2.47.3 + diff --git a/kvm-i386-apic-Skip-kvm_apic_put-for-TDX.patch b/kvm-i386-apic-Skip-kvm_apic_put-for-TDX.patch new file mode 100644 index 0000000..be9e7af --- /dev/null +++ b/kvm-i386-apic-Skip-kvm_apic_put-for-TDX.patch @@ -0,0 +1,55 @@ +From 7b7bddc0fed46d4d671dfb73e25608a9b4154afa Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:48 +0200 +Subject: [PATCH 055/100] i386/apic: Skip kvm_apic_put() for TDX + +KVM neithers allow writing to MSR_IA32_APICBASE for TDs, nor allow for +KVM_SET_LAPIC[*]. + +Note, KVM_GET_LAPIC is also disallowed for TDX. It is called in the path + + do_kvm_cpu_synchronize_state() + -> kvm_arch_get_registers() + -> kvm_get_apic() + +and it's already disllowed for confidential guest through +guest_state_protected. + +[*] https://lore.kernel.org/all/Z3w4Ku4Jq0CrtXne@google.com/ + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-42-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 62a1a8b89d90cd3fbee0e6d38e6a4c0d833e978a) +Signed-off-by: Paolo Bonzini +--- + hw/i386/kvm/apic.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c +index 7575106000..cb65fca495 100644 +--- a/hw/i386/kvm/apic.c ++++ b/hw/i386/kvm/apic.c +@@ -17,6 +17,7 @@ + #include "system/hw_accel.h" + #include "system/kvm.h" + #include "kvm/kvm_i386.h" ++#include "kvm/tdx.h" + + static inline void kvm_apic_set_reg(struct kvm_lapic_state *kapic, + int reg_id, uint32_t val) +@@ -141,6 +142,10 @@ static void kvm_apic_put(CPUState *cs, run_on_cpu_data data) + struct kvm_lapic_state kapic; + int ret; + ++ if (is_tdx_vm()) { ++ return; ++ } ++ + kvm_put_apicbase(s->cpu, s->apicbase); + kvm_put_apic_state(s, &kapic); + +-- +2.47.3 + diff --git a/kvm-i386-cgs-Introduce-x86_confidential_guest_check_feat.patch b/kvm-i386-cgs-Introduce-x86_confidential_guest_check_feat.patch new file mode 100644 index 0000000..8868995 --- /dev/null +++ b/kvm-i386-cgs-Introduce-x86_confidential_guest_check_feat.patch @@ -0,0 +1,72 @@ +From b7021bfb1502f918d8f58998774437b0cb544c6b Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:48 +0200 +Subject: [PATCH 064/100] i386/cgs: Introduce + x86_confidential_guest_check_features() + +To do cgs specific feature checking. Note the feature checking in +x86_cpu_filter_features() is valid for non-cgs VMs. For cgs VMs like +TDX, what features can be supported has more restrictions. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-51-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit dc0b08b303ad34983b43936a4c978672e0f9a9d8) +Signed-off-by: Paolo Bonzini +--- + target/i386/confidential-guest.h | 13 +++++++++++++ + target/i386/kvm/kvm.c | 8 ++++++++ + 2 files changed, 21 insertions(+) + +diff --git a/target/i386/confidential-guest.h b/target/i386/confidential-guest.h +index 777d43cc96..48b88dbd31 100644 +--- a/target/i386/confidential-guest.h ++++ b/target/i386/confidential-guest.h +@@ -42,6 +42,7 @@ struct X86ConfidentialGuestClass { + void (*cpu_instance_init)(X86ConfidentialGuest *cg, CPUState *cpu); + uint32_t (*adjust_cpuid_features)(X86ConfidentialGuest *cg, uint32_t feature, + uint32_t index, int reg, uint32_t value); ++ int (*check_features)(X86ConfidentialGuest *cg, CPUState *cs); + }; + + /** +@@ -91,4 +92,16 @@ static inline int x86_confidential_guest_adjust_cpuid_features(X86ConfidentialGu + } + } + ++static inline int x86_confidential_guest_check_features(X86ConfidentialGuest *cg, ++ CPUState *cs) ++{ ++ X86ConfidentialGuestClass *klass = X86_CONFIDENTIAL_GUEST_GET_CLASS(cg); ++ ++ if (klass->check_features) { ++ return klass->check_features(cg, cs); ++ } ++ ++ return 0; ++} ++ + #endif +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index d1111f67c2..6eddb3d58e 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -2092,6 +2092,14 @@ int kvm_arch_init_vcpu(CPUState *cs) + int r; + Error *local_err = NULL; + ++ if (current_machine->cgs) { ++ r = x86_confidential_guest_check_features( ++ X86_CONFIDENTIAL_GUEST(current_machine->cgs), cs); ++ if (r < 0) { ++ return r; ++ } ++ } ++ + memset(&cpuid_data, 0, sizeof(cpuid_data)); + + cpuid_i = 0; +-- +2.47.3 + diff --git a/kvm-i386-cgs-Rename-mask_cpuid_features-to-adjust_cpuid_.patch b/kvm-i386-cgs-Rename-mask_cpuid_features-to-adjust_cpuid_.patch new file mode 100644 index 0000000..b373871 --- /dev/null +++ b/kvm-i386-cgs-Rename-mask_cpuid_features-to-adjust_cpuid_.patch @@ -0,0 +1,108 @@ +From 066c48e0071545c00a1c6e4cbf3dfcefb9d1301b Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:48 +0200 +Subject: [PATCH 057/100] i386/cgs: Rename *mask_cpuid_features() to + *adjust_cpuid_features() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Because for TDX case, there are also fixed-1 bits that enforced by TDX +module. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-44-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 695bfaee7153153708228946aa26c6d879599c04) +Signed-off-by: Paolo Bonzini +--- + target/i386/confidential-guest.h | 20 ++++++++++---------- + target/i386/kvm/kvm.c | 2 +- + target/i386/sev.c | 4 ++-- + 3 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/target/i386/confidential-guest.h b/target/i386/confidential-guest.h +index a86c42a475..777d43cc96 100644 +--- a/target/i386/confidential-guest.h ++++ b/target/i386/confidential-guest.h +@@ -40,8 +40,8 @@ struct X86ConfidentialGuestClass { + /* */ + int (*kvm_type)(X86ConfidentialGuest *cg); + void (*cpu_instance_init)(X86ConfidentialGuest *cg, CPUState *cpu); +- uint32_t (*mask_cpuid_features)(X86ConfidentialGuest *cg, uint32_t feature, uint32_t index, +- int reg, uint32_t value); ++ uint32_t (*adjust_cpuid_features)(X86ConfidentialGuest *cg, uint32_t feature, ++ uint32_t index, int reg, uint32_t value); + }; + + /** +@@ -71,21 +71,21 @@ static inline void x86_confidential_guest_cpu_instance_init(X86ConfidentialGuest + } + + /** +- * x86_confidential_guest_mask_cpuid_features: ++ * x86_confidential_guest_adjust_cpuid_features: + * +- * Removes unsupported features from a confidential guest's CPUID values, returns +- * the value with the bits removed. The bits removed should be those that KVM +- * provides independent of host-supported CPUID features, but are not supported by +- * the confidential computing firmware. ++ * Adjust the supported features from a confidential guest's CPUID values, ++ * returns the adjusted value. There are bits being removed that are not ++ * supported by the confidential computing firmware or bits being added that ++ * are forcibly exposed to guest by the confidential computing firmware. + */ +-static inline int x86_confidential_guest_mask_cpuid_features(X86ConfidentialGuest *cg, ++static inline int x86_confidential_guest_adjust_cpuid_features(X86ConfidentialGuest *cg, + uint32_t feature, uint32_t index, + int reg, uint32_t value) + { + X86ConfidentialGuestClass *klass = X86_CONFIDENTIAL_GUEST_GET_CLASS(cg); + +- if (klass->mask_cpuid_features) { +- return klass->mask_cpuid_features(cg, feature, index, reg, value); ++ if (klass->adjust_cpuid_features) { ++ return klass->adjust_cpuid_features(cg, feature, index, reg, value); + } else { + return value; + } +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 3d58966f60..c3cecd871b 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -573,7 +573,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, + } + + if (current_machine->cgs) { +- ret = x86_confidential_guest_mask_cpuid_features( ++ ret = x86_confidential_guest_adjust_cpuid_features( + X86_CONFIDENTIAL_GUEST(current_machine->cgs), + function, index, reg, ret); + } +diff --git a/target/i386/sev.c b/target/i386/sev.c +index ba88976e9f..56b12d7403 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -946,7 +946,7 @@ out: + } + + static uint32_t +-sev_snp_mask_cpuid_features(X86ConfidentialGuest *cg, uint32_t feature, uint32_t index, ++sev_snp_adjust_cpuid_features(X86ConfidentialGuest *cg, uint32_t feature, uint32_t index, + int reg, uint32_t value) + { + switch (feature) { +@@ -2404,7 +2404,7 @@ sev_snp_guest_class_init(ObjectClass *oc, void *data) + klass->launch_finish = sev_snp_launch_finish; + klass->launch_update_data = sev_snp_launch_update_data; + klass->kvm_init = sev_snp_kvm_init; +- x86_klass->mask_cpuid_features = sev_snp_mask_cpuid_features; ++ x86_klass->adjust_cpuid_features = sev_snp_adjust_cpuid_features; + x86_klass->kvm_type = sev_snp_kvm_type; + + object_class_property_add(oc, "policy", "uint64", +-- +2.47.3 + diff --git a/kvm-i386-cpu-Cleanup-host_cpu_max_instance_init.patch b/kvm-i386-cpu-Cleanup-host_cpu_max_instance_init.patch new file mode 100644 index 0000000..9d01bca --- /dev/null +++ b/kvm-i386-cpu-Cleanup-host_cpu_max_instance_init.patch @@ -0,0 +1,41 @@ +From 22156c1abec6f1d905c62091ce34dfee34cdfa18 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:50 +0200 +Subject: [PATCH 092/100] i386/cpu: Cleanup host_cpu_max_instance_init() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The implementation of host_cpu_max_instance_init() was merged into +host_cpu_instance_init() by commit 29f1ba338baf ("target/i386: merge +host_cpu_instance_init() and host_cpu_max_instance_init()"), while the +declaration of it remains in host-cpu.h. + +Clean it up. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Philippe Mathieu-DaudĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250716063117.602050-1-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 5fe6b9a854a91df86fdb794cbeb67d0656756137) +Signed-off-by: Paolo Bonzini +--- + target/i386/host-cpu.h | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/target/i386/host-cpu.h b/target/i386/host-cpu.h +index b97ec01c9b..5b2ad491a8 100644 +--- a/target/i386/host-cpu.h ++++ b/target/i386/host-cpu.h +@@ -12,7 +12,6 @@ + + uint32_t host_cpu_phys_bits(void); + void host_cpu_instance_init(X86CPU *cpu); +-void host_cpu_max_instance_init(X86CPU *cpu); + bool host_cpu_realizefn(CPUState *cs, Error **errp); + + void host_cpu_vendor_fms(char *vendor, int *family, int *model, int *stepping); +-- +2.47.3 + diff --git a/kvm-i386-cpu-Consolidate-the-helper-to-get-Host-s-vendor.patch b/kvm-i386-cpu-Consolidate-the-helper-to-get-Host-s-vendor.patch new file mode 100644 index 0000000..c165f06 --- /dev/null +++ b/kvm-i386-cpu-Consolidate-the-helper-to-get-Host-s-vendor.patch @@ -0,0 +1,70 @@ +From af71d6ff7cc571cb6db31a7304b6ce8cef2969db Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:45 +0200 +Subject: [PATCH 005/100] i386/cpu: Consolidate the helper to get Host's vendor + +Extend host_cpu_vendor_fms() to help more cases to get Host's vendor +information. + +Cc: Dongli Zhang +Signed-off-by: Zhao Liu +Link: https://lore.kernel.org/r/20250410075619.145792-1-zhao1.liu@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit ae39acef49e29169f90cd3a799d6cd0b50bc65d2) +Signed-off-by: Paolo Bonzini +--- + target/i386/host-cpu.c | 10 ++++++---- + target/i386/kvm/vmsr_energy.c | 3 +-- + 2 files changed, 7 insertions(+), 6 deletions(-) + +diff --git a/target/i386/host-cpu.c b/target/i386/host-cpu.c +index 3e4e85e729..072731a4dd 100644 +--- a/target/i386/host-cpu.c ++++ b/target/i386/host-cpu.c +@@ -109,9 +109,13 @@ void host_cpu_vendor_fms(char *vendor, int *family, int *model, int *stepping) + { + uint32_t eax, ebx, ecx, edx; + +- host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx); ++ host_cpuid(0x0, 0, NULL, &ebx, &ecx, &edx); + x86_cpu_vendor_words2str(vendor, ebx, edx, ecx); + ++ if (!family && !model && !stepping) { ++ return; ++ } ++ + host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx); + if (family) { + *family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF); +@@ -129,11 +133,9 @@ void host_cpu_instance_init(X86CPU *cpu) + X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu); + + if (xcc->model) { +- uint32_t ebx = 0, ecx = 0, edx = 0; + char vendor[CPUID_VENDOR_SZ + 1]; + +- host_cpuid(0, 0, NULL, &ebx, &ecx, &edx); +- x86_cpu_vendor_words2str(vendor, ebx, edx, ecx); ++ host_cpu_vendor_fms(vendor, NULL, NULL, NULL); + object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abort); + } + } +diff --git a/target/i386/kvm/vmsr_energy.c b/target/i386/kvm/vmsr_energy.c +index 31508d4e77..f499ec6e8b 100644 +--- a/target/i386/kvm/vmsr_energy.c ++++ b/target/i386/kvm/vmsr_energy.c +@@ -29,10 +29,9 @@ char *vmsr_compute_default_paths(void) + + bool is_host_cpu_intel(void) + { +- int family, model, stepping; + char vendor[CPUID_VENDOR_SZ + 1]; + +- host_cpu_vendor_fms(vendor, &family, &model, &stepping); ++ host_cpu_vendor_fms(vendor, NULL, NULL, NULL); + + return g_str_equal(vendor, CPUID_VENDOR_INTEL); + } +-- +2.47.3 + diff --git a/kvm-i386-cpu-Introduce-enable_cpuid_0x1f-to-force-exposi.patch b/kvm-i386-cpu-Introduce-enable_cpuid_0x1f-to-force-exposi.patch new file mode 100644 index 0000000..6a4cdf7 --- /dev/null +++ b/kvm-i386-cpu-Introduce-enable_cpuid_0x1f-to-force-exposi.patch @@ -0,0 +1,97 @@ +From 60debdcd44d072b46a5855a735e4fb2a3f6f3ce7 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:47 +0200 +Subject: [PATCH 047/100] i386/cpu: Introduce enable_cpuid_0x1f to force + exposing CPUID 0x1f + +Currently, QEMU exposes CPUID 0x1f to guest only when necessary, i.e., +when topology level that cannot be enumerated by leaf 0xB, e.g., die or +module level, are configured for the guest, e.g., -smp xx,dies=2. + +However, TDX architecture forces to require CPUID 0x1f to configure CPU +topology. + +Introduce a bool flag, enable_cpuid_0x1f, in CPU for the case that +requires CPUID leaf 0x1f to be exposed to guest. + +Introduce a new function x86_has_cpuid_0x1f(), which is the wrapper of +cpu->enable_cpuid_0x1f and x86_has_extended_topo() to check if it needs +to enable cpuid leaf 0x1f for the guest. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-34-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit ab8bd85adf75900edc2764d0ebe8b53867cc54aa) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 4 ++-- + target/i386/cpu.h | 9 +++++++++ + target/i386/kvm/kvm.c | 2 +- + 3 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index a6da8c0c88..cb5a8de684 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -7460,7 +7460,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, + break; + case 0x1F: + /* V2 Extended Topology Enumeration Leaf */ +- if (!x86_has_extended_topo(env->avail_cpu_topo)) { ++ if (!x86_has_cpuid_0x1f(cpu)) { + *eax = *ebx = *ecx = *edx = 0; + break; + } +@@ -8324,7 +8324,7 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) + * cpu->vendor_cpuid_only has been unset for compatibility with older + * machine types. + */ +- if (x86_has_extended_topo(env->avail_cpu_topo) && ++ if (x86_has_cpuid_0x1f(cpu) && + (IS_INTEL_CPU(env) || !cpu->vendor_cpuid_only)) { + x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x1F); + } +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index d7dcd59b2d..ed74dfeba8 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -2255,6 +2255,9 @@ struct ArchCPU { + /* Compatibility bits for old machine types: */ + bool enable_cpuid_0xb; + ++ /* Force to enable cpuid 0x1f */ ++ bool enable_cpuid_0x1f; ++ + /* Enable auto level-increase for all CPUID leaves */ + bool full_cpuid_auto_level; + +@@ -2517,6 +2520,12 @@ void host_cpuid(uint32_t function, uint32_t count, + uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); + bool cpu_has_x2apic_feature(CPUX86State *env); + ++static inline bool x86_has_cpuid_0x1f(X86CPU *cpu) ++{ ++ return cpu->enable_cpuid_0x1f || ++ x86_has_extended_topo(cpu->env.avail_cpu_topo); ++} ++ + /* helper.c */ + void x86_cpu_set_a20(X86CPU *cpu, int a20_state); + void cpu_sync_avx_hflag(CPUX86State *env); +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 8fb0e31b5e..6c3d7e9d85 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -1871,7 +1871,7 @@ uint32_t kvm_x86_build_cpuid(CPUX86State *env, struct kvm_cpuid_entry2 *entries, + break; + } + case 0x1f: +- if (!x86_has_extended_topo(env->avail_cpu_topo)) { ++ if (!x86_has_cpuid_0x1f(env_archcpu(env))) { + cpuid_i--; + break; + } +-- +2.47.3 + diff --git a/kvm-i386-cpu-Move-adjustment-of-CPUID_EXT_PDCM-before-fe.patch b/kvm-i386-cpu-Move-adjustment-of-CPUID_EXT_PDCM-before-fe.patch new file mode 100644 index 0000000..d300407 --- /dev/null +++ b/kvm-i386-cpu-Move-adjustment-of-CPUID_EXT_PDCM-before-fe.patch @@ -0,0 +1,51 @@ +From e8ce1b2ea0eecc36e6bf6df777c6d395d5679e26 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:49 +0200 +Subject: [PATCH 072/100] i386/cpu: Move adjustment of CPUID_EXT_PDCM before + feature_dependencies[] check + +There is one entry relates to CPUID_EXT_PDCM in feature_dependencies[]. +So it needs to get correct value of CPUID_EXT_PDCM before using +feature_dependencies[] to apply dependencies. + +Besides, it also ensures CPUID_EXT_PDCM value is tracked in +env->features[FEAT_1_ECX]. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250304052450.465445-2-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit e68ec2980901c8e7f948f3305770962806c53f0b) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 587da2cb84..7220181806 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -7309,9 +7309,6 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, + if (threads_per_pkg > 1) { + *ebx |= threads_per_pkg << 16; + } +- if (!cpu->enable_pmu) { +- *ecx &= ~CPUID_EXT_PDCM; +- } + break; + case 2: + /* cache info: needed for Pentium Pro compatibility */ +@@ -8301,6 +8298,10 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) + } + } + ++ if (!cpu->enable_pmu) { ++ env->features[FEAT_1_ECX] &= ~CPUID_EXT_PDCM; ++ } ++ + for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) { + FeatureDep *d = &feature_dependencies[i]; + if (!(env->features[d->from.index] & d->from.mask)) { +-- +2.47.3 + diff --git a/kvm-i386-cpu-Move-x86_ext_save_areas-initialization-to-..patch b/kvm-i386-cpu-Move-x86_ext_save_areas-initialization-to-..patch new file mode 100644 index 0000000..c31c45b --- /dev/null +++ b/kvm-i386-cpu-Move-x86_ext_save_areas-initialization-to-..patch @@ -0,0 +1,83 @@ +From c2ab5610affa19708d5a77a750431fdc45b0a3b4 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:50 +0200 +Subject: [PATCH 090/100] i386/cpu: Move x86_ext_save_areas[] initialization to + .instance_init + +In x86_cpu_post_initfn(), the initialization of x86_ext_save_areas[] +marks the unsupported xsave areas based on Host support. + +This step must be done before accel_cpu_instance_init(), otherwise, +KVM's assertion on host xsave support would fail: + +qemu-system-x86_64: ../target/i386/kvm/kvm-cpu.c:149: +kvm_cpu_xsave_init: Assertion `esa->size == eax' failed. + +(on AMD EPYC 7302 16-Core Processor) + +Move x86_ext_save_areas[] initialization to .instance_init and place it +before accel_cpu_instance_init(). + +Fixes: commit 5f158abef44c ("target/i386: move accel_cpu_instance_init to .instance_init") +Reported-by: Paolo Abeni +Tested-by: Paolo Abeni +Signed-off-by: Zhao Liu +Link: https://lore.kernel.org/r/20250717023933.2502109-1-zhao1.liu@intel.com +Reviewed-by: Xiaoyao Li +Signed-off-by: Paolo Bonzini +(cherry picked from commit e52af92e9e6f8fc00f2ae6b63214b3d6213b3cec) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 15ee4281ba..8ba92de50c 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -8975,6 +8975,16 @@ static void x86_cpu_register_feature_bit_props(X86CPUClass *xcc, + } + + static void x86_cpu_post_initfn(Object *obj) ++{ ++#ifndef CONFIG_USER_ONLY ++ if (current_machine && current_machine->cgs) { ++ x86_confidential_guest_cpu_instance_init( ++ X86_CONFIDENTIAL_GUEST(current_machine->cgs), (CPU(obj))); ++ } ++#endif ++} ++ ++static void x86_cpu_init_xsave(void) + { + static bool first = true; + uint64_t supported_xcr0; +@@ -8995,13 +9005,6 @@ static void x86_cpu_post_initfn(Object *obj) + } + } + } +- +-#ifndef CONFIG_USER_ONLY +- if (current_machine && current_machine->cgs) { +- x86_confidential_guest_cpu_instance_init( +- X86_CONFIDENTIAL_GUEST(current_machine->cgs), (CPU(obj))); +- } +-#endif + } + + static void x86_cpu_init_default_topo(X86CPU *cpu) +@@ -9071,6 +9074,11 @@ static void x86_cpu_initfn(Object *obj) + x86_cpu_load_model(cpu, xcc->model); + } + ++ /* ++ * accel's cpu_instance_init may have the xsave check, ++ * so x86_ext_save_areas[] must be initialized before this. ++ */ ++ x86_cpu_init_xsave(); + accel_cpu_instance_init(CPU(obj)); + } + +-- +2.47.3 + diff --git a/kvm-i386-cpu-Rename-enable_cpuid_0x1f-to-force_cpuid_0x1.patch b/kvm-i386-cpu-Rename-enable_cpuid_0x1f-to-force_cpuid_0x1.patch new file mode 100644 index 0000000..5606b11 --- /dev/null +++ b/kvm-i386-cpu-Rename-enable_cpuid_0x1f-to-force_cpuid_0x1.patch @@ -0,0 +1,65 @@ +From 5e159af244f9dfed5462d7248c3a90cfff5fa8dd Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:49 +0200 +Subject: [PATCH 074/100] i386/cpu: Rename enable_cpuid_0x1f to + force_cpuid_0x1f +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The name of "enable_cpuid_0x1f" isn't right to its behavior because the +leaf 0x1f can be enabled even when "enable_cpuid_0x1f" is false. + +Rename it to "force_cpuid_0x1f" to better reflect its behavior. + +Suggested-by: Igor Mammedov +Signed-off-by: Xiaoyao Li +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Igor Mammedov +Link: https://lore.kernel.org/r/20250603050305.1704586-2-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 90d2bbd1f6edfa22a056070ee62ded55099cd56d) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.h | 4 ++-- + target/i386/kvm/tdx.c | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 2ff5668dc9..3038746425 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -2282,7 +2282,7 @@ struct ArchCPU { + bool enable_cpuid_0xb; + + /* Force to enable cpuid 0x1f */ +- bool enable_cpuid_0x1f; ++ bool force_cpuid_0x1f; + + /* Enable auto level-increase for all CPUID leaves */ + bool full_cpuid_auto_level; +@@ -2553,7 +2553,7 @@ void mark_forced_on_features(X86CPU *cpu, FeatureWord w, uint64_t mask, + + static inline bool x86_has_cpuid_0x1f(X86CPU *cpu) + { +- return cpu->enable_cpuid_0x1f || ++ return cpu->force_cpuid_0x1f || + x86_has_extended_topo(cpu->env.avail_cpu_topo); + } + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 6ac1200c96..40516c9186 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -752,7 +752,7 @@ static void tdx_cpu_instance_init(X86ConfidentialGuest *cg, CPUState *cpu) + /* invtsc is fixed1 for TD guest */ + object_property_set_bool(OBJECT(cpu), "invtsc", true, &error_abort); + +- x86cpu->enable_cpuid_0x1f = true; ++ x86cpu->force_cpuid_0x1f = true; + } + + static uint32_t tdx_adjust_cpuid_features(X86ConfidentialGuest *cg, +-- +2.47.3 + diff --git a/kvm-i386-cpu-introduce-x86_confidential_guest_cpu_instan.patch b/kvm-i386-cpu-introduce-x86_confidential_guest_cpu_instan.patch new file mode 100644 index 0000000..f5a6c64 --- /dev/null +++ b/kvm-i386-cpu-introduce-x86_confidential_guest_cpu_instan.patch @@ -0,0 +1,77 @@ +From 5ee546fd1a41975882113bd2c121cc40ace472ee Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 25 Jul 2025 16:43:17 +0200 +Subject: [PATCH 045/100] i386/cpu: introduce + x86_confidential_guest_cpu_instance_init() + +To allow execute confidential guest specific cpu init operations. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-32-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 8583c53e2b619b1b9569d3f2d3f3cb2904a573ad) +Signed-off-by: Paolo Bonzini +--- + target/i386/confidential-guest.h | 11 +++++++++++ + target/i386/cpu.c | 8 ++++++++ + 2 files changed, 19 insertions(+) + +diff --git a/target/i386/confidential-guest.h b/target/i386/confidential-guest.h +index 164be7633a..a86c42a475 100644 +--- a/target/i386/confidential-guest.h ++++ b/target/i386/confidential-guest.h +@@ -39,6 +39,7 @@ struct X86ConfidentialGuestClass { + + /* */ + int (*kvm_type)(X86ConfidentialGuest *cg); ++ void (*cpu_instance_init)(X86ConfidentialGuest *cg, CPUState *cpu); + uint32_t (*mask_cpuid_features)(X86ConfidentialGuest *cg, uint32_t feature, uint32_t index, + int reg, uint32_t value); + }; +@@ -59,6 +60,16 @@ static inline int x86_confidential_guest_kvm_type(X86ConfidentialGuest *cg) + } + } + ++static inline void x86_confidential_guest_cpu_instance_init(X86ConfidentialGuest *cg, ++ CPUState *cpu) ++{ ++ X86ConfidentialGuestClass *klass = X86_CONFIDENTIAL_GUEST_GET_CLASS(cg); ++ ++ if (klass->cpu_instance_init) { ++ klass->cpu_instance_init(cg, cpu); ++ } ++} ++ + /** + * x86_confidential_guest_mask_cpuid_features: + * +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 3c15b7346c..a6da8c0c88 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -36,6 +36,7 @@ + #include "hw/qdev-properties.h" + #include "hw/i386/topology.h" + #ifndef CONFIG_USER_ONLY ++#include "confidential-guest.h" + #include "system/reset.h" + #include "qapi/qapi-commands-machine-target.h" + #include "system/address-spaces.h" +@@ -8958,6 +8959,13 @@ static void x86_cpu_post_initfn(Object *obj) + } + + accel_cpu_instance_init(CPU(obj)); ++ ++#ifndef CONFIG_USER_ONLY ++ if (current_machine && current_machine->cgs) { ++ x86_confidential_guest_cpu_instance_init( ++ X86_CONFIDENTIAL_GUEST(current_machine->cgs), (CPU(obj))); ++ } ++#endif + } + + static void x86_cpu_init_default_topo(X86CPU *cpu) +-- +2.47.3 + diff --git a/kvm-i386-tdvf-Fix-build-on-32-bit-host.patch b/kvm-i386-tdvf-Fix-build-on-32-bit-host.patch new file mode 100644 index 0000000..fa6b9ca --- /dev/null +++ b/kvm-i386-tdvf-Fix-build-on-32-bit-host.patch @@ -0,0 +1,47 @@ +From 14f3d68fbc5149bd4767b32d144f0e360c656b45 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:49 +0200 +Subject: [PATCH 071/100] i386/tdvf: Fix build on 32-bit host +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use PRI formats where required. + +Cc: Isaku Yamahata +Signed-off-by: CĂ©dric Le Goater +Link: https://lore.kernel.org/r/20250602173101.1052983-3-clg@redhat.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 6f1035fc65406c4e72e1dbd76e64924415edd616) +Signed-off-by: Paolo Bonzini +--- + hw/i386/tdvf.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/hw/i386/tdvf.c b/hw/i386/tdvf.c +index bd993ea2f0..645d9d1294 100644 +--- a/hw/i386/tdvf.c ++++ b/hw/i386/tdvf.c +@@ -101,16 +101,16 @@ static int tdvf_parse_and_check_section_entry(const TdvfSectionEntry *src, + + /* sanity check */ + if (entry->size < entry->data_len) { +- error_report("Broken metadata RawDataSize 0x%x MemoryDataSize 0x%lx", ++ error_report("Broken metadata RawDataSize 0x%x MemoryDataSize 0x%"PRIx64, + entry->data_len, entry->size); + return -1; + } + if (!QEMU_IS_ALIGNED(entry->address, TDVF_ALIGNMENT)) { +- error_report("MemoryAddress 0x%lx not page aligned", entry->address); ++ error_report("MemoryAddress 0x%"PRIx64" not page aligned", entry->address); + return -1; + } + if (!QEMU_IS_ALIGNED(entry->size, TDVF_ALIGNMENT)) { +- error_report("MemoryDataSize 0x%lx not page aligned", entry->size); ++ error_report("MemoryDataSize 0x%"PRIx64" not page aligned", entry->size); + return -1; + } + +-- +2.47.3 + diff --git a/kvm-i386-tdvf-Introduce-function-to-parse-TDVF-metadata.patch b/kvm-i386-tdvf-Introduce-function-to-parse-TDVF-metadata.patch new file mode 100644 index 0000000..3c066aa --- /dev/null +++ b/kvm-i386-tdvf-Introduce-function-to-parse-TDVF-metadata.patch @@ -0,0 +1,305 @@ +From eac34a8fbf8ccf374824748b8f54fa19179320b2 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 25 Jul 2025 16:40:22 +0200 +Subject: [PATCH 031/100] i386/tdvf: Introduce function to parse TDVF metadata + +TDX VM needs to boot with its specialized firmware, Trusted Domain +Virtual Firmware (TDVF). QEMU needs to parse TDVF and map it in TD +guest memory prior to running the TDX VM. + +A TDVF Metadata in TDVF image describes the structure of firmware. +QEMU refers to it to setup memory for TDVF. Introduce function +tdvf_parse_metadata() to parse the metadata from TDVF image and store +the info of each TDVF section. + +TDX metadata is located by a TDX metadata offset block, which is a +GUID-ed structure. The data portion of the GUID structure contains +only an 4-byte field that is the offset of TDX metadata to the end +of firmware file. + +Select X86_FW_OVMF when TDX is enable to leverage existing functions +to parse and search OVMF's GUID-ed structures. + +Signed-off-by: Isaku Yamahata +Co-developed-by: Xiaoyao Li +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-18-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit b65a6011d16c4f7cb2eb227ab1bc735850475288) +Signed-off-by: Paolo Bonzini +--- + hw/i386/Kconfig | 1 + + hw/i386/meson.build | 1 + + hw/i386/tdvf.c | 188 +++++++++++++++++++++++++++++++++++++++++ + include/hw/i386/tdvf.h | 38 +++++++++ + 4 files changed, 228 insertions(+) + create mode 100644 hw/i386/tdvf.c + create mode 100644 include/hw/i386/tdvf.h + +diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig +index cce9521ba9..eb65bda6e0 100644 +--- a/hw/i386/Kconfig ++++ b/hw/i386/Kconfig +@@ -12,6 +12,7 @@ config SGX + + config TDX + bool ++ select X86_FW_OVMF + depends on KVM + + config PC +diff --git a/hw/i386/meson.build b/hw/i386/meson.build +index 10bdfde27c..3bc1da2b6e 100644 +--- a/hw/i386/meson.build ++++ b/hw/i386/meson.build +@@ -32,6 +32,7 @@ i386_ss.add(when: 'CONFIG_PC', if_true: files( + 'port92.c')) + i386_ss.add(when: 'CONFIG_X86_FW_OVMF', if_true: files('pc_sysfw_ovmf.c'), + if_false: files('pc_sysfw_ovmf-stubs.c')) ++i386_ss.add(when: 'CONFIG_TDX', if_true: files('tdvf.c')) + + subdir('kvm') + subdir('xen') +diff --git a/hw/i386/tdvf.c b/hw/i386/tdvf.c +new file mode 100644 +index 0000000000..e2d486946a +--- /dev/null ++++ b/hw/i386/tdvf.c +@@ -0,0 +1,188 @@ ++/* ++ * Copyright (c) 2025 Intel Corporation ++ * Author: Isaku Yamahata ++ * ++ * Xiaoyao Li ++ * ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ */ ++ ++#include "qemu/osdep.h" ++#include "qemu/error-report.h" ++ ++#include "hw/i386/pc.h" ++#include "hw/i386/tdvf.h" ++#include "system/kvm.h" ++ ++#define TDX_METADATA_OFFSET_GUID "e47a6535-984a-4798-865e-4685a7bf8ec2" ++#define TDX_METADATA_VERSION 1 ++#define TDVF_SIGNATURE 0x46564454 /* TDVF as little endian */ ++#define TDVF_ALIGNMENT 4096 ++ ++/* ++ * the raw structs read from TDVF keeps the name convention in ++ * TDVF Design Guide spec. ++ */ ++typedef struct { ++ uint32_t DataOffset; ++ uint32_t RawDataSize; ++ uint64_t MemoryAddress; ++ uint64_t MemoryDataSize; ++ uint32_t Type; ++ uint32_t Attributes; ++} TdvfSectionEntry; ++ ++typedef struct { ++ uint32_t Signature; ++ uint32_t Length; ++ uint32_t Version; ++ uint32_t NumberOfSectionEntries; ++ TdvfSectionEntry SectionEntries[]; ++} TdvfMetadata; ++ ++struct tdx_metadata_offset { ++ uint32_t offset; ++}; ++ ++static TdvfMetadata *tdvf_get_metadata(void *flash_ptr, int size) ++{ ++ TdvfMetadata *metadata; ++ uint32_t offset = 0; ++ uint8_t *data; ++ ++ if ((uint32_t) size != size) { ++ return NULL; ++ } ++ ++ if (pc_system_ovmf_table_find(TDX_METADATA_OFFSET_GUID, &data, NULL)) { ++ offset = size - le32_to_cpu(((struct tdx_metadata_offset *)data)->offset); ++ ++ if (offset + sizeof(*metadata) > size) { ++ return NULL; ++ } ++ } else { ++ error_report("Cannot find TDX_METADATA_OFFSET_GUID"); ++ return NULL; ++ } ++ ++ metadata = flash_ptr + offset; ++ ++ /* Finally, verify the signature to determine if this is a TDVF image. */ ++ metadata->Signature = le32_to_cpu(metadata->Signature); ++ if (metadata->Signature != TDVF_SIGNATURE) { ++ error_report("Invalid TDVF signature in metadata!"); ++ return NULL; ++ } ++ ++ /* Sanity check that the TDVF doesn't overlap its own metadata. */ ++ metadata->Length = le32_to_cpu(metadata->Length); ++ if (offset + metadata->Length > size) { ++ return NULL; ++ } ++ ++ /* Only version 1 is supported/defined. */ ++ metadata->Version = le32_to_cpu(metadata->Version); ++ if (metadata->Version != TDX_METADATA_VERSION) { ++ return NULL; ++ } ++ ++ return metadata; ++} ++ ++static int tdvf_parse_and_check_section_entry(const TdvfSectionEntry *src, ++ TdxFirmwareEntry *entry) ++{ ++ entry->data_offset = le32_to_cpu(src->DataOffset); ++ entry->data_len = le32_to_cpu(src->RawDataSize); ++ entry->address = le64_to_cpu(src->MemoryAddress); ++ entry->size = le64_to_cpu(src->MemoryDataSize); ++ entry->type = le32_to_cpu(src->Type); ++ entry->attributes = le32_to_cpu(src->Attributes); ++ ++ /* sanity check */ ++ if (entry->size < entry->data_len) { ++ error_report("Broken metadata RawDataSize 0x%x MemoryDataSize 0x%lx", ++ entry->data_len, entry->size); ++ return -1; ++ } ++ if (!QEMU_IS_ALIGNED(entry->address, TDVF_ALIGNMENT)) { ++ error_report("MemoryAddress 0x%lx not page aligned", entry->address); ++ return -1; ++ } ++ if (!QEMU_IS_ALIGNED(entry->size, TDVF_ALIGNMENT)) { ++ error_report("MemoryDataSize 0x%lx not page aligned", entry->size); ++ return -1; ++ } ++ ++ switch (entry->type) { ++ case TDVF_SECTION_TYPE_BFV: ++ case TDVF_SECTION_TYPE_CFV: ++ /* The sections that must be copied from firmware image to TD memory */ ++ if (entry->data_len == 0) { ++ error_report("%d section with RawDataSize == 0", entry->type); ++ return -1; ++ } ++ break; ++ case TDVF_SECTION_TYPE_TD_HOB: ++ case TDVF_SECTION_TYPE_TEMP_MEM: ++ /* The sections that no need to be copied from firmware image */ ++ if (entry->data_len != 0) { ++ error_report("%d section with RawDataSize 0x%x != 0", ++ entry->type, entry->data_len); ++ return -1; ++ } ++ break; ++ default: ++ error_report("TDVF contains unsupported section type %d", entry->type); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++int tdvf_parse_metadata(TdxFirmware *fw, void *flash_ptr, int size) ++{ ++ g_autofree TdvfSectionEntry *sections = NULL; ++ TdvfMetadata *metadata; ++ ssize_t entries_size; ++ int i; ++ ++ metadata = tdvf_get_metadata(flash_ptr, size); ++ if (!metadata) { ++ return -EINVAL; ++ } ++ ++ /* load and parse metadata entries */ ++ fw->nr_entries = le32_to_cpu(metadata->NumberOfSectionEntries); ++ if (fw->nr_entries < 2) { ++ error_report("Invalid number of fw entries (%u) in TDVF Metadata", ++ fw->nr_entries); ++ return -EINVAL; ++ } ++ ++ entries_size = fw->nr_entries * sizeof(TdvfSectionEntry); ++ if (metadata->Length != sizeof(*metadata) + entries_size) { ++ error_report("TDVF metadata len (0x%x) mismatch, expected (0x%x)", ++ metadata->Length, ++ (uint32_t)(sizeof(*metadata) + entries_size)); ++ return -EINVAL; ++ } ++ ++ fw->entries = g_new(TdxFirmwareEntry, fw->nr_entries); ++ sections = g_new(TdvfSectionEntry, fw->nr_entries); ++ ++ memcpy(sections, (void *)metadata + sizeof(*metadata), entries_size); ++ ++ for (i = 0; i < fw->nr_entries; i++) { ++ if (tdvf_parse_and_check_section_entry(§ions[i], &fw->entries[i])) { ++ goto err; ++ } ++ } ++ ++ return 0; ++ ++err: ++ fw->entries = 0; ++ g_free(fw->entries); ++ return -EINVAL; ++} +diff --git a/include/hw/i386/tdvf.h b/include/hw/i386/tdvf.h +new file mode 100644 +index 0000000000..7ebcac42a3 +--- /dev/null ++++ b/include/hw/i386/tdvf.h +@@ -0,0 +1,38 @@ ++/* ++ * Copyright (c) 2025 Intel Corporation ++ * Author: Isaku Yamahata ++ * ++ * ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ */ ++ ++#ifndef HW_I386_TDVF_H ++#define HW_I386_TDVF_H ++ ++#include "qemu/osdep.h" ++ ++#define TDVF_SECTION_TYPE_BFV 0 ++#define TDVF_SECTION_TYPE_CFV 1 ++#define TDVF_SECTION_TYPE_TD_HOB 2 ++#define TDVF_SECTION_TYPE_TEMP_MEM 3 ++ ++#define TDVF_SECTION_ATTRIBUTES_MR_EXTEND (1U << 0) ++#define TDVF_SECTION_ATTRIBUTES_PAGE_AUG (1U << 1) ++ ++typedef struct TdxFirmwareEntry { ++ uint32_t data_offset; ++ uint32_t data_len; ++ uint64_t address; ++ uint64_t size; ++ uint32_t type; ++ uint32_t attributes; ++} TdxFirmwareEntry; ++ ++typedef struct TdxFirmware { ++ uint32_t nr_entries; ++ TdxFirmwareEntry *entries; ++} TdxFirmware; ++ ++int tdvf_parse_metadata(TdxFirmware *fw, void *flash_ptr, int size); ++ ++#endif /* HW_I386_TDVF_H */ +-- +2.47.3 + diff --git a/kvm-i386-tdx-Add-TDVF-memory-via-KVM_TDX_INIT_MEM_REGION.patch b/kvm-i386-tdx-Add-TDVF-memory-via-KVM_TDX_INIT_MEM_REGION.patch new file mode 100644 index 0000000..7fd731a --- /dev/null +++ b/kvm-i386-tdx-Add-TDVF-memory-via-KVM_TDX_INIT_MEM_REGION.patch @@ -0,0 +1,96 @@ +From 4f49fa494704ae2821a754703eac5215adc5a031 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 25 Jul 2025 16:40:22 +0200 +Subject: [PATCH 038/100] i386/tdx: Add TDVF memory via KVM_TDX_INIT_MEM_REGION + +TDVF firmware (CODE and VARS) needs to be copied to TD's private +memory via KVM_TDX_INIT_MEM_REGION, as well as TD HOB and TEMP memory. + +If the TDVF section has TDVF_SECTION_ATTRIBUTES_MR_EXTEND set in the +flag, calling KVM_TDX_EXTEND_MEMORY to extend the measurement. + +After populating the TDVF memory, the original image located in shared +ramblock can be discarded. + +Signed-off-by: Isaku Yamahata +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-25-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit ebc2d2b497c59414ac3c91de32bc546d27940e74) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 7837bcd902..954cfb3962 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -17,6 +17,7 @@ + #include "qom/object_interfaces.h" + #include "crypto/hash.h" + #include "system/system.h" ++#include "system/ramblock.h" + + #include "hw/i386/e820_memory_layout.h" + #include "hw/i386/tdvf.h" +@@ -262,6 +263,9 @@ static void tdx_finalize_vm(Notifier *notifier, void *unused) + { + TdxFirmware *tdvf = &tdx_guest->tdvf; + TdxFirmwareEntry *entry; ++ RAMBlock *ram_block; ++ Error *local_err = NULL; ++ int r; + + tdx_init_ram_entries(); + +@@ -297,6 +301,44 @@ static void tdx_finalize_vm(Notifier *notifier, void *unused) + sizeof(TdxRamEntry), &tdx_ram_entry_compare); + + tdvf_hob_create(tdx_guest, tdx_get_hob_entry(tdx_guest)); ++ ++ for_each_tdx_fw_entry(tdvf, entry) { ++ struct kvm_tdx_init_mem_region region; ++ uint32_t flags; ++ ++ region = (struct kvm_tdx_init_mem_region) { ++ .source_addr = (uint64_t)entry->mem_ptr, ++ .gpa = entry->address, ++ .nr_pages = entry->size >> 12, ++ }; ++ ++ flags = entry->attributes & TDVF_SECTION_ATTRIBUTES_MR_EXTEND ? ++ KVM_TDX_MEASURE_MEMORY_REGION : 0; ++ ++ do { ++ error_free(local_err); ++ local_err = NULL; ++ r = tdx_vcpu_ioctl(first_cpu, KVM_TDX_INIT_MEM_REGION, flags, ++ ®ion, &local_err); ++ } while (r == -EAGAIN || r == -EINTR); ++ if (r < 0) { ++ error_report_err(local_err); ++ exit(1); ++ } ++ ++ if (entry->type == TDVF_SECTION_TYPE_TD_HOB || ++ entry->type == TDVF_SECTION_TYPE_TEMP_MEM) { ++ qemu_ram_munmap(-1, entry->mem_ptr, entry->size); ++ entry->mem_ptr = NULL; ++ } ++ } ++ ++ /* ++ * TDVF image has been copied into private region above via ++ * KVM_MEMORY_MAPPING. It becomes useless. ++ */ ++ ram_block = tdx_guest->tdvf_mr->ram_block; ++ ram_block_discard_range(ram_block, 0, ram_block->max_length); + } + + static Notifier tdx_machine_done_notify = { +-- +2.47.3 + diff --git a/kvm-i386-tdx-Add-TDX-fixed1-bits-to-supported-CPUIDs.patch b/kvm-i386-tdx-Add-TDX-fixed1-bits-to-supported-CPUIDs.patch new file mode 100644 index 0000000..35dd0fe --- /dev/null +++ b/kvm-i386-tdx-Add-TDX-fixed1-bits-to-supported-CPUIDs.patch @@ -0,0 +1,241 @@ +From 1301067ee2e7438c2292b34779717f37443d8898 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:48 +0200 +Subject: [PATCH 059/100] i386/tdx: Add TDX fixed1 bits to supported CPUIDs + +TDX architecture forcibly sets some CPUID bits for TD guest that VMM +cannot disable it. They are fixed1 bits. + +Fixed1 bits are not covered by tdx_caps.cpuid (which only contains the +directly configurable bits), while fixed1 bits are supported for TD guest +obviously. + +Add fixed1 bits to tdx_supported_cpuid. Besides, set all the fixed1 +bits to the initial set of KVM's support since KVM might not report them +as supported. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-46-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 0ba06e46d09b84a2cb97a268da5576aaca3a24ca) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.h | 2 + + target/i386/kvm/kvm_i386.h | 7 ++ + target/i386/kvm/tdx.c | 134 +++++++++++++++++++++++++++++++++++++ + target/i386/sev.c | 8 --- + 4 files changed, 143 insertions(+), 8 deletions(-) + +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index a8bffcdd3a..da543af2ba 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -924,6 +924,8 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); + #define CPUID_7_0_EDX_FSRM (1U << 4) + /* AVX512 Vector Pair Intersection to a Pair of Mask Registers */ + #define CPUID_7_0_EDX_AVX512_VP2INTERSECT (1U << 8) ++ /* "md_clear" VERW clears CPU buffers */ ++#define CPUID_7_0_EDX_MD_CLEAR (1U << 10) + /* SERIALIZE instruction */ + #define CPUID_7_0_EDX_SERIALIZE (1U << 14) + /* TSX Suspend Load Address Tracking instruction */ +diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h +index 484a1de84d..5f83e8850a 100644 +--- a/target/i386/kvm/kvm_i386.h ++++ b/target/i386/kvm/kvm_i386.h +@@ -44,6 +44,13 @@ void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask); + + #ifdef CONFIG_KVM + ++#include ++ ++typedef struct KvmCpuidInfo { ++ struct kvm_cpuid2 cpuid; ++ struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES]; ++} KvmCpuidInfo; ++ + bool kvm_is_vm_type_supported(int type); + bool kvm_has_adjust_clock_stable(void); + bool kvm_has_exception_payload(void); +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index dc426d1cdb..c113a181e8 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -367,6 +367,133 @@ static Notifier tdx_machine_done_notify = { + .notify = tdx_finalize_vm, + }; + ++/* ++ * Some CPUID bits change from fixed1 to configurable bits when TDX module ++ * supports TDX_FEATURES0.VE_REDUCTION. e.g., MCA/MCE/MTRR/CORE_CAPABILITY. ++ * ++ * To make QEMU work with all the versions of TDX module, keep the fixed1 bits ++ * here if they are ever fixed1 bits in any of the version though not fixed1 in ++ * the latest version. Otherwise, with the older version of TDX module, QEMU may ++ * treat the fixed1 bit as unsupported. ++ * ++ * For newer TDX module, it does no harm to keep them in tdx_fixed1_bits even ++ * though they changed to configurable bits. Because tdx_fixed1_bits is used to ++ * setup the supported bits. ++ */ ++KvmCpuidInfo tdx_fixed1_bits = { ++ .cpuid.nent = 8, ++ .entries[0] = { ++ .function = 0x1, ++ .index = 0, ++ .ecx = CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_DTES64 | ++ CPUID_EXT_DSCPL | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | ++ CPUID_EXT_PDCM | CPUID_EXT_PCID | CPUID_EXT_SSE41 | ++ CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE | ++ CPUID_EXT_POPCNT | CPUID_EXT_AES | CPUID_EXT_XSAVE | ++ CPUID_EXT_RDRAND | CPUID_EXT_HYPERVISOR, ++ .edx = CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | ++ CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | ++ CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | ++ CPUID_PAT | CPUID_CLFLUSH | CPUID_DTS | CPUID_MMX | CPUID_FXSR | ++ CPUID_SSE | CPUID_SSE2, ++ }, ++ .entries[1] = { ++ .function = 0x6, ++ .index = 0, ++ .eax = CPUID_6_EAX_ARAT, ++ }, ++ .entries[2] = { ++ .function = 0x7, ++ .index = 0, ++ .flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX, ++ .ebx = CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_FDP_EXCPTN_ONLY | ++ CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_INVPCID | ++ CPUID_7_0_EBX_ZERO_FCS_FDS | CPUID_7_0_EBX_RDSEED | ++ CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT | ++ CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_SHA_NI, ++ .ecx = CPUID_7_0_ECX_BUS_LOCK_DETECT | CPUID_7_0_ECX_MOVDIRI | ++ CPUID_7_0_ECX_MOVDIR64B, ++ .edx = CPUID_7_0_EDX_MD_CLEAR | CPUID_7_0_EDX_SPEC_CTRL | ++ CPUID_7_0_EDX_STIBP | CPUID_7_0_EDX_FLUSH_L1D | ++ CPUID_7_0_EDX_ARCH_CAPABILITIES | CPUID_7_0_EDX_CORE_CAPABILITY | ++ CPUID_7_0_EDX_SPEC_CTRL_SSBD, ++ }, ++ .entries[3] = { ++ .function = 0x7, ++ .index = 2, ++ .flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX, ++ .edx = CPUID_7_2_EDX_PSFD | CPUID_7_2_EDX_IPRED_CTRL | ++ CPUID_7_2_EDX_RRSBA_CTRL | CPUID_7_2_EDX_BHI_CTRL, ++ }, ++ .entries[4] = { ++ .function = 0xD, ++ .index = 0, ++ .flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX, ++ .eax = XSTATE_FP_MASK | XSTATE_SSE_MASK, ++ }, ++ .entries[5] = { ++ .function = 0xD, ++ .index = 1, ++ .flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX, ++ .eax = CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC| ++ CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES, ++ }, ++ .entries[6] = { ++ .function = 0x80000001, ++ .index = 0, ++ .ecx = CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | CPUID_EXT3_3DNOWPREFETCH, ++ /* ++ * Strictly speaking, SYSCALL is not fixed1 bit since it depends on ++ * the CPU to be in 64-bit mode. But here fixed1 is used to serve the ++ * purpose of supported bits for TDX. In this sense, SYACALL is always ++ * supported. ++ */ ++ .edx = CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_PDPE1GB | ++ CPUID_EXT2_RDTSCP | CPUID_EXT2_LM, ++ }, ++ .entries[7] = { ++ .function = 0x80000007, ++ .index = 0, ++ .edx = CPUID_APM_INVTSC, ++ }, ++}; ++ ++static struct kvm_cpuid_entry2 *find_in_supported_entry(uint32_t function, ++ uint32_t index) ++{ ++ struct kvm_cpuid_entry2 *e; ++ ++ e = cpuid_find_entry(tdx_supported_cpuid, function, index); ++ if (!e) { ++ if (tdx_supported_cpuid->nent >= KVM_MAX_CPUID_ENTRIES) { ++ error_report("tdx_supported_cpuid requries more space than %d entries", ++ KVM_MAX_CPUID_ENTRIES); ++ exit(1); ++ } ++ e = &tdx_supported_cpuid->entries[tdx_supported_cpuid->nent++]; ++ e->function = function; ++ e->index = index; ++ } ++ ++ return e; ++} ++ ++static void tdx_add_supported_cpuid_by_fixed1_bits(void) ++{ ++ struct kvm_cpuid_entry2 *e, *e1; ++ int i; ++ ++ for (i = 0; i < tdx_fixed1_bits.cpuid.nent; i++) { ++ e = &tdx_fixed1_bits.entries[i]; ++ ++ e1 = find_in_supported_entry(e->function, e->index); ++ e1->eax |= e->eax; ++ e1->ebx |= e->ebx; ++ e1->ecx |= e->ecx; ++ e1->edx |= e->edx; ++ } ++} ++ + static void tdx_setup_supported_cpuid(void) + { + if (tdx_supported_cpuid) { +@@ -379,6 +506,8 @@ static void tdx_setup_supported_cpuid(void) + memcpy(tdx_supported_cpuid->entries, tdx_caps->cpuid.entries, + tdx_caps->cpuid.nent * sizeof(struct kvm_cpuid_entry2)); + tdx_supported_cpuid->nent = tdx_caps->cpuid.nent; ++ ++ tdx_add_supported_cpuid_by_fixed1_bits(); + } + + static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) +@@ -463,6 +592,11 @@ static uint32_t tdx_adjust_cpuid_features(X86ConfidentialGuest *cg, + { + struct kvm_cpuid_entry2 *e; + ++ e = cpuid_find_entry(&tdx_fixed1_bits.cpuid, feature, index); ++ if (e) { ++ value |= cpuid_entry_get_reg(e, reg); ++ } ++ + if (is_feature_word_cpuid(feature, index, reg)) { + e = cpuid_find_entry(tdx_supported_cpuid, feature, index); + if (e) { +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 56b12d7403..8459d69a14 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -211,14 +211,6 @@ static const char *const sev_fw_errlist[] = { + + #define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist) + +-/* doesn't expose this, so re-use the max from kvm.c */ +-#define KVM_MAX_CPUID_ENTRIES 100 +- +-typedef struct KvmCpuidInfo { +- struct kvm_cpuid2 cpuid; +- struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES]; +-} KvmCpuidInfo; +- + #define SNP_CPUID_FUNCTION_MAXCOUNT 64 + #define SNP_CPUID_FUNCTION_UNKNOWN 0xFFFFFFFF + +-- +2.47.3 + diff --git a/kvm-i386-tdx-Add-XFD-to-supported-bit-of-TDX.patch b/kvm-i386-tdx-Add-XFD-to-supported-bit-of-TDX.patch new file mode 100644 index 0000000..9272e3c --- /dev/null +++ b/kvm-i386-tdx-Add-XFD-to-supported-bit-of-TDX.patch @@ -0,0 +1,52 @@ +From 88294d638ecc1b78d07c59909e237e6906fb18f4 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:48 +0200 +Subject: [PATCH 062/100] i386/tdx: Add XFD to supported bit of TDX + +Just mark XFD as always supported for TDX. This simple solution relies +on the fact KVM will report XFD as 0 when it's not supported by the +hardware. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-49-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 9f5771c57dbe92d46361afd992a5851c846d0322) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.h | 1 + + target/i386/kvm/tdx.c | 6 ++++++ + 2 files changed, 7 insertions(+) + +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index e953d85417..79903ea6fe 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -1130,6 +1130,7 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); + #define CPUID_XSAVE_XSAVEC (1U << 1) + #define CPUID_XSAVE_XGETBV1 (1U << 2) + #define CPUID_XSAVE_XSAVES (1U << 3) ++#define CPUID_XSAVE_XFD (1U << 4) + + #define CPUID_6_EAX_ARAT (1U << 2) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index a6d92232a3..d964f1cd2f 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -621,6 +621,12 @@ static void tdx_add_supported_cpuid_by_xfam(void) + e->edx |= (tdx_caps->supported_xfam & CPUID_XSTATE_XCR0_MASK) >> 32; + + e = find_in_supported_entry(0xd, 1); ++ /* ++ * Mark XFD always support for TDX, it will be cleared finally in ++ * tdx_adjust_cpuid_features() if XFD is unavailable on the hardware ++ * because in this case the original data has it as 0. ++ */ ++ e->eax |= CPUID_XSAVE_XFD; + e->ecx |= (tdx_caps->supported_xfam & CPUID_XSTATE_XSS_MASK); + e->edx |= (tdx_caps->supported_xfam & CPUID_XSTATE_XSS_MASK) >> 32; + } +-- +2.47.3 + diff --git a/kvm-i386-tdx-Add-property-sept-ve-disable-for-tdx-guest-.patch b/kvm-i386-tdx-Add-property-sept-ve-disable-for-tdx-guest-.patch new file mode 100644 index 0000000..9fbeda5 --- /dev/null +++ b/kvm-i386-tdx-Add-property-sept-ve-disable-for-tdx-guest-.patch @@ -0,0 +1,105 @@ +From f9a9eb3efc3ff7baada3aa94bee890cd683ac2a5 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:46 +0200 +Subject: [PATCH 023/100] i386/tdx: Add property sept-ve-disable for tdx-guest + object +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bit 28 of TD attribute, named SEPT_VE_DISABLE. When set to 1, it disables +EPT violation conversion to #VE on guest TD access of PENDING pages. + +Some guest OS (e.g., Linux TD guest) may require this bit as 1. +Otherwise refuse to boot. + +Add sept-ve-disable property for tdx-guest object, for user to configure +this bit. + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Acked-by: Markus Armbruster +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-10-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 6016e2972d94c90307b6caf55a8e3aee5424c09b) +Signed-off-by: Paolo Bonzini +--- + qapi/qom.json | 8 +++++++- + target/i386/kvm/tdx.c | 23 +++++++++++++++++++++++ + 2 files changed, 30 insertions(+), 1 deletion(-) + +diff --git a/qapi/qom.json b/qapi/qom.json +index c0b61df964..f229bb07aa 100644 +--- a/qapi/qom.json ++++ b/qapi/qom.json +@@ -1055,10 +1055,16 @@ + # @attributes: The 'attributes' of a TD guest that is passed to + # KVM_TDX_INIT_VM + # ++# @sept-ve-disable: toggle bit 28 of TD attributes to control disabling ++# of EPT violation conversion to #VE on guest TD access of PENDING ++# pages. Some guest OS (e.g., Linux TD guest) may require this to ++# be set, otherwise they refuse to boot. ++# + # Since: 10.1 + ## + { 'struct': 'TdxGuestProperties', +- 'data': { '*attributes': 'uint64' } } ++ 'data': { '*attributes': 'uint64', ++ '*sept-ve-disable': 'bool' } } + + ## + # @ThreadContextProperties: +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 8f02c76249..370bd86f2c 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -18,6 +18,8 @@ + #include "kvm_i386.h" + #include "tdx.h" + ++#define TDX_TD_ATTRIBUTES_SEPT_VE_DISABLE BIT_ULL(28) ++ + static TdxGuest *tdx_guest; + + static struct kvm_tdx_capabilities *tdx_caps; +@@ -252,6 +254,24 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) + return 0; + } + ++static bool tdx_guest_get_sept_ve_disable(Object *obj, Error **errp) ++{ ++ TdxGuest *tdx = TDX_GUEST(obj); ++ ++ return !!(tdx->attributes & TDX_TD_ATTRIBUTES_SEPT_VE_DISABLE); ++} ++ ++static void tdx_guest_set_sept_ve_disable(Object *obj, bool value, Error **errp) ++{ ++ TdxGuest *tdx = TDX_GUEST(obj); ++ ++ if (value) { ++ tdx->attributes |= TDX_TD_ATTRIBUTES_SEPT_VE_DISABLE; ++ } else { ++ tdx->attributes &= ~TDX_TD_ATTRIBUTES_SEPT_VE_DISABLE; ++ } ++} ++ + /* tdx guest */ + OBJECT_DEFINE_TYPE_WITH_INTERFACES(TdxGuest, + tdx_guest, +@@ -272,6 +292,9 @@ static void tdx_guest_init(Object *obj) + + object_property_add_uint64_ptr(obj, "attributes", &tdx->attributes, + OBJ_PROP_FLAG_READWRITE); ++ object_property_add_bool(obj, "sept-ve-disable", ++ tdx_guest_get_sept_ve_disable, ++ tdx_guest_set_sept_ve_disable); + } + + static void tdx_guest_finalize(Object *obj) +-- +2.47.3 + diff --git a/kvm-i386-tdx-Add-supported-CPUID-bits-related-to-TD-Attr.patch b/kvm-i386-tdx-Add-supported-CPUID-bits-related-to-TD-Attr.patch new file mode 100644 index 0000000..acf745f --- /dev/null +++ b/kvm-i386-tdx-Add-supported-CPUID-bits-related-to-TD-Attr.patch @@ -0,0 +1,136 @@ +From 409a55924f943cd2424eb7c3d3a6c9030ae05723 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:48 +0200 +Subject: [PATCH 060/100] i386/tdx: Add supported CPUID bits related to TD + Attributes + +For TDX, some CPUID feature bit is configured via TD attributes. They +are not covered by tdx_caps.cpuid (which only contians the directly +configurable CPUID bits), but they are actually supported when the +related attributre bit is supported. + +Note, LASS and KeyLocker are not supported by KVM for TDX, nor does +QEMU support it (see TDX_SUPPORTED_TD_ATTRS). They are defined in +tdx_attrs_maps[] for the completeness of the existing TD Attribute +bits that are related with CPUID features. + +Signed-off-by: Xiaoyao Li +Link: https://lore.kernel.org/r/20250508150002.689633-47-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 31df29c532a9ef473c6efd497950a620099bf1da) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.h | 4 +++ + target/i386/kvm/tdx.c | 60 +++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 64 insertions(+) + +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index da543af2ba..2a9e85618e 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -903,6 +903,8 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); + #define CPUID_7_0_ECX_LA57 (1U << 16) + /* Read Processor ID */ + #define CPUID_7_0_ECX_RDPID (1U << 22) ++/* KeyLocker */ ++#define CPUID_7_0_ECX_KeyLocker (1U << 23) + /* Bus Lock Debug Exception */ + #define CPUID_7_0_ECX_BUS_LOCK_DETECT (1U << 24) + /* Cache Line Demote Instruction */ +@@ -963,6 +965,8 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); + #define CPUID_7_1_EAX_AVX_VNNI (1U << 4) + /* AVX512 BFloat16 Instruction */ + #define CPUID_7_1_EAX_AVX512_BF16 (1U << 5) ++/* Linear address space separation */ ++#define CPUID_7_1_EAX_LASS (1U << 6) + /* CMPCCXADD Instructions */ + #define CPUID_7_1_EAX_CMPCCXADD (1U << 7) + /* Fast Zero REP MOVS */ +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index c113a181e8..017252c94b 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -458,6 +458,34 @@ KvmCpuidInfo tdx_fixed1_bits = { + }, + }; + ++typedef struct TdxAttrsMap { ++ uint32_t attr_index; ++ uint32_t cpuid_leaf; ++ uint32_t cpuid_subleaf; ++ int cpuid_reg; ++ uint32_t feat_mask; ++} TdxAttrsMap; ++ ++static TdxAttrsMap tdx_attrs_maps[] = { ++ {.attr_index = 27, ++ .cpuid_leaf = 7, ++ .cpuid_subleaf = 1, ++ .cpuid_reg = R_EAX, ++ .feat_mask = CPUID_7_1_EAX_LASS,}, ++ ++ {.attr_index = 30, ++ .cpuid_leaf = 7, ++ .cpuid_subleaf = 0, ++ .cpuid_reg = R_ECX, ++ .feat_mask = CPUID_7_0_ECX_PKS,}, ++ ++ {.attr_index = 31, ++ .cpuid_leaf = 7, ++ .cpuid_subleaf = 0, ++ .cpuid_reg = R_ECX, ++ .feat_mask = CPUID_7_0_ECX_KeyLocker,}, ++}; ++ + static struct kvm_cpuid_entry2 *find_in_supported_entry(uint32_t function, + uint32_t index) + { +@@ -494,6 +522,37 @@ static void tdx_add_supported_cpuid_by_fixed1_bits(void) + } + } + ++static void tdx_add_supported_cpuid_by_attrs(void) ++{ ++ struct kvm_cpuid_entry2 *e; ++ TdxAttrsMap *map; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(tdx_attrs_maps); i++) { ++ map = &tdx_attrs_maps[i]; ++ if (!((1ULL << map->attr_index) & tdx_caps->supported_attrs)) { ++ continue; ++ } ++ ++ e = find_in_supported_entry(map->cpuid_leaf, map->cpuid_subleaf); ++ ++ switch(map->cpuid_reg) { ++ case R_EAX: ++ e->eax |= map->feat_mask; ++ break; ++ case R_EBX: ++ e->ebx |= map->feat_mask; ++ break; ++ case R_ECX: ++ e->ecx |= map->feat_mask; ++ break; ++ case R_EDX: ++ e->edx |= map->feat_mask; ++ break; ++ } ++ } ++} ++ + static void tdx_setup_supported_cpuid(void) + { + if (tdx_supported_cpuid) { +@@ -508,6 +567,7 @@ static void tdx_setup_supported_cpuid(void) + tdx_supported_cpuid->nent = tdx_caps->cpuid.nent; + + tdx_add_supported_cpuid_by_fixed1_bits(); ++ tdx_add_supported_cpuid_by_attrs(); + } + + static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) +-- +2.47.3 + diff --git a/kvm-i386-tdx-Add-supported-CPUID-bits-relates-to-XFAM.patch b/kvm-i386-tdx-Add-supported-CPUID-bits-relates-to-XFAM.patch new file mode 100644 index 0000000..86d1ca1 --- /dev/null +++ b/kvm-i386-tdx-Add-supported-CPUID-bits-relates-to-XFAM.patch @@ -0,0 +1,212 @@ +From 34cc35b8d41a88d0122c5934d5c11beb4bba72ca Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:48 +0200 +Subject: [PATCH 061/100] i386/tdx: Add supported CPUID bits relates to XFAM + +Some CPUID bits are controlled by XFAM. They are not covered by +tdx_caps.cpuid (which only contians the directly configurable bits), but +they are actually supported when the related XFAM bit is supported. + +Add these XFAM controlled bits to TDX supported CPUID bits based on the +supported_xfam. + +Besides, incorporate the supported_xfam into the supported CPUID leaf of +0xD. + +Signed-off-by: Xiaoyao Li +Link: https://lore.kernel.org/r/20250508150002.689633-48-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 8c94c84cb9e0140b48acc9c9d404525ca7ef7457) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 12 ------- + target/i386/cpu.h | 16 ++++++++++ + target/i386/kvm/tdx.c | 73 +++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 89 insertions(+), 12 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index d85aa3d9bc..9f05f4f142 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -1672,15 +1672,6 @@ bool is_feature_word_cpuid(uint32_t feature, uint32_t index, int reg) + return false; + } + +-typedef struct FeatureMask { +- FeatureWord index; +- uint64_t mask; +-} FeatureMask; +- +-typedef struct FeatureDep { +- FeatureMask from, to; +-} FeatureDep; +- + static FeatureDep feature_dependencies[] = { + { + .from = { FEAT_7_0_EDX, CPUID_7_0_EDX_ARCH_CAPABILITIES }, +@@ -1849,9 +1840,6 @@ static const X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = { + }; + #undef REGISTER + +-/* CPUID feature bits available in XSS */ +-#define CPUID_XSTATE_XSS_MASK (XSTATE_ARCH_LBR_MASK) +- + ExtSaveArea x86_ext_save_areas[XSAVE_STATE_AREA_COUNT] = { + [XSTATE_FP_BIT] = { + /* x87 FP state component is always enabled if XSAVE is supported */ +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 2a9e85618e..e953d85417 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -588,6 +588,7 @@ typedef enum X86Seg { + #define XSTATE_OPMASK_BIT 5 + #define XSTATE_ZMM_Hi256_BIT 6 + #define XSTATE_Hi16_ZMM_BIT 7 ++#define XSTATE_PT_BIT 8 + #define XSTATE_PKRU_BIT 9 + #define XSTATE_ARCH_LBR_BIT 15 + #define XSTATE_XTILE_CFG_BIT 17 +@@ -601,6 +602,7 @@ typedef enum X86Seg { + #define XSTATE_OPMASK_MASK (1ULL << XSTATE_OPMASK_BIT) + #define XSTATE_ZMM_Hi256_MASK (1ULL << XSTATE_ZMM_Hi256_BIT) + #define XSTATE_Hi16_ZMM_MASK (1ULL << XSTATE_Hi16_ZMM_BIT) ++#define XSTATE_PT_MASK (1ULL << XSTATE_PT_BIT) + #define XSTATE_PKRU_MASK (1ULL << XSTATE_PKRU_BIT) + #define XSTATE_ARCH_LBR_MASK (1ULL << XSTATE_ARCH_LBR_BIT) + #define XSTATE_XTILE_CFG_MASK (1ULL << XSTATE_XTILE_CFG_BIT) +@@ -623,6 +625,11 @@ typedef enum X86Seg { + XSTATE_Hi16_ZMM_MASK | XSTATE_PKRU_MASK | \ + XSTATE_XTILE_CFG_MASK | XSTATE_XTILE_DATA_MASK) + ++/* CPUID feature bits available in XSS */ ++#define CPUID_XSTATE_XSS_MASK (XSTATE_ARCH_LBR_MASK) ++ ++#define CPUID_XSTATE_MASK (CPUID_XSTATE_XCR0_MASK | CPUID_XSTATE_XSS_MASK) ++ + /* CPUID feature words */ + typedef enum FeatureWord { + FEAT_1_EDX, /* CPUID[1].EDX */ +@@ -671,6 +678,15 @@ typedef enum FeatureWord { + FEATURE_WORDS, + } FeatureWord; + ++typedef struct FeatureMask { ++ FeatureWord index; ++ uint64_t mask; ++} FeatureMask; ++ ++typedef struct FeatureDep { ++ FeatureMask from, to; ++} FeatureDep; ++ + typedef uint64_t FeatureWordArray[FEATURE_WORDS]; + uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 017252c94b..a6d92232a3 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -23,6 +23,8 @@ + + #include + ++#include "cpu.h" ++#include "cpu-internal.h" + #include "hw/i386/e820_memory_layout.h" + #include "hw/i386/tdvf.h" + #include "hw/i386/x86.h" +@@ -486,6 +488,32 @@ static TdxAttrsMap tdx_attrs_maps[] = { + .feat_mask = CPUID_7_0_ECX_KeyLocker,}, + }; + ++typedef struct TdxXFAMDep { ++ int xfam_bit; ++ FeatureMask feat_mask; ++} TdxXFAMDep; ++ ++/* ++ * Note, only the CPUID bits whose virtualization type are "XFAM & Native" are ++ * defiend here. ++ * ++ * For those whose virtualization type are "XFAM & Configured & Native", they ++ * are reported as configurable bits. And they are not supported if not in the ++ * configureable bits list from KVM even if the corresponding XFAM bit is ++ * supported. ++ */ ++TdxXFAMDep tdx_xfam_deps[] = { ++ { XSTATE_YMM_BIT, { FEAT_1_ECX, CPUID_EXT_FMA }}, ++ { XSTATE_YMM_BIT, { FEAT_7_0_EBX, CPUID_7_0_EBX_AVX2 }}, ++ { XSTATE_OPMASK_BIT, { FEAT_7_0_ECX, CPUID_7_0_ECX_AVX512_VBMI}}, ++ { XSTATE_OPMASK_BIT, { FEAT_7_0_EDX, CPUID_7_0_EDX_AVX512_FP16}}, ++ { XSTATE_PT_BIT, { FEAT_7_0_EBX, CPUID_7_0_EBX_INTEL_PT}}, ++ { XSTATE_PKRU_BIT, { FEAT_7_0_ECX, CPUID_7_0_ECX_PKU}}, ++ { XSTATE_XTILE_CFG_BIT, { FEAT_7_0_EDX, CPUID_7_0_EDX_AMX_BF16 }}, ++ { XSTATE_XTILE_CFG_BIT, { FEAT_7_0_EDX, CPUID_7_0_EDX_AMX_TILE }}, ++ { XSTATE_XTILE_CFG_BIT, { FEAT_7_0_EDX, CPUID_7_0_EDX_AMX_INT8 }}, ++}; ++ + static struct kvm_cpuid_entry2 *find_in_supported_entry(uint32_t function, + uint32_t index) + { +@@ -553,6 +581,50 @@ static void tdx_add_supported_cpuid_by_attrs(void) + } + } + ++static void tdx_add_supported_cpuid_by_xfam(void) ++{ ++ struct kvm_cpuid_entry2 *e; ++ int i; ++ ++ const TdxXFAMDep *xfam_dep; ++ const FeatureWordInfo *f; ++ for (i = 0; i < ARRAY_SIZE(tdx_xfam_deps); i++) { ++ xfam_dep = &tdx_xfam_deps[i]; ++ if (!((1ULL << xfam_dep->xfam_bit) & tdx_caps->supported_xfam)) { ++ continue; ++ } ++ ++ f = &feature_word_info[xfam_dep->feat_mask.index]; ++ if (f->type != CPUID_FEATURE_WORD) { ++ continue; ++ } ++ ++ e = find_in_supported_entry(f->cpuid.eax, f->cpuid.ecx); ++ switch(f->cpuid.reg) { ++ case R_EAX: ++ e->eax |= xfam_dep->feat_mask.mask; ++ break; ++ case R_EBX: ++ e->ebx |= xfam_dep->feat_mask.mask; ++ break; ++ case R_ECX: ++ e->ecx |= xfam_dep->feat_mask.mask; ++ break; ++ case R_EDX: ++ e->edx |= xfam_dep->feat_mask.mask; ++ break; ++ } ++ } ++ ++ e = find_in_supported_entry(0xd, 0); ++ e->eax |= (tdx_caps->supported_xfam & CPUID_XSTATE_XCR0_MASK); ++ e->edx |= (tdx_caps->supported_xfam & CPUID_XSTATE_XCR0_MASK) >> 32; ++ ++ e = find_in_supported_entry(0xd, 1); ++ e->ecx |= (tdx_caps->supported_xfam & CPUID_XSTATE_XSS_MASK); ++ e->edx |= (tdx_caps->supported_xfam & CPUID_XSTATE_XSS_MASK) >> 32; ++} ++ + static void tdx_setup_supported_cpuid(void) + { + if (tdx_supported_cpuid) { +@@ -568,6 +640,7 @@ static void tdx_setup_supported_cpuid(void) + + tdx_add_supported_cpuid_by_fixed1_bits(); + tdx_add_supported_cpuid_by_attrs(); ++ tdx_add_supported_cpuid_by_xfam(); + } + + static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) +-- +2.47.3 + diff --git a/kvm-i386-tdx-Call-KVM_TDX_INIT_VCPU-to-initialize-TDX-vc.patch b/kvm-i386-tdx-Call-KVM_TDX_INIT_VCPU-to-initialize-TDX-vc.patch new file mode 100644 index 0000000..2a71855 --- /dev/null +++ b/kvm-i386-tdx-Call-KVM_TDX_INIT_VCPU-to-initialize-TDX-vc.patch @@ -0,0 +1,58 @@ +From f4ddcd84da69020096cb21b8585bff71529cfc70 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:46 +0200 +Subject: [PATCH 039/100] i386/tdx: Call KVM_TDX_INIT_VCPU to initialize TDX + vcpu + +TDX vcpu needs to be initialized by SEAMCALL(TDH.VP.INIT) and KVM +provides vcpu level IOCTL KVM_TDX_INIT_VCPU for it. + +KVM_TDX_INIT_VCPU needs the address of the HOB as input. Invoke it for +each vcpu after HOB list is created. + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-26-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 41f7fd22073561a23229c0479d9d708dee9d3a1e) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 954cfb3962..86fc78b0e6 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -259,6 +259,18 @@ static void tdx_init_ram_entries(void) + tdx_guest->nr_ram_entries = j; + } + ++static void tdx_post_init_vcpus(void) ++{ ++ TdxFirmwareEntry *hob; ++ CPUState *cpu; ++ ++ hob = tdx_get_hob_entry(tdx_guest); ++ CPU_FOREACH(cpu) { ++ tdx_vcpu_ioctl(cpu, KVM_TDX_INIT_VCPU, 0, (void *)hob->address, ++ &error_fatal); ++ } ++} ++ + static void tdx_finalize_vm(Notifier *notifier, void *unused) + { + TdxFirmware *tdvf = &tdx_guest->tdvf; +@@ -302,6 +314,8 @@ static void tdx_finalize_vm(Notifier *notifier, void *unused) + + tdvf_hob_create(tdx_guest, tdx_get_hob_entry(tdx_guest)); + ++ tdx_post_init_vcpus(); ++ + for_each_tdx_fw_entry(tdvf, entry) { + struct kvm_tdx_init_mem_region region; + uint32_t flags; +-- +2.47.3 + diff --git a/kvm-i386-tdx-Clarify-the-error-message-of-mrconfigid-mro.patch b/kvm-i386-tdx-Clarify-the-error-message-of-mrconfigid-mro.patch new file mode 100644 index 0000000..0116c3f --- /dev/null +++ b/kvm-i386-tdx-Clarify-the-error-message-of-mrconfigid-mro.patch @@ -0,0 +1,67 @@ +From 70bc9fb239637a674519cb4d6be85aed9869e116 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:49 +0200 +Subject: [PATCH 076/100] i386/tdx: Clarify the error message of + mrconfigid/mrowner/mrownerconfig +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The error message is misleading - we successfully decoded the data, +the decoded data was simply with the wrong length. + +Change the error message to show it is an length check failure with both +the received and expected values. + +Suggested-by: Daniel P. BerrangĂ© +Signed-off-by: Xiaoyao Li +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Igor Mammedov +Link: https://lore.kernel.org/r/20250603050305.1704586-4-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 41cd354d350d3c64915be9c5decbf20abd84e486) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 40516c9186..f5050fc7bc 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -1032,7 +1032,9 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) + return -1; + } + if (data_len != QCRYPTO_HASH_DIGEST_LEN_SHA384) { +- error_setg(errp, "TDX: failed to decode mrconfigid"); ++ error_setg(errp, "TDX 'mrconfigid' sha384 digest was %ld bytes, " ++ "expected %d bytes", data_len, ++ QCRYPTO_HASH_DIGEST_LEN_SHA384); + return -1; + } + memcpy(init_vm->mrconfigid, data, data_len); +@@ -1045,7 +1047,9 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) + return -1; + } + if (data_len != QCRYPTO_HASH_DIGEST_LEN_SHA384) { +- error_setg(errp, "TDX: failed to decode mrowner"); ++ error_setg(errp, "TDX 'mrowner' sha384 digest was %ld bytes, " ++ "expected %d bytes", data_len, ++ QCRYPTO_HASH_DIGEST_LEN_SHA384); + return -1; + } + memcpy(init_vm->mrowner, data, data_len); +@@ -1058,7 +1062,9 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) + return -1; + } + if (data_len != QCRYPTO_HASH_DIGEST_LEN_SHA384) { +- error_setg(errp, "TDX: failed to decode mrownerconfig"); ++ error_setg(errp, "TDX 'mrownerconfig' sha384 digest was %ld bytes, " ++ "expected %d bytes", data_len, ++ QCRYPTO_HASH_DIGEST_LEN_SHA384); + return -1; + } + memcpy(init_vm->mrownerconfig, data, data_len); +-- +2.47.3 + diff --git a/kvm-i386-tdx-Define-supported-KVM-features-for-TDX.patch b/kvm-i386-tdx-Define-supported-KVM-features-for-TDX.patch new file mode 100644 index 0000000..afc4dd7 --- /dev/null +++ b/kvm-i386-tdx-Define-supported-KVM-features-for-TDX.patch @@ -0,0 +1,72 @@ +From db09b669a027591ab9a658c856ac6fcbd2954ad7 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:48 +0200 +Subject: [PATCH 063/100] i386/tdx: Define supported KVM features for TDX + +For TDX, only limited KVM PV features are supported. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-50-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 4d6e288a350a977b0fb0613db952087928ccd93e) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index d964f1cd2f..3ee163e032 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -32,6 +32,8 @@ + #include "kvm_i386.h" + #include "tdx.h" + ++#include "standard-headers/asm-x86/kvm_para.h" ++ + #define TDX_MIN_TSC_FREQUENCY_KHZ (100 * 1000) + #define TDX_MAX_TSC_FREQUENCY_KHZ (10 * 1000 * 1000) + +@@ -44,6 +46,14 @@ + TDX_TD_ATTRIBUTES_PKS | \ + TDX_TD_ATTRIBUTES_PERFMON) + ++#define TDX_SUPPORTED_KVM_FEATURES ((1U << KVM_FEATURE_NOP_IO_DELAY) | \ ++ (1U << KVM_FEATURE_PV_UNHALT) | \ ++ (1U << KVM_FEATURE_PV_TLB_FLUSH) | \ ++ (1U << KVM_FEATURE_PV_SEND_IPI) | \ ++ (1U << KVM_FEATURE_POLL_CONTROL) | \ ++ (1U << KVM_FEATURE_PV_SCHED_YIELD) | \ ++ (1U << KVM_FEATURE_MSI_EXT_DEST_ID)) ++ + static TdxGuest *tdx_guest; + + static struct kvm_tdx_capabilities *tdx_caps; +@@ -631,6 +641,14 @@ static void tdx_add_supported_cpuid_by_xfam(void) + e->edx |= (tdx_caps->supported_xfam & CPUID_XSTATE_XSS_MASK) >> 32; + } + ++static void tdx_add_supported_kvm_features(void) ++{ ++ struct kvm_cpuid_entry2 *e; ++ ++ e = find_in_supported_entry(0x40000001, 0); ++ e->eax = TDX_SUPPORTED_KVM_FEATURES; ++} ++ + static void tdx_setup_supported_cpuid(void) + { + if (tdx_supported_cpuid) { +@@ -647,6 +665,8 @@ static void tdx_setup_supported_cpuid(void) + tdx_add_supported_cpuid_by_fixed1_bits(); + tdx_add_supported_cpuid_by_attrs(); + tdx_add_supported_cpuid_by_xfam(); ++ ++ tdx_add_supported_kvm_features(); + } + + static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) +-- +2.47.3 + diff --git a/kvm-i386-tdx-Disable-PIC-for-TDX-VMs.patch b/kvm-i386-tdx-Disable-PIC-for-TDX-VMs.patch new file mode 100644 index 0000000..20d84df --- /dev/null +++ b/kvm-i386-tdx-Disable-PIC-for-TDX-VMs.patch @@ -0,0 +1,48 @@ +From 8ecdbd86e4f4986984a08ce1c0c4807c6f10a5a4 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:47 +0200 +Subject: [PATCH 051/100] i386/tdx: Disable PIC for TDX VMs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Legacy PIC (8259) cannot be supported for TDX VMs since TDX module +doesn't allow directly interrupt injection. Using posted interrupts +for the PIC is not a viable option as the guest BIOS/kernel will not +do EOI for PIC IRQs, i.e. will leave the vIRR bit set. + +Hence disable PIC for TDX VMs and error out if user wants PIC. + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-38-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit e7ef60892c80a9ce5b8504ceb13a81f4e0d4b3f7) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index c93d40bcc9..b70f557ccc 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -381,6 +381,13 @@ static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + return -EINVAL; + } + ++ if (x86ms->pic == ON_OFF_AUTO_AUTO) { ++ x86ms->pic = ON_OFF_AUTO_OFF; ++ } else if (x86ms->pic == ON_OFF_AUTO_ON) { ++ error_setg(errp, "TDX VM doesn't support PIC"); ++ return -EINVAL; ++ } ++ + if (!tdx_caps) { + r = get_tdx_capabilities(errp); + if (r) { +-- +2.47.3 + diff --git a/kvm-i386-tdx-Disable-SMM-for-TDX-VMs.patch b/kvm-i386-tdx-Disable-SMM-for-TDX-VMs.patch new file mode 100644 index 0000000..5206301 --- /dev/null +++ b/kvm-i386-tdx-Disable-SMM-for-TDX-VMs.patch @@ -0,0 +1,53 @@ +From bd676d76f9019e16eddc63bb9212a1c56a229dd1 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:47 +0200 +Subject: [PATCH 050/100] i386/tdx: Disable SMM for TDX VMs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +TDX doesn't support SMM and VMM cannot emulate SMM for TDX VMs because +VMM cannot manipulate TDX VM's memory. + +Disable SMM for TDX VMs and error out if user requests to enable SMM. + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-37-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 810d4e83d07ca0d072205453a42c324a51d5a5fa) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index e49b37c436..c93d40bcc9 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -367,11 +367,20 @@ static Notifier tdx_machine_done_notify = { + + static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + { ++ MachineState *ms = MACHINE(qdev_get_machine()); ++ X86MachineState *x86ms = X86_MACHINE(ms); + TdxGuest *tdx = TDX_GUEST(cgs); + int r = 0; + + kvm_mark_guest_state_protected(); + ++ if (x86ms->smm == ON_OFF_AUTO_AUTO) { ++ x86ms->smm = ON_OFF_AUTO_OFF; ++ } else if (x86ms->smm == ON_OFF_AUTO_ON) { ++ error_setg(errp, "TDX VM doesn't support SMM"); ++ return -EINVAL; ++ } ++ + if (!tdx_caps) { + r = get_tdx_capabilities(errp); + if (r) { +-- +2.47.3 + diff --git a/kvm-i386-tdx-Don-t-initialize-pc.rom-for-TDX-VMs.patch b/kvm-i386-tdx-Don-t-initialize-pc.rom-for-TDX-VMs.patch new file mode 100644 index 0000000..d771a54 --- /dev/null +++ b/kvm-i386-tdx-Don-t-initialize-pc.rom-for-TDX-VMs.patch @@ -0,0 +1,70 @@ +From 49179b9294d57db0d3f662cd4fa5479dd50c2071 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:46 +0200 +Subject: [PATCH 033/100] i386/tdx: Don't initialize pc.rom for TDX VMs + +For TDX, the address below 1MB are entirely general RAM. No need to +initialize pc.rom memory region for TDs. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-20-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 49b1f0f812372129736c1df0421c8f67d86d362b) +Signed-off-by: Paolo Bonzini +--- + hw/i386/pc.c | 29 ++++++++++++++++------------- + 1 file changed, 16 insertions(+), 13 deletions(-) + +diff --git a/hw/i386/pc.c b/hw/i386/pc.c +index 5ae388789b..8429164a1a 100644 +--- a/hw/i386/pc.c ++++ b/hw/i386/pc.c +@@ -43,6 +43,7 @@ + #include "system/xen.h" + #include "system/reset.h" + #include "kvm/kvm_i386.h" ++#include "kvm/tdx.h" + #include "hw/xen/xen.h" + #include "qobject/qlist.h" + #include "qemu/error-report.h" +@@ -1031,21 +1032,23 @@ void pc_memory_init(PCMachineState *pcms, + /* Initialize PC system firmware */ + pc_system_firmware_init(pcms, rom_memory); + +- option_rom_mr = g_malloc(sizeof(*option_rom_mr)); +- if (machine_require_guest_memfd(machine)) { +- memory_region_init_ram_guest_memfd(option_rom_mr, NULL, "pc.rom", +- PC_ROM_SIZE, &error_fatal); +- } else { +- memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE, +- &error_fatal); +- if (pcmc->pci_enabled) { +- memory_region_set_readonly(option_rom_mr, true); ++ if (!is_tdx_vm()) { ++ option_rom_mr = g_malloc(sizeof(*option_rom_mr)); ++ if (machine_require_guest_memfd(machine)) { ++ memory_region_init_ram_guest_memfd(option_rom_mr, NULL, "pc.rom", ++ PC_ROM_SIZE, &error_fatal); ++ } else { ++ memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE, ++ &error_fatal); ++ if (pcmc->pci_enabled) { ++ memory_region_set_readonly(option_rom_mr, true); ++ } + } ++ memory_region_add_subregion_overlap(rom_memory, ++ PC_ROM_MIN_VGA, ++ option_rom_mr, ++ 1); + } +- memory_region_add_subregion_overlap(rom_memory, +- PC_ROM_MIN_VGA, +- option_rom_mr, +- 1); + + fw_cfg = fw_cfg_arch_create(machine, + x86ms->boot_cpus, x86ms->apic_id_limit); +-- +2.47.3 + diff --git a/kvm-i386-tdx-Don-t-mask-off-CPUID_EXT_PDCM.patch b/kvm-i386-tdx-Don-t-mask-off-CPUID_EXT_PDCM.patch new file mode 100644 index 0000000..e0f109f --- /dev/null +++ b/kvm-i386-tdx-Don-t-mask-off-CPUID_EXT_PDCM.patch @@ -0,0 +1,49 @@ +From 2d6348de26d12f5bf6866f5f587e0dc854bf43b7 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:50 +0200 +Subject: [PATCH 089/100] i386/tdx: Don't mask off CPUID_EXT_PDCM + +It gets below warning when booting TDX VMs: + + warning: TDX forcibly sets the feature: CPUID[eax=01h].ECX.pdcm [bit 15] + +Because CPUID_EXT_PDCM is fixed1 for TDX, and MSR_IA32_PERF_CAPABILITIES is +supported for TDX guest unconditioanlly. + +Don't mask off CPUID_EXT_PDCM for TDX. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250625035710.2770679-1-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 7ff24fb657d35c014f735f69aef03810fde607ab) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 8a8607591e..15ee4281ba 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -28,6 +28,7 @@ + #include "system/hvf.h" + #include "hvf/hvf-i386.h" + #include "kvm/kvm_i386.h" ++#include "kvm/tdx.h" + #include "sev.h" + #include "qapi/error.h" + #include "qemu/error-report.h" +@@ -8300,7 +8301,8 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) + } + } + +- if (!cpu->enable_pmu) { ++ /* PDCM is fixed1 bit for TDX */ ++ if (!cpu->enable_pmu && !is_tdx_vm()) { + env->features[FEAT_1_ECX] &= ~CPUID_EXT_PDCM; + } + +-- +2.47.3 + diff --git a/kvm-i386-tdx-Don-t-synchronize-guest-tsc-for-TDs.patch b/kvm-i386-tdx-Don-t-synchronize-guest-tsc-for-TDs.patch new file mode 100644 index 0000000..2e584e5 --- /dev/null +++ b/kvm-i386-tdx-Don-t-synchronize-guest-tsc-for-TDs.patch @@ -0,0 +1,38 @@ +From f99f200da174eab7cb31ab803967734c69055d32 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:47 +0200 +Subject: [PATCH 053/100] i386/tdx: Don't synchronize guest tsc for TDs + +TSC of TDs is not accessible and KVM doesn't allow access of +MSR_IA32_TSC for TDs. To avoid the assert() in kvm_get_tsc, make +kvm_synchronize_all_tsc() noop for TDs, + +Signed-off-by: Isaku Yamahata +Reviewed-by: Connor Kuehl +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-40-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 0ed55865b49b703af93e160d48935812a7114e07) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/kvm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 6c3d7e9d85..12b0a25b1f 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -327,7 +327,7 @@ void kvm_synchronize_all_tsc(void) + { + CPUState *cpu; + +- if (kvm_enabled()) { ++ if (kvm_enabled() && !is_tdx_vm()) { + CPU_FOREACH(cpu) { + run_on_cpu(cpu, do_kvm_synchronize_tsc, RUN_ON_CPU_NULL); + } +-- +2.47.3 + diff --git a/kvm-i386-tdx-Don-t-treat-SYSCALL-as-unavailable.patch b/kvm-i386-tdx-Don-t-treat-SYSCALL-as-unavailable.patch new file mode 100644 index 0000000..309bd39 --- /dev/null +++ b/kvm-i386-tdx-Don-t-treat-SYSCALL-as-unavailable.patch @@ -0,0 +1,52 @@ +From c93d983c7e9de741a0c6c1f1c058b53f07bbed34 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:48 +0200 +Subject: [PATCH 066/100] i386/tdx: Don't treat SYSCALL as unavailable + +On Intel CPU, the value of CPUID_EXT2_SYSCALL depends on the mode of +the vcpu. It's 0 outside 64-bit mode and 1 in 64-bit mode. + +The initial state of TDX vcpu is 32-bit protected mode. At the time of +calling KVM_TDX_GET_CPUID, vcpu hasn't started running so the value read +is 0. + +In reality, 64-bit mode should always be supported. So mark +CPUID_EXT2_SYSCALL always supported to avoid false warning. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-53-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit deb9db6fb789cfe80527b75983e86137589227a4) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 4aa651e75d..688992c81b 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -845,6 +845,19 @@ static int tdx_check_features(X86ConfidentialGuest *cg, CPUState *cs) + continue; + } + ++ /* Fixup for special cases */ ++ switch (w) { ++ case FEAT_8000_0001_EDX: ++ /* ++ * Intel enumerates SYSCALL bit as 1 only when processor in 64-bit ++ * mode and before vcpu running it's not in 64-bit mode. ++ */ ++ actual |= CPUID_EXT2_SYSCALL; ++ break; ++ default: ++ break; ++ } ++ + requested = env->features[w]; + unavailable = requested & ~actual; + mark_unavailable_features(cpu, w, unavailable, unav_prefix); +-- +2.47.3 + diff --git a/kvm-i386-tdx-Enable-user-exit-on-KVM_HC_MAP_GPA_RANGE.patch b/kvm-i386-tdx-Enable-user-exit-on-KVM_HC_MAP_GPA_RANGE.patch new file mode 100644 index 0000000..e9fc57a --- /dev/null +++ b/kvm-i386-tdx-Enable-user-exit-on-KVM_HC_MAP_GPA_RANGE.patch @@ -0,0 +1,47 @@ +From 67da1168ed0e1b6e2357860c1b61fb9d6e0f53d9 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:47 +0200 +Subject: [PATCH 041/100] i386/tdx: Enable user exit on KVM_HC_MAP_GPA_RANGE + +KVM translates TDG.VP.VMCALL to KVM_HC_MAP_GPA_RANGE, and QEMU +needs to enable user exit on KVM_HC_MAP_GPA_RANGE in order to handle the +memory conversion requested by TD guest. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-28-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 1ff5048d74e661943260c33e864c4118acb37ab4) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 9d169d4368..6ad4f82864 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -19,6 +19,8 @@ + #include "system/system.h" + #include "system/ramblock.h" + ++#include ++ + #include "hw/i386/e820_memory_layout.h" + #include "hw/i386/tdvf.h" + #include "hw/i386/x86.h" +@@ -376,6 +378,11 @@ static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + } + } + ++ /* TDX relies on KVM_HC_MAP_GPA_RANGE to handle TDG.VP.VMCALL */ ++ if (!kvm_enable_hypercall(BIT_ULL(KVM_HC_MAP_GPA_RANGE))) { ++ return -EOPNOTSUPP; ++ } ++ + qemu_add_machine_init_done_notifier(&tdx_machine_done_notify); + + tdx_guest = tdx; +-- +2.47.3 + diff --git a/kvm-i386-tdx-Error-and-exit-when-named-cpu-model-is-requ.patch b/kvm-i386-tdx-Error-and-exit-when-named-cpu-model-is-requ.patch new file mode 100644 index 0000000..e028ebb --- /dev/null +++ b/kvm-i386-tdx-Error-and-exit-when-named-cpu-model-is-requ.patch @@ -0,0 +1,51 @@ +From 63b6a50ddb09648005834acaaecba068284c84bb Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:49 +0200 +Subject: [PATCH 073/100] i386/tdx: Error and exit when named cpu model is + requested + +Currently, it gets below error when requesting any named cpu model with +"-cpu" to boot a TDX VM: + + qemu-system-x86_64: KVM_TDX_INIT_VM failed: Invalid argument + +It misleads people to think it's the bug of KVM or QEMU. It is just that +current QEMU doesn't support named cpu model for TDX. + +To support named cpu models for TDX guest, there are opens to be +finalized and needs a mount of additional work. + +For now, explicitly check the case when named cpu model is requested. +Error report a hint and exit. + +Signed-off-by: Xiaoyao Li +Link: https://lore.kernel.org/r/20250612133801.2238342-1-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 750560f8a832361cf5cc4cd7bc4f56e1e76206f6) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index d3c120fc5a..6ac1200c96 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -739,8 +739,14 @@ static int tdx_kvm_type(X86ConfidentialGuest *cg) + + static void tdx_cpu_instance_init(X86ConfidentialGuest *cg, CPUState *cpu) + { ++ X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu); + X86CPU *x86cpu = X86_CPU(cpu); + ++ if (xcc->model) { ++ error_report("Named cpu model is not supported for TDX yet!"); ++ exit(1); ++ } ++ + object_property_set_bool(OBJECT(cpu), "pmu", false, &error_abort); + + /* invtsc is fixed1 for TD guest */ +-- +2.47.3 + diff --git a/kvm-i386-tdx-Fetch-and-validate-CPUID-of-TD-guest.patch b/kvm-i386-tdx-Fetch-and-validate-CPUID-of-TD-guest.patch new file mode 100644 index 0000000..4b734c8 --- /dev/null +++ b/kvm-i386-tdx-Fetch-and-validate-CPUID-of-TD-guest.patch @@ -0,0 +1,225 @@ +From 228e40f33048812c2bc68552b0d0d3bf6c7d9d12 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:48 +0200 +Subject: [PATCH 065/100] i386/tdx: Fetch and validate CPUID of TD guest + +Use KVM_TDX_GET_CPUID to get the CPUIDs that are managed and enfored +by TDX module for TD guest. Check QEMU's configuration against the +fetched data. + +Print wanring message when 1. a feature is not supported but requested +by QEMU or 2. QEMU doesn't want to expose a feature while it is enforced +enabled. + +- If cpu->enforced_cpuid is not set, prints the warning message of both +1) and 2) and tweak QEMU's configuration. + +- If cpu->enforced_cpuid is set, quit if any case of 1) or 2). + +Signed-off-by: Xiaoyao Li +Link: https://lore.kernel.org/r/20250508150002.689633-52-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit e3d1a4a6d1d61cf5fbd0e4b389cfb3976093739f) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 33 +++++++++++++- + target/i386/cpu.h | 7 +++ + target/i386/kvm/tdx.c | 101 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 139 insertions(+), 2 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 9f05f4f142..587da2cb84 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -6224,8 +6224,8 @@ static bool x86_cpu_have_filtered_features(X86CPU *cpu) + return false; + } + +-static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint64_t mask, +- const char *verbose_prefix) ++void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint64_t mask, ++ const char *verbose_prefix) + { + CPUX86State *env = &cpu->env; + FeatureWordInfo *f = &feature_word_info[w]; +@@ -6252,6 +6252,35 @@ static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint64_t mask, + } + } + ++void mark_forced_on_features(X86CPU *cpu, FeatureWord w, uint64_t mask, ++ const char *verbose_prefix) ++{ ++ CPUX86State *env = &cpu->env; ++ FeatureWordInfo *f = &feature_word_info[w]; ++ int i; ++ ++ if (!cpu->force_features) { ++ env->features[w] |= mask; ++ } ++ ++ cpu->forced_on_features[w] |= mask; ++ ++ if (!verbose_prefix) { ++ return; ++ } ++ ++ for (i = 0; i < 64; ++i) { ++ if ((1ULL << i) & mask) { ++ g_autofree char *feat_word_str = feature_word_description(f); ++ warn_report("%s: %s%s%s [bit %d]", ++ verbose_prefix, ++ feat_word_str, ++ f->feat_names[i] ? "." : "", ++ f->feat_names[i] ? f->feat_names[i] : "", i); ++ } ++ } ++} ++ + static void x86_cpuid_version_get_family(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 79903ea6fe..2ff5668dc9 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -2231,6 +2231,9 @@ struct ArchCPU { + /* Features that were filtered out because of missing host capabilities */ + FeatureWordArray filtered_features; + ++ /* Features that are forced enabled by underlying hypervisor, e.g., TDX */ ++ FeatureWordArray forced_on_features; ++ + /* Enable PMU CPUID bits. This can't be enabled by default yet because + * it doesn't have ABI stability guarantees, as it passes all PMU CPUID + * bits returned by GET_SUPPORTED_CPUID (that depend on host CPU and kernel +@@ -2543,6 +2546,10 @@ void host_cpuid(uint32_t function, uint32_t count, + uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); + bool cpu_has_x2apic_feature(CPUX86State *env); + bool is_feature_word_cpuid(uint32_t feature, uint32_t index, int reg); ++void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint64_t mask, ++ const char *verbose_prefix); ++void mark_forced_on_features(X86CPU *cpu, FeatureWord w, uint64_t mask, ++ const char *verbose_prefix); + + static inline bool x86_has_cpuid_0x1f(X86CPU *cpu) + { +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 3ee163e032..4aa651e75d 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -766,6 +766,106 @@ static uint32_t tdx_adjust_cpuid_features(X86ConfidentialGuest *cg, + return value; + } + ++static struct kvm_cpuid2 *tdx_fetch_cpuid(CPUState *cpu, int *ret) ++{ ++ struct kvm_cpuid2 *fetch_cpuid; ++ int size = KVM_MAX_CPUID_ENTRIES; ++ Error *local_err = NULL; ++ int r; ++ ++ do { ++ error_free(local_err); ++ local_err = NULL; ++ ++ fetch_cpuid = g_malloc0(sizeof(*fetch_cpuid) + ++ sizeof(struct kvm_cpuid_entry2) * size); ++ fetch_cpuid->nent = size; ++ r = tdx_vcpu_ioctl(cpu, KVM_TDX_GET_CPUID, 0, fetch_cpuid, &local_err); ++ if (r == -E2BIG) { ++ g_free(fetch_cpuid); ++ size = fetch_cpuid->nent; ++ } ++ } while (r == -E2BIG); ++ ++ if (r < 0) { ++ error_report_err(local_err); ++ *ret = r; ++ return NULL; ++ } ++ ++ return fetch_cpuid; ++} ++ ++static int tdx_check_features(X86ConfidentialGuest *cg, CPUState *cs) ++{ ++ uint64_t actual, requested, unavailable, forced_on; ++ g_autofree struct kvm_cpuid2 *fetch_cpuid; ++ const char *forced_on_prefix = NULL; ++ const char *unav_prefix = NULL; ++ struct kvm_cpuid_entry2 *entry; ++ X86CPU *cpu = X86_CPU(cs); ++ CPUX86State *env = &cpu->env; ++ FeatureWordInfo *wi; ++ FeatureWord w; ++ bool mismatch = false; ++ int r; ++ ++ fetch_cpuid = tdx_fetch_cpuid(cs, &r); ++ if (!fetch_cpuid) { ++ return r; ++ } ++ ++ if (cpu->check_cpuid || cpu->enforce_cpuid) { ++ unav_prefix = "TDX doesn't support requested feature"; ++ forced_on_prefix = "TDX forcibly sets the feature"; ++ } ++ ++ for (w = 0; w < FEATURE_WORDS; w++) { ++ wi = &feature_word_info[w]; ++ actual = 0; ++ ++ switch (wi->type) { ++ case CPUID_FEATURE_WORD: ++ entry = cpuid_find_entry(fetch_cpuid, wi->cpuid.eax, wi->cpuid.ecx); ++ if (!entry) { ++ /* ++ * If KVM doesn't report it means it's totally configurable ++ * by QEMU ++ */ ++ continue; ++ } ++ ++ actual = cpuid_entry_get_reg(entry, wi->cpuid.reg); ++ break; ++ case MSR_FEATURE_WORD: ++ /* ++ * TODO: ++ * validate MSR features when KVM has interface report them. ++ */ ++ continue; ++ } ++ ++ requested = env->features[w]; ++ unavailable = requested & ~actual; ++ mark_unavailable_features(cpu, w, unavailable, unav_prefix); ++ if (unavailable) { ++ mismatch = true; ++ } ++ ++ forced_on = actual & ~requested; ++ mark_forced_on_features(cpu, w, forced_on, forced_on_prefix); ++ if (forced_on) { ++ mismatch = true; ++ } ++ } ++ ++ if (cpu->enforce_cpuid && mismatch) { ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static int tdx_validate_attributes(TdxGuest *tdx, Error **errp) + { + if ((tdx->attributes & ~tdx_caps->supported_attrs)) { +@@ -1161,4 +1261,5 @@ static void tdx_guest_class_init(ObjectClass *oc, void *data) + x86_klass->kvm_type = tdx_kvm_type; + x86_klass->cpu_instance_init = tdx_cpu_instance_init; + x86_klass->adjust_cpuid_features = tdx_adjust_cpuid_features; ++ x86_klass->check_features = tdx_check_features; + } +-- +2.47.3 + diff --git a/kvm-i386-tdx-Finalize-TDX-VM.patch b/kvm-i386-tdx-Finalize-TDX-VM.patch new file mode 100644 index 0000000..bfaf179 --- /dev/null +++ b/kvm-i386-tdx-Finalize-TDX-VM.patch @@ -0,0 +1,36 @@ +From 82457f8670a7bbbec4c613ed2cbbdd513cbe6baf Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:47 +0200 +Subject: [PATCH 040/100] i386/tdx: Finalize TDX VM + +Invoke KVM_TDX_FINALIZE_VM to finalize the TD's measurement and make +the TD vCPUs runnable once machine initialization is complete. + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-27-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit ae60ff4e9f9e5790f79abf866ec67270c28ca477) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 86fc78b0e6..9d169d4368 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -353,6 +353,9 @@ static void tdx_finalize_vm(Notifier *notifier, void *unused) + */ + ram_block = tdx_guest->tdvf_mr->ram_block; + ram_block_discard_range(ram_block, 0, ram_block->max_length); ++ ++ tdx_vm_ioctl(KVM_TDX_FINALIZE_VM, 0, NULL, &error_fatal); ++ CONFIDENTIAL_GUEST_SUPPORT(tdx_guest)->ready = true; + } + + static Notifier tdx_machine_done_notify = { +-- +2.47.3 + diff --git a/kvm-i386-tdx-Fix-build-on-32-bit-host.patch b/kvm-i386-tdx-Fix-build-on-32-bit-host.patch new file mode 100644 index 0000000..68b8bca --- /dev/null +++ b/kvm-i386-tdx-Fix-build-on-32-bit-host.patch @@ -0,0 +1,113 @@ +From ea0aa4100bff08f39840f977457dd292ea461292 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:49 +0200 +Subject: [PATCH 070/100] i386/tdx: Fix build on 32-bit host +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use PRI formats where required and fix pointer cast. + +Cc: Xiaoyao Li +Signed-off-by: CĂ©dric Le Goater +Link: https://lore.kernel.org/r/20250602173101.1052983-2-clg@redhat.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit e7f926eb7f5b81c709313974b476ed181c9c76d5) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 4b5847e92a..d3c120fc5a 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -284,7 +284,7 @@ static void tdx_post_init_vcpus(void) + + hob = tdx_get_hob_entry(tdx_guest); + CPU_FOREACH(cpu) { +- tdx_vcpu_ioctl(cpu, KVM_TDX_INIT_VCPU, 0, (void *)hob->address, ++ tdx_vcpu_ioctl(cpu, KVM_TDX_INIT_VCPU, 0, (void *)(uintptr_t)hob->address, + &error_fatal); + } + } +@@ -339,7 +339,7 @@ static void tdx_finalize_vm(Notifier *notifier, void *unused) + uint32_t flags; + + region = (struct kvm_tdx_init_mem_region) { +- .source_addr = (uint64_t)entry->mem_ptr, ++ .source_addr = (uintptr_t)entry->mem_ptr, + .gpa = entry->address, + .nr_pages = entry->size >> 12, + }; +@@ -893,16 +893,16 @@ static int tdx_check_features(X86ConfidentialGuest *cg, CPUState *cs) + static int tdx_validate_attributes(TdxGuest *tdx, Error **errp) + { + if ((tdx->attributes & ~tdx_caps->supported_attrs)) { +- error_setg(errp, "Invalid attributes 0x%lx for TDX VM " +- "(KVM supported: 0x%llx)", tdx->attributes, +- tdx_caps->supported_attrs); ++ error_setg(errp, "Invalid attributes 0x%"PRIx64" for TDX VM " ++ "(KVM supported: 0x%"PRIx64")", tdx->attributes, ++ (uint64_t)tdx_caps->supported_attrs); + return -1; + } + + if (tdx->attributes & ~TDX_SUPPORTED_TD_ATTRS) { + error_setg(errp, "Some QEMU unsupported TD attribute bits being " +- "requested: 0x%lx (QEMU supported: 0x%llx)", +- tdx->attributes, TDX_SUPPORTED_TD_ATTRS); ++ "requested: 0x%"PRIx64" (QEMU supported: 0x%"PRIx64")", ++ tdx->attributes, (uint64_t)TDX_SUPPORTED_TD_ATTRS); + return -1; + } + +@@ -931,8 +931,8 @@ static int setup_td_xfam(X86CPU *x86cpu, Error **errp) + env->features[FEAT_XSAVE_XSS_HI]; + + if (xfam & ~tdx_caps->supported_xfam) { +- error_setg(errp, "Invalid XFAM 0x%lx for TDX VM (supported: 0x%llx))", +- xfam, tdx_caps->supported_xfam); ++ error_setg(errp, "Invalid XFAM 0x%"PRIx64" for TDX VM (supported: 0x%"PRIx64"))", ++ xfam, (uint64_t)tdx_caps->supported_xfam); + return -1; + } + +@@ -999,14 +999,14 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) + + if (env->tsc_khz && (env->tsc_khz < TDX_MIN_TSC_FREQUENCY_KHZ || + env->tsc_khz > TDX_MAX_TSC_FREQUENCY_KHZ)) { +- error_setg(errp, "Invalid TSC %ld KHz, must specify cpu_frequency " ++ error_setg(errp, "Invalid TSC %"PRId64" KHz, must specify cpu_frequency " + "between [%d, %d] kHz", env->tsc_khz, + TDX_MIN_TSC_FREQUENCY_KHZ, TDX_MAX_TSC_FREQUENCY_KHZ); + return -EINVAL; + } + + if (env->tsc_khz % (25 * 1000)) { +- error_setg(errp, "Invalid TSC %ld KHz, it must be multiple of 25MHz", ++ error_setg(errp, "Invalid TSC %"PRId64" KHz, it must be multiple of 25MHz", + env->tsc_khz); + return -EINVAL; + } +@@ -1014,7 +1014,7 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) + /* it's safe even env->tsc_khz is 0. KVM uses host's tsc_khz in this case */ + r = kvm_vm_ioctl(kvm_state, KVM_SET_TSC_KHZ, env->tsc_khz); + if (r < 0) { +- error_setg_errno(errp, -r, "Unable to set TSC frequency to %ld kHz", ++ error_setg_errno(errp, -r, "Unable to set TSC frequency to %"PRId64" kHz", + env->tsc_khz); + return r; + } +@@ -1139,7 +1139,7 @@ int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm_run *run) + uint64_t gpa = -1ull; + + if (error_code & 0xffff) { +- error_report("TDX: REPORT_FATAL_ERROR: invalid error code: 0x%lx", ++ error_report("TDX: REPORT_FATAL_ERROR: invalid error code: 0x%"PRIx64, + error_code); + return -1; + } +-- +2.47.3 + diff --git a/kvm-i386-tdx-Fix-the-report-of-gpa-in-QAPI.patch b/kvm-i386-tdx-Fix-the-report-of-gpa-in-QAPI.patch new file mode 100644 index 0000000..2676129 --- /dev/null +++ b/kvm-i386-tdx-Fix-the-report-of-gpa-in-QAPI.patch @@ -0,0 +1,70 @@ +From 393bab367b714f5db82239445dfa58d35f3036a0 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:50 +0200 +Subject: [PATCH 087/100] i386/tdx: Fix the report of gpa in QAPI +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Gpa is defined in QAPI but never reported to monitor because has_gpa is +never set to ture. + +Fix it by setting has_gpa to ture when TDX_REPORT_FATAL_ERROR_GPA_VALID +is set in error_code. + +Fixes: 6e250463b08b ("i386/tdx: Wire TDX_REPORT_FATAL_ERROR with GuestPanic facility") +Signed-off-by: Zhenzhong Duan +Reviewed-by: Daniel P. BerrangĂ© +Link: https://lore.kernel.org/r/20250710035538.303136-1-zhenzhong.duan@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit b28f6d5c16f19f8c56926c10929db29f913895ad) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 416dd41ab8..aad56f600d 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -1321,7 +1321,8 @@ void tdx_handle_setup_event_notify_interrupt(X86CPU *cpu, struct kvm_run *run) + } + + static void tdx_panicked_on_fatal_error(X86CPU *cpu, uint64_t error_code, +- char *message, uint64_t gpa) ++ char *message, bool has_gpa, ++ uint64_t gpa) + { + GuestPanicInformation *panic_info; + +@@ -1330,6 +1331,7 @@ static void tdx_panicked_on_fatal_error(X86CPU *cpu, uint64_t error_code, + panic_info->u.tdx.error_code = (uint32_t) error_code; + panic_info->u.tdx.message = message; + panic_info->u.tdx.gpa = gpa; ++ panic_info->u.tdx.has_gpa = has_gpa; + + qemu_system_guest_panicked(panic_info); + } +@@ -1349,6 +1351,7 @@ int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm_run *run) + char *message = NULL; + uint64_t *tmp; + uint64_t gpa = -1ull; ++ bool has_gpa = false; + + if (error_code & 0xffff) { + error_report("TDX: REPORT_FATAL_ERROR: invalid error code: 0x%"PRIx64, +@@ -1381,9 +1384,10 @@ int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm_run *run) + + if (error_code & TDX_REPORT_FATAL_ERROR_GPA_VALID) { + gpa = run->system_event.data[R_R13]; ++ has_gpa = true; + } + +- tdx_panicked_on_fatal_error(cpu, error_code, message, gpa); ++ tdx_panicked_on_fatal_error(cpu, error_code, message, has_gpa, gpa); + + return -1; + } +-- +2.47.3 + diff --git a/kvm-i386-tdx-Fix-the-typo-of-the-comment-of-struct-TdxGu.patch b/kvm-i386-tdx-Fix-the-typo-of-the-comment-of-struct-TdxGu.patch new file mode 100644 index 0000000..6de7fd7 --- /dev/null +++ b/kvm-i386-tdx-Fix-the-typo-of-the-comment-of-struct-TdxGu.patch @@ -0,0 +1,42 @@ +From 731ce705d47476b1defeb7926be8bca5eeeba186 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:49 +0200 +Subject: [PATCH 075/100] i386/tdx: Fix the typo of the comment of struct + TdxGuest +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Change sha348 to sha384. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Igor Mammedov +Link: https://lore.kernel.org/r/20250603050305.1704586-3-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit a38da9f4876bb17d7ed9c6e24964b12b61877d38) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h +index 04b5afe199..8dd66e9014 100644 +--- a/target/i386/kvm/tdx.h ++++ b/target/i386/kvm/tdx.h +@@ -40,9 +40,9 @@ typedef struct TdxGuest { + bool initialized; + uint64_t attributes; /* TD attributes */ + uint64_t xfam; +- char *mrconfigid; /* base64 encoded sha348 digest */ +- char *mrowner; /* base64 encoded sha348 digest */ +- char *mrownerconfig; /* base64 encoded sha348 digest */ ++ char *mrconfigid; /* base64 encoded sha384 digest */ ++ char *mrowner; /* base64 encoded sha384 digest */ ++ char *mrownerconfig; /* base64 encoded sha384 digest */ + + MemoryRegion *tdvf_mr; + TdxFirmware tdvf; +-- +2.47.3 + diff --git a/kvm-i386-tdx-Force-exposing-CPUID-0x1f.patch b/kvm-i386-tdx-Force-exposing-CPUID-0x1f.patch new file mode 100644 index 0000000..36d3c6a --- /dev/null +++ b/kvm-i386-tdx-Force-exposing-CPUID-0x1f.patch @@ -0,0 +1,37 @@ +From b478562c6120f493a9254067eafe90a753e4f390 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:47 +0200 +Subject: [PATCH 048/100] i386/tdx: Force exposing CPUID 0x1f + +TDX uses CPUID 0x1f to configure TD guest's CPU topology. So set +enable_cpuid_0x1f for TDs. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-35-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 9002494f80b751a7655045c5f46bf90bc1d3bbd0) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 0c9a895a2f..66db034e05 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -400,7 +400,11 @@ static int tdx_kvm_type(X86ConfidentialGuest *cg) + + static void tdx_cpu_instance_init(X86ConfidentialGuest *cg, CPUState *cpu) + { ++ X86CPU *x86cpu = X86_CPU(cpu); ++ + object_property_set_bool(OBJECT(cpu), "pmu", false, &error_abort); ++ ++ x86cpu->enable_cpuid_0x1f = true; + } + + static int tdx_validate_attributes(TdxGuest *tdx, Error **errp) +-- +2.47.3 + diff --git a/kvm-i386-tdx-Get-tdx_capabilities-via-KVM_TDX_CAPABILITI.patch b/kvm-i386-tdx-Get-tdx_capabilities-via-KVM_TDX_CAPABILITI.patch new file mode 100644 index 0000000..70aa1de --- /dev/null +++ b/kvm-i386-tdx-Get-tdx_capabilities-via-KVM_TDX_CAPABILITI.patch @@ -0,0 +1,185 @@ +From 54603fdc5c74e002cf8806873823526c4ee828f8 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:45 +0200 +Subject: [PATCH 019/100] i386/tdx: Get tdx_capabilities via + KVM_TDX_CAPABILITIES + +KVM provides TDX capabilities via sub command KVM_TDX_CAPABILITIES of +IOCTL(KVM_MEMORY_ENCRYPT_OP). Get the capabilities when initializing +TDX context. It will be used to validate user's setting later. + +Since there is no interface reporting how many cpuid configs contains in +KVM_TDX_CAPABILITIES, QEMU chooses to try starting with a known number +and abort when it exceeds KVM_MAX_CPUID_ENTRIES. + +Besides, introduce the interfaces to invoke TDX "ioctls" at VCPU scope +in preparation. + +Signed-off-by: Xiaoyao Li +Link: https://lore.kernel.org/r/20250508150002.689633-6-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 8eddedc3701d2190db976a05155a8263c8ec175b) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/kvm.c | 2 - + target/i386/kvm/kvm_i386.h | 2 + + target/i386/kvm/tdx.c | 107 ++++++++++++++++++++++++++++++++++++- + 3 files changed, 108 insertions(+), 3 deletions(-) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 3efdb9c713..dcb432cb48 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -1779,8 +1779,6 @@ static int hyperv_init_vcpu(X86CPU *cpu) + + static Error *invtsc_mig_blocker; + +-#define KVM_MAX_CPUID_ENTRIES 100 +- + static void kvm_init_xsave(CPUX86State *env) + { + if (has_xsave2) { +diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h +index 88565e8dba..ed1e61fb8b 100644 +--- a/target/i386/kvm/kvm_i386.h ++++ b/target/i386/kvm/kvm_i386.h +@@ -13,6 +13,8 @@ + + #include "system/kvm.h" + ++#define KVM_MAX_CPUID_ENTRIES 100 ++ + /* always false if !CONFIG_KVM */ + #define kvm_pit_in_kernel() \ + (kvm_irqchip_in_kernel() && !kvm_irqchip_is_split()) +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 4ff9486081..c67be5e618 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -10,17 +10,122 @@ + */ + + #include "qemu/osdep.h" ++#include "qemu/error-report.h" ++#include "qapi/error.h" + #include "qom/object_interfaces.h" + + #include "hw/i386/x86.h" + #include "kvm_i386.h" + #include "tdx.h" + ++static struct kvm_tdx_capabilities *tdx_caps; ++ ++enum tdx_ioctl_level { ++ TDX_VM_IOCTL, ++ TDX_VCPU_IOCTL, ++}; ++ ++static int tdx_ioctl_internal(enum tdx_ioctl_level level, void *state, ++ int cmd_id, __u32 flags, void *data, ++ Error **errp) ++{ ++ struct kvm_tdx_cmd tdx_cmd = {}; ++ int r; ++ ++ const char *tdx_ioctl_name[] = { ++ [KVM_TDX_CAPABILITIES] = "KVM_TDX_CAPABILITIES", ++ [KVM_TDX_INIT_VM] = "KVM_TDX_INIT_VM", ++ [KVM_TDX_INIT_VCPU] = "KVM_TDX_INIT_VCPU", ++ [KVM_TDX_INIT_MEM_REGION] = "KVM_TDX_INIT_MEM_REGION", ++ [KVM_TDX_FINALIZE_VM] = "KVM_TDX_FINALIZE_VM", ++ [KVM_TDX_GET_CPUID] = "KVM_TDX_GET_CPUID", ++ }; ++ ++ tdx_cmd.id = cmd_id; ++ tdx_cmd.flags = flags; ++ tdx_cmd.data = (__u64)(unsigned long)data; ++ ++ switch (level) { ++ case TDX_VM_IOCTL: ++ r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, &tdx_cmd); ++ break; ++ case TDX_VCPU_IOCTL: ++ r = kvm_vcpu_ioctl(state, KVM_MEMORY_ENCRYPT_OP, &tdx_cmd); ++ break; ++ default: ++ error_setg(errp, "Invalid tdx_ioctl_level %d", level); ++ return -EINVAL; ++ } ++ ++ if (r < 0) { ++ error_setg_errno(errp, -r, "TDX ioctl %s failed, hw_errors: 0x%llx", ++ tdx_ioctl_name[cmd_id], tdx_cmd.hw_error); ++ } ++ return r; ++} ++ ++static inline int tdx_vm_ioctl(int cmd_id, __u32 flags, void *data, ++ Error **errp) ++{ ++ return tdx_ioctl_internal(TDX_VM_IOCTL, NULL, cmd_id, flags, data, errp); ++} ++ ++static inline int tdx_vcpu_ioctl(CPUState *cpu, int cmd_id, __u32 flags, ++ void *data, Error **errp) ++{ ++ return tdx_ioctl_internal(TDX_VCPU_IOCTL, cpu, cmd_id, flags, data, errp); ++} ++ ++static int get_tdx_capabilities(Error **errp) ++{ ++ struct kvm_tdx_capabilities *caps; ++ /* 1st generation of TDX reports 6 cpuid configs */ ++ int nr_cpuid_configs = 6; ++ size_t size; ++ int r; ++ ++ do { ++ Error *local_err = NULL; ++ size = sizeof(struct kvm_tdx_capabilities) + ++ nr_cpuid_configs * sizeof(struct kvm_cpuid_entry2); ++ caps = g_malloc0(size); ++ caps->cpuid.nent = nr_cpuid_configs; ++ ++ r = tdx_vm_ioctl(KVM_TDX_CAPABILITIES, 0, caps, &local_err); ++ if (r == -E2BIG) { ++ g_free(caps); ++ nr_cpuid_configs *= 2; ++ if (nr_cpuid_configs > KVM_MAX_CPUID_ENTRIES) { ++ error_report("KVM TDX seems broken that number of CPUID entries" ++ " in kvm_tdx_capabilities exceeds limit: %d", ++ KVM_MAX_CPUID_ENTRIES); ++ error_propagate(errp, local_err); ++ return r; ++ } ++ error_free(local_err); ++ } else if (r < 0) { ++ g_free(caps); ++ error_propagate(errp, local_err); ++ return r; ++ } ++ } while (r == -E2BIG); ++ ++ tdx_caps = caps; ++ ++ return 0; ++} ++ + static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + { ++ int r = 0; ++ + kvm_mark_guest_state_protected(); + +- return 0; ++ if (!tdx_caps) { ++ r = get_tdx_capabilities(errp); ++ } ++ ++ return r; + } + + static int tdx_kvm_type(X86ConfidentialGuest *cg) +-- +2.47.3 + diff --git a/kvm-i386-tdx-Handle-KVM_SYSTEM_EVENT_TDX_FATAL.patch b/kvm-i386-tdx-Handle-KVM_SYSTEM_EVENT_TDX_FATAL.patch new file mode 100644 index 0000000..29d4c91 --- /dev/null +++ b/kvm-i386-tdx-Handle-KVM_SYSTEM_EVENT_TDX_FATAL.patch @@ -0,0 +1,138 @@ +From cde0058437607598e0a96332e8ba58453763c71b Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:47 +0200 +Subject: [PATCH 042/100] i386/tdx: Handle KVM_SYSTEM_EVENT_TDX_FATAL + +TD guest can use TDG.VP.VMCALL to request +termination. KVM translates such request into KVM_EXIT_SYSTEM_EVENT with +type of KVM_SYSTEM_EVENT_TDX_FATAL. + +Add hanlder for such exit. Parse and print the error message, and +terminate the TD guest in the handler. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-29-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 98dbfd6849f117de02ac6f513f2a1f95563e60ae) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/kvm.c | 10 +++++++++ + target/i386/kvm/tdx-stub.c | 5 +++++ + target/i386/kvm/tdx.c | 46 ++++++++++++++++++++++++++++++++++++++ + target/i386/kvm/tdx.h | 2 ++ + 4 files changed, 63 insertions(+) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 6a2a207693..8fb0e31b5e 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -6132,6 +6132,16 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) + case KVM_EXIT_HYPERCALL: + ret = kvm_handle_hypercall(run); + break; ++ case KVM_EXIT_SYSTEM_EVENT: ++ switch (run->system_event.type) { ++ case KVM_SYSTEM_EVENT_TDX_FATAL: ++ ret = tdx_handle_report_fatal_error(cpu, run); ++ break; ++ default: ++ ret = -1; ++ break; ++ } ++ break; + default: + fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason); + ret = -1; +diff --git a/target/i386/kvm/tdx-stub.c b/target/i386/kvm/tdx-stub.c +index 7748b6d0a4..720a4ff046 100644 +--- a/target/i386/kvm/tdx-stub.c ++++ b/target/i386/kvm/tdx-stub.c +@@ -13,3 +13,8 @@ int tdx_parse_tdvf(void *flash_ptr, int size) + { + return -EINVAL; + } ++ ++int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm_run *run) ++{ ++ return -EINVAL; ++} +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 6ad4f82864..1030bf12dc 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -615,6 +615,52 @@ int tdx_parse_tdvf(void *flash_ptr, int size) + return tdvf_parse_metadata(&tdx_guest->tdvf, flash_ptr, size); + } + ++/* ++ * Only 8 registers can contain valid ASCII byte stream to form the fatal ++ * message, and their sequence is: R14, R15, RBX, RDI, RSI, R8, R9, RDX ++ */ ++#define TDX_FATAL_MESSAGE_MAX 64 ++ ++int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm_run *run) ++{ ++ uint64_t error_code = run->system_event.data[R_R12]; ++ uint64_t reg_mask = run->system_event.data[R_ECX]; ++ char *message = NULL; ++ uint64_t *tmp; ++ ++ if (error_code & 0xffff) { ++ error_report("TDX: REPORT_FATAL_ERROR: invalid error code: 0x%lx", ++ error_code); ++ return -1; ++ } ++ ++ if (reg_mask) { ++ message = g_malloc0(TDX_FATAL_MESSAGE_MAX + 1); ++ tmp = (uint64_t *)message; ++ ++#define COPY_REG(REG) \ ++ do { \ ++ if (reg_mask & BIT_ULL(REG)) { \ ++ *(tmp++) = run->system_event.data[REG]; \ ++ } \ ++ } while (0) ++ ++ COPY_REG(R_R14); ++ COPY_REG(R_R15); ++ COPY_REG(R_EBX); ++ COPY_REG(R_EDI); ++ COPY_REG(R_ESI); ++ COPY_REG(R_R8); ++ COPY_REG(R_R9); ++ COPY_REG(R_EDX); ++ *((char *)tmp) = '\0'; ++ } ++#undef COPY_REG ++ ++ error_report("TD guest reports fatal error. %s", message ? : ""); ++ return -1; ++} ++ + static bool tdx_guest_get_sept_ve_disable(Object *obj, Error **errp) + { + TdxGuest *tdx = TDX_GUEST(obj); +diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h +index 36a7400e74..04b5afe199 100644 +--- a/target/i386/kvm/tdx.h ++++ b/target/i386/kvm/tdx.h +@@ -8,6 +8,7 @@ + #endif + + #include "confidential-guest.h" ++#include "cpu.h" + #include "hw/i386/tdvf.h" + + #define TYPE_TDX_GUEST "tdx-guest" +@@ -59,5 +60,6 @@ bool is_tdx_vm(void); + int tdx_pre_create_vcpu(CPUState *cpu, Error **errp); + void tdx_set_tdvf_region(MemoryRegion *tdvf_mr); + int tdx_parse_tdvf(void *flash_ptr, int size); ++int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm_run *run); + + #endif /* QEMU_I386_TDX_H */ +-- +2.47.3 + diff --git a/kvm-i386-tdx-Implement-adjust_cpuid_features-for-TDX.patch b/kvm-i386-tdx-Implement-adjust_cpuid_features-for-TDX.patch new file mode 100644 index 0000000..d29623d --- /dev/null +++ b/kvm-i386-tdx-Implement-adjust_cpuid_features-for-TDX.patch @@ -0,0 +1,171 @@ +From 73cb33c35d7863ad0db22f2e5c97386d106cd2d0 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:48 +0200 +Subject: [PATCH 058/100] i386/tdx: Implement adjust_cpuid_features() for TDX + +Maintain a TDX specific supported CPUID set, and use it to mask the +common supported CPUID value of KVM. It can avoid newly added supported +features (reported via KVM_GET_SUPPORTED_CPUID) for common VMs being +falsely reported as supported for TDX. + +As the first step, initialize the TDX supported CPUID set with all the +configurable CPUID bits. It's not complete because there are other CPUID +bits are supported for TDX but not reported as directly configurable. +E.g. the XFAM related bits, attribute related bits and fixed-1 bits. +They will be handled in the future. + +Also, what matters are the CPUID bits related to QEMU's feature word. +Only mask the CPUID leafs which are feature word leaf. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-45-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 75ec6189f5c65cab210dd9f16cf4eef368038d45) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 16 ++++++++++++++++ + target/i386/cpu.h | 1 + + target/i386/kvm/kvm.c | 2 +- + target/i386/kvm/kvm_i386.h | 1 + + target/i386/kvm/tdx.c | 34 ++++++++++++++++++++++++++++++++++ + 5 files changed, 53 insertions(+), 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index cb5a8de684..d85aa3d9bc 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -1656,6 +1656,22 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + }, + }; + ++bool is_feature_word_cpuid(uint32_t feature, uint32_t index, int reg) ++{ ++ FeatureWordInfo *wi; ++ FeatureWord w; ++ ++ for (w = 0; w < FEATURE_WORDS; w++) { ++ wi = &feature_word_info[w]; ++ if (wi->type == CPUID_FEATURE_WORD && wi->cpuid.eax == feature && ++ (!wi->cpuid.needs_ecx || wi->cpuid.ecx == index) && ++ wi->cpuid.reg == reg) { ++ return true; ++ } ++ } ++ return false; ++} ++ + typedef struct FeatureMask { + FeatureWord index; + uint64_t mask; +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index ed74dfeba8..a8bffcdd3a 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -2519,6 +2519,7 @@ void cpu_set_apic_feature(CPUX86State *env); + void host_cpuid(uint32_t function, uint32_t count, + uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); + bool cpu_has_x2apic_feature(CPUX86State *env); ++bool is_feature_word_cpuid(uint32_t feature, uint32_t index, int reg); + + static inline bool x86_has_cpuid_0x1f(X86CPU *cpu) + { +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index c3cecd871b..d1111f67c2 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -393,7 +393,7 @@ static bool host_tsx_broken(void) + + /* Returns the value for a specific register on the cpuid entry + */ +-static uint32_t cpuid_entry_get_reg(struct kvm_cpuid_entry2 *entry, int reg) ++uint32_t cpuid_entry_get_reg(struct kvm_cpuid_entry2 *entry, int reg) + { + uint32_t ret = 0; + switch (reg) { +diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h +index dc696cb723..484a1de84d 100644 +--- a/target/i386/kvm/kvm_i386.h ++++ b/target/i386/kvm/kvm_i386.h +@@ -62,6 +62,7 @@ void kvm_update_msi_routes_all(void *private, bool global, + struct kvm_cpuid_entry2 *cpuid_find_entry(struct kvm_cpuid2 *cpuid, + uint32_t function, + uint32_t index); ++uint32_t cpuid_entry_get_reg(struct kvm_cpuid_entry2 *entry, int reg); + uint32_t kvm_x86_build_cpuid(CPUX86State *env, struct kvm_cpuid_entry2 *entries, + uint32_t cpuid_i); + #endif /* CONFIG_KVM */ +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 8b01e7f993..dc426d1cdb 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -45,6 +45,7 @@ + static TdxGuest *tdx_guest; + + static struct kvm_tdx_capabilities *tdx_caps; ++static struct kvm_cpuid2 *tdx_supported_cpuid; + + /* Valid after kvm_arch_init()->confidential_guest_kvm_init()->tdx_kvm_init() */ + bool is_tdx_vm(void) +@@ -366,6 +367,20 @@ static Notifier tdx_machine_done_notify = { + .notify = tdx_finalize_vm, + }; + ++static void tdx_setup_supported_cpuid(void) ++{ ++ if (tdx_supported_cpuid) { ++ return; ++ } ++ ++ tdx_supported_cpuid = g_malloc0(sizeof(*tdx_supported_cpuid) + ++ KVM_MAX_CPUID_ENTRIES * sizeof(struct kvm_cpuid_entry2)); ++ ++ memcpy(tdx_supported_cpuid->entries, tdx_caps->cpuid.entries, ++ tdx_caps->cpuid.nent * sizeof(struct kvm_cpuid_entry2)); ++ tdx_supported_cpuid->nent = tdx_caps->cpuid.nent; ++} ++ + static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + { + MachineState *ms = MACHINE(qdev_get_machine()); +@@ -403,6 +418,8 @@ static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + } + } + ++ tdx_setup_supported_cpuid(); ++ + /* TDX relies on KVM_HC_MAP_GPA_RANGE to handle TDG.VP.VMCALL */ + if (!kvm_enable_hypercall(BIT_ULL(KVM_HC_MAP_GPA_RANGE))) { + return -EOPNOTSUPP; +@@ -440,6 +457,22 @@ static void tdx_cpu_instance_init(X86ConfidentialGuest *cg, CPUState *cpu) + x86cpu->enable_cpuid_0x1f = true; + } + ++static uint32_t tdx_adjust_cpuid_features(X86ConfidentialGuest *cg, ++ uint32_t feature, uint32_t index, ++ int reg, uint32_t value) ++{ ++ struct kvm_cpuid_entry2 *e; ++ ++ if (is_feature_word_cpuid(feature, index, reg)) { ++ e = cpuid_find_entry(tdx_supported_cpuid, feature, index); ++ if (e) { ++ value &= cpuid_entry_get_reg(e, reg); ++ } ++ } ++ ++ return value; ++} ++ + static int tdx_validate_attributes(TdxGuest *tdx, Error **errp) + { + if ((tdx->attributes & ~tdx_caps->supported_attrs)) { +@@ -834,4 +867,5 @@ static void tdx_guest_class_init(ObjectClass *oc, void *data) + klass->kvm_init = tdx_kvm_init; + x86_klass->kvm_type = tdx_kvm_type; + x86_klass->cpu_instance_init = tdx_cpu_instance_init; ++ x86_klass->adjust_cpuid_features = tdx_adjust_cpuid_features; + } +-- +2.47.3 + diff --git a/kvm-i386-tdx-Implement-tdx_kvm_init-to-initialize-TDX-VM.patch b/kvm-i386-tdx-Implement-tdx_kvm_init-to-initialize-TDX-VM.patch new file mode 100644 index 0000000..1a84f21 --- /dev/null +++ b/kvm-i386-tdx-Implement-tdx_kvm_init-to-initialize-TDX-VM.patch @@ -0,0 +1,84 @@ +From e63413a6e3bebeb6884973320dde6bdbbca8b9e6 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:45 +0200 +Subject: [PATCH 018/100] i386/tdx: Implement tdx_kvm_init() to initialize TDX + VM context +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Implement TDX specific ConfidentialGuestSupportClass::kvm_init() +callback, tdx_kvm_init(). + +Mark guest state is proctected for TDX VM. More TDX specific +initialization will be added later. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-5-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 631a2ac5a4beab740b342367550562cd659b4c4a) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/kvm.c | 11 +---------- + target/i386/kvm/tdx.c | 10 ++++++++++ + 2 files changed, 11 insertions(+), 10 deletions(-) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 1b42738e43..3efdb9c713 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -3206,16 +3206,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) + Error *local_err = NULL; + + /* +- * Initialize SEV context, if required +- * +- * If no memory encryption is requested (ms->cgs == NULL) this is +- * a no-op. +- * +- * It's also a no-op if a non-SEV confidential guest support +- * mechanism is selected. SEV is the only mechanism available to +- * select on x86 at present, so this doesn't arise, but if new +- * mechanisms are supported in future (e.g. TDX), they'll need +- * their own initialization either here or elsewhere. ++ * Initialize confidential guest (SEV/TDX) context, if required + */ + if (ms->cgs) { + ret = confidential_guest_kvm_init(ms->cgs, &local_err); +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index d785c1f6d1..4ff9486081 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -12,9 +12,17 @@ + #include "qemu/osdep.h" + #include "qom/object_interfaces.h" + ++#include "hw/i386/x86.h" + #include "kvm_i386.h" + #include "tdx.h" + ++static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) ++{ ++ kvm_mark_guest_state_protected(); ++ ++ return 0; ++} ++ + static int tdx_kvm_type(X86ConfidentialGuest *cg) + { + /* Do the object check */ +@@ -49,7 +57,9 @@ static void tdx_guest_finalize(Object *obj) + + static void tdx_guest_class_init(ObjectClass *oc, void *data) + { ++ ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc); + X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc); + ++ klass->kvm_init = tdx_kvm_init; + x86_klass->kvm_type = tdx_kvm_type; + } +-- +2.47.3 + diff --git a/kvm-i386-tdx-Implement-tdx_kvm_type-for-TDX.patch b/kvm-i386-tdx-Implement-tdx_kvm_type-for-TDX.patch new file mode 100644 index 0000000..d37db79 --- /dev/null +++ b/kvm-i386-tdx-Implement-tdx_kvm_type-for-TDX.patch @@ -0,0 +1,68 @@ +From cb8a55b3c178bda83d440c4cf38d84373ef3ff47 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:45 +0200 +Subject: [PATCH 017/100] i386/tdx: Implement tdx_kvm_type() for TDX +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +TDX VM requires VM type to be KVM_X86_TDX_VM. Implement tdx_kvm_type() +as X86ConfidentialGuestClass->kvm_type. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-4-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit b455880e5515a9fc2b923bfc6c60bb54519b51d3) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/kvm.c | 1 + + target/i386/kvm/tdx.c | 12 ++++++++++++ + 2 files changed, 13 insertions(+) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 9cb2512c7c..1b42738e43 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -191,6 +191,7 @@ static const char *vm_type_name[] = { + [KVM_X86_SEV_VM] = "SEV", + [KVM_X86_SEV_ES_VM] = "SEV-ES", + [KVM_X86_SNP_VM] = "SEV-SNP", ++ [KVM_X86_TDX_VM] = "TDX", + }; + + bool kvm_is_vm_type_supported(int type) +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index ec84ae2947..d785c1f6d1 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -12,8 +12,17 @@ + #include "qemu/osdep.h" + #include "qom/object_interfaces.h" + ++#include "kvm_i386.h" + #include "tdx.h" + ++static int tdx_kvm_type(X86ConfidentialGuest *cg) ++{ ++ /* Do the object check */ ++ TDX_GUEST(cg); ++ ++ return KVM_X86_TDX_VM; ++} ++ + /* tdx guest */ + OBJECT_DEFINE_TYPE_WITH_INTERFACES(TdxGuest, + tdx_guest, +@@ -40,4 +49,7 @@ static void tdx_guest_finalize(Object *obj) + + static void tdx_guest_class_init(ObjectClass *oc, void *data) + { ++ X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc); ++ ++ x86_klass->kvm_type = tdx_kvm_type; + } +-- +2.47.3 + diff --git a/kvm-i386-tdx-Implement-user-specified-tsc-frequency.patch b/kvm-i386-tdx-Implement-user-specified-tsc-frequency.patch new file mode 100644 index 0000000..c68843c --- /dev/null +++ b/kvm-i386-tdx-Implement-user-specified-tsc-frequency.patch @@ -0,0 +1,93 @@ +From be6087488ac54f5dfad7395324337d1f721b7c47 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:46 +0200 +Subject: [PATCH 029/100] i386/tdx: Implement user specified tsc frequency +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reuse "-cpu,tsc-frequency=" to get user wanted tsc frequency and call VM +scope VM_SET_TSC_KHZ to set the tsc frequency of TD before KVM_TDX_INIT_VM. + +Besides, sanity check the tsc frequency to be in the legal range and +legal granularity (required by TDX module). + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-16-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 0e73b843616e52882940ab89e1b0e86e22be2162) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/kvm.c | 9 +++++++++ + target/i386/kvm/tdx.c | 25 +++++++++++++++++++++++++ + 2 files changed, 34 insertions(+) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index aec01acd7a..6a2a207693 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -869,6 +869,15 @@ static int kvm_arch_set_tsc_khz(CPUState *cs) + int r, cur_freq; + bool set_ioctl = false; + ++ /* ++ * TSC of TD vcpu is immutable, it cannot be set/changed via vcpu scope ++ * VM_SET_TSC_KHZ, but only be initialized via VM scope VM_SET_TSC_KHZ ++ * before ioctl KVM_TDX_INIT_VM in tdx_pre_create_vcpu() ++ */ ++ if (is_tdx_vm()) { ++ return 0; ++ } ++ + if (!env->tsc_khz) { + return 0; + } +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index c96e8eb7b8..56ad5f599d 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -20,6 +20,9 @@ + #include "kvm_i386.h" + #include "tdx.h" + ++#define TDX_MIN_TSC_FREQUENCY_KHZ (100 * 1000) ++#define TDX_MAX_TSC_FREQUENCY_KHZ (10 * 1000 * 1000) ++ + #define TDX_TD_ATTRIBUTES_DEBUG BIT_ULL(0) + #define TDX_TD_ATTRIBUTES_SEPT_VE_DISABLE BIT_ULL(28) + #define TDX_TD_ATTRIBUTES_PKS BIT_ULL(30) +@@ -267,6 +270,28 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) + return r; + } + ++ if (env->tsc_khz && (env->tsc_khz < TDX_MIN_TSC_FREQUENCY_KHZ || ++ env->tsc_khz > TDX_MAX_TSC_FREQUENCY_KHZ)) { ++ error_setg(errp, "Invalid TSC %ld KHz, must specify cpu_frequency " ++ "between [%d, %d] kHz", env->tsc_khz, ++ TDX_MIN_TSC_FREQUENCY_KHZ, TDX_MAX_TSC_FREQUENCY_KHZ); ++ return -EINVAL; ++ } ++ ++ if (env->tsc_khz % (25 * 1000)) { ++ error_setg(errp, "Invalid TSC %ld KHz, it must be multiple of 25MHz", ++ env->tsc_khz); ++ return -EINVAL; ++ } ++ ++ /* it's safe even env->tsc_khz is 0. KVM uses host's tsc_khz in this case */ ++ r = kvm_vm_ioctl(kvm_state, KVM_SET_TSC_KHZ, env->tsc_khz); ++ if (r < 0) { ++ error_setg_errno(errp, -r, "Unable to set TSC frequency to %ld kHz", ++ env->tsc_khz); ++ return r; ++ } ++ + if (tdx_guest->mrconfigid) { + g_autofree uint8_t *data = qbase64_decode(tdx_guest->mrconfigid, + strlen(tdx_guest->mrconfigid), &data_len, errp); +-- +2.47.3 + diff --git a/kvm-i386-tdx-Initialize-TDX-before-creating-TD-vcpus.patch b/kvm-i386-tdx-Initialize-TDX-before-creating-TD-vcpus.patch new file mode 100644 index 0000000..9cee36a --- /dev/null +++ b/kvm-i386-tdx-Initialize-TDX-before-creating-TD-vcpus.patch @@ -0,0 +1,275 @@ +From 64a05a6625cfe0010adf5ea751b426e912e1a229 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:46 +0200 +Subject: [PATCH 022/100] i386/tdx: Initialize TDX before creating TD vcpus + +Invoke KVM_TDX_INIT_VM in kvm_arch_pre_create_vcpu() that +KVM_TDX_INIT_VM configures global TD configurations, e.g. the canonical +CPUID config, and must be executed prior to creating vCPUs. + +Use kvm_x86_arch_cpuid() to setup the CPUID settings for TDX VM. + +Note, this doesn't address the fact that QEMU may change the CPUID +configuration when creating vCPUs, i.e. punts on refactoring QEMU to +provide a stable CPUID config prior to kvm_arch_init(). + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Acked-by: Markus Armbruster +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-9-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit f15898b0f50609d66465326221aa54b6699da674) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/kvm.c | 16 +++--- + target/i386/kvm/kvm_i386.h | 5 ++ + target/i386/kvm/meson.build | 2 +- + target/i386/kvm/tdx-stub.c | 10 ++++ + target/i386/kvm/tdx.c | 105 ++++++++++++++++++++++++++++++++++++ + target/i386/kvm/tdx.h | 6 +++ + 6 files changed, 137 insertions(+), 7 deletions(-) + create mode 100644 target/i386/kvm/tdx-stub.c + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 3affc7193b..aec01acd7a 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -38,6 +38,7 @@ + #include "kvm_i386.h" + #include "../confidential-guest.h" + #include "sev.h" ++#include "tdx.h" + #include "xen-emu.h" + #include "hyperv.h" + #include "hyperv-proto.h" +@@ -414,9 +415,9 @@ static uint32_t cpuid_entry_get_reg(struct kvm_cpuid_entry2 *entry, int reg) + + /* Find matching entry for function/index on kvm_cpuid2 struct + */ +-static struct kvm_cpuid_entry2 *cpuid_find_entry(struct kvm_cpuid2 *cpuid, +- uint32_t function, +- uint32_t index) ++struct kvm_cpuid_entry2 *cpuid_find_entry(struct kvm_cpuid2 *cpuid, ++ uint32_t function, ++ uint32_t index) + { + int i; + for (i = 0; i < cpuid->nent; ++i) { +@@ -1821,9 +1822,8 @@ static void kvm_init_nested_state(CPUX86State *env) + } + } + +-static uint32_t kvm_x86_build_cpuid(CPUX86State *env, +- struct kvm_cpuid_entry2 *entries, +- uint32_t cpuid_i) ++uint32_t kvm_x86_build_cpuid(CPUX86State *env, struct kvm_cpuid_entry2 *entries, ++ uint32_t cpuid_i) + { + uint32_t limit, i, j; + uint32_t unused; +@@ -2052,6 +2052,10 @@ full: + + int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp) + { ++ if (is_tdx_vm()) { ++ return tdx_pre_create_vcpu(cpu, errp); ++ } ++ + return 0; + } + +diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h +index ed1e61fb8b..dc696cb723 100644 +--- a/target/i386/kvm/kvm_i386.h ++++ b/target/i386/kvm/kvm_i386.h +@@ -59,6 +59,11 @@ uint64_t kvm_swizzle_msi_ext_dest_id(uint64_t address); + void kvm_update_msi_routes_all(void *private, bool global, + uint32_t index, uint32_t mask); + ++struct kvm_cpuid_entry2 *cpuid_find_entry(struct kvm_cpuid2 *cpuid, ++ uint32_t function, ++ uint32_t index); ++uint32_t kvm_x86_build_cpuid(CPUX86State *env, struct kvm_cpuid_entry2 *entries, ++ uint32_t cpuid_i); + #endif /* CONFIG_KVM */ + + void kvm_pc_setup_irq_routing(bool pci_enabled); +diff --git a/target/i386/kvm/meson.build b/target/i386/kvm/meson.build +index 466bccb9cb..3f44cdedb7 100644 +--- a/target/i386/kvm/meson.build ++++ b/target/i386/kvm/meson.build +@@ -8,7 +8,7 @@ i386_kvm_ss.add(files( + + i386_kvm_ss.add(when: 'CONFIG_XEN_EMU', if_true: files('xen-emu.c')) + +-i386_kvm_ss.add(when: 'CONFIG_TDX', if_true: files('tdx.c')) ++i386_kvm_ss.add(when: 'CONFIG_TDX', if_true: files('tdx.c'), if_false: files('tdx-stub.c')) + + i386_system_ss.add(when: 'CONFIG_HYPERV', if_true: files('hyperv.c'), if_false: files('hyperv-stub.c')) + +diff --git a/target/i386/kvm/tdx-stub.c b/target/i386/kvm/tdx-stub.c +new file mode 100644 +index 0000000000..2344433594 +--- /dev/null ++++ b/target/i386/kvm/tdx-stub.c +@@ -0,0 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#include "qemu/osdep.h" ++ ++#include "tdx.h" ++ ++int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) ++{ ++ return -EINVAL; ++} +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 16f67e18ae..8f02c76249 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -149,6 +149,109 @@ static int tdx_kvm_type(X86ConfidentialGuest *cg) + return KVM_X86_TDX_VM; + } + ++static int setup_td_xfam(X86CPU *x86cpu, Error **errp) ++{ ++ CPUX86State *env = &x86cpu->env; ++ uint64_t xfam; ++ ++ xfam = env->features[FEAT_XSAVE_XCR0_LO] | ++ env->features[FEAT_XSAVE_XCR0_HI] | ++ env->features[FEAT_XSAVE_XSS_LO] | ++ env->features[FEAT_XSAVE_XSS_HI]; ++ ++ if (xfam & ~tdx_caps->supported_xfam) { ++ error_setg(errp, "Invalid XFAM 0x%lx for TDX VM (supported: 0x%llx))", ++ xfam, tdx_caps->supported_xfam); ++ return -1; ++ } ++ ++ tdx_guest->xfam = xfam; ++ return 0; ++} ++ ++static void tdx_filter_cpuid(struct kvm_cpuid2 *cpuids) ++{ ++ int i, dest_cnt = 0; ++ struct kvm_cpuid_entry2 *src, *dest, *conf; ++ ++ for (i = 0; i < cpuids->nent; i++) { ++ src = cpuids->entries + i; ++ conf = cpuid_find_entry(&tdx_caps->cpuid, src->function, src->index); ++ if (!conf) { ++ continue; ++ } ++ dest = cpuids->entries + dest_cnt; ++ ++ dest->function = src->function; ++ dest->index = src->index; ++ dest->flags = src->flags; ++ dest->eax = src->eax & conf->eax; ++ dest->ebx = src->ebx & conf->ebx; ++ dest->ecx = src->ecx & conf->ecx; ++ dest->edx = src->edx & conf->edx; ++ ++ dest_cnt++; ++ } ++ cpuids->nent = dest_cnt++; ++} ++ ++int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) ++{ ++ X86CPU *x86cpu = X86_CPU(cpu); ++ CPUX86State *env = &x86cpu->env; ++ g_autofree struct kvm_tdx_init_vm *init_vm = NULL; ++ Error *local_err = NULL; ++ int retry = 10000; ++ int r = 0; ++ ++ QEMU_LOCK_GUARD(&tdx_guest->lock); ++ if (tdx_guest->initialized) { ++ return r; ++ } ++ ++ init_vm = g_malloc0(sizeof(struct kvm_tdx_init_vm) + ++ sizeof(struct kvm_cpuid_entry2) * KVM_MAX_CPUID_ENTRIES); ++ ++ r = setup_td_xfam(x86cpu, errp); ++ if (r) { ++ return r; ++ } ++ ++ init_vm->cpuid.nent = kvm_x86_build_cpuid(env, init_vm->cpuid.entries, 0); ++ tdx_filter_cpuid(&init_vm->cpuid); ++ ++ init_vm->attributes = tdx_guest->attributes; ++ init_vm->xfam = tdx_guest->xfam; ++ ++ /* ++ * KVM_TDX_INIT_VM gets -EAGAIN when KVM side SEAMCALL(TDH_MNG_CREATE) ++ * gets TDX_RND_NO_ENTROPY due to Random number generation (e.g., RDRAND or ++ * RDSEED) is busy. ++ * ++ * Retry for the case. ++ */ ++ do { ++ error_free(local_err); ++ local_err = NULL; ++ r = tdx_vm_ioctl(KVM_TDX_INIT_VM, 0, init_vm, &local_err); ++ } while (r == -EAGAIN && --retry); ++ ++ if (r < 0) { ++ if (!retry) { ++ error_append_hint(&local_err, "Hardware RNG (Random Number " ++ "Generator) is busy occupied by someone (via RDRAND/RDSEED) " ++ "maliciously, which leads to KVM_TDX_INIT_VM keeping failure " ++ "due to lack of entropy.\n"); ++ } ++ error_propagate(errp, local_err); ++ return r; ++ } ++ ++ tdx_guest->initialized = true; ++ ++ return 0; ++} ++ + /* tdx guest */ + OBJECT_DEFINE_TYPE_WITH_INTERFACES(TdxGuest, + tdx_guest, +@@ -162,6 +265,8 @@ static void tdx_guest_init(Object *obj) + ConfidentialGuestSupport *cgs = CONFIDENTIAL_GUEST_SUPPORT(obj); + TdxGuest *tdx = TDX_GUEST(obj); + ++ qemu_mutex_init(&tdx->lock); ++ + cgs->require_guest_memfd = true; + tdx->attributes = 0; + +diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h +index de8ae91961..4e2b5c61ff 100644 +--- a/target/i386/kvm/tdx.h ++++ b/target/i386/kvm/tdx.h +@@ -19,7 +19,11 @@ typedef struct TdxGuestClass { + typedef struct TdxGuest { + X86ConfidentialGuest parent_obj; + ++ QemuMutex lock; ++ ++ bool initialized; + uint64_t attributes; /* TD attributes */ ++ uint64_t xfam; + } TdxGuest; + + #ifdef CONFIG_TDX +@@ -28,4 +32,6 @@ bool is_tdx_vm(void); + #define is_tdx_vm() 0 + #endif /* CONFIG_TDX */ + ++int tdx_pre_create_vcpu(CPUState *cpu, Error **errp); ++ + #endif /* QEMU_I386_TDX_H */ +-- +2.47.3 + diff --git a/kvm-i386-tdx-Introduce-is_tdx_vm-helper-and-cache-tdx_gu.patch b/kvm-i386-tdx-Introduce-is_tdx_vm-helper-and-cache-tdx_gu.patch new file mode 100644 index 0000000..cb89e9e --- /dev/null +++ b/kvm-i386-tdx-Introduce-is_tdx_vm-helper-and-cache-tdx_gu.patch @@ -0,0 +1,96 @@ +From c0fe437ea3e98414b7f79ee5a6924bfd1658d01c Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:45 +0200 +Subject: [PATCH 020/100] i386/tdx: Introduce is_tdx_vm() helper and cache + tdx_guest object + +It will need special handling for TDX VMs all around the QEMU. +Introduce is_tdx_vm() helper to query if it's a TDX VM. + +Cache tdx_guest object thus no need to cast from ms->cgs every time. + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Isaku Yamahata +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-7-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 1619d0e45be0d1e48a46d80963b4e77dc1b000a2) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 15 ++++++++++++++- + target/i386/kvm/tdx.h | 10 ++++++++++ + 2 files changed, 24 insertions(+), 1 deletion(-) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index c67be5e618..16f67e18ae 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -18,8 +18,16 @@ + #include "kvm_i386.h" + #include "tdx.h" + ++static TdxGuest *tdx_guest; ++ + static struct kvm_tdx_capabilities *tdx_caps; + ++/* Valid after kvm_arch_init()->confidential_guest_kvm_init()->tdx_kvm_init() */ ++bool is_tdx_vm(void) ++{ ++ return !!tdx_guest; ++} ++ + enum tdx_ioctl_level { + TDX_VM_IOCTL, + TDX_VCPU_IOCTL, +@@ -117,15 +125,20 @@ static int get_tdx_capabilities(Error **errp) + + static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + { ++ TdxGuest *tdx = TDX_GUEST(cgs); + int r = 0; + + kvm_mark_guest_state_protected(); + + if (!tdx_caps) { + r = get_tdx_capabilities(errp); ++ if (r) { ++ return r; ++ } + } + +- return r; ++ tdx_guest = tdx; ++ return 0; + } + + static int tdx_kvm_type(X86ConfidentialGuest *cg) +diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h +index f3b7253361..de8ae91961 100644 +--- a/target/i386/kvm/tdx.h ++++ b/target/i386/kvm/tdx.h +@@ -3,6 +3,10 @@ + #ifndef QEMU_I386_TDX_H + #define QEMU_I386_TDX_H + ++#ifndef CONFIG_USER_ONLY ++#include CONFIG_DEVICES /* CONFIG_TDX */ ++#endif ++ + #include "confidential-guest.h" + + #define TYPE_TDX_GUEST "tdx-guest" +@@ -18,4 +22,10 @@ typedef struct TdxGuest { + uint64_t attributes; /* TD attributes */ + } TdxGuest; + ++#ifdef CONFIG_TDX ++bool is_tdx_vm(void); ++#else ++#define is_tdx_vm() 0 ++#endif /* CONFIG_TDX */ ++ + #endif /* QEMU_I386_TDX_H */ +-- +2.47.3 + diff --git a/kvm-i386-tdx-Make-invtsc-default-on.patch b/kvm-i386-tdx-Make-invtsc-default-on.patch new file mode 100644 index 0000000..b685682 --- /dev/null +++ b/kvm-i386-tdx-Make-invtsc-default-on.patch @@ -0,0 +1,34 @@ +From 2532d70be0e63887a31266ad0a5768c01709def3 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:48 +0200 +Subject: [PATCH 067/100] i386/tdx: Make invtsc default on + +Because it's fixed1 bit that enforced by TDX module. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-54-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit ea4867b911fc2f6d4c8bd50ec62f0dc0fa190fab) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 688992c81b..73a0abbcc9 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -742,6 +742,9 @@ static void tdx_cpu_instance_init(X86ConfidentialGuest *cg, CPUState *cpu) + + object_property_set_bool(OBJECT(cpu), "pmu", false, &error_abort); + ++ /* invtsc is fixed1 for TD guest */ ++ object_property_set_bool(OBJECT(cpu), "invtsc", true, &error_abort); ++ + x86cpu->enable_cpuid_0x1f = true; + } + +-- +2.47.3 + diff --git a/kvm-i386-tdx-Make-sept_ve_disable-set-by-default.patch b/kvm-i386-tdx-Make-sept_ve_disable-set-by-default.patch new file mode 100644 index 0000000..5d087b1 --- /dev/null +++ b/kvm-i386-tdx-Make-sept_ve_disable-set-by-default.patch @@ -0,0 +1,40 @@ +From 8090a7299cdf149054272c4e1efabc3b8b28e3f5 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:46 +0200 +Subject: [PATCH 024/100] i386/tdx: Make sept_ve_disable set by default +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For TDX KVM use case, Linux guest is the most major one. It requires +sept_ve_disable set. Make it default for the main use case. For other use +case, it can be enabled/disabled via qemu command line. + +Signed-off-by: Isaku Yamahata +Signed-off-by: Xiaoyao Li +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-11-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 714af52276e74a1829674d180ef26ecb6261834c) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 370bd86f2c..2ed40b7614 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -288,7 +288,7 @@ static void tdx_guest_init(Object *obj) + qemu_mutex_init(&tdx->lock); + + cgs->require_guest_memfd = true; +- tdx->attributes = 0; ++ tdx->attributes = TDX_TD_ATTRIBUTES_SEPT_VE_DISABLE; + + object_property_add_uint64_ptr(obj, "attributes", &tdx->attributes, + OBJ_PROP_FLAG_READWRITE); +-- +2.47.3 + diff --git a/kvm-i386-tdx-Only-configure-MSR_IA32_UCODE_REV-in-kvm_in.patch b/kvm-i386-tdx-Only-configure-MSR_IA32_UCODE_REV-in-kvm_in.patch new file mode 100644 index 0000000..7043c59 --- /dev/null +++ b/kvm-i386-tdx-Only-configure-MSR_IA32_UCODE_REV-in-kvm_in.patch @@ -0,0 +1,84 @@ +From 1c8ddb84de492e3de0bc8a2ad6c5fca5960322a8 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:47 +0200 +Subject: [PATCH 054/100] i386/tdx: Only configure MSR_IA32_UCODE_REV in + kvm_init_msrs() for TDs + +For TDs, only MSR_IA32_UCODE_REV in kvm_init_msrs() can be configured +by VMM, while the features enumerated/controlled by other MSRs except +MSR_IA32_UCODE_REV in kvm_init_msrs() are not under control of VMM. + +Only configure MSR_IA32_UCODE_REV for TDs. + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-41-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit f9aaad3362a5886d78e7d4d50d563ac16c6acdde) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/kvm.c | 40 +++++++++++++++++++++------------------- + 1 file changed, 21 insertions(+), 19 deletions(-) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 12b0a25b1f..3d58966f60 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -3863,32 +3863,34 @@ static void kvm_init_msrs(X86CPU *cpu) + CPUX86State *env = &cpu->env; + + kvm_msr_buf_reset(cpu); +- if (has_msr_arch_capabs) { +- kvm_msr_entry_add(cpu, MSR_IA32_ARCH_CAPABILITIES, +- env->features[FEAT_ARCH_CAPABILITIES]); +- } + +- if (has_msr_core_capabs) { +- kvm_msr_entry_add(cpu, MSR_IA32_CORE_CAPABILITY, +- env->features[FEAT_CORE_CAPABILITY]); +- } ++ if (!is_tdx_vm()) { ++ if (has_msr_arch_capabs) { ++ kvm_msr_entry_add(cpu, MSR_IA32_ARCH_CAPABILITIES, ++ env->features[FEAT_ARCH_CAPABILITIES]); ++ } ++ ++ if (has_msr_core_capabs) { ++ kvm_msr_entry_add(cpu, MSR_IA32_CORE_CAPABILITY, ++ env->features[FEAT_CORE_CAPABILITY]); ++ } ++ ++ if (has_msr_perf_capabs && cpu->enable_pmu) { ++ kvm_msr_entry_add_perf(cpu, env->features); ++ } + +- if (has_msr_perf_capabs && cpu->enable_pmu) { +- kvm_msr_entry_add_perf(cpu, env->features); ++ /* ++ * Older kernels do not include VMX MSRs in KVM_GET_MSR_INDEX_LIST, but ++ * all kernels with MSR features should have them. ++ */ ++ if (kvm_feature_msrs && cpu_has_vmx(env)) { ++ kvm_msr_entry_add_vmx(cpu, env->features); ++ } + } + + if (has_msr_ucode_rev) { + kvm_msr_entry_add(cpu, MSR_IA32_UCODE_REV, cpu->ucode_rev); + } +- +- /* +- * Older kernels do not include VMX MSRs in KVM_GET_MSR_INDEX_LIST, but +- * all kernels with MSR features should have them. +- */ +- if (kvm_feature_msrs && cpu_has_vmx(env)) { +- kvm_msr_entry_add_vmx(cpu, env->features); +- } +- + assert(kvm_buf_set_msrs(cpu) == 0); + } + +-- +2.47.3 + diff --git a/kvm-i386-tdx-Parse-TDVF-metadata-for-TDX-VM.patch b/kvm-i386-tdx-Parse-TDVF-metadata-for-TDX-VM.patch new file mode 100644 index 0000000..bd033b1 --- /dev/null +++ b/kvm-i386-tdx-Parse-TDVF-metadata-for-TDX-VM.patch @@ -0,0 +1,108 @@ +From a2b4b84989772654580cd299c6222a38801d426d Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:46 +0200 +Subject: [PATCH 032/100] i386/tdx: Parse TDVF metadata for TDX VM +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +After TDVF is loaded to bios MemoryRegion, it needs parse TDVF metadata. + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-19-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit cb5d65a854e58abeb705a2ce14cc3eb28973c606) +Signed-off-by: Paolo Bonzini +--- + hw/i386/pc_sysfw.c | 7 +++++++ + target/i386/kvm/tdx-stub.c | 5 +++++ + target/i386/kvm/tdx.c | 5 +++++ + target/i386/kvm/tdx.h | 3 +++ + 4 files changed, 20 insertions(+) + +diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c +index 1eeb58ab37..821396c16e 100644 +--- a/hw/i386/pc_sysfw.c ++++ b/hw/i386/pc_sysfw.c +@@ -37,6 +37,7 @@ + #include "hw/block/flash.h" + #include "system/kvm.h" + #include "target/i386/sev.h" ++#include "kvm/tdx.h" + + #define FLASH_SECTOR_SIZE 4096 + +@@ -280,5 +281,11 @@ void x86_firmware_configure(hwaddr gpa, void *ptr, int size) + } + + sev_encrypt_flash(gpa, ptr, size, &error_fatal); ++ } else if (is_tdx_vm()) { ++ ret = tdx_parse_tdvf(ptr, size); ++ if (ret) { ++ error_report("failed to parse TDVF for TDX VM"); ++ exit(1); ++ } + } + } +diff --git a/target/i386/kvm/tdx-stub.c b/target/i386/kvm/tdx-stub.c +index 2344433594..7748b6d0a4 100644 +--- a/target/i386/kvm/tdx-stub.c ++++ b/target/i386/kvm/tdx-stub.c +@@ -8,3 +8,8 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) + { + return -EINVAL; + } ++ ++int tdx_parse_tdvf(void *flash_ptr, int size) ++{ ++ return -EINVAL; ++} +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 2522f2030d..71be3bd28d 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -382,6 +382,11 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) + return 0; + } + ++int tdx_parse_tdvf(void *flash_ptr, int size) ++{ ++ return tdvf_parse_metadata(&tdx_guest->tdvf, flash_ptr, size); ++} ++ + static bool tdx_guest_get_sept_ve_disable(Object *obj, Error **errp) + { + TdxGuest *tdx = TDX_GUEST(obj); +diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h +index b73461b8d8..28a03c2a7b 100644 +--- a/target/i386/kvm/tdx.h ++++ b/target/i386/kvm/tdx.h +@@ -8,6 +8,7 @@ + #endif + + #include "confidential-guest.h" ++#include "hw/i386/tdvf.h" + + #define TYPE_TDX_GUEST "tdx-guest" + #define TDX_GUEST(obj) OBJECT_CHECK(TdxGuest, (obj), TYPE_TDX_GUEST) +@@ -32,6 +33,7 @@ typedef struct TdxGuest { + char *mrownerconfig; /* base64 encoded sha348 digest */ + + MemoryRegion *tdvf_mr; ++ TdxFirmware tdvf; + } TdxGuest; + + #ifdef CONFIG_TDX +@@ -42,5 +44,6 @@ bool is_tdx_vm(void); + + int tdx_pre_create_vcpu(CPUState *cpu, Error **errp); + void tdx_set_tdvf_region(MemoryRegion *tdvf_mr); ++int tdx_parse_tdvf(void *flash_ptr, int size); + + #endif /* QEMU_I386_TDX_H */ +-- +2.47.3 + diff --git a/kvm-i386-tdx-Remove-enumeration-of-GetQuote-in-tdx_handl.patch b/kvm-i386-tdx-Remove-enumeration-of-GetQuote-in-tdx_handl.patch new file mode 100644 index 0000000..b188dc7 --- /dev/null +++ b/kvm-i386-tdx-Remove-enumeration-of-GetQuote-in-tdx_handl.patch @@ -0,0 +1,62 @@ +From 6bfb399607926598d36003bc879f32a8e1d0d51c Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:49 +0200 +Subject: [PATCH 084/100] i386/tdx: Remove enumeration of GetQuote in + tdx_handle_get_tdvmcall_info() + +GHCI is finalized with the being one of the base VMCALLs, and +not enuemrated via . + +Adjust tdx_handle_get_tdvmcall_info() to match with GHCI. + +Opportunistically fix the wrong indentation and explicitly set the +ret to TDG_VP_VMCALL_SUCCESS (in case KVM leaves unexpected value). + +Signed-off-by: Xiaoyao Li +Link: https://lore.kernel.org/r/20250703024021.3559286-2-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit b57999bb258349fabe497c8ff70277b5e5b281e2) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 6 ++++-- + target/i386/kvm/tdx.h | 2 -- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index fa02ca5b5e..7be17fda23 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -1259,13 +1259,15 @@ out_free: + void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run) + { + if (run->tdx.get_tdvmcall_info.leaf != 1) { +- return; ++ return; + } + +- run->tdx.get_tdvmcall_info.r11 = TDG_VP_VMCALL_SUBFUNC_GET_QUOTE; ++ run->tdx.get_tdvmcall_info.r11 = 0; + run->tdx.get_tdvmcall_info.r12 = 0; + run->tdx.get_tdvmcall_info.r13 = 0; + run->tdx.get_tdvmcall_info.r14 = 0; ++ ++ run->tdx.get_tdvmcall_info.ret = TDG_VP_VMCALL_SUCCESS; + } + + static void tdx_panicked_on_fatal_error(X86CPU *cpu, uint64_t error_code, +diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h +index 35a09c19c5..d439078a87 100644 +--- a/target/i386/kvm/tdx.h ++++ b/target/i386/kvm/tdx.h +@@ -32,8 +32,6 @@ typedef struct TdxGuestClass { + #define TDG_VP_VMCALL_GPA_INUSE 0x8000000000000001ULL + #define TDG_VP_VMCALL_ALIGN_ERROR 0x8000000000000002ULL + +-#define TDG_VP_VMCALL_SUBFUNC_GET_QUOTE 0x0000000000000001ULL +- + enum TdxRamType { + TDX_RAM_UNACCEPTED, + TDX_RAM_ADDED, +-- +2.47.3 + diff --git a/kvm-i386-tdx-Remove-task-watch-only-when-it-s-valid.patch b/kvm-i386-tdx-Remove-task-watch-only-when-it-s-valid.patch new file mode 100644 index 0000000..b15ac1d --- /dev/null +++ b/kvm-i386-tdx-Remove-task-watch-only-when-it-s-valid.patch @@ -0,0 +1,42 @@ +From 68daaece41d47325639930ac8def585919d27076 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:50 +0200 +Subject: [PATCH 088/100] i386/tdx: Remove task->watch only when it's valid + +In some case (e.g., failed to connect to QGS socket), +tdx_generate_quote_cleanup() is called with task->watch invalid. It +triggers assertion of + + qemu-system-x86_64: GLib: g_source_remove: assertion 'tag > 0' failed + +Fix it by checking task->watch. + +Fixes: 40da501d8989 ("i386/tdx: handle TDG.VP.VMCALL") +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250625035505.2770580-1-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 50fd57418c3f08f13eb964dcb49f065246f2ecbf) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx-quote-generator.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/target/i386/kvm/tdx-quote-generator.c b/target/i386/kvm/tdx-quote-generator.c +index f59715f617..dee8334b27 100644 +--- a/target/i386/kvm/tdx-quote-generator.c ++++ b/target/i386/kvm/tdx-quote-generator.c +@@ -75,7 +75,9 @@ static void tdx_generate_quote_cleanup(TdxGenerateQuoteTask *task) + { + timer_del(&task->timer); + +- g_source_remove(task->watch); ++ if (task->watch) { ++ g_source_remove(task->watch); ++ } + qio_channel_close(QIO_CHANNEL(task->sioc), NULL); + object_unref(OBJECT(task->sioc)); + +-- +2.47.3 + diff --git a/kvm-i386-tdx-Remove-the-redundant-qemu_mutex_init-tdx-lo.patch b/kvm-i386-tdx-Remove-the-redundant-qemu_mutex_init-tdx-lo.patch new file mode 100644 index 0000000..60ce984 --- /dev/null +++ b/kvm-i386-tdx-Remove-the-redundant-qemu_mutex_init-tdx-lo.patch @@ -0,0 +1,42 @@ +From bb5ff40813ec38b73dc7656bd324ed08ec9eb7ed Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:50 +0200 +Subject: [PATCH 093/100] i386/tdx: Remove the redundant + qemu_mutex_init(&tdx->lock) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit 40da501d8989 ("i386/tdx: handle TDG.VP.VMCALL") added +redundant qemu_mutex_init(&tdx->lock) in tdx_guest_init by mistake. + +Fix it by removing the redundant one. + +Fixes: 40da501d8989 ("i386/tdx: handle TDG.VP.VMCALL") +Reported-by: Peter Maydell +Signed-off-by: Xiaoyao Li +Reviewed-by: Daniel P. BerrangĂ© +Link: https://lore.kernel.org/r/20250717103707.688929-1-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit f64832033d1262983bfe759669b4f65080f760dc) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index b8084758cb..cc46c0e2f1 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -1527,8 +1527,6 @@ static void tdx_guest_init(Object *obj) + tdx_guest_set_qgs, + NULL, NULL); + +- qemu_mutex_init(&tdx->lock); +- + tdx->event_notify_vector = -1; + tdx->event_notify_apicid = -1; + } +-- +2.47.3 + diff --git a/kvm-i386-tdx-Set-APIC-bus-rate-to-match-with-what-TDX-mo.patch b/kvm-i386-tdx-Set-APIC-bus-rate-to-match-with-what-TDX-mo.patch new file mode 100644 index 0000000..dec933e --- /dev/null +++ b/kvm-i386-tdx-Set-APIC-bus-rate-to-match-with-what-TDX-mo.patch @@ -0,0 +1,70 @@ +From c3bda3a18190f9d20b1568ede187c009f0124687 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:46 +0200 +Subject: [PATCH 028/100] i386/tdx: Set APIC bus rate to match with what TDX + module enforces +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +TDX advertises core crystal clock with cpuid[0x15] as 25MHz for TD +guests and it's unchangeable from VMM. As a result, TDX guest reads +the APIC timer at the same frequency, 25MHz. + +While KVM's default emulated frequency for APIC bus is 1GHz, set the +APIC bus rate to match with TDX explicitly to ensure KVM provide correct +emulated APIC timer for TD guest. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-15-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit d529a2ac5ef4620173439942f78ec668f9165fc1) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 13 +++++++++++++ + target/i386/kvm/tdx.h | 3 +++ + 2 files changed, 16 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 39fd964c6b..c96e8eb7b8 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -254,6 +254,19 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) + init_vm = g_malloc0(sizeof(struct kvm_tdx_init_vm) + + sizeof(struct kvm_cpuid_entry2) * KVM_MAX_CPUID_ENTRIES); + ++ if (!kvm_check_extension(kvm_state, KVM_CAP_X86_APIC_BUS_CYCLES_NS)) { ++ error_setg(errp, "KVM doesn't support KVM_CAP_X86_APIC_BUS_CYCLES_NS"); ++ return -EOPNOTSUPP; ++ } ++ ++ r = kvm_vm_enable_cap(kvm_state, KVM_CAP_X86_APIC_BUS_CYCLES_NS, ++ 0, TDX_APIC_BUS_CYCLES_NS); ++ if (r < 0) { ++ error_setg_errno(errp, -r, ++ "Unable to set core crystal clock frequency to 25MHz"); ++ return r; ++ } ++ + if (tdx_guest->mrconfigid) { + g_autofree uint8_t *data = qbase64_decode(tdx_guest->mrconfigid, + strlen(tdx_guest->mrconfigid), &data_len, errp); +diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h +index e472b11fb0..d39e733d9f 100644 +--- a/target/i386/kvm/tdx.h ++++ b/target/i386/kvm/tdx.h +@@ -16,6 +16,9 @@ typedef struct TdxGuestClass { + X86ConfidentialGuestClass parent_class; + } TdxGuestClass; + ++/* TDX requires bus frequency 25MHz */ ++#define TDX_APIC_BUS_CYCLES_NS 40 ++ + typedef struct TdxGuest { + X86ConfidentialGuest parent_obj; + +-- +2.47.3 + diff --git a/kvm-i386-tdx-Set-and-check-kernel_irqchip-mode-for-TDX.patch b/kvm-i386-tdx-Set-and-check-kernel_irqchip-mode-for-TDX.patch new file mode 100644 index 0000000..a971ec0 --- /dev/null +++ b/kvm-i386-tdx-Set-and-check-kernel_irqchip-mode-for-TDX.patch @@ -0,0 +1,54 @@ +From 81e91259672b5afe31f7eb733d27542041889c01 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 25 Jul 2025 16:40:23 +0200 +Subject: [PATCH 052/100] i386/tdx: Set and check kernel_irqchip mode for TDX +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +KVM mandates kernel_irqchip to be split mode. + +Set it to split mode automatically when users don't provide an explicit +value, otherwise check it to be the split mode. + +Suggested-by: Daniel P. BerrangĂ© +Signed-off-by: Xiaoyao Li +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-39-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit bb45580d842530d78b58179eaf80b6331b15324e) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index b70f557ccc..8b01e7f993 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -16,6 +16,7 @@ + #include "qapi/error.h" + #include "qom/object_interfaces.h" + #include "crypto/hash.h" ++#include "system/kvm_int.h" + #include "system/runstate.h" + #include "system/system.h" + #include "system/ramblock.h" +@@ -388,6 +389,13 @@ static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + return -EINVAL; + } + ++ if (kvm_state->kernel_irqchip_split == ON_OFF_AUTO_AUTO) { ++ kvm_state->kernel_irqchip_split = ON_OFF_AUTO_ON; ++ } else if (kvm_state->kernel_irqchip_split != ON_OFF_AUTO_ON) { ++ error_setg(errp, "TDX VM requires kernel_irqchip to be split"); ++ return -EINVAL; ++ } ++ + if (!tdx_caps) { + r = get_tdx_capabilities(errp); + if (r) { +-- +2.47.3 + diff --git a/kvm-i386-tdx-Set-kvm_readonly_mem_enabled-to-false-for-T.patch b/kvm-i386-tdx-Set-kvm_readonly_mem_enabled-to-false-for-T.patch new file mode 100644 index 0000000..33ce828 --- /dev/null +++ b/kvm-i386-tdx-Set-kvm_readonly_mem_enabled-to-false-for-T.patch @@ -0,0 +1,46 @@ +From 42a79876d07b74e86ab83c7b272e75b1235ed6f7 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:47 +0200 +Subject: [PATCH 049/100] i386/tdx: Set kvm_readonly_mem_enabled to false for + TDX VM + +TDX only supports readonly for shared memory but not for private memory. + +In the view of QEMU, it has no idea whether a memslot is used as shared +memory of private. Thus just mark kvm_readonly_mem_enabled to false to +TDX VM for simplicity. + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-36-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit da6728658bf63d6a3989f1587a33566b3e54bed8) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 66db034e05..e49b37c436 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -384,6 +384,15 @@ static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + return -EOPNOTSUPP; + } + ++ /* ++ * Set kvm_readonly_mem_allowed to false, because TDX only supports readonly ++ * memory for shared memory but not for private memory. Besides, whether a ++ * memslot is private or shared is not determined by QEMU. ++ * ++ * Thus, just mark readonly memory not supported for simplicity. ++ */ ++ kvm_readonly_mem_allowed = false; ++ + qemu_add_machine_init_done_notifier(&tdx_machine_done_notify); + + tdx_guest = tdx; +-- +2.47.3 + diff --git a/kvm-i386-tdx-Set-value-of-GetTdVmCallInfo-based-on-capab.patch b/kvm-i386-tdx-Set-value-of-GetTdVmCallInfo-based-on-capab.patch new file mode 100644 index 0000000..a91c9b4 --- /dev/null +++ b/kvm-i386-tdx-Set-value-of-GetTdVmCallInfo-based-on-capab.patch @@ -0,0 +1,52 @@ +From d96da4f8abd1e007adee3c8a0b3ea8e4fdfefb51 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:50 +0200 +Subject: [PATCH 085/100] i386/tdx: Set value of based on + capabilities of both KVM and QEMU + +KVM reports the supported TDVMCALL sub leafs in TDX capabilities. + +one for kernel-supported + TDVMCALLs (userspace can set those blindly) and one for user-supported + TDVMCALLs (userspace can set those if it knows how to handle them) + +Signed-off-by: Xiaoyao Li +Link: https://lore.kernel.org/r/20250703024021.3559286-4-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 55be385b10658a2372f944fa41aaba016e1e8433) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 7be17fda23..7748474322 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -1256,14 +1256,21 @@ out_free: + g_free(task); + } + ++#define SUPPORTED_TDVMCALLINFO_1_R11 (0) ++#define SUPPORTED_TDVMCALLINFO_1_R12 (0) ++ + void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run) + { + if (run->tdx.get_tdvmcall_info.leaf != 1) { + return; + } + +- run->tdx.get_tdvmcall_info.r11 = 0; +- run->tdx.get_tdvmcall_info.r12 = 0; ++ run->tdx.get_tdvmcall_info.r11 = (tdx_caps->user_tdvmcallinfo_1_r11 & ++ SUPPORTED_TDVMCALLINFO_1_R11) | ++ tdx_caps->kernel_tdvmcallinfo_1_r11; ++ run->tdx.get_tdvmcall_info.r12 = (tdx_caps->user_tdvmcallinfo_1_r12 & ++ SUPPORTED_TDVMCALLINFO_1_R12) | ++ tdx_caps->kernel_tdvmcallinfo_1_r12; + run->tdx.get_tdvmcall_info.r13 = 0; + run->tdx.get_tdvmcall_info.r14 = 0; + +-- +2.47.3 + diff --git a/kvm-i386-tdx-Setup-the-TD-HOB-list.patch b/kvm-i386-tdx-Setup-the-TD-HOB-list.patch new file mode 100644 index 0000000..839acca --- /dev/null +++ b/kvm-i386-tdx-Setup-the-TD-HOB-list.patch @@ -0,0 +1,256 @@ +From 8da0a7cb40298a9b8af36c9d665c38ac66f5387c Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:46 +0200 +Subject: [PATCH 037/100] i386/tdx: Setup the TD HOB list + +The TD HOB list is used to pass the information from VMM to TDVF. The TD +HOB must include PHIT HOB and Resource Descriptor HOB. More details can +be found in TDVF specification and PI specification. + +Build the TD HOB in TDX's machine_init_done callback. + +Co-developed-by: Isaku Yamahata +Signed-off-by: Isaku Yamahata +Co-developed-by: Sean Christopherson +Signed-off-by: Sean Christopherson +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-24-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit a731425980a4d3f8bb96fc41893b6437672875ee) +Signed-off-by: Paolo Bonzini +--- + hw/i386/meson.build | 2 +- + hw/i386/tdvf-hob.c | 130 ++++++++++++++++++++++++++++++++++++++++++ + hw/i386/tdvf-hob.h | 26 +++++++++ + target/i386/kvm/tdx.c | 16 ++++++ + 4 files changed, 173 insertions(+), 1 deletion(-) + create mode 100644 hw/i386/tdvf-hob.c + create mode 100644 hw/i386/tdvf-hob.h + +diff --git a/hw/i386/meson.build b/hw/i386/meson.build +index 3bc1da2b6e..7896f348cf 100644 +--- a/hw/i386/meson.build ++++ b/hw/i386/meson.build +@@ -32,7 +32,7 @@ i386_ss.add(when: 'CONFIG_PC', if_true: files( + 'port92.c')) + i386_ss.add(when: 'CONFIG_X86_FW_OVMF', if_true: files('pc_sysfw_ovmf.c'), + if_false: files('pc_sysfw_ovmf-stubs.c')) +-i386_ss.add(when: 'CONFIG_TDX', if_true: files('tdvf.c')) ++i386_ss.add(when: 'CONFIG_TDX', if_true: files('tdvf.c', 'tdvf-hob.c')) + + subdir('kvm') + subdir('xen') +diff --git a/hw/i386/tdvf-hob.c b/hw/i386/tdvf-hob.c +new file mode 100644 +index 0000000000..782b3d1578 +--- /dev/null ++++ b/hw/i386/tdvf-hob.c +@@ -0,0 +1,130 @@ ++/* ++ * Copyright (c) 2025 Intel Corporation ++ * Author: Isaku Yamahata ++ * ++ * Xiaoyao Li ++ * ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ */ ++ ++#include "qemu/osdep.h" ++#include "qemu/error-report.h" ++#include "standard-headers/uefi/uefi.h" ++#include "hw/pci/pcie_host.h" ++#include "tdvf-hob.h" ++ ++typedef struct TdvfHob { ++ hwaddr hob_addr; ++ void *ptr; ++ int size; ++ ++ /* working area */ ++ void *current; ++ void *end; ++} TdvfHob; ++ ++static uint64_t tdvf_current_guest_addr(const TdvfHob *hob) ++{ ++ return hob->hob_addr + (hob->current - hob->ptr); ++} ++ ++static void tdvf_align(TdvfHob *hob, size_t align) ++{ ++ hob->current = QEMU_ALIGN_PTR_UP(hob->current, align); ++} ++ ++static void *tdvf_get_area(TdvfHob *hob, uint64_t size) ++{ ++ void *ret; ++ ++ if (hob->current + size > hob->end) { ++ error_report("TD_HOB overrun, size = 0x%" PRIx64, size); ++ exit(1); ++ } ++ ++ ret = hob->current; ++ hob->current += size; ++ tdvf_align(hob, 8); ++ return ret; ++} ++ ++static void tdvf_hob_add_memory_resources(TdxGuest *tdx, TdvfHob *hob) ++{ ++ EFI_HOB_RESOURCE_DESCRIPTOR *region; ++ EFI_RESOURCE_ATTRIBUTE_TYPE attr; ++ EFI_RESOURCE_TYPE resource_type; ++ ++ TdxRamEntry *e; ++ int i; ++ ++ for (i = 0; i < tdx->nr_ram_entries; i++) { ++ e = &tdx->ram_entries[i]; ++ ++ if (e->type == TDX_RAM_UNACCEPTED) { ++ resource_type = EFI_RESOURCE_MEMORY_UNACCEPTED; ++ attr = EFI_RESOURCE_ATTRIBUTE_TDVF_UNACCEPTED; ++ } else if (e->type == TDX_RAM_ADDED) { ++ resource_type = EFI_RESOURCE_SYSTEM_MEMORY; ++ attr = EFI_RESOURCE_ATTRIBUTE_TDVF_PRIVATE; ++ } else { ++ error_report("unknown TDX_RAM_ENTRY type %d", e->type); ++ exit(1); ++ } ++ ++ region = tdvf_get_area(hob, sizeof(*region)); ++ *region = (EFI_HOB_RESOURCE_DESCRIPTOR) { ++ .Header = { ++ .HobType = EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, ++ .HobLength = cpu_to_le16(sizeof(*region)), ++ .Reserved = cpu_to_le32(0), ++ }, ++ .Owner = EFI_HOB_OWNER_ZERO, ++ .ResourceType = cpu_to_le32(resource_type), ++ .ResourceAttribute = cpu_to_le32(attr), ++ .PhysicalStart = cpu_to_le64(e->address), ++ .ResourceLength = cpu_to_le64(e->length), ++ }; ++ } ++} ++ ++void tdvf_hob_create(TdxGuest *tdx, TdxFirmwareEntry *td_hob) ++{ ++ TdvfHob hob = { ++ .hob_addr = td_hob->address, ++ .size = td_hob->size, ++ .ptr = td_hob->mem_ptr, ++ ++ .current = td_hob->mem_ptr, ++ .end = td_hob->mem_ptr + td_hob->size, ++ }; ++ ++ EFI_HOB_GENERIC_HEADER *last_hob; ++ EFI_HOB_HANDOFF_INFO_TABLE *hit; ++ ++ /* Note, Efi{Free}Memory{Bottom,Top} are ignored, leave 'em zeroed. */ ++ hit = tdvf_get_area(&hob, sizeof(*hit)); ++ *hit = (EFI_HOB_HANDOFF_INFO_TABLE) { ++ .Header = { ++ .HobType = EFI_HOB_TYPE_HANDOFF, ++ .HobLength = cpu_to_le16(sizeof(*hit)), ++ .Reserved = cpu_to_le32(0), ++ }, ++ .Version = cpu_to_le32(EFI_HOB_HANDOFF_TABLE_VERSION), ++ .BootMode = cpu_to_le32(0), ++ .EfiMemoryTop = cpu_to_le64(0), ++ .EfiMemoryBottom = cpu_to_le64(0), ++ .EfiFreeMemoryTop = cpu_to_le64(0), ++ .EfiFreeMemoryBottom = cpu_to_le64(0), ++ .EfiEndOfHobList = cpu_to_le64(0), /* initialized later */ ++ }; ++ ++ tdvf_hob_add_memory_resources(tdx, &hob); ++ ++ last_hob = tdvf_get_area(&hob, sizeof(*last_hob)); ++ *last_hob = (EFI_HOB_GENERIC_HEADER) { ++ .HobType = EFI_HOB_TYPE_END_OF_HOB_LIST, ++ .HobLength = cpu_to_le16(sizeof(*last_hob)), ++ .Reserved = cpu_to_le32(0), ++ }; ++ hit->EfiEndOfHobList = tdvf_current_guest_addr(&hob); ++} +diff --git a/hw/i386/tdvf-hob.h b/hw/i386/tdvf-hob.h +new file mode 100644 +index 0000000000..4fc6a3740a +--- /dev/null ++++ b/hw/i386/tdvf-hob.h +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#ifndef HW_I386_TD_HOB_H ++#define HW_I386_TD_HOB_H ++ ++#include "hw/i386/tdvf.h" ++#include "target/i386/kvm/tdx.h" ++ ++void tdvf_hob_create(TdxGuest *tdx, TdxFirmwareEntry *td_hob); ++ ++#define EFI_RESOURCE_ATTRIBUTE_TDVF_PRIVATE \ ++ (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ ++ EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ ++ EFI_RESOURCE_ATTRIBUTE_TESTED) ++ ++#define EFI_RESOURCE_ATTRIBUTE_TDVF_UNACCEPTED \ ++ (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ ++ EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ ++ EFI_RESOURCE_ATTRIBUTE_TESTED) ++ ++#define EFI_RESOURCE_ATTRIBUTE_TDVF_MMIO \ ++ (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ ++ EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ ++ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE) ++ ++#endif +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 699a2ff979..7837bcd902 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -21,6 +21,7 @@ + #include "hw/i386/e820_memory_layout.h" + #include "hw/i386/tdvf.h" + #include "hw/i386/x86.h" ++#include "hw/i386/tdvf-hob.h" + #include "kvm_i386.h" + #include "tdx.h" + +@@ -147,6 +148,19 @@ void tdx_set_tdvf_region(MemoryRegion *tdvf_mr) + tdx_guest->tdvf_mr = tdvf_mr; + } + ++static TdxFirmwareEntry *tdx_get_hob_entry(TdxGuest *tdx) ++{ ++ TdxFirmwareEntry *entry; ++ ++ for_each_tdx_fw_entry(&tdx->tdvf, entry) { ++ if (entry->type == TDVF_SECTION_TYPE_TD_HOB) { ++ return entry; ++ } ++ } ++ error_report("TDVF metadata doesn't specify TD_HOB location."); ++ exit(1); ++} ++ + static void tdx_add_ram_entry(uint64_t address, uint64_t length, + enum TdxRamType type) + { +@@ -281,6 +295,8 @@ static void tdx_finalize_vm(Notifier *notifier, void *unused) + + qsort(tdx_guest->ram_entries, tdx_guest->nr_ram_entries, + sizeof(TdxRamEntry), &tdx_ram_entry_compare); ++ ++ tdvf_hob_create(tdx_guest, tdx_get_hob_entry(tdx_guest)); + } + + static Notifier tdx_machine_done_notify = { +-- +2.47.3 + diff --git a/kvm-i386-tdx-Support-user-configurable-mrconfigid-mrowne.patch b/kvm-i386-tdx-Support-user-configurable-mrconfigid-mrowne.patch new file mode 100644 index 0000000..8170ec8 --- /dev/null +++ b/kvm-i386-tdx-Support-user-configurable-mrconfigid-mrowne.patch @@ -0,0 +1,218 @@ +From 38bf2076716fb5557a3e96720c9088b4b5f9d994 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:46 +0200 +Subject: [PATCH 027/100] i386/tdx: Support user configurable + mrconfigid/mrowner/mrownerconfig + +Three sha384 hash values, mrconfigid, mrowner and mrownerconfig, of a TD +can be provided for TDX attestation. Detailed meaning of them can be +found: https://lore.kernel.org/qemu-devel/31d6dbc1-f453-4cef-ab08-4813f4e0ff92@intel.com/ + +Allow user to specify those values via property mrconfigid, mrowner and +mrownerconfig. They are all in base64 format. + +example +-object tdx-guest, \ + mrconfigid=ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v,\ + mrowner=ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v,\ + mrownerconfig=ASNFZ4mrze8BI0VniavN7wEjRWeJq83vASNFZ4mrze8BI0VniavN7wEjRWeJq83v + +Signed-off-by: Isaku Yamahata +Co-developed-by: Xiaoyao Li +Signed-off-by: Xiaoyao Li +Acked-by: Markus Armbruster +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-14-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit d05a0858cf876f79b57a622716fbad07f5b2ea08) +Signed-off-by: Paolo Bonzini +--- + qapi/qom.json | 16 +++++++- + target/i386/kvm/tdx.c | 95 +++++++++++++++++++++++++++++++++++++++++++ + target/i386/kvm/tdx.h | 3 ++ + 3 files changed, 113 insertions(+), 1 deletion(-) + +diff --git a/qapi/qom.json b/qapi/qom.json +index f229bb07aa..a8379bac17 100644 +--- a/qapi/qom.json ++++ b/qapi/qom.json +@@ -1060,11 +1060,25 @@ + # pages. Some guest OS (e.g., Linux TD guest) may require this to + # be set, otherwise they refuse to boot. + # ++# @mrconfigid: ID for non-owner-defined configuration of the guest TD, ++# e.g., run-time or OS configuration (base64 encoded SHA384 digest). ++# Defaults to all zeros. ++# ++# @mrowner: ID for the guest TD’s owner (base64 encoded SHA384 digest). ++# Defaults to all zeros. ++# ++# @mrownerconfig: ID for owner-defined configuration of the guest TD, ++# e.g., specific to the workload rather than the run-time or OS ++# (base64 encoded SHA384 digest). Defaults to all zeros. ++# + # Since: 10.1 + ## + { 'struct': 'TdxGuestProperties', + 'data': { '*attributes': 'uint64', +- '*sept-ve-disable': 'bool' } } ++ '*sept-ve-disable': 'bool', ++ '*mrconfigid': 'str', ++ '*mrowner': 'str', ++ '*mrownerconfig': 'str' } } + + ## + # @ThreadContextProperties: +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 3de3b5fa6a..39fd964c6b 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -11,8 +11,10 @@ + + #include "qemu/osdep.h" + #include "qemu/error-report.h" ++#include "qemu/base64.h" + #include "qapi/error.h" + #include "qom/object_interfaces.h" ++#include "crypto/hash.h" + + #include "hw/i386/x86.h" + #include "kvm_i386.h" +@@ -240,6 +242,7 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) + CPUX86State *env = &x86cpu->env; + g_autofree struct kvm_tdx_init_vm *init_vm = NULL; + Error *local_err = NULL; ++ size_t data_len; + int retry = 10000; + int r = 0; + +@@ -251,6 +254,45 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) + init_vm = g_malloc0(sizeof(struct kvm_tdx_init_vm) + + sizeof(struct kvm_cpuid_entry2) * KVM_MAX_CPUID_ENTRIES); + ++ if (tdx_guest->mrconfigid) { ++ g_autofree uint8_t *data = qbase64_decode(tdx_guest->mrconfigid, ++ strlen(tdx_guest->mrconfigid), &data_len, errp); ++ if (!data) { ++ return -1; ++ } ++ if (data_len != QCRYPTO_HASH_DIGEST_LEN_SHA384) { ++ error_setg(errp, "TDX: failed to decode mrconfigid"); ++ return -1; ++ } ++ memcpy(init_vm->mrconfigid, data, data_len); ++ } ++ ++ if (tdx_guest->mrowner) { ++ g_autofree uint8_t *data = qbase64_decode(tdx_guest->mrowner, ++ strlen(tdx_guest->mrowner), &data_len, errp); ++ if (!data) { ++ return -1; ++ } ++ if (data_len != QCRYPTO_HASH_DIGEST_LEN_SHA384) { ++ error_setg(errp, "TDX: failed to decode mrowner"); ++ return -1; ++ } ++ memcpy(init_vm->mrowner, data, data_len); ++ } ++ ++ if (tdx_guest->mrownerconfig) { ++ g_autofree uint8_t *data = qbase64_decode(tdx_guest->mrownerconfig, ++ strlen(tdx_guest->mrownerconfig), &data_len, errp); ++ if (!data) { ++ return -1; ++ } ++ if (data_len != QCRYPTO_HASH_DIGEST_LEN_SHA384) { ++ error_setg(errp, "TDX: failed to decode mrownerconfig"); ++ return -1; ++ } ++ memcpy(init_vm->mrownerconfig, data, data_len); ++ } ++ + r = setup_td_guest_attributes(x86cpu, errp); + if (r) { + return r; +@@ -314,6 +356,51 @@ static void tdx_guest_set_sept_ve_disable(Object *obj, bool value, Error **errp) + } + } + ++static char *tdx_guest_get_mrconfigid(Object *obj, Error **errp) ++{ ++ TdxGuest *tdx = TDX_GUEST(obj); ++ ++ return g_strdup(tdx->mrconfigid); ++} ++ ++static void tdx_guest_set_mrconfigid(Object *obj, const char *value, Error **errp) ++{ ++ TdxGuest *tdx = TDX_GUEST(obj); ++ ++ g_free(tdx->mrconfigid); ++ tdx->mrconfigid = g_strdup(value); ++} ++ ++static char *tdx_guest_get_mrowner(Object *obj, Error **errp) ++{ ++ TdxGuest *tdx = TDX_GUEST(obj); ++ ++ return g_strdup(tdx->mrowner); ++} ++ ++static void tdx_guest_set_mrowner(Object *obj, const char *value, Error **errp) ++{ ++ TdxGuest *tdx = TDX_GUEST(obj); ++ ++ g_free(tdx->mrowner); ++ tdx->mrowner = g_strdup(value); ++} ++ ++static char *tdx_guest_get_mrownerconfig(Object *obj, Error **errp) ++{ ++ TdxGuest *tdx = TDX_GUEST(obj); ++ ++ return g_strdup(tdx->mrownerconfig); ++} ++ ++static void tdx_guest_set_mrownerconfig(Object *obj, const char *value, Error **errp) ++{ ++ TdxGuest *tdx = TDX_GUEST(obj); ++ ++ g_free(tdx->mrownerconfig); ++ tdx->mrownerconfig = g_strdup(value); ++} ++ + /* tdx guest */ + OBJECT_DEFINE_TYPE_WITH_INTERFACES(TdxGuest, + tdx_guest, +@@ -337,6 +424,14 @@ static void tdx_guest_init(Object *obj) + object_property_add_bool(obj, "sept-ve-disable", + tdx_guest_get_sept_ve_disable, + tdx_guest_set_sept_ve_disable); ++ object_property_add_str(obj, "mrconfigid", ++ tdx_guest_get_mrconfigid, ++ tdx_guest_set_mrconfigid); ++ object_property_add_str(obj, "mrowner", ++ tdx_guest_get_mrowner, tdx_guest_set_mrowner); ++ object_property_add_str(obj, "mrownerconfig", ++ tdx_guest_get_mrownerconfig, ++ tdx_guest_set_mrownerconfig); + } + + static void tdx_guest_finalize(Object *obj) +diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h +index 4e2b5c61ff..e472b11fb0 100644 +--- a/target/i386/kvm/tdx.h ++++ b/target/i386/kvm/tdx.h +@@ -24,6 +24,9 @@ typedef struct TdxGuest { + bool initialized; + uint64_t attributes; /* TD attributes */ + uint64_t xfam; ++ char *mrconfigid; /* base64 encoded sha348 digest */ ++ char *mrowner; /* base64 encoded sha348 digest */ ++ char *mrownerconfig; /* base64 encoded sha348 digest */ + } TdxGuest; + + #ifdef CONFIG_TDX +-- +2.47.3 + diff --git a/kvm-i386-tdx-Track-RAM-entries-for-TDX-VM.patch b/kvm-i386-tdx-Track-RAM-entries-for-TDX-VM.patch new file mode 100644 index 0000000..27885a4 --- /dev/null +++ b/kvm-i386-tdx-Track-RAM-entries-for-TDX-VM.patch @@ -0,0 +1,215 @@ +From 7861c315d2e5b94af1c87e04d99d6a93cf4291d4 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:46 +0200 +Subject: [PATCH 035/100] i386/tdx: Track RAM entries for TDX VM + +The RAM of TDX VM can be classified into two types: + + - TDX_RAM_UNACCEPTED: default type of TDX memory, which needs to be + accepted by TDX guest before it can be used and will be all-zeros + after being accepted. + + - TDX_RAM_ADDED: the RAM that is ADD'ed to TD guest before running, and + can be used directly. E.g., TD HOB and TEMP MEM that needed by TDVF. + +Maintain TdxRamEntries[] which grabs the initial RAM info from e820 table +and mark each RAM range as default type TDX_RAM_UNACCEPTED. + +Then turn the range of TD HOB and TEMP MEM to TDX_RAM_ADDED since these +ranges will be ADD'ed before TD runs and no need to be accepted runtime. + +The TdxRamEntries[] are later used to setup the memory TD resource HOB +that passes memory info from QEMU to TDVF. + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-22-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit f18672e4cf91feed4b91ef85a264a500935a2865) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 109 ++++++++++++++++++++++++++++++++++++++++++ + target/i386/kvm/tdx.h | 14 ++++++ + 2 files changed, 123 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index e2794843a9..699a2ff979 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -18,6 +18,7 @@ + #include "crypto/hash.h" + #include "system/system.h" + ++#include "hw/i386/e820_memory_layout.h" + #include "hw/i386/tdvf.h" + #include "hw/i386/x86.h" + #include "kvm_i386.h" +@@ -146,11 +147,110 @@ void tdx_set_tdvf_region(MemoryRegion *tdvf_mr) + tdx_guest->tdvf_mr = tdvf_mr; + } + ++static void tdx_add_ram_entry(uint64_t address, uint64_t length, ++ enum TdxRamType type) ++{ ++ uint32_t nr_entries = tdx_guest->nr_ram_entries; ++ tdx_guest->ram_entries = g_renew(TdxRamEntry, tdx_guest->ram_entries, ++ nr_entries + 1); ++ ++ tdx_guest->ram_entries[nr_entries].address = address; ++ tdx_guest->ram_entries[nr_entries].length = length; ++ tdx_guest->ram_entries[nr_entries].type = type; ++ tdx_guest->nr_ram_entries++; ++} ++ ++static int tdx_accept_ram_range(uint64_t address, uint64_t length) ++{ ++ uint64_t head_start, tail_start, head_length, tail_length; ++ uint64_t tmp_address, tmp_length; ++ TdxRamEntry *e; ++ int i = 0; ++ ++ do { ++ if (i == tdx_guest->nr_ram_entries) { ++ return -1; ++ } ++ ++ e = &tdx_guest->ram_entries[i++]; ++ } while (address + length <= e->address || address >= e->address + e->length); ++ ++ /* ++ * The to-be-accepted ram range must be fully contained by one ++ * RAM entry. ++ */ ++ if (e->address > address || ++ e->address + e->length < address + length) { ++ return -1; ++ } ++ ++ if (e->type == TDX_RAM_ADDED) { ++ return 0; ++ } ++ ++ tmp_address = e->address; ++ tmp_length = e->length; ++ ++ e->address = address; ++ e->length = length; ++ e->type = TDX_RAM_ADDED; ++ ++ head_length = address - tmp_address; ++ if (head_length > 0) { ++ head_start = tmp_address; ++ tdx_add_ram_entry(head_start, head_length, TDX_RAM_UNACCEPTED); ++ } ++ ++ tail_start = address + length; ++ if (tail_start < tmp_address + tmp_length) { ++ tail_length = tmp_address + tmp_length - tail_start; ++ tdx_add_ram_entry(tail_start, tail_length, TDX_RAM_UNACCEPTED); ++ } ++ ++ return 0; ++} ++ ++static int tdx_ram_entry_compare(const void *lhs_, const void* rhs_) ++{ ++ const TdxRamEntry *lhs = lhs_; ++ const TdxRamEntry *rhs = rhs_; ++ ++ if (lhs->address == rhs->address) { ++ return 0; ++ } ++ if (le64_to_cpu(lhs->address) > le64_to_cpu(rhs->address)) { ++ return 1; ++ } ++ return -1; ++} ++ ++static void tdx_init_ram_entries(void) ++{ ++ unsigned i, j, nr_e820_entries; ++ ++ nr_e820_entries = e820_get_table(NULL); ++ tdx_guest->ram_entries = g_new(TdxRamEntry, nr_e820_entries); ++ ++ for (i = 0, j = 0; i < nr_e820_entries; i++) { ++ uint64_t addr, len; ++ ++ if (e820_get_entry(i, E820_RAM, &addr, &len)) { ++ tdx_guest->ram_entries[j].address = addr; ++ tdx_guest->ram_entries[j].length = len; ++ tdx_guest->ram_entries[j].type = TDX_RAM_UNACCEPTED; ++ j++; ++ } ++ } ++ tdx_guest->nr_ram_entries = j; ++} ++ + static void tdx_finalize_vm(Notifier *notifier, void *unused) + { + TdxFirmware *tdvf = &tdx_guest->tdvf; + TdxFirmwareEntry *entry; + ++ tdx_init_ram_entries(); ++ + for_each_tdx_fw_entry(tdvf, entry) { + switch (entry->type) { + case TDVF_SECTION_TYPE_BFV: +@@ -166,12 +266,21 @@ static void tdx_finalize_vm(Notifier *notifier, void *unused) + entry->type); + exit(1); + } ++ if (tdx_accept_ram_range(entry->address, entry->size)) { ++ error_report("Failed to accept memory for TDVF section %d", ++ entry->type); ++ qemu_ram_munmap(-1, entry->mem_ptr, entry->size); ++ exit(1); ++ } + break; + default: + error_report("Unsupported TDVF section %d", entry->type); + exit(1); + } + } ++ ++ qsort(tdx_guest->ram_entries, tdx_guest->nr_ram_entries, ++ sizeof(TdxRamEntry), &tdx_ram_entry_compare); + } + + static Notifier tdx_machine_done_notify = { +diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h +index 28a03c2a7b..36a7400e74 100644 +--- a/target/i386/kvm/tdx.h ++++ b/target/i386/kvm/tdx.h +@@ -20,6 +20,17 @@ typedef struct TdxGuestClass { + /* TDX requires bus frequency 25MHz */ + #define TDX_APIC_BUS_CYCLES_NS 40 + ++enum TdxRamType { ++ TDX_RAM_UNACCEPTED, ++ TDX_RAM_ADDED, ++}; ++ ++typedef struct TdxRamEntry { ++ uint64_t address; ++ uint64_t length; ++ enum TdxRamType type; ++} TdxRamEntry; ++ + typedef struct TdxGuest { + X86ConfidentialGuest parent_obj; + +@@ -34,6 +45,9 @@ typedef struct TdxGuest { + + MemoryRegion *tdvf_mr; + TdxFirmware tdvf; ++ ++ uint32_t nr_ram_entries; ++ TdxRamEntry *ram_entries; + } TdxGuest; + + #ifdef CONFIG_TDX +-- +2.47.3 + diff --git a/kvm-i386-tdx-Track-mem_ptr-for-each-firmware-entry-of-TD.patch b/kvm-i386-tdx-Track-mem_ptr-for-each-firmware-entry-of-TD.patch new file mode 100644 index 0000000..e1fc6d7 --- /dev/null +++ b/kvm-i386-tdx-Track-mem_ptr-for-each-firmware-entry-of-TD.patch @@ -0,0 +1,141 @@ +From 5dcbd3148b756baefe284e99eaf3202951c76594 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 25 Jul 2025 16:40:22 +0200 +Subject: [PATCH 034/100] i386/tdx: Track mem_ptr for each firmware entry of + TDVF + +For each TDVF sections, QEMU needs to copy the content to guest +private memory via KVM API (KVM_TDX_INIT_MEM_REGION). + +Introduce a field @mem_ptr for TdxFirmwareEntry to track the memory +pointer of each TDVF sections. So that QEMU can add/copy them to guest +private memory later. + +TDVF sections can be classified into two groups: + - Firmware itself, e.g., TDVF BFV and CFV, that located separately from + guest RAM. Its memory pointer is the bios pointer. + + - Sections located at guest RAM, e.g., TEMP_MEM and TD_HOB. + mmap a new memory range for them. + +Register a machine_init_done callback to do the stuff. + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-21-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 4420ba0ebbf014acc68f78669e0767e288313ed6) +Signed-off-by: Paolo Bonzini +--- + hw/i386/tdvf.c | 1 + + include/hw/i386/tdvf.h | 7 +++++++ + target/i386/kvm/tdx.c | 37 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 45 insertions(+) + +diff --git a/hw/i386/tdvf.c b/hw/i386/tdvf.c +index e2d486946a..bd993ea2f0 100644 +--- a/hw/i386/tdvf.c ++++ b/hw/i386/tdvf.c +@@ -179,6 +179,7 @@ int tdvf_parse_metadata(TdxFirmware *fw, void *flash_ptr, int size) + } + } + ++ fw->mem_ptr = flash_ptr; + return 0; + + err: +diff --git a/include/hw/i386/tdvf.h b/include/hw/i386/tdvf.h +index 7ebcac42a3..e75c8d1acc 100644 +--- a/include/hw/i386/tdvf.h ++++ b/include/hw/i386/tdvf.h +@@ -26,13 +26,20 @@ typedef struct TdxFirmwareEntry { + uint64_t size; + uint32_t type; + uint32_t attributes; ++ ++ void *mem_ptr; + } TdxFirmwareEntry; + + typedef struct TdxFirmware { ++ void *mem_ptr; ++ + uint32_t nr_entries; + TdxFirmwareEntry *entries; + } TdxFirmware; + ++#define for_each_tdx_fw_entry(fw, e) \ ++ for (e = (fw)->entries; e != (fw)->entries + (fw)->nr_entries; e++) ++ + int tdvf_parse_metadata(TdxFirmware *fw, void *flash_ptr, int size); + + #endif /* HW_I386_TDVF_H */ +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 71be3bd28d..e2794843a9 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -12,10 +12,13 @@ + #include "qemu/osdep.h" + #include "qemu/error-report.h" + #include "qemu/base64.h" ++#include "qemu/mmap-alloc.h" + #include "qapi/error.h" + #include "qom/object_interfaces.h" + #include "crypto/hash.h" ++#include "system/system.h" + ++#include "hw/i386/tdvf.h" + #include "hw/i386/x86.h" + #include "kvm_i386.h" + #include "tdx.h" +@@ -143,6 +146,38 @@ void tdx_set_tdvf_region(MemoryRegion *tdvf_mr) + tdx_guest->tdvf_mr = tdvf_mr; + } + ++static void tdx_finalize_vm(Notifier *notifier, void *unused) ++{ ++ TdxFirmware *tdvf = &tdx_guest->tdvf; ++ TdxFirmwareEntry *entry; ++ ++ for_each_tdx_fw_entry(tdvf, entry) { ++ switch (entry->type) { ++ case TDVF_SECTION_TYPE_BFV: ++ case TDVF_SECTION_TYPE_CFV: ++ entry->mem_ptr = tdvf->mem_ptr + entry->data_offset; ++ break; ++ case TDVF_SECTION_TYPE_TD_HOB: ++ case TDVF_SECTION_TYPE_TEMP_MEM: ++ entry->mem_ptr = qemu_ram_mmap(-1, entry->size, ++ qemu_real_host_page_size(), 0, 0); ++ if (entry->mem_ptr == MAP_FAILED) { ++ error_report("Failed to mmap memory for TDVF section %d", ++ entry->type); ++ exit(1); ++ } ++ break; ++ default: ++ error_report("Unsupported TDVF section %d", entry->type); ++ exit(1); ++ } ++ } ++} ++ ++static Notifier tdx_machine_done_notify = { ++ .notify = tdx_finalize_vm, ++}; ++ + static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + { + TdxGuest *tdx = TDX_GUEST(cgs); +@@ -157,6 +192,8 @@ static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + } + } + ++ qemu_add_machine_init_done_notifier(&tdx_machine_done_notify); ++ + tdx_guest = tdx; + return 0; + } +-- +2.47.3 + diff --git a/kvm-i386-tdx-Validate-TD-attributes.patch b/kvm-i386-tdx-Validate-TD-attributes.patch new file mode 100644 index 0000000..d131356 --- /dev/null +++ b/kvm-i386-tdx-Validate-TD-attributes.patch @@ -0,0 +1,98 @@ +From 50d4b03732771104c45f09f21a15834f830b80f3 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:46 +0200 +Subject: [PATCH 026/100] i386/tdx: Validate TD attributes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Validate TD attributes with tdx_caps that only supported bits are +allowed by KVM. + +Besides, sanity check the attribute bits that have not been supported by +QEMU yet. e.g., debug bit, it will be allowed in the future when debug +TD support lands in QEMU. + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Zhao Liu +Reviewed-by: Daniel P. BerrangĂ© +Link: https://lore.kernel.org/r/20250508150002.689633-13-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 53b6f406b4f1a215fb3ec60e56ddba2e019a45ef) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 33 +++++++++++++++++++++++++++++++-- + 1 file changed, 31 insertions(+), 2 deletions(-) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 1ab063f790..3de3b5fa6a 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -18,10 +18,15 @@ + #include "kvm_i386.h" + #include "tdx.h" + ++#define TDX_TD_ATTRIBUTES_DEBUG BIT_ULL(0) + #define TDX_TD_ATTRIBUTES_SEPT_VE_DISABLE BIT_ULL(28) + #define TDX_TD_ATTRIBUTES_PKS BIT_ULL(30) + #define TDX_TD_ATTRIBUTES_PERFMON BIT_ULL(63) + ++#define TDX_SUPPORTED_TD_ATTRS (TDX_TD_ATTRIBUTES_SEPT_VE_DISABLE |\ ++ TDX_TD_ATTRIBUTES_PKS | \ ++ TDX_TD_ATTRIBUTES_PERFMON) ++ + static TdxGuest *tdx_guest; + + static struct kvm_tdx_capabilities *tdx_caps; +@@ -153,13 +158,34 @@ static int tdx_kvm_type(X86ConfidentialGuest *cg) + return KVM_X86_TDX_VM; + } + +-static void setup_td_guest_attributes(X86CPU *x86cpu) ++static int tdx_validate_attributes(TdxGuest *tdx, Error **errp) ++{ ++ if ((tdx->attributes & ~tdx_caps->supported_attrs)) { ++ error_setg(errp, "Invalid attributes 0x%lx for TDX VM " ++ "(KVM supported: 0x%llx)", tdx->attributes, ++ tdx_caps->supported_attrs); ++ return -1; ++ } ++ ++ if (tdx->attributes & ~TDX_SUPPORTED_TD_ATTRS) { ++ error_setg(errp, "Some QEMU unsupported TD attribute bits being " ++ "requested: 0x%lx (QEMU supported: 0x%llx)", ++ tdx->attributes, TDX_SUPPORTED_TD_ATTRS); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int setup_td_guest_attributes(X86CPU *x86cpu, Error **errp) + { + CPUX86State *env = &x86cpu->env; + + tdx_guest->attributes |= (env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKS) ? + TDX_TD_ATTRIBUTES_PKS : 0; + tdx_guest->attributes |= x86cpu->enable_pmu ? TDX_TD_ATTRIBUTES_PERFMON : 0; ++ ++ return tdx_validate_attributes(tdx_guest, errp); + } + + static int setup_td_xfam(X86CPU *x86cpu, Error **errp) +@@ -225,7 +251,10 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) + init_vm = g_malloc0(sizeof(struct kvm_tdx_init_vm) + + sizeof(struct kvm_cpuid_entry2) * KVM_MAX_CPUID_ENTRIES); + +- setup_td_guest_attributes(x86cpu); ++ r = setup_td_guest_attributes(x86cpu, errp); ++ if (r) { ++ return r; ++ } + + r = setup_td_xfam(x86cpu, errp); + if (r) { +-- +2.47.3 + diff --git a/kvm-i386-tdx-Validate-phys_bits-against-host-value.patch b/kvm-i386-tdx-Validate-phys_bits-against-host-value.patch new file mode 100644 index 0000000..3940bc7 --- /dev/null +++ b/kvm-i386-tdx-Validate-phys_bits-against-host-value.patch @@ -0,0 +1,80 @@ +From a6713abb01ac9544db96f444e44ee92085b072ad Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:48 +0200 +Subject: [PATCH 068/100] i386/tdx: Validate phys_bits against host value +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For TDX guest, the phys_bits is not configurable and can only be +host/native value. + +Validate phys_bits inside tdx_check_features(). + +Signed-off-by: Xiaoyao Li +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-55-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 907ee7b67e50a7eea2768c66e3ad67c9aa4ffd3c) +Signed-off-by: Paolo Bonzini +--- + target/i386/host-cpu.c | 2 +- + target/i386/host-cpu.h | 1 + + target/i386/kvm/tdx.c | 8 ++++++++ + 3 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/target/i386/host-cpu.c b/target/i386/host-cpu.c +index 072731a4dd..a78be2e220 100644 +--- a/target/i386/host-cpu.c ++++ b/target/i386/host-cpu.c +@@ -15,7 +15,7 @@ + #include "system/system.h" + + /* Note: Only safe for use on x86(-64) hosts */ +-static uint32_t host_cpu_phys_bits(void) ++uint32_t host_cpu_phys_bits(void) + { + uint32_t eax; + uint32_t host_phys_bits; +diff --git a/target/i386/host-cpu.h b/target/i386/host-cpu.h +index 6a9bc918ba..b97ec01c9b 100644 +--- a/target/i386/host-cpu.h ++++ b/target/i386/host-cpu.h +@@ -10,6 +10,7 @@ + #ifndef HOST_CPU_H + #define HOST_CPU_H + ++uint32_t host_cpu_phys_bits(void); + void host_cpu_instance_init(X86CPU *cpu); + void host_cpu_max_instance_init(X86CPU *cpu); + bool host_cpu_realizefn(CPUState *cs, Error **errp); +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 73a0abbcc9..4b5847e92a 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -25,6 +25,7 @@ + + #include "cpu.h" + #include "cpu-internal.h" ++#include "host-cpu.h" + #include "hw/i386/e820_memory_layout.h" + #include "hw/i386/tdvf.h" + #include "hw/i386/x86.h" +@@ -879,6 +880,13 @@ static int tdx_check_features(X86ConfidentialGuest *cg, CPUState *cs) + return -EINVAL; + } + ++ if (cpu->phys_bits != host_cpu_phys_bits()) { ++ error_report("TDX requires guest CPU physical bits (%u) " ++ "to match host CPU physical bits (%u)", ++ cpu->phys_bits, host_cpu_phys_bits()); ++ return -EINVAL; ++ } ++ + return 0; + } + +-- +2.47.3 + diff --git a/kvm-i386-tdx-Wire-CPU-features-up-with-attributes-of-TD-.patch b/kvm-i386-tdx-Wire-CPU-features-up-with-attributes-of-TD-.patch new file mode 100644 index 0000000..a847b3a --- /dev/null +++ b/kvm-i386-tdx-Wire-CPU-features-up-with-attributes-of-TD-.patch @@ -0,0 +1,70 @@ +From 571e4c6f4a04f0a6358c5c2e3da64db1dd621362 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:46 +0200 +Subject: [PATCH 025/100] i386/tdx: Wire CPU features up with attributes of TD + guest +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For QEMU VMs, + - PKS is configured via CPUID_7_0_ECX_PKS, e.g., -cpu xxx,+pks and + - PMU is configured by x86cpu->enable_pmu, e.g., -cpu xxx,pmu=on + +While the bit 30 (PKS) and bit 63 (PERFMON) of TD's attributes are also +used to configure the PKS and PERFMON/PMU of TD, reuse the existing +configuration interfaces of 'cpu' for TD's attributes. + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-12-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit bb3be394cf80d68251e5b89e823dddc679b6e644) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 2ed40b7614..1ab063f790 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -19,6 +19,8 @@ + #include "tdx.h" + + #define TDX_TD_ATTRIBUTES_SEPT_VE_DISABLE BIT_ULL(28) ++#define TDX_TD_ATTRIBUTES_PKS BIT_ULL(30) ++#define TDX_TD_ATTRIBUTES_PERFMON BIT_ULL(63) + + static TdxGuest *tdx_guest; + +@@ -151,6 +153,15 @@ static int tdx_kvm_type(X86ConfidentialGuest *cg) + return KVM_X86_TDX_VM; + } + ++static void setup_td_guest_attributes(X86CPU *x86cpu) ++{ ++ CPUX86State *env = &x86cpu->env; ++ ++ tdx_guest->attributes |= (env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKS) ? ++ TDX_TD_ATTRIBUTES_PKS : 0; ++ tdx_guest->attributes |= x86cpu->enable_pmu ? TDX_TD_ATTRIBUTES_PERFMON : 0; ++} ++ + static int setup_td_xfam(X86CPU *x86cpu, Error **errp) + { + CPUX86State *env = &x86cpu->env; +@@ -214,6 +225,8 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp) + init_vm = g_malloc0(sizeof(struct kvm_tdx_init_vm) + + sizeof(struct kvm_cpuid_entry2) * KVM_MAX_CPUID_ENTRIES); + ++ setup_td_guest_attributes(x86cpu); ++ + r = setup_td_xfam(x86cpu, errp); + if (r) { + return r; +-- +2.47.3 + diff --git a/kvm-i386-tdx-Wire-TDX_REPORT_FATAL_ERROR-with-GuestPanic.patch b/kvm-i386-tdx-Wire-TDX_REPORT_FATAL_ERROR-with-GuestPanic.patch new file mode 100644 index 0000000..d51117e --- /dev/null +++ b/kvm-i386-tdx-Wire-TDX_REPORT_FATAL_ERROR-with-GuestPanic.patch @@ -0,0 +1,230 @@ +From 9c1ae7ab2b826154a7bbc5fc6a8f1f57cb0a40b4 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 25 Jul 2025 16:40:22 +0200 +Subject: [PATCH 043/100] i386/tdx: Wire TDX_REPORT_FATAL_ERROR with GuestPanic + facility + +Integrate TDX's TDX_REPORT_FATAL_ERROR into QEMU GuestPanic facility + +Originated-from: Isaku Yamahata +Signed-off-by: Xiaoyao Li +Acked-by: Markus Armbruster +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-30-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 6e250463b08b4028123f201343ee72099ef81e68) +Signed-off-by: Paolo Bonzini +--- + qapi/run-state.json | 31 +++++++++++++++++++-- + system/runstate.c | 65 +++++++++++++++++++++++++++++++++++++++++++ + target/i386/kvm/tdx.c | 25 ++++++++++++++++- + 3 files changed, 118 insertions(+), 3 deletions(-) + +diff --git a/qapi/run-state.json b/qapi/run-state.json +index ce95cfa46b..ee11adc508 100644 +--- a/qapi/run-state.json ++++ b/qapi/run-state.json +@@ -501,10 +501,12 @@ + # + # @s390: s390 guest panic information type (Since: 2.12) + # ++# @tdx: tdx guest panic information type (Since: 10.1) ++# + # Since: 2.9 + ## + { 'enum': 'GuestPanicInformationType', +- 'data': [ 'hyper-v', 's390' ] } ++ 'data': [ 'hyper-v', 's390', 'tdx' ] } + + ## + # @GuestPanicInformation: +@@ -519,7 +521,8 @@ + 'base': {'type': 'GuestPanicInformationType'}, + 'discriminator': 'type', + 'data': {'hyper-v': 'GuestPanicInformationHyperV', +- 's390': 'GuestPanicInformationS390'}} ++ 's390': 'GuestPanicInformationS390', ++ 'tdx' : 'GuestPanicInformationTdx'}} + + ## + # @GuestPanicInformationHyperV: +@@ -598,6 +601,30 @@ + 'psw-addr': 'uint64', + 'reason': 'S390CrashReason'}} + ++## ++# @GuestPanicInformationTdx: ++# ++# TDX Guest panic information specific to TDX, as specified in the ++# "Guest-Hypervisor Communication Interface (GHCI) Specification", ++# section TDG.VP.VMCALL. ++# ++# @error-code: TD-specific error code ++# ++# @message: Human-readable error message provided by the guest. Not ++# to be trusted. ++# ++# @gpa: guest-physical address of a page that contains more verbose ++# error information, as zero-terminated string. Present when the ++# "GPA valid" bit (bit 63) is set in @error-code. ++# ++# ++# Since: 10.1 ++## ++{'struct': 'GuestPanicInformationTdx', ++ 'data': {'error-code': 'uint32', ++ 'message': 'str', ++ '*gpa': 'uint64'}} ++ + ## + # @MEMORY_FAILURE: + # +diff --git a/system/runstate.c b/system/runstate.c +index 272801d307..e9d5d7505b 100644 +--- a/system/runstate.c ++++ b/system/runstate.c +@@ -565,6 +565,58 @@ static void qemu_system_wakeup(void) + } + } + ++static char *tdx_parse_panic_message(char *message) ++{ ++ bool printable = false; ++ char *buf = NULL; ++ int len = 0, i; ++ ++ /* ++ * Although message is defined as a json string, we shouldn't ++ * unconditionally treat it as is because the guest generated it and ++ * it's not necessarily trustable. ++ */ ++ if (message) { ++ /* The caller guarantees the NULL-terminated string. */ ++ len = strlen(message); ++ ++ printable = len > 0; ++ for (i = 0; i < len; i++) { ++ if (!(0x20 <= message[i] && message[i] <= 0x7e)) { ++ printable = false; ++ break; ++ } ++ } ++ } ++ ++ if (len == 0) { ++ buf = g_malloc(1); ++ buf[0] = '\0'; ++ } else { ++ if (!printable) { ++ /* 3 = length of "%02x " */ ++ buf = g_malloc(len * 3); ++ for (i = 0; i < len; i++) { ++ if (message[i] == '\0') { ++ break; ++ } else { ++ sprintf(buf + 3 * i, "%02x ", message[i]); ++ } ++ } ++ if (i > 0) { ++ /* replace the last ' '(space) to NULL */ ++ buf[i * 3 - 1] = '\0'; ++ } else { ++ buf[0] = '\0'; ++ } ++ } else { ++ buf = g_strdup(message); ++ } ++ } ++ ++ return buf; ++} ++ + void qemu_system_guest_panicked(GuestPanicInformation *info) + { + qemu_log_mask(LOG_GUEST_ERROR, "Guest crashed"); +@@ -606,7 +658,20 @@ void qemu_system_guest_panicked(GuestPanicInformation *info) + S390CrashReason_str(info->u.s390.reason), + info->u.s390.psw_mask, + info->u.s390.psw_addr); ++ } else if (info->type == GUEST_PANIC_INFORMATION_TYPE_TDX) { ++ char *message = tdx_parse_panic_message(info->u.tdx.message); ++ qemu_log_mask(LOG_GUEST_ERROR, ++ "\nTDX guest reports fatal error." ++ " error code: 0x%" PRIx32 " error message:\"%s\"\n", ++ info->u.tdx.error_code, message); ++ g_free(message); ++ if (info->u.tdx.gpa != -1ull) { ++ qemu_log_mask(LOG_GUEST_ERROR, "Additional error information " ++ "can be found at gpa page: 0x%" PRIx64 "\n", ++ info->u.tdx.gpa); ++ } + } ++ + qapi_free_GuestPanicInformation(info); + } + } +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 1030bf12dc..3b71b52c00 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -16,6 +16,7 @@ + #include "qapi/error.h" + #include "qom/object_interfaces.h" + #include "crypto/hash.h" ++#include "system/runstate.h" + #include "system/system.h" + #include "system/ramblock.h" + +@@ -615,18 +616,35 @@ int tdx_parse_tdvf(void *flash_ptr, int size) + return tdvf_parse_metadata(&tdx_guest->tdvf, flash_ptr, size); + } + ++static void tdx_panicked_on_fatal_error(X86CPU *cpu, uint64_t error_code, ++ char *message, uint64_t gpa) ++{ ++ GuestPanicInformation *panic_info; ++ ++ panic_info = g_new0(GuestPanicInformation, 1); ++ panic_info->type = GUEST_PANIC_INFORMATION_TYPE_TDX; ++ panic_info->u.tdx.error_code = (uint32_t) error_code; ++ panic_info->u.tdx.message = message; ++ panic_info->u.tdx.gpa = gpa; ++ ++ qemu_system_guest_panicked(panic_info); ++} ++ + /* + * Only 8 registers can contain valid ASCII byte stream to form the fatal + * message, and their sequence is: R14, R15, RBX, RDI, RSI, R8, R9, RDX + */ + #define TDX_FATAL_MESSAGE_MAX 64 + ++#define TDX_REPORT_FATAL_ERROR_GPA_VALID BIT_ULL(63) ++ + int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm_run *run) + { + uint64_t error_code = run->system_event.data[R_R12]; + uint64_t reg_mask = run->system_event.data[R_ECX]; + char *message = NULL; + uint64_t *tmp; ++ uint64_t gpa = -1ull; + + if (error_code & 0xffff) { + error_report("TDX: REPORT_FATAL_ERROR: invalid error code: 0x%lx", +@@ -657,7 +675,12 @@ int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm_run *run) + } + #undef COPY_REG + +- error_report("TD guest reports fatal error. %s", message ? : ""); ++ if (error_code & TDX_REPORT_FATAL_ERROR_GPA_VALID) { ++ gpa = run->system_event.data[R_R13]; ++ } ++ ++ tdx_panicked_on_fatal_error(cpu, error_code, message, gpa); ++ + return -1; + } + +-- +2.47.3 + diff --git a/kvm-i386-tdx-handle-TDG.VP.VMCALL-GetQuote.patch b/kvm-i386-tdx-handle-TDG.VP.VMCALL-GetQuote.patch new file mode 100644 index 0000000..ebda4d6 --- /dev/null +++ b/kvm-i386-tdx-handle-TDG.VP.VMCALL-GetQuote.patch @@ -0,0 +1,792 @@ +From 2927fae1033496d3c1cbc72a45df3322c1cfe33e Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:26:18 +0200 +Subject: [PATCH 078/100] i386/tdx: handle TDG.VP.VMCALL + +Add property "quote-generation-socket" to tdx-guest, which is a property +of type SocketAddress to specify Quote Generation Service(QGS). + +On request of GetQuote, it connects to the QGS socket, read request +data from shared guest memory, send the request data to the QGS, +and store the response into shared guest memory, at last notify +TD guest by interrupt. + +command line example: + qemu-system-x86_64 \ + -object '{"qom-type":"tdx-guest","id":"tdx0","quote-generation-socket":{"type":"unix", "path":"/var/run/tdx-qgs/qgs.socket"}}' \ + -machine confidential-guest-support=tdx0 + +Note, above example uses the unix socket. It can be other types, like vsock, +which depends on the implementation of QGS. + +To avoid no response from QGS server, setup a timer for the transaction. +If timeout, make it an error and interrupt guest. Define the threshold of +time to 30s at present, maybe change to other value if not appropriate. + +Signed-off-by: Isaku Yamahata +Co-developed-by: Chenyi Qiang +Signed-off-by: Chenyi Qiang +Co-developed-by: Xiaoyao Li +Signed-off-by: Xiaoyao Li +Tested-by: Xiaoyao Li +Signed-off-by: Paolo Bonzini +(cherry picked from commit 40da501d8989913935660dc24953ece02c9e98b8) +Signed-off-by: Paolo Bonzini + +Conflicts: system/ -> sysemu/,exec/ +(cherry picked from commit a8a8d33b7895308c8884f83a9757da3f77d73bda) +Signed-off-by: Paolo Bonzini +--- + qapi/qom.json | 8 +- + target/i386/kvm/kvm.c | 3 + + target/i386/kvm/meson.build | 2 +- + target/i386/kvm/tdx-quote-generator.c | 300 ++++++++++++++++++++++++++ + target/i386/kvm/tdx-quote-generator.h | 82 +++++++ + target/i386/kvm/tdx-stub.c | 4 + + target/i386/kvm/tdx.c | 176 ++++++++++++++- + target/i386/kvm/tdx.h | 10 + + 8 files changed, 582 insertions(+), 3 deletions(-) + create mode 100644 target/i386/kvm/tdx-quote-generator.c + create mode 100644 target/i386/kvm/tdx-quote-generator.h + +diff --git a/qapi/qom.json b/qapi/qom.json +index a8379bac17..3f13696448 100644 +--- a/qapi/qom.json ++++ b/qapi/qom.json +@@ -1071,6 +1071,11 @@ + # e.g., specific to the workload rather than the run-time or OS + # (base64 encoded SHA384 digest). Defaults to all zeros. + # ++# @quote-generation-socket: socket address for Quote Generation ++# Service (QGS). QGS is a daemon running on the host. Without ++# it, the guest will not be able to get a TD quote for ++# attestation. ++# + # Since: 10.1 + ## + { 'struct': 'TdxGuestProperties', +@@ -1078,7 +1083,8 @@ + '*sept-ve-disable': 'bool', + '*mrconfigid': 'str', + '*mrowner': 'str', +- '*mrownerconfig': 'str' } } ++ '*mrownerconfig': 'str', ++ '*quote-generation-socket': 'SocketAddress' } } + + ## + # @ThreadContextProperties: +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 8f83a29b5b..700b805cca 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -6158,6 +6158,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) + * does not handle the TDVMCALL. + */ + switch (run->tdx.nr) { ++ case TDVMCALL_GET_QUOTE: ++ tdx_handle_get_quote(cpu, run); ++ break; + case TDVMCALL_GET_TD_VM_CALL_INFO: + tdx_handle_get_tdvmcall_info(cpu, run); + break; +diff --git a/target/i386/kvm/meson.build b/target/i386/kvm/meson.build +index 3f44cdedb7..2675bf8902 100644 +--- a/target/i386/kvm/meson.build ++++ b/target/i386/kvm/meson.build +@@ -8,7 +8,7 @@ i386_kvm_ss.add(files( + + i386_kvm_ss.add(when: 'CONFIG_XEN_EMU', if_true: files('xen-emu.c')) + +-i386_kvm_ss.add(when: 'CONFIG_TDX', if_true: files('tdx.c'), if_false: files('tdx-stub.c')) ++i386_kvm_ss.add(when: 'CONFIG_TDX', if_true: files('tdx.c', 'tdx-quote-generator.c'), if_false: files('tdx-stub.c')) + + i386_system_ss.add(when: 'CONFIG_HYPERV', if_true: files('hyperv.c'), if_false: files('hyperv-stub.c')) + +diff --git a/target/i386/kvm/tdx-quote-generator.c b/target/i386/kvm/tdx-quote-generator.c +new file mode 100644 +index 0000000000..f59715f617 +--- /dev/null ++++ b/target/i386/kvm/tdx-quote-generator.c +@@ -0,0 +1,300 @@ ++/* ++ * QEMU TDX Quote Generation Support ++ * ++ * Copyright (c) 2025 Intel Corporation ++ * ++ * Author: ++ * Xiaoyao Li ++ * ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ */ ++ ++#include "qemu/osdep.h" ++#include "qemu/error-report.h" ++#include "qapi/error.h" ++#include "qapi/qapi-visit-sockets.h" ++ ++#include "tdx-quote-generator.h" ++ ++#define QGS_MSG_LIB_MAJOR_VER 1 ++#define QGS_MSG_LIB_MINOR_VER 1 ++ ++typedef enum _qgs_msg_type_t { ++ GET_QUOTE_REQ = 0, ++ GET_QUOTE_RESP = 1, ++ GET_COLLATERAL_REQ = 2, ++ GET_COLLATERAL_RESP = 3, ++ GET_PLATFORM_INFO_REQ = 4, ++ GET_PLATFORM_INFO_RESP = 5, ++ QGS_MSG_TYPE_MAX ++} qgs_msg_type_t; ++ ++typedef struct _qgs_msg_header_t { ++ uint16_t major_version; ++ uint16_t minor_version; ++ uint32_t type; ++ uint32_t size; // size of the whole message, include this header, in byte ++ uint32_t error_code; // used in response only ++} qgs_msg_header_t; ++ ++typedef struct _qgs_msg_get_quote_req_t { ++ qgs_msg_header_t header; // header.type = GET_QUOTE_REQ ++ uint32_t report_size; // cannot be 0 ++ uint32_t id_list_size; // length of id_list, in byte, can be 0 ++} qgs_msg_get_quote_req_t; ++ ++typedef struct _qgs_msg_get_quote_resp_s { ++ qgs_msg_header_t header; // header.type = GET_QUOTE_RESP ++ uint32_t selected_id_size; // can be 0 in case only one id is sent in request ++ uint32_t quote_size; // length of quote_data, in byte ++ uint8_t id_quote[]; // selected id followed by quote ++} qgs_msg_get_quote_resp_t; ++ ++#define HEADER_SIZE 4 ++ ++static uint32_t decode_header(const char *buf, size_t len) { ++ if (len < HEADER_SIZE) { ++ return 0; ++ } ++ uint32_t msg_size = 0; ++ for (uint32_t i = 0; i < HEADER_SIZE; ++i) { ++ msg_size = msg_size * 256 + (buf[i] & 0xFF); ++ } ++ return msg_size; ++} ++ ++static void encode_header(char *buf, size_t len, uint32_t size) { ++ assert(len >= HEADER_SIZE); ++ buf[0] = ((size >> 24) & 0xFF); ++ buf[1] = ((size >> 16) & 0xFF); ++ buf[2] = ((size >> 8) & 0xFF); ++ buf[3] = (size & 0xFF); ++} ++ ++static void tdx_generate_quote_cleanup(TdxGenerateQuoteTask *task) ++{ ++ timer_del(&task->timer); ++ ++ g_source_remove(task->watch); ++ qio_channel_close(QIO_CHANNEL(task->sioc), NULL); ++ object_unref(OBJECT(task->sioc)); ++ ++ task->completion(task); ++} ++ ++static gboolean tdx_get_quote_read(QIOChannel *ioc, GIOCondition condition, ++ gpointer opaque) ++{ ++ TdxGenerateQuoteTask *task = opaque; ++ Error *err = NULL; ++ int ret; ++ ++ ret = qio_channel_read(ioc, task->receive_buf + task->receive_buf_received, ++ task->payload_len - task->receive_buf_received, &err); ++ if (ret < 0) { ++ if (ret == QIO_CHANNEL_ERR_BLOCK) { ++ return G_SOURCE_CONTINUE; ++ } else { ++ error_report_err(err); ++ task->status_code = TDX_VP_GET_QUOTE_ERROR; ++ goto end; ++ } ++ } ++ ++ if (ret == 0) { ++ error_report("End of file before reply received"); ++ task->status_code = TDX_VP_GET_QUOTE_ERROR; ++ goto end; ++ } ++ ++ task->receive_buf_received += ret; ++ if (task->receive_buf_received >= HEADER_SIZE) { ++ uint32_t len = decode_header(task->receive_buf, ++ task->receive_buf_received); ++ if (len == 0 || ++ len > (task->payload_len - HEADER_SIZE)) { ++ error_report("Message len %u must be non-zero & less than %zu", ++ len, (task->payload_len - HEADER_SIZE)); ++ task->status_code = TDX_VP_GET_QUOTE_ERROR; ++ goto end; ++ } ++ ++ /* Now we know the size, shrink to fit */ ++ task->payload_len = HEADER_SIZE + len; ++ task->receive_buf = g_renew(char, ++ task->receive_buf, ++ task->payload_len); ++ } ++ ++ if (task->receive_buf_received >= (sizeof(qgs_msg_header_t) + HEADER_SIZE)) { ++ qgs_msg_header_t *hdr = (qgs_msg_header_t *)(task->receive_buf + HEADER_SIZE); ++ if (hdr->major_version != QGS_MSG_LIB_MAJOR_VER || ++ hdr->minor_version != QGS_MSG_LIB_MINOR_VER) { ++ error_report("Invalid QGS message header version %d.%d", ++ hdr->major_version, ++ hdr->minor_version); ++ task->status_code = TDX_VP_GET_QUOTE_ERROR; ++ goto end; ++ } ++ if (hdr->type != GET_QUOTE_RESP) { ++ error_report("Invalid QGS message type %d", ++ hdr->type); ++ task->status_code = TDX_VP_GET_QUOTE_ERROR; ++ goto end; ++ } ++ if (hdr->size > (task->payload_len - HEADER_SIZE)) { ++ error_report("QGS message size %d exceeds payload capacity %zu", ++ hdr->size, task->payload_len); ++ task->status_code = TDX_VP_GET_QUOTE_ERROR; ++ goto end; ++ } ++ if (hdr->error_code != 0) { ++ error_report("QGS message error code %d", ++ hdr->error_code); ++ task->status_code = TDX_VP_GET_QUOTE_ERROR; ++ goto end; ++ } ++ } ++ if (task->receive_buf_received >= (sizeof(qgs_msg_get_quote_resp_t) + HEADER_SIZE)) { ++ qgs_msg_get_quote_resp_t *msg = (qgs_msg_get_quote_resp_t *)(task->receive_buf + HEADER_SIZE); ++ if (msg->selected_id_size != 0) { ++ error_report("QGS message selected ID was %d not 0", ++ msg->selected_id_size); ++ task->status_code = TDX_VP_GET_QUOTE_ERROR; ++ goto end; ++ } ++ ++ if ((task->payload_len - HEADER_SIZE - sizeof(qgs_msg_get_quote_resp_t)) != ++ msg->quote_size) { ++ error_report("QGS quote size %d should be %zu", ++ msg->quote_size, ++ (task->payload_len - sizeof(qgs_msg_get_quote_resp_t))); ++ task->status_code = TDX_VP_GET_QUOTE_ERROR; ++ goto end; ++ } ++ } ++ ++ if (task->receive_buf_received == task->payload_len) { ++ size_t strip = HEADER_SIZE + sizeof(qgs_msg_get_quote_resp_t); ++ memmove(task->receive_buf, ++ task->receive_buf + strip, ++ task->receive_buf_received - strip); ++ task->receive_buf_received -= strip; ++ task->status_code = TDX_VP_GET_QUOTE_SUCCESS; ++ goto end; ++ } ++ ++ return G_SOURCE_CONTINUE; ++ ++end: ++ tdx_generate_quote_cleanup(task); ++ return G_SOURCE_REMOVE; ++} ++ ++static gboolean tdx_send_report(QIOChannel *ioc, GIOCondition condition, ++ gpointer opaque) ++{ ++ TdxGenerateQuoteTask *task = opaque; ++ Error *err = NULL; ++ int ret; ++ ++ ret = qio_channel_write(ioc, task->send_data + task->send_data_sent, ++ task->send_data_size - task->send_data_sent, &err); ++ if (ret < 0) { ++ if (ret == QIO_CHANNEL_ERR_BLOCK) { ++ ret = 0; ++ } else { ++ error_report_err(err); ++ task->status_code = TDX_VP_GET_QUOTE_ERROR; ++ tdx_generate_quote_cleanup(task); ++ goto end; ++ } ++ } ++ task->send_data_sent += ret; ++ ++ if (task->send_data_sent == task->send_data_size) { ++ task->watch = qio_channel_add_watch(QIO_CHANNEL(task->sioc), G_IO_IN, ++ tdx_get_quote_read, task, NULL); ++ goto end; ++ } ++ ++ return G_SOURCE_CONTINUE; ++ ++end: ++ return G_SOURCE_REMOVE; ++} ++ ++static void tdx_quote_generator_connected(QIOTask *qio_task, gpointer opaque) ++{ ++ TdxGenerateQuoteTask *task = opaque; ++ Error *err = NULL; ++ int ret; ++ ++ ret = qio_task_propagate_error(qio_task, &err); ++ if (ret) { ++ error_report_err(err); ++ task->status_code = TDX_VP_GET_QUOTE_QGS_UNAVAILABLE; ++ tdx_generate_quote_cleanup(task); ++ return; ++ } ++ ++ task->watch = qio_channel_add_watch(QIO_CHANNEL(task->sioc), G_IO_OUT, ++ tdx_send_report, task, NULL); ++} ++ ++#define TRANSACTION_TIMEOUT 30000 ++ ++static void getquote_expired(void *opaque) ++{ ++ TdxGenerateQuoteTask *task = opaque; ++ ++ task->status_code = TDX_VP_GET_QUOTE_ERROR; ++ tdx_generate_quote_cleanup(task); ++} ++ ++static void setup_get_quote_timer(TdxGenerateQuoteTask *task) ++{ ++ int64_t time; ++ ++ timer_init_ms(&task->timer, QEMU_CLOCK_VIRTUAL, getquote_expired, task); ++ time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); ++ timer_mod(&task->timer, time + TRANSACTION_TIMEOUT); ++} ++ ++void tdx_generate_quote(TdxGenerateQuoteTask *task, ++ SocketAddress *qg_sock_addr) ++{ ++ QIOChannelSocket *sioc; ++ qgs_msg_get_quote_req_t msg; ++ ++ /* Prepare a QGS message prelude */ ++ msg.header.major_version = QGS_MSG_LIB_MAJOR_VER; ++ msg.header.minor_version = QGS_MSG_LIB_MINOR_VER; ++ msg.header.type = GET_QUOTE_REQ; ++ msg.header.size = sizeof(msg) + task->send_data_size; ++ msg.header.error_code = 0; ++ msg.report_size = task->send_data_size; ++ msg.id_list_size = 0; ++ ++ /* Make room to add the QGS message prelude */ ++ task->send_data = g_renew(char, ++ task->send_data, ++ task->send_data_size + sizeof(msg) + HEADER_SIZE); ++ memmove(task->send_data + sizeof(msg) + HEADER_SIZE, ++ task->send_data, ++ task->send_data_size); ++ memcpy(task->send_data + HEADER_SIZE, ++ &msg, ++ sizeof(msg)); ++ encode_header(task->send_data, HEADER_SIZE, task->send_data_size + sizeof(msg)); ++ task->send_data_size += sizeof(msg) + HEADER_SIZE; ++ ++ sioc = qio_channel_socket_new(); ++ task->sioc = sioc; ++ ++ setup_get_quote_timer(task); ++ ++ qio_channel_socket_connect_async(sioc, qg_sock_addr, ++ tdx_quote_generator_connected, task, ++ NULL, NULL); ++} +diff --git a/target/i386/kvm/tdx-quote-generator.h b/target/i386/kvm/tdx-quote-generator.h +new file mode 100644 +index 0000000000..3bd9b8ef33 +--- /dev/null ++++ b/target/i386/kvm/tdx-quote-generator.h +@@ -0,0 +1,82 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#ifndef QEMU_I386_TDX_QUOTE_GENERATOR_H ++#define QEMU_I386_TDX_QUOTE_GENERATOR_H ++ ++#include "qom/object_interfaces.h" ++#include "io/channel-socket.h" ++#include "exec/hwaddr.h" ++ ++#define TDX_GET_QUOTE_STRUCTURE_VERSION 1ULL ++ ++#define TDX_VP_GET_QUOTE_SUCCESS 0ULL ++#define TDX_VP_GET_QUOTE_IN_FLIGHT (-1ULL) ++#define TDX_VP_GET_QUOTE_ERROR 0x8000000000000000ULL ++#define TDX_VP_GET_QUOTE_QGS_UNAVAILABLE 0x8000000000000001ULL ++ ++/* Limit to avoid resource starvation. */ ++#define TDX_GET_QUOTE_MAX_BUF_LEN (128 * 1024) ++#define TDX_MAX_GET_QUOTE_REQUEST 16 ++ ++#define TDX_GET_QUOTE_HDR_SIZE 24 ++ ++/* Format of pages shared with guest. */ ++struct tdx_get_quote_header { ++ /* Format version: must be 1 in little endian. */ ++ uint64_t structure_version; ++ ++ /* ++ * GetQuote status code in little endian: ++ * Guest must set error_code to 0 to avoid information leak. ++ * Qemu sets this before interrupting guest. ++ */ ++ uint64_t error_code; ++ ++ /* ++ * in-message size in little endian: The message will follow this header. ++ * The in-message will be send to QGS. ++ */ ++ uint32_t in_len; ++ ++ /* ++ * out-message size in little endian: ++ * On request, out_len must be zero to avoid information leak. ++ * On return, message size from QGS. Qemu overwrites this field. ++ * The message will follows this header. The in-message is overwritten. ++ */ ++ uint32_t out_len; ++ ++ /* ++ * Message buffer follows. ++ * Guest sets message that will be send to QGS. If out_len > in_len, guest ++ * should zero remaining buffer to avoid information leak. ++ * Qemu overwrites this buffer with a message returned from QGS. ++ */ ++}; ++ ++typedef struct TdxGenerateQuoteTask { ++ hwaddr buf_gpa; ++ hwaddr payload_gpa; ++ uint64_t payload_len; ++ ++ char *send_data; ++ uint64_t send_data_size; ++ uint64_t send_data_sent; ++ ++ char *receive_buf; ++ uint64_t receive_buf_received; ++ ++ uint64_t status_code; ++ struct tdx_get_quote_header hdr; ++ ++ QIOChannelSocket *sioc; ++ guint watch; ++ QEMUTimer timer; ++ ++ void (*completion)(struct TdxGenerateQuoteTask *task); ++ void *opaque; ++} TdxGenerateQuoteTask; ++ ++void tdx_generate_quote(TdxGenerateQuoteTask *task, SocketAddress *qg_sock_addr); ++ ++#endif /* QEMU_I386_TDX_QUOTE_GENERATOR_H */ +diff --git a/target/i386/kvm/tdx-stub.c b/target/i386/kvm/tdx-stub.c +index 62a12a0677..76fee49eff 100644 +--- a/target/i386/kvm/tdx-stub.c ++++ b/target/i386/kvm/tdx-stub.c +@@ -19,6 +19,10 @@ int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm_run *run) + return -EINVAL; + } + ++void tdx_handle_get_quote(X86CPU *cpu, struct kvm_run *run) ++{ ++} ++ + void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run) + { + } +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 6d1a9c111c..fa02ca5b5e 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -14,12 +14,14 @@ + #include "qemu/base64.h" + #include "qemu/mmap-alloc.h" + #include "qapi/error.h" ++#include "qapi/qapi-visit-sockets.h" + #include "qom/object_interfaces.h" + #include "crypto/hash.h" + #include "system/kvm_int.h" + #include "system/runstate.h" + #include "system/system.h" + #include "system/ramblock.h" ++#include "system/address-spaces.h" + + #include + +@@ -32,6 +34,7 @@ + #include "hw/i386/tdvf-hob.h" + #include "kvm_i386.h" + #include "tdx.h" ++#include "tdx-quote-generator.h" + + #include "standard-headers/asm-x86/kvm_para.h" + +@@ -1120,13 +1123,146 @@ int tdx_parse_tdvf(void *flash_ptr, int size) + return tdvf_parse_metadata(&tdx_guest->tdvf, flash_ptr, size); + } + ++static void tdx_get_quote_completion(TdxGenerateQuoteTask *task) ++{ ++ TdxGuest *tdx = task->opaque; ++ int ret; ++ ++ /* Maintain the number of in-flight requests. */ ++ qemu_mutex_lock(&tdx->lock); ++ tdx->num--; ++ qemu_mutex_unlock(&tdx->lock); ++ ++ if (task->status_code == TDX_VP_GET_QUOTE_SUCCESS) { ++ ret = address_space_write(&address_space_memory, task->payload_gpa, ++ MEMTXATTRS_UNSPECIFIED, task->receive_buf, ++ task->receive_buf_received); ++ if (ret != MEMTX_OK) { ++ error_report("TDX: get-quote: failed to write quote data."); ++ } else { ++ task->hdr.out_len = cpu_to_le64(task->receive_buf_received); ++ } ++ } ++ task->hdr.error_code = cpu_to_le64(task->status_code); ++ ++ /* Publish the response contents before marking this request completed. */ ++ smp_wmb(); ++ ret = address_space_write(&address_space_memory, task->buf_gpa, ++ MEMTXATTRS_UNSPECIFIED, &task->hdr, ++ TDX_GET_QUOTE_HDR_SIZE); ++ if (ret != MEMTX_OK) { ++ error_report("TDX: get-quote: failed to update GetQuote header."); ++ } ++ ++ g_free(task->send_data); ++ g_free(task->receive_buf); ++ g_free(task); ++ object_unref(tdx); ++} ++ ++void tdx_handle_get_quote(X86CPU *cpu, struct kvm_run *run) ++{ ++ TdxGenerateQuoteTask *task; ++ struct tdx_get_quote_header hdr; ++ hwaddr buf_gpa = run->tdx.get_quote.gpa; ++ uint64_t buf_len = run->tdx.get_quote.size; ++ ++ QEMU_BUILD_BUG_ON(sizeof(struct tdx_get_quote_header) != TDX_GET_QUOTE_HDR_SIZE); ++ ++ run->tdx.get_quote.ret = TDG_VP_VMCALL_INVALID_OPERAND; ++ ++ if (buf_len == 0) { ++ return; ++ } ++ ++ if (!QEMU_IS_ALIGNED(buf_gpa, 4096) || !QEMU_IS_ALIGNED(buf_len, 4096)) { ++ run->tdx.get_quote.ret = TDG_VP_VMCALL_ALIGN_ERROR; ++ return; ++ } ++ ++ if (address_space_read(&address_space_memory, buf_gpa, MEMTXATTRS_UNSPECIFIED, ++ &hdr, TDX_GET_QUOTE_HDR_SIZE) != MEMTX_OK) { ++ error_report("TDX: get-quote: failed to read GetQuote header."); ++ return; ++ } ++ ++ if (le64_to_cpu(hdr.structure_version) != TDX_GET_QUOTE_STRUCTURE_VERSION) { ++ return; ++ } ++ ++ /* Only safe-guard check to avoid too large buffer size. */ ++ if (buf_len > TDX_GET_QUOTE_MAX_BUF_LEN || ++ le32_to_cpu(hdr.in_len) > buf_len - TDX_GET_QUOTE_HDR_SIZE) { ++ return; ++ } ++ ++ if (!tdx_guest->qg_sock_addr) { ++ hdr.error_code = cpu_to_le64(TDX_VP_GET_QUOTE_QGS_UNAVAILABLE); ++ if (address_space_write(&address_space_memory, buf_gpa, ++ MEMTXATTRS_UNSPECIFIED, ++ &hdr, TDX_GET_QUOTE_HDR_SIZE) != MEMTX_OK) { ++ error_report("TDX: failed to update GetQuote header."); ++ return; ++ } ++ run->tdx.get_quote.ret = TDG_VP_VMCALL_SUCCESS; ++ return; ++ } ++ ++ qemu_mutex_lock(&tdx_guest->lock); ++ if (tdx_guest->num >= TDX_MAX_GET_QUOTE_REQUEST) { ++ qemu_mutex_unlock(&tdx_guest->lock); ++ run->tdx.get_quote.ret = TDG_VP_VMCALL_RETRY; ++ return; ++ } ++ tdx_guest->num++; ++ qemu_mutex_unlock(&tdx_guest->lock); ++ ++ task = g_new(TdxGenerateQuoteTask, 1); ++ task->buf_gpa = buf_gpa; ++ task->payload_gpa = buf_gpa + TDX_GET_QUOTE_HDR_SIZE; ++ task->payload_len = buf_len - TDX_GET_QUOTE_HDR_SIZE; ++ task->hdr = hdr; ++ task->completion = tdx_get_quote_completion; ++ ++ task->send_data_size = le32_to_cpu(hdr.in_len); ++ task->send_data = g_malloc(task->send_data_size); ++ task->send_data_sent = 0; ++ ++ if (address_space_read(&address_space_memory, task->payload_gpa, ++ MEMTXATTRS_UNSPECIFIED, task->send_data, ++ task->send_data_size) != MEMTX_OK) { ++ goto out_free; ++ } ++ ++ /* Mark the buffer in-flight. */ ++ hdr.error_code = cpu_to_le64(TDX_VP_GET_QUOTE_IN_FLIGHT); ++ if (address_space_write(&address_space_memory, buf_gpa, ++ MEMTXATTRS_UNSPECIFIED, ++ &hdr, TDX_GET_QUOTE_HDR_SIZE) != MEMTX_OK) { ++ goto out_free; ++ } ++ ++ task->receive_buf = g_malloc0(task->payload_len); ++ task->receive_buf_received = 0; ++ task->opaque = tdx_guest; ++ ++ object_ref(tdx_guest); ++ tdx_generate_quote(task, tdx_guest->qg_sock_addr); ++ run->tdx.get_quote.ret = TDG_VP_VMCALL_SUCCESS; ++ return; ++ ++out_free: ++ g_free(task->send_data); ++ g_free(task); ++} ++ + void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run) + { + if (run->tdx.get_tdvmcall_info.leaf != 1) { + return; + } + +- run->tdx.get_tdvmcall_info.r11 = 0; ++ run->tdx.get_tdvmcall_info.r11 = TDG_VP_VMCALL_SUBFUNC_GET_QUOTE; + run->tdx.get_tdvmcall_info.r12 = 0; + run->tdx.get_tdvmcall_info.r13 = 0; + run->tdx.get_tdvmcall_info.r14 = 0; +@@ -1263,6 +1399,37 @@ static void tdx_guest_set_mrownerconfig(Object *obj, const char *value, Error ** + tdx->mrownerconfig = g_strdup(value); + } + ++static void tdx_guest_get_qgs(Object *obj, Visitor *v, ++ const char *name, void *opaque, ++ Error **errp) ++{ ++ TdxGuest *tdx = TDX_GUEST(obj); ++ ++ if (!tdx->qg_sock_addr) { ++ error_setg(errp, "quote-generation-socket is not set"); ++ return; ++ } ++ visit_type_SocketAddress(v, name, &tdx->qg_sock_addr, errp); ++} ++ ++static void tdx_guest_set_qgs(Object *obj, Visitor *v, ++ const char *name, void *opaque, ++ Error **errp) ++{ ++ TdxGuest *tdx = TDX_GUEST(obj); ++ SocketAddress *sock = NULL; ++ ++ if (!visit_type_SocketAddress(v, name, &sock, errp)) { ++ return; ++ } ++ ++ if (tdx->qg_sock_addr) { ++ qapi_free_SocketAddress(tdx->qg_sock_addr); ++ } ++ ++ tdx->qg_sock_addr = sock; ++} ++ + /* tdx guest */ + OBJECT_DEFINE_TYPE_WITH_INTERFACES(TdxGuest, + tdx_guest, +@@ -1294,6 +1461,13 @@ static void tdx_guest_init(Object *obj) + object_property_add_str(obj, "mrownerconfig", + tdx_guest_get_mrownerconfig, + tdx_guest_set_mrownerconfig); ++ ++ object_property_add(obj, "quote-generation-socket", "SocketAddress", ++ tdx_guest_get_qgs, ++ tdx_guest_set_qgs, ++ NULL, NULL); ++ ++ qemu_mutex_init(&tdx->lock); + } + + static void tdx_guest_finalize(Object *obj) +diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h +index 0dd41d5811..35a09c19c5 100644 +--- a/target/i386/kvm/tdx.h ++++ b/target/i386/kvm/tdx.h +@@ -11,6 +11,8 @@ + #include "cpu.h" + #include "hw/i386/tdvf.h" + ++#include "tdx-quote-generator.h" ++ + #define TYPE_TDX_GUEST "tdx-guest" + #define TDX_GUEST(obj) OBJECT_CHECK(TdxGuest, (obj), TYPE_TDX_GUEST) + +@@ -22,6 +24,7 @@ typedef struct TdxGuestClass { + #define TDX_APIC_BUS_CYCLES_NS 40 + + #define TDVMCALL_GET_TD_VM_CALL_INFO 0x10000 ++#define TDVMCALL_GET_QUOTE 0x10002 + + #define TDG_VP_VMCALL_SUCCESS 0x0000000000000000ULL + #define TDG_VP_VMCALL_RETRY 0x0000000000000001ULL +@@ -29,6 +32,8 @@ typedef struct TdxGuestClass { + #define TDG_VP_VMCALL_GPA_INUSE 0x8000000000000001ULL + #define TDG_VP_VMCALL_ALIGN_ERROR 0x8000000000000002ULL + ++#define TDG_VP_VMCALL_SUBFUNC_GET_QUOTE 0x0000000000000001ULL ++ + enum TdxRamType { + TDX_RAM_UNACCEPTED, + TDX_RAM_ADDED, +@@ -57,6 +62,10 @@ typedef struct TdxGuest { + + uint32_t nr_ram_entries; + TdxRamEntry *ram_entries; ++ ++ /* GetQuote */ ++ SocketAddress *qg_sock_addr; ++ int num; + } TdxGuest; + + #ifdef CONFIG_TDX +@@ -69,6 +78,7 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp); + void tdx_set_tdvf_region(MemoryRegion *tdvf_mr); + int tdx_parse_tdvf(void *flash_ptr, int size); + int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm_run *run); ++void tdx_handle_get_quote(X86CPU *cpu, struct kvm_run *run); + void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run); + + #endif /* QEMU_I386_TDX_H */ +-- +2.47.3 + diff --git a/kvm-i386-tdx-handle-TDG.VP.VMCALL-GetTdVmCallInfo.patch b/kvm-i386-tdx-handle-TDG.VP.VMCALL-GetTdVmCallInfo.patch new file mode 100644 index 0000000..ce1ad62 --- /dev/null +++ b/kvm-i386-tdx-handle-TDG.VP.VMCALL-GetTdVmCallInfo.patch @@ -0,0 +1,103 @@ +From 1223d719fce41a56464e685c1603343dce09cb84 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:49 +0200 +Subject: [PATCH 077/100] i386/tdx: handle TDG.VP.VMCALL + +Signed-off-by: Binbin Wu +Signed-off-by: Paolo Bonzini +(cherry picked from commit 427b8cf47a6959cd8b0db12bcf66e9009afa2c07) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/kvm.c | 12 ++++++++++++ + target/i386/kvm/tdx-stub.c | 4 ++++ + target/i386/kvm/tdx.c | 12 ++++++++++++ + target/i386/kvm/tdx.h | 9 +++++++++ + 4 files changed, 37 insertions(+) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 6eddb3d58e..8f83a29b5b 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -6152,6 +6152,18 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) + break; + } + break; ++ case KVM_EXIT_TDX: ++ /* ++ * run->tdx is already set up for the case where userspace ++ * does not handle the TDVMCALL. ++ */ ++ switch (run->tdx.nr) { ++ case TDVMCALL_GET_TD_VM_CALL_INFO: ++ tdx_handle_get_tdvmcall_info(cpu, run); ++ break; ++ } ++ ret = 0; ++ break; + default: + fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason); + ret = -1; +diff --git a/target/i386/kvm/tdx-stub.c b/target/i386/kvm/tdx-stub.c +index 720a4ff046..62a12a0677 100644 +--- a/target/i386/kvm/tdx-stub.c ++++ b/target/i386/kvm/tdx-stub.c +@@ -18,3 +18,7 @@ int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm_run *run) + { + return -EINVAL; + } ++ ++void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run) ++{ ++} +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index f5050fc7bc..6d1a9c111c 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -1120,6 +1120,18 @@ int tdx_parse_tdvf(void *flash_ptr, int size) + return tdvf_parse_metadata(&tdx_guest->tdvf, flash_ptr, size); + } + ++void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run) ++{ ++ if (run->tdx.get_tdvmcall_info.leaf != 1) { ++ return; ++ } ++ ++ run->tdx.get_tdvmcall_info.r11 = 0; ++ run->tdx.get_tdvmcall_info.r12 = 0; ++ run->tdx.get_tdvmcall_info.r13 = 0; ++ run->tdx.get_tdvmcall_info.r14 = 0; ++} ++ + static void tdx_panicked_on_fatal_error(X86CPU *cpu, uint64_t error_code, + char *message, uint64_t gpa) + { +diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h +index 8dd66e9014..0dd41d5811 100644 +--- a/target/i386/kvm/tdx.h ++++ b/target/i386/kvm/tdx.h +@@ -21,6 +21,14 @@ typedef struct TdxGuestClass { + /* TDX requires bus frequency 25MHz */ + #define TDX_APIC_BUS_CYCLES_NS 40 + ++#define TDVMCALL_GET_TD_VM_CALL_INFO 0x10000 ++ ++#define TDG_VP_VMCALL_SUCCESS 0x0000000000000000ULL ++#define TDG_VP_VMCALL_RETRY 0x0000000000000001ULL ++#define TDG_VP_VMCALL_INVALID_OPERAND 0x8000000000000000ULL ++#define TDG_VP_VMCALL_GPA_INUSE 0x8000000000000001ULL ++#define TDG_VP_VMCALL_ALIGN_ERROR 0x8000000000000002ULL ++ + enum TdxRamType { + TDX_RAM_UNACCEPTED, + TDX_RAM_ADDED, +@@ -61,5 +69,6 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp); + void tdx_set_tdvf_region(MemoryRegion *tdvf_mr); + int tdx_parse_tdvf(void *flash_ptr, int size); + int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm_run *run); ++void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run); + + #endif /* QEMU_I386_TDX_H */ +-- +2.47.3 + diff --git a/kvm-i386-tdx-handle-TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUP.patch b/kvm-i386-tdx-handle-TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUP.patch new file mode 100644 index 0000000..17b311d --- /dev/null +++ b/kvm-i386-tdx-handle-TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUP.patch @@ -0,0 +1,189 @@ +From 4e1337f2c2162ff95430a7278dc033bc0d3778ab Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:50 +0200 +Subject: [PATCH 086/100] i386/tdx: handle + TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT + +Record the interrupt vector and the apic id of the vcpu that calls +TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT. + +Inject the interrupt to TD guest to notify the completion of +when notify interrupt vector is valid. + +Signed-off-by: Xiaoyao Li +Link: https://lore.kernel.org/r/20250703024021.3559286-5-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit efa742b23eff2a799c196d756bd506fe74e96fdc) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/kvm.c | 3 +++ + target/i386/kvm/tdx-stub.c | 4 ++++ + target/i386/kvm/tdx.c | 48 +++++++++++++++++++++++++++++++++++++- + target/i386/kvm/tdx.h | 7 ++++++ + 4 files changed, 61 insertions(+), 1 deletion(-) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 700b805cca..fe077814e7 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -6164,6 +6164,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) + case TDVMCALL_GET_TD_VM_CALL_INFO: + tdx_handle_get_tdvmcall_info(cpu, run); + break; ++ case TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT: ++ tdx_handle_setup_event_notify_interrupt(cpu, run); ++ break; + } + ret = 0; + break; +diff --git a/target/i386/kvm/tdx-stub.c b/target/i386/kvm/tdx-stub.c +index 76fee49eff..1f0e108a69 100644 +--- a/target/i386/kvm/tdx-stub.c ++++ b/target/i386/kvm/tdx-stub.c +@@ -26,3 +26,7 @@ void tdx_handle_get_quote(X86CPU *cpu, struct kvm_run *run) + void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run) + { + } ++ ++void tdx_handle_setup_event_notify_interrupt(X86CPU *cpu, struct kvm_run *run) ++{ ++} +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 7748474322..416dd41ab8 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -28,10 +28,13 @@ + #include "cpu.h" + #include "cpu-internal.h" + #include "host-cpu.h" ++#include "hw/i386/apic_internal.h" ++#include "hw/i386/apic-msidef.h" + #include "hw/i386/e820_memory_layout.h" + #include "hw/i386/tdvf.h" + #include "hw/i386/x86.h" + #include "hw/i386/tdvf-hob.h" ++#include "hw/pci/msi.h" + #include "kvm_i386.h" + #include "tdx.h" + #include "tdx-quote-generator.h" +@@ -1123,6 +1126,28 @@ int tdx_parse_tdvf(void *flash_ptr, int size) + return tdvf_parse_metadata(&tdx_guest->tdvf, flash_ptr, size); + } + ++static void tdx_inject_interrupt(uint32_t apicid, uint32_t vector) ++{ ++ int ret; ++ ++ if (vector < 32 || vector > 255) { ++ return; ++ } ++ ++ MSIMessage msg = { ++ .address = ((apicid & 0xff) << MSI_ADDR_DEST_ID_SHIFT) | ++ (((uint64_t)apicid & 0xffffff00) << 32), ++ .data = vector | (APIC_DM_FIXED << MSI_DATA_DELIVERY_MODE_SHIFT), ++ }; ++ ++ ret = kvm_irqchip_send_msi(kvm_state, msg); ++ if (ret < 0) { ++ /* In this case, no better way to tell it to guest. Log it. */ ++ error_report("TDX: injection interrupt %d failed, interrupt lost (%s).", ++ vector, strerror(-ret)); ++ } ++} ++ + static void tdx_get_quote_completion(TdxGenerateQuoteTask *task) + { + TdxGuest *tdx = task->opaque; +@@ -1154,6 +1179,9 @@ static void tdx_get_quote_completion(TdxGenerateQuoteTask *task) + error_report("TDX: get-quote: failed to update GetQuote header."); + } + ++ tdx_inject_interrupt(tdx_guest->event_notify_apicid, ++ tdx_guest->event_notify_vector); ++ + g_free(task->send_data); + g_free(task->receive_buf); + g_free(task); +@@ -1256,7 +1284,7 @@ out_free: + g_free(task); + } + +-#define SUPPORTED_TDVMCALLINFO_1_R11 (0) ++#define SUPPORTED_TDVMCALLINFO_1_R11 (TDG_VP_VMCALL_SUBFUNC_SET_EVENT_NOTIFY_INTERRUPT) + #define SUPPORTED_TDVMCALLINFO_1_R12 (0) + + void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run) +@@ -1277,6 +1305,21 @@ void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run) + run->tdx.get_tdvmcall_info.ret = TDG_VP_VMCALL_SUCCESS; + } + ++void tdx_handle_setup_event_notify_interrupt(X86CPU *cpu, struct kvm_run *run) ++{ ++ uint64_t vector = run->tdx.setup_event_notify.vector; ++ ++ if (vector >= 32 && vector < 256) { ++ qemu_mutex_lock(&tdx_guest->lock); ++ tdx_guest->event_notify_vector = vector; ++ tdx_guest->event_notify_apicid = cpu->apic_id; ++ qemu_mutex_unlock(&tdx_guest->lock); ++ run->tdx.setup_event_notify.ret = TDG_VP_VMCALL_SUCCESS; ++ } else { ++ run->tdx.setup_event_notify.ret = TDG_VP_VMCALL_INVALID_OPERAND; ++ } ++} ++ + static void tdx_panicked_on_fatal_error(X86CPU *cpu, uint64_t error_code, + char *message, uint64_t gpa) + { +@@ -1477,6 +1520,9 @@ static void tdx_guest_init(Object *obj) + NULL, NULL); + + qemu_mutex_init(&tdx->lock); ++ ++ tdx->event_notify_vector = -1; ++ tdx->event_notify_apicid = -1; + } + + static void tdx_guest_finalize(Object *obj) +diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h +index d439078a87..1c38faf983 100644 +--- a/target/i386/kvm/tdx.h ++++ b/target/i386/kvm/tdx.h +@@ -25,6 +25,7 @@ typedef struct TdxGuestClass { + + #define TDVMCALL_GET_TD_VM_CALL_INFO 0x10000 + #define TDVMCALL_GET_QUOTE 0x10002 ++#define TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT 0x10004 + + #define TDG_VP_VMCALL_SUCCESS 0x0000000000000000ULL + #define TDG_VP_VMCALL_RETRY 0x0000000000000001ULL +@@ -32,6 +33,8 @@ typedef struct TdxGuestClass { + #define TDG_VP_VMCALL_GPA_INUSE 0x8000000000000001ULL + #define TDG_VP_VMCALL_ALIGN_ERROR 0x8000000000000002ULL + ++#define TDG_VP_VMCALL_SUBFUNC_SET_EVENT_NOTIFY_INTERRUPT BIT_ULL(1) ++ + enum TdxRamType { + TDX_RAM_UNACCEPTED, + TDX_RAM_ADDED, +@@ -64,6 +67,9 @@ typedef struct TdxGuest { + /* GetQuote */ + SocketAddress *qg_sock_addr; + int num; ++ ++ uint32_t event_notify_vector; ++ uint32_t event_notify_apicid; + } TdxGuest; + + #ifdef CONFIG_TDX +@@ -78,5 +84,6 @@ int tdx_parse_tdvf(void *flash_ptr, int size); + int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm_run *run); + void tdx_handle_get_quote(X86CPU *cpu, struct kvm_run *run); + void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run); ++void tdx_handle_setup_event_notify_interrupt(X86CPU *cpu, struct kvm_run *run); + + #endif /* QEMU_I386_TDX_H */ +-- +2.47.3 + diff --git a/kvm-i386-tdx-implement-tdx_cpu_instance_init.patch b/kvm-i386-tdx-implement-tdx_cpu_instance_init.patch new file mode 100644 index 0000000..a9e1ad8 --- /dev/null +++ b/kvm-i386-tdx-implement-tdx_cpu_instance_init.patch @@ -0,0 +1,42 @@ +From 2248e2f7e980b4fb2e4b38a7dce72088b3c00619 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:47 +0200 +Subject: [PATCH 046/100] i386/tdx: implement tdx_cpu_instance_init() + +Currently, pmu is not supported for TDX by KVM. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-33-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 7c615242671dbe65e198c20889dcaa9b4b9a1624) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 3b71b52c00..0c9a895a2f 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -398,6 +398,11 @@ static int tdx_kvm_type(X86ConfidentialGuest *cg) + return KVM_X86_TDX_VM; + } + ++static void tdx_cpu_instance_init(X86ConfidentialGuest *cg, CPUState *cpu) ++{ ++ object_property_set_bool(OBJECT(cpu), "pmu", false, &error_abort); ++} ++ + static int tdx_validate_attributes(TdxGuest *tdx, Error **errp) + { + if ((tdx->attributes & ~tdx_caps->supported_attrs)) { +@@ -791,4 +796,5 @@ static void tdx_guest_class_init(ObjectClass *oc, void *data) + + klass->kvm_init = tdx_kvm_init; + x86_klass->kvm_type = tdx_kvm_type; ++ x86_klass->cpu_instance_init = tdx_cpu_instance_init; + } +-- +2.47.3 + diff --git a/kvm-i386-tdx-load-TDVF-for-TD-guest.patch b/kvm-i386-tdx-load-TDVF-for-TD-guest.patch new file mode 100644 index 0000000..034e526 --- /dev/null +++ b/kvm-i386-tdx-load-TDVF-for-TD-guest.patch @@ -0,0 +1,97 @@ +From d1d79277d9bf5042aec7640ded7756eb863d99f1 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:46 +0200 +Subject: [PATCH 030/100] i386/tdx: load TDVF for TD guest + +TDVF(OVMF) needs to run at private memory for TD guest. TDX cannot +support pflash device since it doesn't support read-only private memory. +Thus load TDVF(OVMF) with -bios option for TDs. + +Use memory_region_init_ram_guest_memfd() to allocate the MemoryRegion +for TDVF because it needs to be located at private memory. + +Also store the MemoryRegion pointer of TDVF since the shared ramblock of +it can be discared after it gets copied to private ramblock. + +Signed-off-by: Chao Peng +Co-developed-by: Xiaoyao Li +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-17-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 0dd5fe5ebeabefc7b3d7f043991b1edfe6b8eda9) +Signed-off-by: Paolo Bonzini +--- + hw/i386/x86-common.c | 6 +++++- + target/i386/kvm/tdx.c | 6 ++++++ + target/i386/kvm/tdx.h | 3 +++ + 3 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c +index 1b0671c523..b1b5f11e73 100644 +--- a/hw/i386/x86-common.c ++++ b/hw/i386/x86-common.c +@@ -44,6 +44,7 @@ + #include "standard-headers/asm-x86/bootparam.h" + #include CONFIG_DEVICES + #include "kvm/kvm_i386.h" ++#include "kvm/tdx.h" + + #ifdef CONFIG_XEN_EMU + #include "hw/xen/xen.h" +@@ -1035,11 +1036,14 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, + if (machine_require_guest_memfd(MACHINE(x86ms))) { + memory_region_init_ram_guest_memfd(&x86ms->bios, NULL, "pc.bios", + bios_size, &error_fatal); ++ if (is_tdx_vm()) { ++ tdx_set_tdvf_region(&x86ms->bios); ++ } + } else { + memory_region_init_ram(&x86ms->bios, NULL, "pc.bios", + bios_size, &error_fatal); + } +- if (sev_enabled()) { ++ if (sev_enabled() || is_tdx_vm()) { + /* + * The concept of a "reset" simply doesn't exist for + * confidential computing guests, we have to destroy and +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index 56ad5f599d..2522f2030d 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -137,6 +137,12 @@ static int get_tdx_capabilities(Error **errp) + return 0; + } + ++void tdx_set_tdvf_region(MemoryRegion *tdvf_mr) ++{ ++ assert(!tdx_guest->tdvf_mr); ++ tdx_guest->tdvf_mr = tdvf_mr; ++} ++ + static int tdx_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + { + TdxGuest *tdx = TDX_GUEST(cgs); +diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h +index d39e733d9f..b73461b8d8 100644 +--- a/target/i386/kvm/tdx.h ++++ b/target/i386/kvm/tdx.h +@@ -30,6 +30,8 @@ typedef struct TdxGuest { + char *mrconfigid; /* base64 encoded sha348 digest */ + char *mrowner; /* base64 encoded sha348 digest */ + char *mrownerconfig; /* base64 encoded sha348 digest */ ++ ++ MemoryRegion *tdvf_mr; + } TdxGuest; + + #ifdef CONFIG_TDX +@@ -39,5 +41,6 @@ bool is_tdx_vm(void); + #endif /* CONFIG_TDX */ + + int tdx_pre_create_vcpu(CPUState *cpu, Error **errp); ++void tdx_set_tdvf_region(MemoryRegion *tdvf_mr); + + #endif /* QEMU_I386_TDX_H */ +-- +2.47.3 + diff --git a/kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch b/kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch deleted file mode 100644 index da7e469..0000000 --- a/kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch +++ /dev/null @@ -1,402 +0,0 @@ -From cd805347076eb3d977ad0779d98a019f5abfaa74 Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:47 -0400 -Subject: [PATCH 15/38] include/hw/s390x: Add include files for common IPL - structs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [14/23] 54bcccfb27e230494b492eede1e074732b4efc17 (thuth/qemu-kvm-cs9) - -Currently, structures defined in both hw/s390x/ipl.h and pc-bios/s390-ccw/iplb.h -must be kept in sync, which is prone to error. Instead, create a new directory -at include/hw/s390x/ipl/ to contain the definitions that must be shared. - -Signed-off-by: Jared Rossi -Reviewed-by: Thomas Huth -Message-ID: <20241020012953.1380075-14-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit ba3658adc80a9370257a9c4e114829ec691311e3) ---- - hw/s390x/ipl.h | 104 +----------------------------- - include/hw/s390x/ipl/qipl.h | 123 ++++++++++++++++++++++++++++++++++++ - pc-bios/s390-ccw/Makefile | 2 +- - pc-bios/s390-ccw/iplb.h | 84 ++---------------------- - 4 files changed, 130 insertions(+), 183 deletions(-) - create mode 100644 include/hw/s390x/ipl/qipl.h - -diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h -index b2105b616a..fa394c339d 100644 ---- a/hw/s390x/ipl.h -+++ b/hw/s390x/ipl.h -@@ -16,95 +16,11 @@ - #include "cpu.h" - #include "exec/address-spaces.h" - #include "hw/qdev-core.h" -+#include "hw/s390x/ipl/qipl.h" - #include "qom/object.h" - --struct IPLBlockPVComp { -- uint64_t tweak_pref; -- uint64_t addr; -- uint64_t size; --} QEMU_PACKED; --typedef struct IPLBlockPVComp IPLBlockPVComp; -- --struct IPLBlockPV { -- uint8_t reserved18[87]; /* 0x18 */ -- uint8_t version; /* 0x6f */ -- uint32_t reserved70; /* 0x70 */ -- uint32_t num_comp; /* 0x74 */ -- uint64_t pv_header_addr; /* 0x78 */ -- uint64_t pv_header_len; /* 0x80 */ -- struct IPLBlockPVComp components[0]; --} QEMU_PACKED; --typedef struct IPLBlockPV IPLBlockPV; -- --struct IplBlockCcw { -- uint8_t reserved0[85]; -- uint8_t ssid; -- uint16_t devno; -- uint8_t vm_flags; -- uint8_t reserved3[3]; -- uint32_t vm_parm_len; -- uint8_t nss_name[8]; -- uint8_t vm_parm[64]; -- uint8_t reserved4[8]; --} QEMU_PACKED; --typedef struct IplBlockCcw IplBlockCcw; -- --struct IplBlockFcp { -- uint8_t reserved1[305 - 1]; -- uint8_t opt; -- uint8_t reserved2[3]; -- uint16_t reserved3; -- uint16_t devno; -- uint8_t reserved4[4]; -- uint64_t wwpn; -- uint64_t lun; -- uint32_t bootprog; -- uint8_t reserved5[12]; -- uint64_t br_lba; -- uint32_t scp_data_len; -- uint8_t reserved6[260]; -- uint8_t scp_data[0]; --} QEMU_PACKED; --typedef struct IplBlockFcp IplBlockFcp; -- --struct IplBlockQemuScsi { -- uint32_t lun; -- uint16_t target; -- uint16_t channel; -- uint8_t reserved0[77]; -- uint8_t ssid; -- uint16_t devno; --} QEMU_PACKED; --typedef struct IplBlockQemuScsi IplBlockQemuScsi; -- - #define DIAG308_FLAGS_LP_VALID 0x80 - --union IplParameterBlock { -- struct { -- uint32_t len; -- uint8_t reserved0[3]; -- uint8_t version; -- uint32_t blk0_len; -- uint8_t pbt; -- uint8_t flags; -- uint16_t reserved01; -- uint8_t loadparm[8]; -- union { -- IplBlockCcw ccw; -- IplBlockFcp fcp; -- IPLBlockPV pv; -- IplBlockQemuScsi scsi; -- }; -- } QEMU_PACKED; -- struct { -- uint8_t reserved1[110]; -- uint16_t devno; -- uint8_t reserved2[88]; -- uint8_t reserved_ext[4096 - 200]; -- } QEMU_PACKED; --} QEMU_PACKED; --typedef union IplParameterBlock IplParameterBlock; -- - int s390_ipl_set_loadparm(uint8_t *loadparm); - void s390_ipl_update_diag308(IplParameterBlock *iplb); - int s390_ipl_prepare_pv_header(Error **errp); -@@ -131,24 +47,6 @@ void s390_ipl_clear_reset_request(void); - #define QIPL_FLAG_BM_OPTS_CMD 0x80 - #define QIPL_FLAG_BM_OPTS_ZIPL 0x40 - --/* -- * The QEMU IPL Parameters will be stored at absolute address -- * 204 (0xcc) which means it is 32-bit word aligned but not -- * double-word aligned. Placement of 64-bit data fields in this -- * area must account for their alignment needs. -- * The total size of the struct must never exceed 28 bytes. -- * This definition must be kept in sync with the definition -- * in pc-bios/s390-ccw/iplb.h. -- */ --struct QemuIplParameters { -- uint8_t qipl_flags; -- uint8_t reserved1[3]; -- uint64_t reserved2; -- uint32_t boot_menu_timeout; -- uint8_t reserved3[12]; --} QEMU_PACKED; --typedef struct QemuIplParameters QemuIplParameters; -- - #define TYPE_S390_IPL "s390-ipl" - OBJECT_DECLARE_SIMPLE_TYPE(S390IPLState, S390_IPL) - -diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h -new file mode 100644 -index 0000000000..0ef04af027 ---- /dev/null -+++ b/include/hw/s390x/ipl/qipl.h -@@ -0,0 +1,123 @@ -+/* -+ * S/390 boot structures -+ * -+ * Copyright 2024 IBM Corp. -+ * Author(s): Jared Rossi -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or (at -+ * your option) any later version. See the COPYING file in the top-level -+ * directory. -+ */ -+ -+#ifndef S390X_QIPL_H -+#define S390X_QIPL_H -+ -+/* Boot Menu flags */ -+#define QIPL_FLAG_BM_OPTS_CMD 0x80 -+#define QIPL_FLAG_BM_OPTS_ZIPL 0x40 -+ -+#define QIPL_ADDRESS 0xcc -+#define LOADPARM_LEN 8 -+ -+/* -+ * The QEMU IPL Parameters will be stored at absolute address -+ * 204 (0xcc) which means it is 32-bit word aligned but not -+ * double-word aligned. Placement of 64-bit data fields in this -+ * area must account for their alignment needs. -+ * The total size of the struct must never exceed 28 bytes. -+ */ -+struct QemuIplParameters { -+ uint8_t qipl_flags; -+ uint8_t reserved1[3]; -+ uint64_t reserved2; -+ uint32_t boot_menu_timeout; -+ uint8_t reserved3[12]; -+} QEMU_PACKED; -+typedef struct QemuIplParameters QemuIplParameters; -+ -+struct IPLBlockPVComp { -+ uint64_t tweak_pref; -+ uint64_t addr; -+ uint64_t size; -+} QEMU_PACKED; -+typedef struct IPLBlockPVComp IPLBlockPVComp; -+ -+struct IPLBlockPV { -+ uint8_t reserved18[87]; /* 0x18 */ -+ uint8_t version; /* 0x6f */ -+ uint32_t reserved70; /* 0x70 */ -+ uint32_t num_comp; /* 0x74 */ -+ uint64_t pv_header_addr; /* 0x78 */ -+ uint64_t pv_header_len; /* 0x80 */ -+ struct IPLBlockPVComp components[0]; -+} QEMU_PACKED; -+typedef struct IPLBlockPV IPLBlockPV; -+ -+struct IplBlockCcw { -+ uint8_t reserved0[85]; -+ uint8_t ssid; -+ uint16_t devno; -+ uint8_t vm_flags; -+ uint8_t reserved3[3]; -+ uint32_t vm_parm_len; -+ uint8_t nss_name[8]; -+ uint8_t vm_parm[64]; -+ uint8_t reserved4[8]; -+} QEMU_PACKED; -+typedef struct IplBlockCcw IplBlockCcw; -+ -+struct IplBlockFcp { -+ uint8_t reserved1[305 - 1]; -+ uint8_t opt; -+ uint8_t reserved2[3]; -+ uint16_t reserved3; -+ uint16_t devno; -+ uint8_t reserved4[4]; -+ uint64_t wwpn; -+ uint64_t lun; -+ uint32_t bootprog; -+ uint8_t reserved5[12]; -+ uint64_t br_lba; -+ uint32_t scp_data_len; -+ uint8_t reserved6[260]; -+ uint8_t scp_data[0]; -+} QEMU_PACKED; -+typedef struct IplBlockFcp IplBlockFcp; -+ -+struct IplBlockQemuScsi { -+ uint32_t lun; -+ uint16_t target; -+ uint16_t channel; -+ uint8_t reserved0[77]; -+ uint8_t ssid; -+ uint16_t devno; -+} QEMU_PACKED; -+typedef struct IplBlockQemuScsi IplBlockQemuScsi; -+ -+union IplParameterBlock { -+ struct { -+ uint32_t len; -+ uint8_t reserved0[3]; -+ uint8_t version; -+ uint32_t blk0_len; -+ uint8_t pbt; -+ uint8_t flags; -+ uint16_t reserved01; -+ uint8_t loadparm[LOADPARM_LEN]; -+ union { -+ IplBlockCcw ccw; -+ IplBlockFcp fcp; -+ IPLBlockPV pv; -+ IplBlockQemuScsi scsi; -+ }; -+ } QEMU_PACKED; -+ struct { -+ uint8_t reserved1[110]; -+ uint16_t devno; -+ uint8_t reserved2[88]; -+ uint8_t reserved_ext[4096 - 200]; -+ } QEMU_PACKED; -+} QEMU_PACKED; -+typedef union IplParameterBlock IplParameterBlock; -+ -+#endif -diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile -index 27cbb354af..db9e8f0892 100644 ---- a/pc-bios/s390-ccw/Makefile -+++ b/pc-bios/s390-ccw/Makefile -@@ -3,7 +3,7 @@ all: build-all - @true - - include config-host.mak --CFLAGS = -O2 -g -+CFLAGS = -O2 -g -I $(SRC_PATH)/../../include/hw/s390x/ipl - MAKEFLAGS += -rR - - GIT_SUBMODULES = roms/SLOF -diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h -index 3758698468..16643f5879 100644 ---- a/pc-bios/s390-ccw/iplb.h -+++ b/pc-bios/s390-ccw/iplb.h -@@ -12,88 +12,14 @@ - #ifndef IPLB_H - #define IPLB_H - --#define LOADPARM_LEN 8 -+#ifndef QEMU_PACKED -+#define QEMU_PACKED __attribute__((packed)) -+#endif - --struct IplBlockCcw { -- uint8_t reserved0[85]; -- uint8_t ssid; -- uint16_t devno; -- uint8_t vm_flags; -- uint8_t reserved3[3]; -- uint32_t vm_parm_len; -- uint8_t nss_name[8]; -- uint8_t vm_parm[64]; -- uint8_t reserved4[8]; --} __attribute__ ((packed)); --typedef struct IplBlockCcw IplBlockCcw; -- --struct IplBlockFcp { -- uint8_t reserved1[305 - 1]; -- uint8_t opt; -- uint8_t reserved2[3]; -- uint16_t reserved3; -- uint16_t devno; -- uint8_t reserved4[4]; -- uint64_t wwpn; -- uint64_t lun; -- uint32_t bootprog; -- uint8_t reserved5[12]; -- uint64_t br_lba; -- uint32_t scp_data_len; -- uint8_t reserved6[260]; -- uint8_t scp_data[]; --} __attribute__ ((packed)); --typedef struct IplBlockFcp IplBlockFcp; -- --struct IplBlockQemuScsi { -- uint32_t lun; -- uint16_t target; -- uint16_t channel; -- uint8_t reserved0[77]; -- uint8_t ssid; -- uint16_t devno; --} __attribute__ ((packed)); --typedef struct IplBlockQemuScsi IplBlockQemuScsi; -- --struct IplParameterBlock { -- uint32_t len; -- uint8_t reserved0[3]; -- uint8_t version; -- uint32_t blk0_len; -- uint8_t pbt; -- uint8_t flags; -- uint16_t reserved01; -- uint8_t loadparm[LOADPARM_LEN]; -- union { -- IplBlockCcw ccw; -- IplBlockFcp fcp; -- IplBlockQemuScsi scsi; -- }; --} __attribute__ ((packed)); --typedef struct IplParameterBlock IplParameterBlock; -- --extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); -- --#define QIPL_ADDRESS 0xcc -- --/* Boot Menu flags */ --#define QIPL_FLAG_BM_OPTS_CMD 0x80 --#define QIPL_FLAG_BM_OPTS_ZIPL 0x40 -- --/* -- * This definition must be kept in sync with the definition -- * in hw/s390x/ipl.h -- */ --struct QemuIplParameters { -- uint8_t qipl_flags; -- uint8_t reserved1[3]; -- uint64_t reserved2; -- uint32_t boot_menu_timeout; -- uint8_t reserved3[12]; --} __attribute__ ((packed)); --typedef struct QemuIplParameters QemuIplParameters; -+#include - - extern QemuIplParameters qipl; -+extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); - - #define S390_IPL_TYPE_FCP 0x00 - #define S390_IPL_TYPE_CCW 0x02 --- -2.39.3 - diff --git a/kvm-include-qemu-compiler-add-QEMU_UNINITIALIZED-attribu.patch b/kvm-include-qemu-compiler-add-QEMU_UNINITIALIZED-attribu.patch index 4400d1a..c5d1e4f 100644 --- a/kvm-include-qemu-compiler-add-QEMU_UNINITIALIZED-attribu.patch +++ b/kvm-include-qemu-compiler-add-QEMU_UNINITIALIZED-attribu.patch @@ -1,17 +1,17 @@ -From cc996b6418e421da1d04f6c4c91984c066a54db4 Mon Sep 17 00:00:00 2001 +From 0aea786f8ab4f7a4122bb2019ebe5136763c9609 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Tue, 10 Jun 2025 13:36:39 +0100 -Subject: [PATCH 02/31] include/qemu/compiler: add QEMU_UNINITIALIZED attribute +Subject: [PATCH 09/43] include/qemu/compiler: add QEMU_UNINITIALIZED attribute macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RH-Author: Stefan Hajnoczi -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 -RH-Commit: [1/30] 8e3758397d4a2ad7355db6d87bc9e3de6c1c23be +RH-Commit: [1/31] ddf39e782add4426708480dfb78ebbd71fb777f0 (stefanha/centos-stream-qemu-kvm) The QEMU_UNINITIALIZED macro is to be used to skip the default compiler variable initialization done by -ftrivial-auto-var-init=zero. @@ -36,19 +36,15 @@ Signed-off-by: Daniel P. BerrangĂ© Signed-off-by: Stefan Hajnoczi (cherry picked from commit c653b67d1863b7ebfa67f7c9f4aec209d7b5ced5) Signed-off-by: Stefan Hajnoczi - -Conflicts: - include/qemu/compiler.h - Context conflict due to clang Thread Safety Analysis macros. --- include/qemu/compiler.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h -index c06954ccb4..cc193d5b82 100644 +index 496dac5ac1..65b89958d3 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h -@@ -212,6 +212,26 @@ +@@ -207,6 +207,26 @@ # define QEMU_USED #endif @@ -73,8 +69,8 @@ index c06954ccb4..cc193d5b82 100644 +#endif + /* - * Ugly CPP trick that is like "defined FOO", but also works in C - * code. Useful to replace #ifdef with "if" statements; assumes + * http://clang.llvm.org/docs/ThreadSafetyAnalysis.html + * -- 2.39.3 diff --git a/kvm-include-system-Move-exec-address-spaces.h-to-system-.patch b/kvm-include-system-Move-exec-address-spaces.h-to-system-.patch new file mode 100644 index 0000000..c6107cd --- /dev/null +++ b/kvm-include-system-Move-exec-address-spaces.h-to-system-.patch @@ -0,0 +1,1736 @@ +From 6c4c6c4eaf2f8843240f52ef630f6df3f6f0fda6 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 25 Jul 2025 16:38:19 +0200 +Subject: [PATCH 008/100] include/system: Move exec/address-spaces.h to + system/address-spaces.h +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Convert the existing includes with sed. + +Reviewed-by: Philippe Mathieu-DaudĂ© +Reviewed-by: Pierrick Bouvier +Signed-off-by: Richard Henderson +(cherry picked from commit dfc56946a70052136126f6a207f237af8032d74a) +Signed-off-by: Paolo Bonzini + +Conflicts: trivial in target/avr/cpu.c +--- + accel/hvf/hvf-accel-ops.c | 2 +- + hw/acpi/erst.c | 2 +- + hw/arm/aspeed_ast10x0.c | 2 +- + hw/arm/bananapi_m2u.c | 2 +- + hw/arm/collie.c | 2 +- + hw/arm/exynos4_boards.c | 2 +- + hw/arm/fsl-imx31.c | 2 +- + hw/arm/fsl-imx8mp.c | 2 +- + hw/arm/imx8mp-evk.c | 2 +- + hw/arm/integratorcp.c | 2 +- + hw/arm/kzm.c | 2 +- + hw/arm/microbit.c | 2 +- + hw/arm/mps2-tz.c | 2 +- + hw/arm/mps2.c | 2 +- + hw/arm/mps3r.c | 2 +- + hw/arm/msf2-soc.c | 2 +- + hw/arm/msf2-som.c | 2 +- + hw/arm/musca.c | 2 +- + hw/arm/omap1.c | 2 +- + hw/arm/omap_sx1.c | 2 +- + hw/arm/orangepi.c | 2 +- + hw/arm/stellaris.c | 2 +- + hw/arm/stm32f100_soc.c | 2 +- + hw/arm/stm32f205_soc.c | 2 +- + hw/arm/stm32f405_soc.c | 2 +- + hw/arm/stm32l4x5_soc.c | 2 +- + hw/avr/atmega.c | 2 +- + hw/char/goldfish_tty.c | 2 +- + hw/char/omap_uart.c | 2 +- + hw/char/riscv_htif.c | 2 +- + hw/core/cpu-system.c | 2 +- + hw/core/null-machine.c | 2 +- + hw/core/sysbus.c | 2 +- + hw/display/apple-gfx.m | 2 +- + hw/dma/rc4030.c | 2 +- + hw/hyperv/hv-balloon.c | 2 +- + hw/hyperv/hyperv.c | 2 +- + hw/i386/kvm/xen_evtchn.c | 2 +- + hw/i386/kvm/xen_gnttab.c | 2 +- + hw/i386/kvm/xen_overlay.c | 2 +- + hw/i386/sgx-epc.c | 2 +- + hw/i386/sgx.c | 2 +- + hw/i386/vapic.c | 2 +- + hw/ide/ahci-sysbus.c | 2 +- + hw/input/lasips2.c | 2 +- + hw/intc/loongarch_extioi.c | 2 +- + hw/intc/riscv_aplic.c | 2 +- + hw/intc/riscv_imsic.c | 2 +- + hw/loongarch/virt.c | 2 +- + hw/mem/memory-device.c | 2 +- + hw/microblaze/petalogix_ml605_mmu.c | 2 +- + hw/microblaze/petalogix_s3adsp1800_mmu.c | 2 +- + hw/microblaze/xlnx-zynqmp-pmu.c | 2 +- + hw/mips/mipssim.c | 2 +- + hw/misc/allwinner-h3-dramc.c | 2 +- + hw/misc/allwinner-r40-dramc.c | 2 +- + hw/misc/ivshmem-flat.c | 2 +- + hw/misc/mac_via.c | 2 +- + hw/net/i82596.c | 2 +- + hw/net/i82596.h | 2 +- + hw/nvram/fw_cfg.c | 2 +- + hw/openrisc/openrisc_sim.c | 2 +- + hw/openrisc/virt.c | 2 +- + hw/pci-host/mv64361.c | 2 +- + hw/ppc/pegasos2.c | 2 +- + hw/ppc/pnv_psi.c | 2 +- + hw/ppc/ppc4xx_sdram.c | 2 +- + hw/ppc/prep_systemio.c | 2 +- + hw/ppc/rs6000_mc.c | 2 +- + hw/ppc/spapr_ovec.c | 2 +- + hw/ppc/vof.c | 2 +- + hw/remote/iommu.c | 2 +- + hw/riscv/microblaze-v-generic.c | 2 +- + hw/riscv/opentitan.c | 2 +- + hw/riscv/shakti_c.c | 2 +- + hw/s390x/css.c | 2 +- + hw/s390x/ipl.h | 2 +- + hw/s390x/s390-skeys.c | 2 +- + hw/s390x/virtio-ccw.c | 2 +- + hw/sparc/sun4m_iommu.c | 2 +- + hw/sparc64/sun4u_iommu.c | 2 +- + hw/timer/hpet.c | 2 +- + hw/tpm/tpm_crb.c | 2 +- + hw/vfio/ap.c | 2 +- + hw/vfio/ccw.c | 2 +- + hw/vfio/common.c | 2 +- + hw/vfio/container.c | 2 +- + hw/vfio/platform.c | 2 +- + hw/vfio/spapr.c | 2 +- + hw/virtio/vhost-vdpa.c | 2 +- + hw/virtio/virtio-balloon.c | 2 +- + hw/virtio/virtio-bus.c | 2 +- + include/hw/misc/lasi.h | 2 +- + include/hw/nubus/nubus.h | 2 +- + include/hw/ppc/vof.h | 2 +- + include/hw/tricore/triboard.h | 2 +- + include/{exec => system}/address-spaces.h | 8 ++------ + include/system/dma.h | 2 +- + monitor/hmp-cmds-target.c | 2 +- + monitor/hmp-cmds.c | 2 +- + rust/wrapper.h | 2 +- + system/ioport.c | 2 +- + system/memory.c | 2 +- + system/memory_mapping.c | 2 +- + target/arm/hvf/hvf.c | 2 +- + target/arm/kvm.c | 2 +- + target/i386/cpu-apic.c | 2 +- + target/i386/cpu.c | 2 +- + target/i386/hvf/vmx.h | 2 +- + target/i386/kvm/xen-emu.c | 2 +- + target/i386/nvmm/nvmm-all.c | 2 +- + target/i386/sev.c | 2 +- + target/i386/tcg/system/misc_helper.c | 2 +- + target/i386/tcg/system/tcg-cpu.c | 2 +- + target/i386/whpx/whpx-all.c | 2 +- + target/loongarch/kvm/kvm.c | 2 +- + target/riscv/kvm/kvm-cpu.c | 2 +- + target/s390x/mmu_helper.c | 2 +- + target/s390x/sigp.c | 2 +- + target/s390x/tcg/excp_helper.c | 2 +- + target/xtensa/dbg_helper.c | 2 +- + 121 files changed, 122 insertions(+), 126 deletions(-) + rename include/{exec => system}/address-spaces.h (89%) + +diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c +index 12fc30c276..601c3bc0ac 100644 +--- a/accel/hvf/hvf-accel-ops.c ++++ b/accel/hvf/hvf-accel-ops.c +@@ -50,7 +50,7 @@ + #include "qemu/osdep.h" + #include "qemu/error-report.h" + #include "qemu/main-loop.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "exec/exec-all.h" + #include "gdbstub/enums.h" + #include "hw/boards.h" +diff --git a/hw/acpi/erst.c b/hw/acpi/erst.c +index 5c4c1dc638..2e49b551f2 100644 +--- a/hw/acpi/erst.c ++++ b/hw/acpi/erst.c +@@ -23,7 +23,7 @@ + #include "hw/acpi/acpi-defs.h" + #include "hw/acpi/aml-build.h" + #include "hw/acpi/bios-linker-loader.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/hostmem.h" + #include "hw/acpi/erst.h" + #include "trace.h" +diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c +index ec329f4991..21ffab10f3 100644 +--- a/hw/arm/aspeed_ast10x0.c ++++ b/hw/arm/aspeed_ast10x0.c +@@ -11,7 +11,7 @@ + + #include "qemu/osdep.h" + #include "qapi/error.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/system.h" + #include "hw/qdev-clock.h" + #include "hw/misc/unimp.h" +diff --git a/hw/arm/bananapi_m2u.c b/hw/arm/bananapi_m2u.c +index 4d84d10d24..b750a575f7 100644 +--- a/hw/arm/bananapi_m2u.c ++++ b/hw/arm/bananapi_m2u.c +@@ -19,7 +19,7 @@ + + #include "qemu/osdep.h" + #include "qemu/units.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qapi/error.h" + #include "qemu/error-report.h" + #include "hw/boards.h" +diff --git a/hw/arm/collie.c b/hw/arm/collie.c +index eaa5c52d45..e83aee58c6 100644 +--- a/hw/arm/collie.c ++++ b/hw/arm/collie.c +@@ -16,7 +16,7 @@ + #include "strongarm.h" + #include "hw/arm/boot.h" + #include "hw/block/flash.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qom/object.h" + #include "qemu/error-report.h" + +diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c +index 43dc89d902..2d8f2d7326 100644 +--- a/hw/arm/exynos4_boards.c ++++ b/hw/arm/exynos4_boards.c +@@ -28,7 +28,7 @@ + #include "hw/sysbus.h" + #include "net/net.h" + #include "hw/arm/boot.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/arm/exynos4210.h" + #include "hw/net/lan9118.h" + #include "hw/qdev-properties.h" +diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c +index 9de0f2148f..2a8ffb15f7 100644 +--- a/hw/arm/fsl-imx31.c ++++ b/hw/arm/fsl-imx31.c +@@ -23,7 +23,7 @@ + #include "qapi/error.h" + #include "hw/arm/fsl-imx31.h" + #include "system/system.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/qdev-properties.h" + #include "chardev/char.h" + #include "target/arm/cpu-qom.h" +diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c +index 82edf61082..af7a7e6745 100644 +--- a/hw/arm/fsl-imx8mp.c ++++ b/hw/arm/fsl-imx8mp.c +@@ -9,7 +9,7 @@ + */ + + #include "qemu/osdep.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/arm/bsa.h" + #include "hw/arm/fsl-imx8mp.h" + #include "hw/intc/arm_gicv3.h" +diff --git a/hw/arm/imx8mp-evk.c b/hw/arm/imx8mp-evk.c +index b5aec06ec5..b3082fa60d 100644 +--- a/hw/arm/imx8mp-evk.c ++++ b/hw/arm/imx8mp-evk.c +@@ -7,7 +7,7 @@ + */ + + #include "qemu/osdep.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/arm/boot.h" + #include "hw/arm/fsl-imx8mp.h" + #include "hw/boards.h" +diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c +index 8aa2e6e98e..ac0c6c6096 100644 +--- a/hw/arm/integratorcp.c ++++ b/hw/arm/integratorcp.c +@@ -16,7 +16,7 @@ + #include "hw/misc/arm_integrator_debug.h" + #include "hw/net/smc91c111.h" + #include "net/net.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/runstate.h" + #include "system/system.h" + #include "qemu/log.h" +diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c +index 08d2b3025c..362c145409 100644 +--- a/hw/arm/kzm.c ++++ b/hw/arm/kzm.c +@@ -19,7 +19,7 @@ + #include "hw/arm/boot.h" + #include "hw/boards.h" + #include "qemu/error-report.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "net/net.h" + #include "hw/net/lan9118.h" + #include "hw/char/serial-mm.h" +diff --git a/hw/arm/microbit.c b/hw/arm/microbit.c +index 3f56fb45ce..ade363daaa 100644 +--- a/hw/arm/microbit.c ++++ b/hw/arm/microbit.c +@@ -13,7 +13,7 @@ + #include "hw/boards.h" + #include "hw/arm/boot.h" + #include "system/system.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + + #include "hw/arm/nrf51_soc.h" + #include "hw/i2c/microbit_i2c.h" +diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c +index 13ed868b6b..b0633a5a69 100644 +--- a/hw/arm/mps2-tz.c ++++ b/hw/arm/mps2-tz.c +@@ -54,7 +54,7 @@ + #include "hw/arm/armv7m.h" + #include "hw/or-irq.h" + #include "hw/boards.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/system.h" + #include "system/reset.h" + #include "hw/misc/unimp.h" +diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c +index 3f8db0cab6..6958485a66 100644 +--- a/hw/arm/mps2.c ++++ b/hw/arm/mps2.c +@@ -33,7 +33,7 @@ + #include "hw/arm/armv7m.h" + #include "hw/or-irq.h" + #include "hw/boards.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/system.h" + #include "hw/qdev-properties.h" + #include "hw/misc/unimp.h" +diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c +index 1bddb5e822..4dd1e8a718 100644 +--- a/hw/arm/mps3r.c ++++ b/hw/arm/mps3r.c +@@ -28,7 +28,7 @@ + #include "qemu/units.h" + #include "qapi/error.h" + #include "qobject/qlist.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "cpu.h" + #include "system/system.h" + #include "hw/boards.h" +diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c +index e8a5b231ba..bc9b419e37 100644 +--- a/hw/arm/msf2-soc.c ++++ b/hw/arm/msf2-soc.c +@@ -25,7 +25,7 @@ + #include "qemu/osdep.h" + #include "qemu/units.h" + #include "qapi/error.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/char/serial-mm.h" + #include "hw/arm/msf2-soc.h" + #include "hw/misc/unimp.h" +diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c +index 9b20f1e2c9..29c76c6860 100644 +--- a/hw/arm/msf2-som.c ++++ b/hw/arm/msf2-som.c +@@ -33,7 +33,7 @@ + #include "hw/qdev-properties.h" + #include "hw/arm/boot.h" + #include "hw/qdev-clock.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/arm/msf2-soc.h" + + #define DDR_BASE_ADDRESS 0xA0000000 +diff --git a/hw/arm/musca.c b/hw/arm/musca.c +index e9c092abc3..a4f43f1992 100644 +--- a/hw/arm/musca.c ++++ b/hw/arm/musca.c +@@ -22,7 +22,7 @@ + #include "qemu/osdep.h" + #include "qemu/error-report.h" + #include "qapi/error.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/system.h" + #include "hw/arm/boot.h" + #include "hw/arm/armsse.h" +diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c +index 3ee10b4777..91d7e3f04b 100644 +--- a/hw/arm/omap1.c ++++ b/hw/arm/omap1.c +@@ -23,7 +23,7 @@ + #include "qemu/main-loop.h" + #include "qapi/error.h" + #include "cpu.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/hw.h" + #include "hw/irq.h" + #include "hw/qdev-properties.h" +diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c +index 24b4043183..aa1e96b3ad 100644 +--- a/hw/arm/omap_sx1.c ++++ b/hw/arm/omap_sx1.c +@@ -34,7 +34,7 @@ + #include "hw/arm/boot.h" + #include "hw/block/flash.h" + #include "system/qtest.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qemu/cutils.h" + #include "qemu/error-report.h" + +diff --git a/hw/arm/orangepi.c b/hw/arm/orangepi.c +index 634af9b0a1..e0956880d1 100644 +--- a/hw/arm/orangepi.c ++++ b/hw/arm/orangepi.c +@@ -19,7 +19,7 @@ + + #include "qemu/osdep.h" + #include "qemu/units.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qapi/error.h" + #include "qemu/error-report.h" + #include "hw/boards.h" +diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c +index 3361111360..cbe914c93e 100644 +--- a/hw/arm/stellaris.c ++++ b/hw/arm/stellaris.c +@@ -20,7 +20,7 @@ + #include "net/net.h" + #include "hw/boards.h" + #include "qemu/log.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/system.h" + #include "hw/arm/armv7m.h" + #include "hw/char/pl011.h" +diff --git a/hw/arm/stm32f100_soc.c b/hw/arm/stm32f100_soc.c +index 53b5636452..0eabaf8d9b 100644 +--- a/hw/arm/stm32f100_soc.c ++++ b/hw/arm/stm32f100_soc.c +@@ -27,7 +27,7 @@ + #include "qapi/error.h" + #include "qemu/module.h" + #include "hw/arm/boot.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/arm/stm32f100_soc.h" + #include "hw/qdev-properties.h" + #include "hw/qdev-clock.h" +diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c +index 47a54e592b..32e96912f0 100644 +--- a/hw/arm/stm32f205_soc.c ++++ b/hw/arm/stm32f205_soc.c +@@ -26,7 +26,7 @@ + #include "qapi/error.h" + #include "qemu/module.h" + #include "hw/arm/boot.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/arm/stm32f205_soc.h" + #include "hw/qdev-properties.h" + #include "hw/qdev-clock.h" +diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c +index 18d8824f29..bba9060daf 100644 +--- a/hw/arm/stm32f405_soc.c ++++ b/hw/arm/stm32f405_soc.c +@@ -24,7 +24,7 @@ + + #include "qemu/osdep.h" + #include "qapi/error.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/system.h" + #include "hw/arm/stm32f405_soc.h" + #include "hw/qdev-clock.h" +diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c +index dbf75329f7..6278d354c8 100644 +--- a/hw/arm/stm32l4x5_soc.c ++++ b/hw/arm/stm32l4x5_soc.c +@@ -24,7 +24,7 @@ + #include "qemu/osdep.h" + #include "qemu/units.h" + #include "qapi/error.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/system.h" + #include "hw/or-irq.h" + #include "hw/arm/stm32l4x5_soc.h" +diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c +index 59c0160283..ee8747781e 100644 +--- a/hw/avr/atmega.c ++++ b/hw/avr/atmega.c +@@ -13,7 +13,7 @@ + #include "qemu/units.h" + #include "qapi/error.h" + #include "system/memory.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/system.h" + #include "hw/qdev-properties.h" + #include "hw/sysbus.h" +diff --git a/hw/char/goldfish_tty.c b/hw/char/goldfish_tty.c +index 7374561141..f0891ffa4d 100644 +--- a/hw/char/goldfish_tty.c ++++ b/hw/char/goldfish_tty.c +@@ -15,7 +15,7 @@ + #include "chardev/char-fe.h" + #include "qemu/log.h" + #include "trace.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/dma.h" + #include "hw/char/goldfish_tty.h" + +diff --git a/hw/char/omap_uart.c b/hw/char/omap_uart.c +index 07fb868965..8cbf6ce803 100644 +--- a/hw/char/omap_uart.c ++++ b/hw/char/omap_uart.c +@@ -21,7 +21,7 @@ + #include "chardev/char.h" + #include "hw/arm/omap.h" + #include "hw/char/serial-mm.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + + /* UARTs */ + struct omap_uart_s { +diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c +index ec5db5a597..c884be5d75 100644 +--- a/hw/char/riscv_htif.c ++++ b/hw/char/riscv_htif.c +@@ -28,7 +28,7 @@ + #include "chardev/char-fe.h" + #include "qemu/timer.h" + #include "qemu/error-report.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "exec/tswap.h" + #include "system/dma.h" + #include "system/runstate.h" +diff --git a/hw/core/cpu-system.c b/hw/core/cpu-system.c +index 5ef8c24b5b..82b68b8927 100644 +--- a/hw/core/cpu-system.c ++++ b/hw/core/cpu-system.c +@@ -20,7 +20,7 @@ + + #include "qemu/osdep.h" + #include "qapi/error.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "exec/cputlb.h" + #include "system/memory.h" + #include "exec/tb-flush.h" +diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c +index 7f1fb562be..a6e477a2d8 100644 +--- a/hw/core/null-machine.c ++++ b/hw/core/null-machine.c +@@ -14,7 +14,7 @@ + #include "qemu/osdep.h" + #include "qemu/error-report.h" + #include "hw/boards.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/core/cpu.h" + + static void machine_none_init(MachineState *mch) +diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c +index 98819d5dc6..6eb4c0f15a 100644 +--- a/hw/core/sysbus.c ++++ b/hw/core/sysbus.c +@@ -21,7 +21,7 @@ + #include "qapi/error.h" + #include "hw/sysbus.h" + #include "monitor/monitor.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + + static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent); + static char *sysbus_get_fw_dev_path(DeviceState *dev); +diff --git a/hw/display/apple-gfx.m b/hw/display/apple-gfx.m +index c4323574e1..2ff1c90df7 100644 +--- a/hw/display/apple-gfx.m ++++ b/hw/display/apple-gfx.m +@@ -18,7 +18,7 @@ + #include "qapi/visitor.h" + #include "qapi/error.h" + #include "block/aio-wait.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/dma.h" + #include "migration/blocker.h" + #include "ui/console.h" +diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c +index 5bf54347ed..6842e7d491 100644 +--- a/hw/dma/rc4030.c ++++ b/hw/dma/rc4030.c +@@ -32,7 +32,7 @@ + #include "qemu/timer.h" + #include "qemu/log.h" + #include "qemu/module.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "trace.h" + #include "qom/object.h" + +diff --git a/hw/hyperv/hv-balloon.c b/hw/hyperv/hv-balloon.c +index 6f33c3e741..0b1da723c8 100644 +--- a/hw/hyperv/hv-balloon.c ++++ b/hw/hyperv/hv-balloon.c +@@ -10,7 +10,7 @@ + #include "qemu/osdep.h" + #include "hv-balloon-internal.h" + +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "exec/cpu-common.h" + #include "exec/ramblock.h" + #include "hw/boards.h" +diff --git a/hw/hyperv/hyperv.c b/hw/hyperv/hyperv.c +index 382c62d668..d21e428eae 100644 +--- a/hw/hyperv/hyperv.c ++++ b/hw/hyperv/hyperv.c +@@ -11,7 +11,7 @@ + #include "qemu/main-loop.h" + #include "qemu/module.h" + #include "qapi/error.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/memory.h" + #include "system/kvm.h" + #include "qemu/bitops.h" +diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c +index 9b8b092bc2..f9223ef1a1 100644 +--- a/hw/i386/kvm/xen_evtchn.c ++++ b/hw/i386/kvm/xen_evtchn.c +@@ -23,7 +23,7 @@ + #include "qobject/qdict.h" + #include "qom/object.h" + #include "exec/target_page.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "migration/vmstate.h" + #include "trace.h" + +diff --git a/hw/i386/kvm/xen_gnttab.c b/hw/i386/kvm/xen_gnttab.c +index 7b843a72b1..430ba62896 100644 +--- a/hw/i386/kvm/xen_gnttab.c ++++ b/hw/i386/kvm/xen_gnttab.c +@@ -17,7 +17,7 @@ + #include "qapi/error.h" + #include "qom/object.h" + #include "exec/target_page.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "migration/vmstate.h" + + #include "hw/sysbus.h" +diff --git a/hw/i386/kvm/xen_overlay.c b/hw/i386/kvm/xen_overlay.c +index db9aa7942d..a2b26e9906 100644 +--- a/hw/i386/kvm/xen_overlay.c ++++ b/hw/i386/kvm/xen_overlay.c +@@ -16,7 +16,7 @@ + #include "qapi/error.h" + #include "qom/object.h" + #include "exec/target_page.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "migration/vmstate.h" + + #include "hw/sysbus.h" +diff --git a/hw/i386/sgx-epc.c b/hw/i386/sgx-epc.c +index 875e1c5c33..00b220d4d6 100644 +--- a/hw/i386/sgx-epc.c ++++ b/hw/i386/sgx-epc.c +@@ -17,7 +17,7 @@ + #include "qapi/error.h" + #include "qapi/visitor.h" + #include "target/i386/cpu.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + + static const Property sgx_epc_properties[] = { + DEFINE_PROP_UINT64(SGX_EPC_ADDR_PROP, SGXEPCDevice, addr, 0), +diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c +index e665e2111c..5685c4fb80 100644 +--- a/hw/i386/sgx.c ++++ b/hw/i386/sgx.c +@@ -20,7 +20,7 @@ + #include "qapi/error.h" + #include "qemu/error-report.h" + #include "qapi/qapi-commands-misc-target.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/hw_accel.h" + #include "system/reset.h" + #include +diff --git a/hw/i386/vapic.c b/hw/i386/vapic.c +index 14de9b7a82..26aae64e5d 100644 +--- a/hw/i386/vapic.c ++++ b/hw/i386/vapic.c +@@ -16,7 +16,7 @@ + #include "system/hw_accel.h" + #include "system/kvm.h" + #include "system/runstate.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/i386/apic_internal.h" + #include "hw/sysbus.h" + #include "hw/boards.h" +diff --git a/hw/ide/ahci-sysbus.c b/hw/ide/ahci-sysbus.c +index 03a5bd42d0..3c1935d81c 100644 +--- a/hw/ide/ahci-sysbus.c ++++ b/hw/ide/ahci-sysbus.c +@@ -22,7 +22,7 @@ + */ + + #include "qemu/osdep.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/qdev-properties.h" + #include "migration/vmstate.h" + +diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c +index d9f8c36778..987034efd3 100644 +--- a/hw/input/lasips2.c ++++ b/hw/input/lasips2.c +@@ -29,7 +29,7 @@ + #include "hw/input/lasips2.h" + #include "exec/hwaddr.h" + #include "trace.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "migration/vmstate.h" + #include "hw/irq.h" + #include "qapi/error.h" +diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c +index a51a215e6e..a558c50185 100644 +--- a/hw/intc/loongarch_extioi.c ++++ b/hw/intc/loongarch_extioi.c +@@ -11,7 +11,7 @@ + #include "qapi/error.h" + #include "hw/irq.h" + #include "hw/loongarch/virt.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/intc/loongarch_extioi.h" + #include "trace.h" + +diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c +index 5964cde7e0..789c4a4d6e 100644 +--- a/hw/intc/riscv_aplic.c ++++ b/hw/intc/riscv_aplic.c +@@ -22,7 +22,7 @@ + #include "qemu/module.h" + #include "qemu/error-report.h" + #include "qemu/bswap.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/sysbus.h" + #include "hw/pci/msi.h" + #include "hw/boards.h" +diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c +index 241b12fef0..852f413e5a 100644 +--- a/hw/intc/riscv_imsic.c ++++ b/hw/intc/riscv_imsic.c +@@ -22,7 +22,7 @@ + #include "qemu/module.h" + #include "qemu/error-report.h" + #include "qemu/bswap.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/sysbus.h" + #include "hw/pci/msi.h" + #include "hw/boards.h" +diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c +index 65c9027feb..f1eb42c2c1 100644 +--- a/hw/loongarch/virt.c ++++ b/hw/loongarch/virt.c +@@ -18,7 +18,7 @@ + #include "system/reset.h" + #include "system/rtc.h" + #include "hw/loongarch/virt.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/irq.h" + #include "net/net.h" + #include "hw/loader.h" +diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c +index 1de8dfec7d..1a432e9bd2 100644 +--- a/hw/mem/memory-device.c ++++ b/hw/mem/memory-device.c +@@ -17,7 +17,7 @@ + #include "qemu/range.h" + #include "hw/virtio/vhost.h" + #include "system/kvm.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "trace.h" + + static bool memory_device_is_empty(const MemoryDeviceState *md) +diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c +index 21ad215e44..c887c7a99e 100644 +--- a/hw/microblaze/petalogix_ml605_mmu.c ++++ b/hw/microblaze/petalogix_ml605_mmu.c +@@ -36,7 +36,7 @@ + #include "hw/boards.h" + #include "hw/char/serial-mm.h" + #include "hw/qdev-properties.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/ssi/ssi.h" + + #include "boot.h" +diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c +index bdba2006b7..f976c90bd2 100644 +--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c ++++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c +@@ -33,7 +33,7 @@ + #include "system/system.h" + #include "hw/boards.h" + #include "hw/misc/unimp.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/char/xilinx_uartlite.h" + + #include "boot.h" +diff --git a/hw/microblaze/xlnx-zynqmp-pmu.c b/hw/microblaze/xlnx-zynqmp-pmu.c +index bdbf7328bf..0922c65295 100644 +--- a/hw/microblaze/xlnx-zynqmp-pmu.c ++++ b/hw/microblaze/xlnx-zynqmp-pmu.c +@@ -17,7 +17,7 @@ + + #include "qemu/osdep.h" + #include "qapi/error.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/boards.h" + #include "cpu.h" + #include "boot.h" +diff --git a/hw/mips/mipssim.c b/hw/mips/mipssim.c +index c530688e76..b6dabf2893 100644 +--- a/hw/mips/mipssim.c ++++ b/hw/mips/mipssim.c +@@ -28,7 +28,7 @@ + #include "qemu/osdep.h" + #include "qapi/error.h" + #include "qemu/datadir.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/clock.h" + #include "hw/mips/mips.h" + #include "hw/char/serial-mm.h" +diff --git a/hw/misc/allwinner-h3-dramc.c b/hw/misc/allwinner-h3-dramc.c +index c4f3eb9274..74ff71b753 100644 +--- a/hw/misc/allwinner-h3-dramc.c ++++ b/hw/misc/allwinner-h3-dramc.c +@@ -24,7 +24,7 @@ + #include "migration/vmstate.h" + #include "qemu/log.h" + #include "qemu/module.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/qdev-properties.h" + #include "qapi/error.h" + #include "hw/misc/allwinner-h3-dramc.h" +diff --git a/hw/misc/allwinner-r40-dramc.c b/hw/misc/allwinner-r40-dramc.c +index 96e1848c21..5908a059e8 100644 +--- a/hw/misc/allwinner-r40-dramc.c ++++ b/hw/misc/allwinner-r40-dramc.c +@@ -24,7 +24,7 @@ + #include "migration/vmstate.h" + #include "qemu/log.h" + #include "qemu/module.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/qdev-properties.h" + #include "qapi/error.h" + #include "qemu/bitops.h" +diff --git a/hw/misc/ivshmem-flat.c b/hw/misc/ivshmem-flat.c +index 40309a8ff3..076c4b42de 100644 +--- a/hw/misc/ivshmem-flat.c ++++ b/hw/misc/ivshmem-flat.c +@@ -17,7 +17,7 @@ + #include "hw/qdev-properties-system.h" + #include "hw/sysbus.h" + #include "chardev/char-fe.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "trace.h" + + #include "hw/misc/ivshmem-flat.h" +diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c +index 03b1feda50..3c0819c58a 100644 +--- a/hw/misc/mac_via.c ++++ b/hw/misc/mac_via.c +@@ -16,7 +16,7 @@ + */ + + #include "qemu/osdep.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "migration/vmstate.h" + #include "hw/sysbus.h" + #include "hw/irq.h" +diff --git a/hw/net/i82596.c b/hw/net/i82596.c +index ee919dab3c..64ed3c8390 100644 +--- a/hw/net/i82596.c ++++ b/hw/net/i82596.c +@@ -15,7 +15,7 @@ + #include "hw/irq.h" + #include "hw/qdev-properties.h" + #include "migration/vmstate.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qemu/module.h" + #include "trace.h" + #include "i82596.h" +diff --git a/hw/net/i82596.h b/hw/net/i82596.h +index 4bdfcaf856..dc1fa1a1dc 100644 +--- a/hw/net/i82596.h ++++ b/hw/net/i82596.h +@@ -4,7 +4,7 @@ + #define I82596_IOPORT_SIZE 0x20 + + #include "system/memory.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + + #define PORT_RESET 0x00 /* reset 82596 */ + #define PORT_SELFTEST 0x01 /* selftest */ +diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c +index a757939cfb..cbfb2b5303 100644 +--- a/hw/nvram/fw_cfg.c ++++ b/hw/nvram/fw_cfg.c +@@ -27,7 +27,7 @@ + #include "system/system.h" + #include "system/dma.h" + #include "system/reset.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/boards.h" + #include "hw/nvram/fw_cfg.h" + #include "hw/qdev-properties.h" +diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c +index 83d7c2a8af..c2284a7d41 100644 +--- a/hw/openrisc/openrisc_sim.c ++++ b/hw/openrisc/openrisc_sim.c +@@ -28,7 +28,7 @@ + #include "net/net.h" + #include "hw/openrisc/boot.h" + #include "hw/qdev-properties.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/device_tree.h" + #include "system/system.h" + #include "hw/sysbus.h" +diff --git a/hw/openrisc/virt.c b/hw/openrisc/virt.c +index 3055306783..0d1c1f103c 100644 +--- a/hw/openrisc/virt.c ++++ b/hw/openrisc/virt.c +@@ -11,7 +11,7 @@ + #include "qemu/guest-random.h" + #include "qapi/error.h" + #include "cpu.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/irq.h" + #include "hw/boards.h" + #include "hw/char/serial-mm.h" +diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c +index 9c41c155fb..a297318c6e 100644 +--- a/hw/pci-host/mv64361.c ++++ b/hw/pci-host/mv64361.c +@@ -17,7 +17,7 @@ + #include "hw/irq.h" + #include "hw/intc/i8259.h" + #include "hw/qdev-properties.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qemu/log.h" + #include "qemu/error-report.h" + #include "trace.h" +diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c +index 246d6d633b..7b2dc6985c 100644 +--- a/hw/ppc/pegasos2.c ++++ b/hw/ppc/pegasos2.c +@@ -31,7 +31,7 @@ + #include "qemu/error-report.h" + #include "system/kvm.h" + #include "kvm_ppc.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qom/qom-qobject.h" + #include "qobject/qdict.h" + #include "trace.h" +diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c +index 1fe11dde50..f832ee61e8 100644 +--- a/hw/ppc/pnv_psi.c ++++ b/hw/ppc/pnv_psi.c +@@ -18,7 +18,7 @@ + */ + + #include "qemu/osdep.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/irq.h" + #include "target/ppc/cpu.h" + #include "qemu/log.h" +diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c +index 562bff8d53..bf0faad9e7 100644 +--- a/hw/ppc/ppc4xx_sdram.c ++++ b/hw/ppc/ppc4xx_sdram.c +@@ -34,7 +34,7 @@ + #include "qapi/error.h" + #include "qemu/log.h" + #include "qemu/error-report.h" +-#include "exec/address-spaces.h" /* get_system_memory() */ ++#include "system/address-spaces.h" /* get_system_memory() */ + #include "hw/irq.h" + #include "hw/qdev-properties.h" + #include "hw/ppc/ppc4xx.h" +diff --git a/hw/ppc/prep_systemio.c b/hw/ppc/prep_systemio.c +index b1f2e130f0..08f29e72e4 100644 +--- a/hw/ppc/prep_systemio.c ++++ b/hw/ppc/prep_systemio.c +@@ -28,7 +28,7 @@ + #include "hw/isa/isa.h" + #include "hw/qdev-properties.h" + #include "migration/vmstate.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qom/object.h" + #include "qemu/error-report.h" /* for error_report() */ + #include "qemu/module.h" +diff --git a/hw/ppc/rs6000_mc.c b/hw/ppc/rs6000_mc.c +index 0e5d53b8b6..27f1c90f06 100644 +--- a/hw/ppc/rs6000_mc.c ++++ b/hw/ppc/rs6000_mc.c +@@ -24,7 +24,7 @@ + #include "hw/isa/isa.h" + #include "hw/qdev-properties.h" + #include "migration/vmstate.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qapi/error.h" + #include "trace.h" + #include "qom/object.h" +diff --git a/hw/ppc/spapr_ovec.c b/hw/ppc/spapr_ovec.c +index 88e29536aa..6d6eaf67cb 100644 +--- a/hw/ppc/spapr_ovec.c ++++ b/hw/ppc/spapr_ovec.c +@@ -15,7 +15,7 @@ + #include "hw/ppc/spapr_ovec.h" + #include "migration/vmstate.h" + #include "qemu/bitmap.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qemu/error-report.h" + #include "trace.h" + #include +diff --git a/hw/ppc/vof.c b/hw/ppc/vof.c +index 09cb77de93..f14efa3a7c 100644 +--- a/hw/ppc/vof.c ++++ b/hw/ppc/vof.c +@@ -15,7 +15,7 @@ + #include "qemu/units.h" + #include "qemu/log.h" + #include "qapi/error.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/ppc/vof.h" + #include "hw/ppc/fdt.h" + #include "system/runstate.h" +diff --git a/hw/remote/iommu.c b/hw/remote/iommu.c +index ec845d1f58..3e0758a21e 100644 +--- a/hw/remote/iommu.c ++++ b/hw/remote/iommu.c +@@ -14,7 +14,7 @@ + #include "hw/pci/pci_bus.h" + #include "hw/pci/pci.h" + #include "system/memory.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "trace.h" + + /** +diff --git a/hw/riscv/microblaze-v-generic.c b/hw/riscv/microblaze-v-generic.c +index d8e67906d2..e863c50cbc 100644 +--- a/hw/riscv/microblaze-v-generic.c ++++ b/hw/riscv/microblaze-v-generic.c +@@ -22,7 +22,7 @@ + #include "net/net.h" + #include "hw/boards.h" + #include "hw/char/serial-mm.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/char/xilinx_uartlite.h" + #include "hw/misc/unimp.h" + +diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c +index 98a67fe52a..019d6b3986 100644 +--- a/hw/riscv/opentitan.c ++++ b/hw/riscv/opentitan.c +@@ -28,7 +28,7 @@ + #include "hw/riscv/boot.h" + #include "qemu/units.h" + #include "system/system.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + + /* + * This version of the OpenTitan machine currently supports +diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c +index e2242b97d0..17c5c72102 100644 +--- a/hw/riscv/shakti_c.c ++++ b/hw/riscv/shakti_c.c +@@ -25,7 +25,7 @@ + #include "hw/intc/riscv_aclint.h" + #include "system/system.h" + #include "hw/qdev-properties.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/riscv/boot.h" + + static const struct MemmapEntry { +diff --git a/hw/s390x/css.c b/hw/s390x/css.c +index 738800c98d..2059c5dd0b 100644 +--- a/hw/s390x/css.c ++++ b/hw/s390x/css.c +@@ -14,7 +14,7 @@ + #include "qapi/visitor.h" + #include "qemu/bitops.h" + #include "qemu/error-report.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/s390x/ioinst.h" + #include "hw/qdev-properties.h" + #include "hw/s390x/css.h" +diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h +index 8e3882d506..c6ecb3433c 100644 +--- a/hw/s390x/ipl.h ++++ b/hw/s390x/ipl.h +@@ -14,7 +14,7 @@ + #define HW_S390_IPL_H + + #include "cpu.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/qdev-core.h" + #include "hw/s390x/ipl/qipl.h" + #include "qom/object.h" +diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c +index 811d892122..425e3e4a87 100644 +--- a/hw/s390x/s390-skeys.c ++++ b/hw/s390x/s390-skeys.c +@@ -19,7 +19,7 @@ + #include "qobject/qdict.h" + #include "qemu/error-report.h" + #include "system/memory_mapping.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/kvm.h" + #include "migration/qemu-file-types.h" + #include "migration/register.h" +diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c +index 43f3b162c8..e8ecb90826 100644 +--- a/hw/s390x/virtio-ccw.c ++++ b/hw/s390x/virtio-ccw.c +@@ -12,7 +12,7 @@ + + #include "qemu/osdep.h" + #include "qapi/error.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/kvm.h" + #include "net/net.h" + #include "hw/virtio/virtio.h" +diff --git a/hw/sparc/sun4m_iommu.c b/hw/sparc/sun4m_iommu.c +index 5a4c1f5e3b..4a542b18d2 100644 +--- a/hw/sparc/sun4m_iommu.c ++++ b/hw/sparc/sun4m_iommu.c +@@ -29,7 +29,7 @@ + #include "hw/sysbus.h" + #include "migration/vmstate.h" + #include "qemu/module.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "trace.h" + + /* +diff --git a/hw/sparc64/sun4u_iommu.c b/hw/sparc64/sun4u_iommu.c +index eba811af0c..533fcae1fb 100644 +--- a/hw/sparc64/sun4u_iommu.c ++++ b/hw/sparc64/sun4u_iommu.c +@@ -27,7 +27,7 @@ + #include "qemu/osdep.h" + #include "hw/sysbus.h" + #include "hw/sparc/sun4u_iommu.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qemu/log.h" + #include "qemu/module.h" + #include "trace.h" +diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c +index ccb97b6806..ea82472105 100644 +--- a/hw/timer/hpet.c ++++ b/hw/timer/hpet.c +@@ -36,7 +36,7 @@ + #include "hw/rtc/mc146818rtc_regs.h" + #include "migration/vmstate.h" + #include "hw/timer/i8254.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qom/object.h" + #include "trace.h" + +diff --git a/hw/tpm/tpm_crb.c b/hw/tpm/tpm_crb.c +index 6cdeb72df0..b668aee97a 100644 +--- a/hw/tpm/tpm_crb.c ++++ b/hw/tpm/tpm_crb.c +@@ -18,7 +18,7 @@ + + #include "qemu/module.h" + #include "qapi/error.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/qdev-properties.h" + #include "hw/pci/pci_ids.h" + #include "hw/acpi/tpm.h" +diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c +index c7ab4ff57a..d6575d7c44 100644 +--- a/hw/vfio/ap.c ++++ b/hw/vfio/ap.c +@@ -28,7 +28,7 @@ + #include "migration/vmstate.h" + #include "hw/qdev-properties.h" + #include "hw/s390x/ap-bridge.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qom/object.h" + + #define TYPE_VFIO_AP_DEVICE "vfio-ap" +diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c +index e5e0d9e3e7..29e804e122 100644 +--- a/hw/vfio/ccw.c ++++ b/hw/vfio/ccw.c +@@ -27,7 +27,7 @@ + #include "hw/s390x/vfio-ccw.h" + #include "hw/qdev-properties.h" + #include "hw/s390x/ccw-device.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qemu/error-report.h" + #include "qemu/main-loop.h" + #include "qemu/module.h" +diff --git a/hw/vfio/common.c b/hw/vfio/common.c +index 989c6ee83d..98832af88d 100644 +--- a/hw/vfio/common.c ++++ b/hw/vfio/common.c +@@ -27,7 +27,7 @@ + + #include "hw/vfio/vfio-common.h" + #include "hw/vfio/pci.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/memory.h" + #include "exec/ram_addr.h" + #include "exec/target_page.h" +diff --git a/hw/vfio/container.c b/hw/vfio/container.c +index 1d1c5f9a77..2e993c7e73 100644 +--- a/hw/vfio/container.c ++++ b/hw/vfio/container.c +@@ -23,7 +23,7 @@ + #include + + #include "hw/vfio/vfio-common.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/memory.h" + #include "exec/ram_addr.h" + #include "qemu/error-report.h" +diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c +index 96c6bf5654..c6edbdd4ae 100644 +--- a/hw/vfio/platform.c ++++ b/hw/vfio/platform.c +@@ -29,7 +29,7 @@ + #include "qemu/module.h" + #include "qemu/range.h" + #include "system/memory.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qemu/queue.h" + #include "hw/sysbus.h" + #include "trace.h" +diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c +index 1a5d1611f2..c9a7dd8d68 100644 +--- a/hw/vfio/spapr.c ++++ b/hw/vfio/spapr.c +@@ -13,7 +13,7 @@ + #include + #include "system/kvm.h" + #include "system/hostmem.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + + #include "hw/vfio/vfio-common.h" + #include "hw/hw.h" +diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c +index 7efbde3d4c..1e0336df1d 100644 +--- a/hw/virtio/vhost-vdpa.c ++++ b/hw/virtio/vhost-vdpa.c +@@ -20,7 +20,7 @@ + #include "hw/virtio/virtio-net.h" + #include "hw/virtio/vhost-shadow-virtqueue.h" + #include "hw/virtio/vhost-vdpa.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "migration/blocker.h" + #include "qemu/cutils.h" + #include "qemu/main-loop.h" +diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c +index 2eb5a14fa2..0d0603c674 100644 +--- a/hw/virtio/virtio-balloon.c ++++ b/hw/virtio/virtio-balloon.c +@@ -24,7 +24,7 @@ + #include "hw/boards.h" + #include "system/balloon.h" + #include "hw/virtio/virtio-balloon.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qapi/error.h" + #include "qapi/qapi-events-machine.h" + #include "qapi/visitor.h" +diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c +index 896feb37a1..d1c79c567b 100644 +--- a/hw/virtio/virtio-bus.c ++++ b/hw/virtio/virtio-bus.c +@@ -28,7 +28,7 @@ + #include "qapi/error.h" + #include "hw/virtio/virtio-bus.h" + #include "hw/virtio/virtio.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + + /* #define DEBUG_VIRTIO_BUS */ + +diff --git a/include/hw/misc/lasi.h b/include/hw/misc/lasi.h +index f01c0f680a..0bdfb11b50 100644 +--- a/include/hw/misc/lasi.h ++++ b/include/hw/misc/lasi.h +@@ -12,7 +12,7 @@ + #ifndef LASI_H + #define LASI_H + +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/pci/pci_host.h" + #include "hw/boards.h" + +diff --git a/include/hw/nubus/nubus.h b/include/hw/nubus/nubus.h +index fee79b71d1..7825840dca 100644 +--- a/include/hw/nubus/nubus.h ++++ b/include/hw/nubus/nubus.h +@@ -11,7 +11,7 @@ + + #include "hw/qdev-properties.h" + #include "hw/sysbus.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qom/object.h" + #include "qemu/units.h" + +diff --git a/include/hw/ppc/vof.h b/include/hw/ppc/vof.h +index 2918aaab12..3a0fbffe54 100644 +--- a/include/hw/ppc/vof.h ++++ b/include/hw/ppc/vof.h +@@ -7,7 +7,7 @@ + #define HW_VOF_H + + #include "qom/object.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/memory.h" + #include "exec/cpu-defs.h" + +diff --git a/include/hw/tricore/triboard.h b/include/hw/tricore/triboard.h +index 8250470643..ca49a0c752 100644 +--- a/include/hw/tricore/triboard.h ++++ b/include/hw/tricore/triboard.h +@@ -21,7 +21,7 @@ + #include "qapi/error.h" + #include "hw/boards.h" + #include "system/system.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qom/object.h" + + #include "hw/tricore/tc27x_soc.h" +diff --git a/include/exec/address-spaces.h b/include/system/address-spaces.h +similarity index 89% +rename from include/exec/address-spaces.h +rename to include/system/address-spaces.h +index 0d0aa61d68..72d17afb0f 100644 +--- a/include/exec/address-spaces.h ++++ b/include/system/address-spaces.h +@@ -11,16 +11,14 @@ + * + */ + +-#ifndef EXEC_ADDRESS_SPACES_H +-#define EXEC_ADDRESS_SPACES_H ++#ifndef SYSTEM_ADDRESS_SPACES_H ++#define SYSTEM_ADDRESS_SPACES_H + + /* + * Internal interfaces between memory.c/exec.c/vl.c. Do not #include unless + * you're one of them. + */ + +-#ifndef CONFIG_USER_ONLY +- + /* Get the root memory region. This interface should only be used temporarily + * until a proper bus interface is available. + */ +@@ -35,5 +33,3 @@ extern AddressSpace address_space_memory; + extern AddressSpace address_space_io; + + #endif +- +-#endif +diff --git a/include/system/dma.h b/include/system/dma.h +index aaa03b9711..82e7ad5437 100644 +--- a/include/system/dma.h ++++ b/include/system/dma.h +@@ -11,7 +11,7 @@ + #define DMA_H + + #include "system/memory.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "block/block.h" + #include "block/accounting.h" + +diff --git a/monitor/hmp-cmds-target.c b/monitor/hmp-cmds-target.c +index 6654d31406..011a367357 100644 +--- a/monitor/hmp-cmds-target.c ++++ b/monitor/hmp-cmds-target.c +@@ -24,7 +24,7 @@ + + #include "qemu/osdep.h" + #include "disas/disas.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "system/memory.h" + #include "monitor/hmp-target.h" + #include "monitor/monitor-internal.h" +diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c +index 7ded3378cf..8ddcdd76c1 100644 +--- a/monitor/hmp-cmds.c ++++ b/monitor/hmp-cmds.c +@@ -14,7 +14,7 @@ + */ + + #include "qemu/osdep.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "exec/ioport.h" + #include "exec/gdbstub.h" + #include "gdbstub/enums.h" +diff --git a/rust/wrapper.h b/rust/wrapper.h +index 94866b7e32..beddd9aab2 100644 +--- a/rust/wrapper.h ++++ b/rust/wrapper.h +@@ -64,5 +64,5 @@ typedef enum memory_order { + #include "chardev/char-serial.h" + #include "exec/memattrs.h" + #include "qemu/timer.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/char/pl011.h" +diff --git a/system/ioport.c b/system/ioport.c +index 5f8718486c..2bc14bdcfa 100644 +--- a/system/ioport.c ++++ b/system/ioport.c +@@ -29,7 +29,7 @@ + #include "cpu.h" + #include "exec/ioport.h" + #include "system/memory.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "trace.h" + + struct MemoryRegionPortioList { +diff --git a/system/memory.c b/system/memory.c +index 6d6b33b366..050bffdbf8 100644 +--- a/system/memory.c ++++ b/system/memory.c +@@ -33,7 +33,7 @@ + #include "qemu/accel.h" + #include "hw/boards.h" + #include "migration/vmstate.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + + //#define DEBUG_UNASSIGNED + +diff --git a/system/memory_mapping.c b/system/memory_mapping.c +index 8538a8241e..da708a08ab 100644 +--- a/system/memory_mapping.c ++++ b/system/memory_mapping.c +@@ -17,7 +17,7 @@ + + #include "system/memory_mapping.h" + #include "system/memory.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/core/cpu.h" + + //#define DEBUG_GUEST_PHYS_REGION_ADD +diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c +index 2439af63a0..93a3f9b53d 100644 +--- a/target/arm/hvf/hvf.c ++++ b/target/arm/hvf/hvf.c +@@ -22,7 +22,7 @@ + + #include + +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/boards.h" + #include "hw/irq.h" + #include "qemu/main-loop.h" +diff --git a/target/arm/kvm.c b/target/arm/kvm.c +index da30bdbb23..97de8c7e93 100644 +--- a/target/arm/kvm.c ++++ b/target/arm/kvm.c +@@ -30,7 +30,7 @@ + #include "internals.h" + #include "hw/pci/pci.h" + #include "exec/memattrs.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "gdbstub/enums.h" + #include "hw/boards.h" + #include "hw/irq.h" +diff --git a/target/i386/cpu-apic.c b/target/i386/cpu-apic.c +index c1708b04bb..242a05fdbe 100644 +--- a/target/i386/cpu-apic.c ++++ b/target/i386/cpu-apic.c +@@ -14,7 +14,7 @@ + #include "system/hw_accel.h" + #include "system/kvm.h" + #include "system/xen.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/qdev-properties.h" + #include "hw/i386/apic_internal.h" + #include "cpu-internal.h" +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index aaa6b79410..3c15b7346c 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -38,7 +38,7 @@ + #ifndef CONFIG_USER_ONLY + #include "system/reset.h" + #include "qapi/qapi-commands-machine-target.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/boards.h" + #include "hw/i386/sgx-epc.h" + #endif +diff --git a/target/i386/hvf/vmx.h b/target/i386/hvf/vmx.h +index 80ce26279b..87a478f7fd 100644 +--- a/target/i386/hvf/vmx.h ++++ b/target/i386/hvf/vmx.h +@@ -33,7 +33,7 @@ + #include "system/hvf.h" + #include "system/hvf_int.h" + +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + + static inline uint64_t rreg(hv_vcpuid_t vcpu, hv_x86_reg_t reg) + { +diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c +index e81a245881..b23010374f 100644 +--- a/target/i386/kvm/xen-emu.c ++++ b/target/i386/kvm/xen-emu.c +@@ -17,7 +17,7 @@ + #include "system/kvm_int.h" + #include "system/kvm_xen.h" + #include "kvm/kvm_i386.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "xen-emu.h" + #include "trace.h" + #include "system/runstate.h" +diff --git a/target/i386/nvmm/nvmm-all.c b/target/i386/nvmm/nvmm-all.c +index 04e5f7e637..91f0e32366 100644 +--- a/target/i386/nvmm/nvmm-all.c ++++ b/target/i386/nvmm/nvmm-all.c +@@ -9,7 +9,7 @@ + + #include "qemu/osdep.h" + #include "cpu.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "exec/ioport.h" + #include "qemu/accel.h" + #include "system/nvmm.h" +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 0e1dbb6959..ba88976e9f 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -39,7 +39,7 @@ + #include "qapi/qapi-commands-misc-target.h" + #include "confidential-guest.h" + #include "hw/i386/pc.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "qemu/queue.h" + + OBJECT_DECLARE_TYPE(SevCommonState, SevCommonStateClass, SEV_COMMON) +diff --git a/target/i386/tcg/system/misc_helper.c b/target/i386/tcg/system/misc_helper.c +index ce18c75b9f..0555cf2604 100644 +--- a/target/i386/tcg/system/misc_helper.c ++++ b/target/i386/tcg/system/misc_helper.c +@@ -22,7 +22,7 @@ + #include "cpu.h" + #include "exec/helper-proto.h" + #include "exec/cpu_ldst.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "exec/cputlb.h" + #include "tcg/helper-tcg.h" + #include "hw/i386/apic.h" +diff --git a/target/i386/tcg/system/tcg-cpu.c b/target/i386/tcg/system/tcg-cpu.c +index 13a3507863..ab1f3c7c59 100644 +--- a/target/i386/tcg/system/tcg-cpu.c ++++ b/target/i386/tcg/system/tcg-cpu.c +@@ -23,7 +23,7 @@ + + #include "system/system.h" + #include "qemu/units.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + + #include "tcg/tcg-cpu.h" + +diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c +index 41fb8c5a4e..d58cb11cee 100644 +--- a/target/i386/whpx/whpx-all.c ++++ b/target/i386/whpx/whpx-all.c +@@ -10,7 +10,7 @@ + + #include "qemu/osdep.h" + #include "cpu.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "exec/ioport.h" + #include "gdbstub/helpers.h" + #include "qemu/accel.h" +diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c +index f0e3cfef03..1bda570482 100644 +--- a/target/loongarch/kvm/kvm.c ++++ b/target/loongarch/kvm/kvm.c +@@ -18,7 +18,7 @@ + #include "system/kvm_int.h" + #include "hw/pci/pci.h" + #include "exec/memattrs.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/boards.h" + #include "hw/irq.h" + #include "hw/loongarch/virt.h" +diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c +index 0f4997a918..5315134e08 100644 +--- a/target/riscv/kvm/kvm-cpu.c ++++ b/target/riscv/kvm/kvm-cpu.c +@@ -35,7 +35,7 @@ + #include "accel/accel-cpu-target.h" + #include "hw/pci/pci.h" + #include "exec/memattrs.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/boards.h" + #include "hw/irq.h" + #include "hw/intc/riscv_imsic.h" +diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c +index d8f483898d..b079d120db 100644 +--- a/target/s390x/mmu_helper.c ++++ b/target/s390x/mmu_helper.c +@@ -17,7 +17,7 @@ + + #include "qemu/osdep.h" + #include "qemu/error-report.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "cpu.h" + #include "s390x-internal.h" + #include "kvm/kvm_s390x.h" +diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c +index 6a4d9c5081..a3347f1236 100644 +--- a/target/s390x/sigp.c ++++ b/target/s390x/sigp.c +@@ -14,7 +14,7 @@ + #include "hw/boards.h" + #include "system/hw_accel.h" + #include "system/runstate.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "exec/cputlb.h" + #include "exec/exec-all.h" + #include "system/tcg.h" +diff --git a/target/s390x/tcg/excp_helper.c b/target/s390x/tcg/excp_helper.c +index f969850f87..ac733f407f 100644 +--- a/target/s390x/tcg/excp_helper.c ++++ b/target/s390x/tcg/excp_helper.c +@@ -28,7 +28,7 @@ + #include "tcg_s390x.h" + #ifndef CONFIG_USER_ONLY + #include "qemu/timer.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + #include "hw/s390x/ioinst.h" + #include "hw/s390x/s390_flic.h" + #include "hw/boards.h" +diff --git a/target/xtensa/dbg_helper.c b/target/xtensa/dbg_helper.c +index 5546c82ecd..163a1ffc7b 100644 +--- a/target/xtensa/dbg_helper.c ++++ b/target/xtensa/dbg_helper.c +@@ -31,7 +31,7 @@ + #include "exec/helper-proto.h" + #include "qemu/host-utils.h" + #include "exec/exec-all.h" +-#include "exec/address-spaces.h" ++#include "system/address-spaces.h" + + void HELPER(wsr_ibreakenable)(CPUXtensaState *env, uint32_t v) + { +-- +2.47.3 + diff --git a/kvm-include-system-Move-exec-ioport.h-to-system-ioport.h.patch b/kvm-include-system-Move-exec-ioport.h-to-system-ioport.h.patch new file mode 100644 index 0000000..57232f5 --- /dev/null +++ b/kvm-include-system-Move-exec-ioport.h-to-system-ioport.h.patch @@ -0,0 +1,249 @@ +From 6589e76f2453f8b8251e45409c23a98ebce76583 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 25 Jul 2025 16:38:38 +0200 +Subject: [PATCH 009/100] include/system: Move exec/ioport.h to system/ioport.h +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Convert the existing includes with sed. + +Reviewed-by: Philippe Mathieu-DaudĂ© +Reviewed-by: Pierrick Bouvier +Signed-off-by: Richard Henderson +(cherry picked from commit 91a853837da22e35d140471058e5d73dbfa87707) +Signed-off-by: Paolo Bonzini + +Conflicts: trivial in system/ioport.c +--- + MAINTAINERS | 2 +- + hw/block/fdc-isa.c | 2 +- + hw/display/vga_int.h | 2 +- + include/hw/char/parallel-isa.h | 2 +- + include/hw/dma/i8257.h | 2 +- + include/hw/ide/ide-bus.h | 2 +- + include/hw/isa/isa.h | 2 +- + include/{exec => system}/ioport.h | 6 ++---- + monitor/hmp-cmds.c | 2 +- + system/ioport.c | 2 +- + system/physmem.c | 2 +- + system/qtest.c | 2 +- + target/i386/nvmm/nvmm-all.c | 2 +- + target/i386/whpx/whpx-all.c | 2 +- + tests/qtest/fuzz/qtest_wrappers.c | 2 +- + 15 files changed, 16 insertions(+), 18 deletions(-) + rename include/{exec => system}/ioport.h (97%) + +diff --git a/MAINTAINERS b/MAINTAINERS +index 02ae4a9f48..b7efd609c2 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -3105,7 +3105,7 @@ M: Peter Xu + M: David Hildenbrand + R: Philippe Mathieu-DaudĂ© + S: Supported +-F: include/exec/ioport.h ++F: include/system/ioport.h + F: include/exec/memop.h + F: include/system/memory.h + F: include/exec/ram_addr.h +diff --git a/hw/block/fdc-isa.c b/hw/block/fdc-isa.c +index a10c24aab1..561cfa47c1 100644 +--- a/hw/block/fdc-isa.c ++++ b/hw/block/fdc-isa.c +@@ -42,7 +42,7 @@ + #include "system/block-backend.h" + #include "system/blockdev.h" + #include "system/system.h" +-#include "exec/ioport.h" ++#include "system/ioport.h" + #include "qemu/log.h" + #include "qemu/main-loop.h" + #include "qemu/module.h" +diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h +index 60ad26e03e..747b5cc6cf 100644 +--- a/hw/display/vga_int.h ++++ b/hw/display/vga_int.h +@@ -26,7 +26,7 @@ + #define HW_VGA_INT_H + + #include "ui/console.h" +-#include "exec/ioport.h" ++#include "system/ioport.h" + #include "system/memory.h" + + #include "hw/display/bochs-vbe.h" +diff --git a/include/hw/char/parallel-isa.h b/include/hw/char/parallel-isa.h +index 5284b2ffec..3edaf9dbe4 100644 +--- a/include/hw/char/parallel-isa.h ++++ b/include/hw/char/parallel-isa.h +@@ -12,7 +12,7 @@ + + #include "parallel.h" + +-#include "exec/ioport.h" ++#include "system/ioport.h" + #include "hw/isa/isa.h" + #include "qom/object.h" + +diff --git a/include/hw/dma/i8257.h b/include/hw/dma/i8257.h +index 4342e4a91e..33b6286d5a 100644 +--- a/include/hw/dma/i8257.h ++++ b/include/hw/dma/i8257.h +@@ -2,7 +2,7 @@ + #define HW_I8257_H + + #include "hw/isa/isa.h" +-#include "exec/ioport.h" ++#include "system/ioport.h" + #include "qom/object.h" + + #define TYPE_I8257 "i8257" +diff --git a/include/hw/ide/ide-bus.h b/include/hw/ide/ide-bus.h +index 4841a7dcd6..121b455fcd 100644 +--- a/include/hw/ide/ide-bus.h ++++ b/include/hw/ide/ide-bus.h +@@ -1,7 +1,7 @@ + #ifndef HW_IDE_BUS_H + #define HW_IDE_BUS_H + +-#include "exec/ioport.h" ++#include "system/ioport.h" + #include "hw/ide/ide-dev.h" + #include "hw/ide/ide-dma.h" + +diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h +index 1d852011b3..a82c5f1004 100644 +--- a/include/hw/isa/isa.h ++++ b/include/hw/isa/isa.h +@@ -4,7 +4,7 @@ + /* ISA bus */ + + #include "system/memory.h" +-#include "exec/ioport.h" ++#include "system/ioport.h" + #include "hw/qdev-core.h" + #include "qom/object.h" + +diff --git a/include/exec/ioport.h b/include/system/ioport.h +similarity index 97% +rename from include/exec/ioport.h +rename to include/system/ioport.h +index ecea3575bc..780ea5a676 100644 +--- a/include/exec/ioport.h ++++ b/include/system/ioport.h +@@ -21,8 +21,8 @@ + * IO ports API + */ + +-#ifndef IOPORT_H +-#define IOPORT_H ++#ifndef SYSTEM_IOPORT_H ++#define SYSTEM_IOPORT_H + + #include "system/memory.h" + +@@ -39,9 +39,7 @@ typedef struct MemoryRegionPortio { + + #define PORTIO_END_OF_LIST() { } + +-#ifndef CONFIG_USER_ONLY + extern const MemoryRegionOps unassigned_io_ops; +-#endif + + void cpu_outb(uint32_t addr, uint8_t val); + void cpu_outw(uint32_t addr, uint16_t val); +diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c +index 8ddcdd76c1..74a0f56566 100644 +--- a/monitor/hmp-cmds.c ++++ b/monitor/hmp-cmds.c +@@ -15,7 +15,7 @@ + + #include "qemu/osdep.h" + #include "system/address-spaces.h" +-#include "exec/ioport.h" ++#include "system/ioport.h" + #include "exec/gdbstub.h" + #include "gdbstub/enums.h" + #include "monitor/hmp.h" +diff --git a/system/ioport.c b/system/ioport.c +index 2bc14bdcfa..ec5c586cf8 100644 +--- a/system/ioport.c ++++ b/system/ioport.c +@@ -27,7 +27,7 @@ + + #include "qemu/osdep.h" + #include "cpu.h" +-#include "exec/ioport.h" ++#include "system/ioport.h" + #include "system/memory.h" + #include "system/address-spaces.h" + #include "trace.h" +diff --git a/system/physmem.c b/system/physmem.c +index e61fea41b5..234e489199 100644 +--- a/system/physmem.c ++++ b/system/physmem.c +@@ -51,7 +51,7 @@ + #include "qemu/memalign.h" + #include "qemu/memfd.h" + #include "system/memory.h" +-#include "exec/ioport.h" ++#include "system/ioport.h" + #include "system/dma.h" + #include "system/hostmem.h" + #include "system/hw_accel.h" +diff --git a/system/qtest.c b/system/qtest.c +index 5407289154..523a047995 100644 +--- a/system/qtest.c ++++ b/system/qtest.c +@@ -16,7 +16,7 @@ + #include "system/qtest.h" + #include "system/runstate.h" + #include "chardev/char-fe.h" +-#include "exec/ioport.h" ++#include "system/ioport.h" + #include "system/memory.h" + #include "exec/tswap.h" + #include "hw/qdev-core.h" +diff --git a/target/i386/nvmm/nvmm-all.c b/target/i386/nvmm/nvmm-all.c +index 91f0e32366..17394d073d 100644 +--- a/target/i386/nvmm/nvmm-all.c ++++ b/target/i386/nvmm/nvmm-all.c +@@ -10,7 +10,7 @@ + #include "qemu/osdep.h" + #include "cpu.h" + #include "system/address-spaces.h" +-#include "exec/ioport.h" ++#include "system/ioport.h" + #include "qemu/accel.h" + #include "system/nvmm.h" + #include "system/cpus.h" +diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c +index d58cb11cee..b64852e13e 100644 +--- a/target/i386/whpx/whpx-all.c ++++ b/target/i386/whpx/whpx-all.c +@@ -11,7 +11,7 @@ + #include "qemu/osdep.h" + #include "cpu.h" + #include "system/address-spaces.h" +-#include "exec/ioport.h" ++#include "system/ioport.h" + #include "gdbstub/helpers.h" + #include "qemu/accel.h" + #include "system/whpx.h" +diff --git a/tests/qtest/fuzz/qtest_wrappers.c b/tests/qtest/fuzz/qtest_wrappers.c +index 0580f8df86..d7adcbe3fd 100644 +--- a/tests/qtest/fuzz/qtest_wrappers.c ++++ b/tests/qtest/fuzz/qtest_wrappers.c +@@ -13,7 +13,7 @@ + + #include "qemu/osdep.h" + #include "hw/core/cpu.h" +-#include "exec/ioport.h" ++#include "system/ioport.h" + + #include "fuzz.h" + +-- +2.47.3 + diff --git a/kvm-include-system-Move-exec-memory.h-to-system-memory.h.patch b/kvm-include-system-Move-exec-memory.h-to-system-memory.h.patch new file mode 100644 index 0000000..47a70d8 --- /dev/null +++ b/kvm-include-system-Move-exec-memory.h-to-system-memory.h.patch @@ -0,0 +1,2190 @@ +From f29ae2f4d82db1272603c7d473fef091d9ac47b3 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 25 Jul 2025 16:37:58 +0200 +Subject: [PATCH 007/100] include/system: Move exec/memory.h to system/memory.h +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Convert the existing includes with + + sed -i ,exec/memory.h,system/memory.h,g + +Move the include within cpu-all.h into a !CONFIG_USER_ONLY block. + +Reviewed-by: Philippe Mathieu-DaudĂ© +Reviewed-by: Pierrick Bouvier +Signed-off-by: Richard Henderson +(cherry picked from commit 8be545ba5a315a9aaf7307f143a4a7926a6e605c) +Signed-off-by: Paolo Bonzini + +Conflicts: trivial in include/exec/ram_addr.h, target/avr/cpu.h; do not + move include around in include/exec/cpu-all.h +--- + MAINTAINERS | 2 +- + accel/kvm/kvm-all.c | 2 +- + accel/tcg/cputlb.c | 2 +- + backends/tpm/tpm_util.c | 2 +- + block/blkio.c | 4 ++-- + disas/disas-mon.c | 2 +- + docs/devel/memory.rst | 2 +- + hw/acpi/erst.c | 2 +- + hw/arm/strongarm.h | 2 +- + hw/avr/atmega.c | 2 +- + hw/block/fdc-sysbus.c | 2 +- + hw/core/cpu-system.c | 2 +- + hw/core/loader-fit.c | 2 +- + hw/core/loader.c | 2 +- + hw/display/apple-gfx.h | 2 +- + hw/display/edid-region.c | 2 +- + hw/display/framebuffer.h | 2 +- + hw/display/vga_int.h | 2 +- + hw/hyperv/hv-balloon-our_range_memslots.h | 2 +- + hw/hyperv/hyperv.c | 2 +- + hw/i386/acpi-common.c | 2 +- + hw/i386/acpi-microvm.c | 2 +- + hw/i386/pc_piix.c | 2 +- + hw/intc/ioapic_internal.h | 2 +- + hw/intc/mips_gic.c | 2 +- + hw/intc/ompic.c | 2 +- + hw/net/i82596.h | 2 +- + hw/net/ne2000.c | 2 +- + hw/net/pcnet.h | 2 +- + hw/pci-bridge/pci_bridge_dev.c | 2 +- + hw/pci-host/remote.c | 2 +- + hw/ppc/pnv_homer.c | 2 +- + hw/ppc/sam460ex.c | 2 +- + hw/remote/iommu.c | 2 +- + hw/remote/machine.c | 2 +- + hw/remote/proxy-memory-listener.c | 2 +- + hw/remote/vfio-user-obj.c | 2 +- + hw/s390x/s390-pci-inst.c | 2 +- + hw/timer/sh_timer.c | 2 +- + hw/tpm/tpm_ppi.h | 2 +- + hw/usb/hcd-uhci.h | 2 +- + hw/vfio/common.c | 2 +- + hw/vfio/container.c | 2 +- + hw/vfio/pci.h | 2 +- + hw/vfio/platform.c | 2 +- + hw/virtio/vhost-iova-tree.h | 2 +- + hw/xtensa/sim.c | 2 +- + hw/xtensa/virt.c | 2 +- + hw/xtensa/xtensa_memory.c | 2 +- + hw/xtensa/xtfpga.c | 2 +- + include/exec/cpu-all.h | 4 +++- + include/exec/ioport.h | 2 +- + include/hw/acpi/acpi.h | 2 +- + include/hw/acpi/ich9_tco.h | 2 +- + include/hw/arm/fsl-imx25.h | 2 +- + include/hw/arm/fsl-imx31.h | 2 +- + include/hw/arm/fsl-imx6.h | 2 +- + include/hw/arm/fsl-imx6ul.h | 2 +- + include/hw/arm/omap.h | 2 +- + include/hw/arm/stm32l4x5_soc.h | 2 +- + include/hw/boards.h | 2 +- + include/hw/char/parallel.h | 2 +- + include/hw/char/riscv_htif.h | 2 +- + include/hw/char/serial-mm.h | 2 +- + include/hw/char/serial.h | 2 +- + include/hw/display/macfb.h | 2 +- + include/hw/fsi/aspeed_apb2opb.h | 2 +- + include/hw/fsi/cfam.h | 2 +- + include/hw/fsi/fsi-master.h | 2 +- + include/hw/fsi/fsi.h | 2 +- + include/hw/fsi/lbus.h | 2 +- + include/hw/gpio/npcm7xx_gpio.h | 2 +- + include/hw/i2c/npcm7xx_smbus.h | 2 +- + include/hw/i2c/pm_smbus.h | 2 +- + include/hw/i386/apic_internal.h | 2 +- + include/hw/i386/x86.h | 2 +- + include/hw/ide/ahci.h | 2 +- + include/hw/ipmi/ipmi.h | 2 +- + include/hw/isa/apm.h | 2 +- + include/hw/isa/isa.h | 2 +- + include/hw/m68k/q800.h | 2 +- + include/hw/mem/npcm7xx_mc.h | 2 +- + include/hw/mem/pc-dimm.h | 2 +- + include/hw/mips/mips.h | 2 +- + include/hw/misc/auxbus.h | 2 +- + include/hw/misc/ivshmem-flat.h | 2 +- + include/hw/misc/mac_via.h | 2 +- + include/hw/misc/npcm7xx_mft.h | 2 +- + include/hw/misc/npcm_clk.h | 2 +- + include/hw/misc/npcm_gcr.h | 2 +- + include/hw/misc/pvpanic.h | 2 +- + include/hw/net/dp8393x.h | 2 +- + include/hw/net/msf2-emac.h | 2 +- + include/hw/nvram/mac_nvram.h | 2 +- + include/hw/nvram/npcm7xx_otp.h | 2 +- + include/hw/pci-host/fsl_imx8m_phy.h | 2 +- + include/hw/pci-host/pam.h | 2 +- + include/hw/pci-host/remote.h | 2 +- + include/hw/pci/pci.h | 2 +- + include/hw/pci/pcie_host.h | 2 +- + include/hw/pci/shpc.h | 2 +- + include/hw/ppc/mac_dbdma.h | 2 +- + include/hw/ppc/pnv_lpc.h | 2 +- + include/hw/ppc/pnv_occ.h | 2 +- + include/hw/ppc/pnv_sbe.h | 2 +- + include/hw/ppc/pnv_xscom.h | 2 +- + include/hw/ppc/ppc4xx.h | 2 +- + include/hw/ppc/vof.h | 2 +- + include/hw/ppc/xics.h | 2 +- + include/hw/register.h | 2 +- + include/hw/remote/proxy-memory-listener.h | 2 +- + include/hw/sh4/sh_intc.h | 2 +- + include/hw/southbridge/ich9.h | 2 +- + include/hw/sysbus.h | 2 +- + include/hw/timer/npcm7xx_timer.h | 2 +- + include/hw/tricore/tricore.h | 2 +- + include/hw/usb.h | 2 +- + include/hw/vfio/vfio-common.h | 2 +- + include/hw/vfio/vfio-container-base.h | 2 +- + include/hw/virtio/vhost-backend.h | 2 +- + include/hw/virtio/vhost.h | 2 +- + include/hw/virtio/virtio.h | 2 +- + include/hw/xen/xen-pvh-common.h | 2 +- + include/hw/xtensa/mx_pic.h | 2 +- + include/qemu/iova-tree.h | 2 +- + include/qemu/reserved-region.h | 2 +- + include/system/dma.h | 2 +- + include/system/hostmem.h | 2 +- + include/system/kvm_int.h | 2 +- + include/{exec => system}/memory.h | 8 ++------ + include/system/vhost-user-backend.h | 2 +- + migration/dirtyrate.c | 2 +- + migration/rdma.c | 2 +- + migration/rdma.h | 2 +- + migration/savevm.c | 2 +- + monitor/hmp-cmds-target.c | 2 +- + rust/wrapper.h | 2 +- + scripts/analyze-inclusions | 2 +- + stubs/ram-block.c | 2 +- + system/dirtylimit.c | 2 +- + system/ioport.c | 2 +- + system/memory.c | 2 +- + system/memory_mapping.c | 2 +- + system/physmem.c | 2 +- + system/qtest.c | 2 +- + target/loongarch/cpu.h | 2 +- + target/mips/cpu.h | 2 +- + target/xtensa/cpu.c | 2 +- + tests/qtest/fuzz/generic_fuzz.c | 2 +- + tests/qtest/fuzz/qos_fuzz.c | 2 +- + tests/unit/test-resv-mem.c | 2 +- + ui/console.c | 2 +- + util/vfio-helpers.c | 2 +- + 153 files changed, 157 insertions(+), 159 deletions(-) + rename include/{exec => system}/memory.h (99%) + +diff --git a/MAINTAINERS b/MAINTAINERS +index 465aedbcfb..02ae4a9f48 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -3107,7 +3107,7 @@ R: Philippe Mathieu-DaudĂ© + S: Supported + F: include/exec/ioport.h + F: include/exec/memop.h +-F: include/exec/memory.h ++F: include/system/memory.h + F: include/exec/ram_addr.h + F: include/exec/ramblock.h + F: include/system/memory_mapping.h +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index f89568bfa3..0d47bb0d9b 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -33,7 +33,7 @@ + #include "system/cpus.h" + #include "system/accel-blocker.h" + #include "qemu/bswap.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/ram_addr.h" + #include "qemu/event_notifier.h" + #include "qemu/main-loop.h" +diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c +index fb22048876..2bf21348b0 100644 +--- a/accel/tcg/cputlb.c ++++ b/accel/tcg/cputlb.c +@@ -22,7 +22,7 @@ + #include "accel/tcg/cpu-ops.h" + #include "exec/exec-all.h" + #include "exec/page-protection.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/cpu_ldst.h" + #include "exec/cputlb.h" + #include "exec/tb-flush.h" +diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c +index f07a2656ce..f2d1739e33 100644 +--- a/backends/tpm/tpm_util.c ++++ b/backends/tpm/tpm_util.c +@@ -25,7 +25,7 @@ + #include "qapi/error.h" + #include "qapi/visitor.h" + #include "tpm_int.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/qdev-properties.h" + #include "system/tpm_backend.h" + #include "system/tpm_util.h" +diff --git a/block/blkio.c b/block/blkio.c +index 5f4fce2b1b..4142673984 100644 +--- a/block/blkio.c ++++ b/block/blkio.c +@@ -11,7 +11,7 @@ + #include "qemu/osdep.h" + #include + #include "block/block_int.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/cpu-common.h" /* for qemu_ram_get_fd() */ + #include "qemu/defer-call.h" + #include "qapi/error.h" +@@ -19,7 +19,7 @@ + #include "qobject/qdict.h" + #include "qemu/module.h" + #include "system/block-backend.h" +-#include "exec/memory.h" /* for ram_block_discard_disable() */ ++#include "system/memory.h" /* for ram_block_discard_disable() */ + + #include "block/block-io.h" + +diff --git a/disas/disas-mon.c b/disas/disas-mon.c +index 37bf16ac79..9c693618c2 100644 +--- a/disas/disas-mon.c ++++ b/disas/disas-mon.c +@@ -7,7 +7,7 @@ + #include "qemu/osdep.h" + #include "disas-internal.h" + #include "disas/disas.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/core/cpu.h" + #include "monitor/monitor.h" + +diff --git a/docs/devel/memory.rst b/docs/devel/memory.rst +index 69c5e3f914..57fb2aec76 100644 +--- a/docs/devel/memory.rst ++++ b/docs/devel/memory.rst +@@ -369,4 +369,4 @@ callbacks are called: + API Reference + ------------- + +-.. kernel-doc:: include/exec/memory.h ++.. kernel-doc:: include/system/memory.h +diff --git a/hw/acpi/erst.c b/hw/acpi/erst.c +index ec64f92893..5c4c1dc638 100644 +--- a/hw/acpi/erst.c ++++ b/hw/acpi/erst.c +@@ -12,7 +12,7 @@ + #include "qemu/osdep.h" + #include "qapi/error.h" + #include "hw/qdev-core.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qom/object.h" + #include "hw/pci/pci_device.h" + #include "qom/object_interfaces.h" +diff --git a/hw/arm/strongarm.h b/hw/arm/strongarm.h +index 192821f6aa..b11b3a3379 100644 +--- a/hw/arm/strongarm.h ++++ b/hw/arm/strongarm.h +@@ -1,7 +1,7 @@ + #ifndef STRONGARM_H + #define STRONGARM_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "target/arm/cpu-qom.h" + + #define SA_CS0 0x00000000 +diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c +index f6844bf118..59c0160283 100644 +--- a/hw/avr/atmega.c ++++ b/hw/avr/atmega.c +@@ -12,7 +12,7 @@ + #include "qemu/module.h" + #include "qemu/units.h" + #include "qapi/error.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/address-spaces.h" + #include "system/system.h" + #include "hw/qdev-properties.h" +diff --git a/hw/block/fdc-sysbus.c b/hw/block/fdc-sysbus.c +index 381b492aec..4955e478cd 100644 +--- a/hw/block/fdc-sysbus.c ++++ b/hw/block/fdc-sysbus.c +@@ -26,7 +26,7 @@ + #include "qemu/osdep.h" + #include "qapi/error.h" + #include "qom/object.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/sysbus.h" + #include "hw/block/fdc.h" + #include "migration/vmstate.h" +diff --git a/hw/core/cpu-system.c b/hw/core/cpu-system.c +index aed5076ec7..5ef8c24b5b 100644 +--- a/hw/core/cpu-system.c ++++ b/hw/core/cpu-system.c +@@ -22,7 +22,7 @@ + #include "qapi/error.h" + #include "exec/address-spaces.h" + #include "exec/cputlb.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/tb-flush.h" + #include "exec/tswap.h" + #include "hw/qdev-core.h" +diff --git a/hw/core/loader-fit.c b/hw/core/loader-fit.c +index 6eb66406b0..2dea485ae0 100644 +--- a/hw/core/loader-fit.c ++++ b/hw/core/loader-fit.c +@@ -20,7 +20,7 @@ + #include "qemu/osdep.h" + #include "qapi/error.h" + #include "qemu/units.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/loader.h" + #include "hw/loader-fit.h" + #include "qemu/cutils.h" +diff --git a/hw/core/loader.c b/hw/core/loader.c +index 2e35f0aa90..a3aa62d132 100644 +--- a/hw/core/loader.c ++++ b/hw/core/loader.c +@@ -59,7 +59,7 @@ + #include "uboot_image.h" + #include "hw/loader.h" + #include "hw/nvram/fw_cfg.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/boards.h" + #include "qemu/cutils.h" + #include "system/runstate.h" +diff --git a/hw/display/apple-gfx.h b/hw/display/apple-gfx.h +index 3900cdbabb..a8b1d1efc0 100644 +--- a/hw/display/apple-gfx.h ++++ b/hw/display/apple-gfx.h +@@ -9,7 +9,7 @@ + #define QEMU_APPLE_GFX_H + + #include "qemu/queue.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/qdev-properties.h" + #include "ui/surface.h" + +diff --git a/hw/display/edid-region.c b/hw/display/edid-region.c +index 675429dc18..f1596fba9a 100644 +--- a/hw/display/edid-region.c ++++ b/hw/display/edid-region.c +@@ -1,5 +1,5 @@ + #include "qemu/osdep.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/display/edid.h" + + static uint64_t edid_region_read(void *ptr, hwaddr addr, unsigned size) +diff --git a/hw/display/framebuffer.h b/hw/display/framebuffer.h +index 38fa0dcec6..29a828ce7a 100644 +--- a/hw/display/framebuffer.h ++++ b/hw/display/framebuffer.h +@@ -1,7 +1,7 @@ + #ifndef QEMU_FRAMEBUFFER_H + #define QEMU_FRAMEBUFFER_H + +-#include "exec/memory.h" ++#include "system/memory.h" + + /* Framebuffer device helper routines. */ + +diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h +index f77c1c1145..60ad26e03e 100644 +--- a/hw/display/vga_int.h ++++ b/hw/display/vga_int.h +@@ -27,7 +27,7 @@ + + #include "ui/console.h" + #include "exec/ioport.h" +-#include "exec/memory.h" ++#include "system/memory.h" + + #include "hw/display/bochs-vbe.h" + #include "hw/acpi/acpi_aml_interface.h" +diff --git a/hw/hyperv/hv-balloon-our_range_memslots.h b/hw/hyperv/hv-balloon-our_range_memslots.h +index df3b686bc7..b1f19d77da 100644 +--- a/hw/hyperv/hv-balloon-our_range_memslots.h ++++ b/hw/hyperv/hv-balloon-our_range_memslots.h +@@ -11,7 +11,7 @@ + #define HW_HYPERV_HV_BALLOON_OUR_RANGE_MEMSLOTS_H + + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qom/object.h" + #include "hv-balloon-page_range_tree.h" + +diff --git a/hw/hyperv/hyperv.c b/hw/hyperv/hyperv.c +index 831e04f214..382c62d668 100644 +--- a/hw/hyperv/hyperv.c ++++ b/hw/hyperv/hyperv.c +@@ -12,7 +12,7 @@ + #include "qemu/module.h" + #include "qapi/error.h" + #include "exec/address-spaces.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "system/kvm.h" + #include "qemu/bitops.h" + #include "qemu/error-report.h" +diff --git a/hw/i386/acpi-common.c b/hw/i386/acpi-common.c +index 0cc2919bb8..7bd08067a7 100644 +--- a/hw/i386/acpi-common.c ++++ b/hw/i386/acpi-common.c +@@ -23,7 +23,7 @@ + #include "qemu/osdep.h" + #include "qapi/error.h" + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/acpi/acpi.h" + #include "hw/acpi/aml-build.h" + #include "hw/acpi/utils.h" +diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c +index 279da6b4aa..bc6571778c 100644 +--- a/hw/i386/acpi-microvm.c ++++ b/hw/i386/acpi-microvm.c +@@ -24,7 +24,7 @@ + #include "qemu/cutils.h" + #include "qapi/error.h" + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/acpi/acpi.h" + #include "hw/acpi/acpi_aml_interface.h" + #include "hw/acpi/aml-build.h" +diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c +index 78e9534a2c..53f4a3565c 100644 +--- a/hw/i386/pc_piix.c ++++ b/hw/i386/pc_piix.c +@@ -47,7 +47,7 @@ + #include "hw/i386/kvm/clock.h" + #include "hw/sysbus.h" + #include "hw/i2c/smbus_eeprom.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/acpi/acpi.h" + #include "qapi/error.h" + #include "qemu/error-report.h" +diff --git a/hw/intc/ioapic_internal.h b/hw/intc/ioapic_internal.h +index 37b8565539..51205767f4 100644 +--- a/hw/intc/ioapic_internal.h ++++ b/hw/intc/ioapic_internal.h +@@ -22,7 +22,7 @@ + #ifndef HW_INTC_IOAPIC_INTERNAL_H + #define HW_INTC_IOAPIC_INTERNAL_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/intc/ioapic.h" + #include "hw/sysbus.h" + #include "qemu/notify.h" +diff --git a/hw/intc/mips_gic.c b/hw/intc/mips_gic.c +index 5e3cbeabec..12d3908938 100644 +--- a/hw/intc/mips_gic.c ++++ b/hw/intc/mips_gic.c +@@ -14,7 +14,7 @@ + #include "qemu/module.h" + #include "qapi/error.h" + #include "hw/sysbus.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "system/kvm.h" + #include "system/reset.h" + #include "kvm_mips.h" +diff --git a/hw/intc/ompic.c b/hw/intc/ompic.c +index 42af4567c6..169baf2ded 100644 +--- a/hw/intc/ompic.c ++++ b/hw/intc/ompic.c +@@ -13,7 +13,7 @@ + #include "hw/qdev-properties.h" + #include "hw/sysbus.h" + #include "migration/vmstate.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qom/object.h" + + #define TYPE_OR1K_OMPIC "or1k-ompic" +diff --git a/hw/net/i82596.h b/hw/net/i82596.h +index f0bbe810eb..4bdfcaf856 100644 +--- a/hw/net/i82596.h ++++ b/hw/net/i82596.h +@@ -3,7 +3,7 @@ + + #define I82596_IOPORT_SIZE 0x20 + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/address-spaces.h" + + #define PORT_RESET 0x00 /* reset 82596 */ +diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c +index b482c5f3af..b1923c8c3e 100644 +--- a/hw/net/ne2000.c ++++ b/hw/net/ne2000.c +@@ -25,7 +25,7 @@ + #include "qemu/osdep.h" + #include "net/eth.h" + #include "qemu/module.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/irq.h" + #include "migration/vmstate.h" + #include "ne2000.h" +diff --git a/hw/net/pcnet.h b/hw/net/pcnet.h +index eb7f46aab3..a94356ec30 100644 +--- a/hw/net/pcnet.h ++++ b/hw/net/pcnet.h +@@ -7,7 +7,7 @@ + #define PCNET_LOOPTEST_CRC 1 + #define PCNET_LOOPTEST_NOCRC 2 + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/irq.h" + + /* BUS CONFIGURATION REGISTERS */ +diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c +index 0a91a8ae6c..4931ea24f6 100644 +--- a/hw/pci-bridge/pci_bridge_dev.c ++++ b/hw/pci-bridge/pci_bridge_dev.c +@@ -28,7 +28,7 @@ + #include "hw/pci/shpc.h" + #include "hw/pci/slotid_cap.h" + #include "hw/qdev-properties.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/pci/pci_bus.h" + #include "hw/hotplug.h" + #include "qom/object.h" +diff --git a/hw/pci-host/remote.c b/hw/pci-host/remote.c +index bfb25ef6af..be077d075e 100644 +--- a/hw/pci-host/remote.c ++++ b/hw/pci-host/remote.c +@@ -28,7 +28,7 @@ + #include "hw/pci/pcie_host.h" + #include "hw/qdev-properties.h" + #include "hw/pci-host/remote.h" +-#include "exec/memory.h" ++#include "system/memory.h" + + static const char *remote_pcihost_root_bus_path(PCIHostState *host_bridge, + PCIBus *rootbus) +diff --git a/hw/ppc/pnv_homer.c b/hw/ppc/pnv_homer.c +index 18a53a80c1..0521f9a428 100644 +--- a/hw/ppc/pnv_homer.c ++++ b/hw/ppc/pnv_homer.c +@@ -20,7 +20,7 @@ + #include "qemu/log.h" + #include "qapi/error.h" + #include "exec/hwaddr.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "system/cpus.h" + #include "hw/qdev-core.h" + #include "hw/qdev-properties.h" +diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c +index 7dc3b309c8..a070de23cf 100644 +--- a/hw/ppc/sam460ex.c ++++ b/hw/ppc/sam460ex.c +@@ -24,7 +24,7 @@ + #include "exec/page-protection.h" + #include "hw/loader.h" + #include "elf.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "ppc440.h" + #include "hw/pci-host/ppc4xx.h" + #include "hw/block/flash.h" +diff --git a/hw/remote/iommu.c b/hw/remote/iommu.c +index 7c56aad0fc..ec845d1f58 100644 +--- a/hw/remote/iommu.c ++++ b/hw/remote/iommu.c +@@ -13,7 +13,7 @@ + #include "hw/remote/iommu.h" + #include "hw/pci/pci_bus.h" + #include "hw/pci/pci.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/address-spaces.h" + #include "trace.h" + +diff --git a/hw/remote/machine.c b/hw/remote/machine.c +index fdc6c441bb..d4616025e8 100644 +--- a/hw/remote/machine.c ++++ b/hw/remote/machine.c +@@ -16,7 +16,7 @@ + #include "qemu/osdep.h" + + #include "hw/remote/machine.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qapi/error.h" + #include "hw/pci/pci_host.h" + #include "hw/remote/iohub.h" +diff --git a/hw/remote/proxy-memory-listener.c b/hw/remote/proxy-memory-listener.c +index a926f61ebe..ce7f5b9bfb 100644 +--- a/hw/remote/proxy-memory-listener.c ++++ b/hw/remote/proxy-memory-listener.c +@@ -10,7 +10,7 @@ + + #include "qemu/int128.h" + #include "qemu/range.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/cpu-common.h" + #include "exec/ram_addr.h" + #include "qapi/error.h" +diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c +index 6e51a92856..9bdd0a465b 100644 +--- a/hw/remote/vfio-user-obj.c ++++ b/hw/remote/vfio-user-obj.c +@@ -57,7 +57,7 @@ + #include "hw/qdev-core.h" + #include "hw/pci/pci.h" + #include "qemu/timer.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/pci/msi.h" + #include "hw/pci/msix.h" + #include "hw/remote/vfio-user-obj.h" +diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c +index 8cdeb6cb7f..b4e003c19c 100644 +--- a/hw/s390x/s390-pci-inst.c ++++ b/hw/s390x/s390-pci-inst.c +@@ -13,7 +13,7 @@ + + #include "qemu/osdep.h" + #include "exec/memop.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/error-report.h" + #include "system/hw_accel.h" + #include "hw/boards.h" +diff --git a/hw/timer/sh_timer.c b/hw/timer/sh_timer.c +index 7788939766..d4fa32c9d6 100644 +--- a/hw/timer/sh_timer.c ++++ b/hw/timer/sh_timer.c +@@ -9,7 +9,7 @@ + */ + + #include "qemu/osdep.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/log.h" + #include "hw/irq.h" + #include "hw/sh4/sh.h" +diff --git a/hw/tpm/tpm_ppi.h b/hw/tpm/tpm_ppi.h +index bf5d4a300f..88f316ee95 100644 +--- a/hw/tpm/tpm_ppi.h ++++ b/hw/tpm/tpm_ppi.h +@@ -12,7 +12,7 @@ + #ifndef TPM_TPM_PPI_H + #define TPM_TPM_PPI_H + +-#include "exec/memory.h" ++#include "system/memory.h" + + typedef struct TPMPPI { + MemoryRegion ram; +diff --git a/hw/usb/hcd-uhci.h b/hw/usb/hcd-uhci.h +index 6d26b94e92..d4664297cf 100644 +--- a/hw/usb/hcd-uhci.h ++++ b/hw/usb/hcd-uhci.h +@@ -28,7 +28,7 @@ + #ifndef HW_USB_HCD_UHCI_H + #define HW_USB_HCD_UHCI_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/timer.h" + #include "hw/pci/pci_device.h" + #include "hw/usb.h" +diff --git a/hw/vfio/common.c b/hw/vfio/common.c +index 1a0d9290f8..989c6ee83d 100644 +--- a/hw/vfio/common.c ++++ b/hw/vfio/common.c +@@ -28,7 +28,7 @@ + #include "hw/vfio/vfio-common.h" + #include "hw/vfio/pci.h" + #include "exec/address-spaces.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/ram_addr.h" + #include "exec/target_page.h" + #include "hw/hw.h" +diff --git a/hw/vfio/container.c b/hw/vfio/container.c +index 7c57bdd27b..1d1c5f9a77 100644 +--- a/hw/vfio/container.c ++++ b/hw/vfio/container.c +@@ -24,7 +24,7 @@ + + #include "hw/vfio/vfio-common.h" + #include "exec/address-spaces.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/ram_addr.h" + #include "qemu/error-report.h" + #include "qemu/range.h" +diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h +index 3854bbcb26..7e87d33530 100644 +--- a/hw/vfio/pci.h ++++ b/hw/vfio/pci.h +@@ -12,7 +12,7 @@ + #ifndef HW_VFIO_VFIO_PCI_H + #define HW_VFIO_VFIO_PCI_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/pci/pci_device.h" + #include "hw/vfio/vfio-common.h" + #include "qemu/event_notifier.h" +diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c +index 67bc57409c..96c6bf5654 100644 +--- a/hw/vfio/platform.c ++++ b/hw/vfio/platform.c +@@ -28,7 +28,7 @@ + #include "qemu/main-loop.h" + #include "qemu/module.h" + #include "qemu/range.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/address-spaces.h" + #include "qemu/queue.h" + #include "hw/sysbus.h" +diff --git a/hw/virtio/vhost-iova-tree.h b/hw/virtio/vhost-iova-tree.h +index 0c4ba5abd5..08f63b61cd 100644 +--- a/hw/virtio/vhost-iova-tree.h ++++ b/hw/virtio/vhost-iova-tree.h +@@ -11,7 +11,7 @@ + #define HW_VIRTIO_VHOST_IOVA_TREE_H + + #include "qemu/iova-tree.h" +-#include "exec/memory.h" ++#include "system/memory.h" + + typedef struct VhostIOVATree VhostIOVATree; + +diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c +index 1cea29c66d..49d17e7bb2 100644 +--- a/hw/xtensa/sim.c ++++ b/hw/xtensa/sim.c +@@ -32,7 +32,7 @@ + #include "hw/boards.h" + #include "hw/loader.h" + #include "elf.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/error-report.h" + #include "xtensa_memory.h" + #include "xtensa_sim.h" +diff --git a/hw/xtensa/virt.c b/hw/xtensa/virt.c +index b08404fc17..b10866ccd8 100644 +--- a/hw/xtensa/virt.c ++++ b/hw/xtensa/virt.c +@@ -33,7 +33,7 @@ + #include "hw/pci-host/gpex.h" + #include "net/net.h" + #include "elf.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/error-report.h" + #include "xtensa_memory.h" + #include "xtensa_sim.h" +diff --git a/hw/xtensa/xtensa_memory.c b/hw/xtensa/xtensa_memory.c +index 2c1095f017..13a6077d86 100644 +--- a/hw/xtensa/xtensa_memory.c ++++ b/hw/xtensa/xtensa_memory.c +@@ -27,7 +27,7 @@ + + #include "qemu/osdep.h" + #include "qapi/error.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/error-report.h" + #include "xtensa_memory.h" + +diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c +index 3f3677f1c9..3bd0ef8268 100644 +--- a/hw/xtensa/xtfpga.c ++++ b/hw/xtensa/xtfpga.c +@@ -34,7 +34,7 @@ + #include "hw/loader.h" + #include "hw/qdev-properties.h" + #include "elf.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/tswap.h" + #include "hw/char/serial-mm.h" + #include "net/net.h" +diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h +index 47b14446b8..f23a1f17d7 100644 +--- a/include/exec/cpu-all.h ++++ b/include/exec/cpu-all.h +@@ -22,7 +22,9 @@ + #include "exec/page-protection.h" + #include "exec/cpu-common.h" + #include "exec/cpu-interrupt.h" +-#include "exec/memory.h" ++#ifndef CONFIG_USER_ONLY ++#include "system/memory.h" ++#endif + #include "exec/tswap.h" + #include "hw/core/cpu.h" + +diff --git a/include/exec/ioport.h b/include/exec/ioport.h +index 4397f12f93..ecea3575bc 100644 +--- a/include/exec/ioport.h ++++ b/include/exec/ioport.h +@@ -24,7 +24,7 @@ + #ifndef IOPORT_H + #define IOPORT_H + +-#include "exec/memory.h" ++#include "system/memory.h" + + #define MAX_IOPORTS (64 * 1024) + #define IOPORTS_MASK (MAX_IOPORTS - 1) +diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h +index d1a4fa2af8..4b8ee094c4 100644 +--- a/include/hw/acpi/acpi.h ++++ b/include/hw/acpi/acpi.h +@@ -21,7 +21,7 @@ + */ + + #include "qemu/notify.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/acpi/acpi_dev_interface.h" + + /* +diff --git a/include/hw/acpi/ich9_tco.h b/include/hw/acpi/ich9_tco.h +index 2562a7cf39..b3c3f69451 100644 +--- a/include/hw/acpi/ich9_tco.h ++++ b/include/hw/acpi/ich9_tco.h +@@ -10,7 +10,7 @@ + #ifndef HW_ACPI_TCO_H + #define HW_ACPI_TCO_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "migration/vmstate.h" + + /* As per ICH9 spec, the internal timer has an error of ~0.6s on every tick */ +diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h +index df2f83980f..b68d4334a0 100644 +--- a/include/hw/arm/fsl-imx25.h ++++ b/include/hw/arm/fsl-imx25.h +@@ -29,7 +29,7 @@ + #include "hw/sd/sdhci.h" + #include "hw/usb/chipidea.h" + #include "hw/watchdog/wdt_imx2.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "target/arm/cpu.h" + #include "qom/object.h" + +diff --git a/include/hw/arm/fsl-imx31.h b/include/hw/arm/fsl-imx31.h +index 40c593a5cf..41232a2237 100644 +--- a/include/hw/arm/fsl-imx31.h ++++ b/include/hw/arm/fsl-imx31.h +@@ -25,7 +25,7 @@ + #include "hw/i2c/imx_i2c.h" + #include "hw/gpio/imx_gpio.h" + #include "hw/watchdog/wdt_imx2.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "target/arm/cpu.h" + #include "qom/object.h" + +diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h +index 9da32fc189..124bbd478f 100644 +--- a/include/hw/arm/fsl-imx6.h ++++ b/include/hw/arm/fsl-imx6.h +@@ -34,7 +34,7 @@ + #include "hw/usb/imx-usb-phy.h" + #include "hw/pci-host/designware.h" + #include "hw/or-irq.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "cpu.h" + #include "qom/object.h" + +diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h +index 8277b0e8b2..4e3209b25b 100644 +--- a/include/hw/arm/fsl-imx6ul.h ++++ b/include/hw/arm/fsl-imx6ul.h +@@ -33,7 +33,7 @@ + #include "hw/net/imx_fec.h" + #include "hw/usb/chipidea.h" + #include "hw/usb/imx-usb-phy.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "cpu.h" + #include "qom/object.h" + #include "qemu/units.h" +diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h +index 7cb87ea89c..6185507373 100644 +--- a/include/hw/arm/omap.h ++++ b/include/hw/arm/omap.h +@@ -20,7 +20,7 @@ + #ifndef HW_ARM_OMAP_H + #define HW_ARM_OMAP_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "target/arm/cpu-qom.h" + #include "qemu/log.h" + #include "qom/object.h" +diff --git a/include/hw/arm/stm32l4x5_soc.h b/include/hw/arm/stm32l4x5_soc.h +index c243fb0e7f..c2fae6e23f 100644 +--- a/include/hw/arm/stm32l4x5_soc.h ++++ b/include/hw/arm/stm32l4x5_soc.h +@@ -24,7 +24,7 @@ + #ifndef HW_ARM_STM32L4x5_SOC_H + #define HW_ARM_STM32L4x5_SOC_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/arm/armv7m.h" + #include "hw/or-irq.h" + #include "hw/misc/stm32l4x5_syscfg.h" +diff --git a/include/hw/boards.h b/include/hw/boards.h +index a43847767f..e6478f4904 100644 +--- a/include/hw/boards.h ++++ b/include/hw/boards.h +@@ -3,7 +3,7 @@ + #ifndef HW_BOARDS_H + #define HW_BOARDS_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "system/hostmem.h" + #include "system/blockdev.h" + #include "qapi/qapi-types-machine.h" +diff --git a/include/hw/char/parallel.h b/include/hw/char/parallel.h +index cfb97cc7cc..7b04478226 100644 +--- a/include/hw/char/parallel.h ++++ b/include/hw/char/parallel.h +@@ -1,7 +1,7 @@ + #ifndef HW_PARALLEL_H + #define HW_PARALLEL_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/isa/isa.h" + #include "hw/irq.h" + #include "chardev/char-fe.h" +diff --git a/include/hw/char/riscv_htif.h b/include/hw/char/riscv_htif.h +index df493fdf6b..ee0ca29902 100644 +--- a/include/hw/char/riscv_htif.h ++++ b/include/hw/char/riscv_htif.h +@@ -22,7 +22,7 @@ + + #include "chardev/char.h" + #include "chardev/char-fe.h" +-#include "exec/memory.h" ++#include "system/memory.h" + + #define TYPE_HTIF_UART "riscv.htif.uart" + +diff --git a/include/hw/char/serial-mm.h b/include/hw/char/serial-mm.h +index 62a8489d69..77abd098e0 100644 +--- a/include/hw/char/serial-mm.h ++++ b/include/hw/char/serial-mm.h +@@ -27,7 +27,7 @@ + #define HW_SERIAL_MM_H + + #include "hw/char/serial.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "chardev/char.h" + #include "hw/sysbus.h" + #include "qom/object.h" +diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h +index 942b372df6..4bf90a46f3 100644 +--- a/include/hw/char/serial.h ++++ b/include/hw/char/serial.h +@@ -27,7 +27,7 @@ + #define HW_SERIAL_H + + #include "chardev/char-fe.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/fifo8.h" + #include "qom/object.h" + +diff --git a/include/hw/display/macfb.h b/include/hw/display/macfb.h +index 27cebefc9e..0fae1f33a6 100644 +--- a/include/hw/display/macfb.h ++++ b/include/hw/display/macfb.h +@@ -13,7 +13,7 @@ + #ifndef MACFB_H + #define MACFB_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/irq.h" + #include "hw/nubus/nubus.h" + #include "hw/sysbus.h" +diff --git a/include/hw/fsi/aspeed_apb2opb.h b/include/hw/fsi/aspeed_apb2opb.h +index f6a2387abf..878619eafa 100644 +--- a/include/hw/fsi/aspeed_apb2opb.h ++++ b/include/hw/fsi/aspeed_apb2opb.h +@@ -8,7 +8,7 @@ + #ifndef FSI_ASPEED_APB2OPB_H + #define FSI_ASPEED_APB2OPB_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/fsi/fsi-master.h" + #include "hw/sysbus.h" + +diff --git a/include/hw/fsi/cfam.h b/include/hw/fsi/cfam.h +index 7abc3b287b..cceb4bd6f1 100644 +--- a/include/hw/fsi/cfam.h ++++ b/include/hw/fsi/cfam.h +@@ -7,7 +7,7 @@ + #ifndef FSI_CFAM_H + #define FSI_CFAM_H + +-#include "exec/memory.h" ++#include "system/memory.h" + + #include "hw/fsi/fsi.h" + #include "hw/fsi/lbus.h" +diff --git a/include/hw/fsi/fsi-master.h b/include/hw/fsi/fsi-master.h +index 68e5f56db2..b634ecd393 100644 +--- a/include/hw/fsi/fsi-master.h ++++ b/include/hw/fsi/fsi-master.h +@@ -7,7 +7,7 @@ + #ifndef FSI_FSI_MASTER_H + #define FSI_FSI_MASTER_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/qdev-core.h" + #include "hw/fsi/fsi.h" + #include "hw/fsi/cfam.h" +diff --git a/include/hw/fsi/fsi.h b/include/hw/fsi/fsi.h +index e00f6ef078..f34765ed80 100644 +--- a/include/hw/fsi/fsi.h ++++ b/include/hw/fsi/fsi.h +@@ -7,7 +7,7 @@ + #ifndef FSI_FSI_H + #define FSI_FSI_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/qdev-core.h" + #include "hw/fsi/lbus.h" + #include "qemu/bitops.h" +diff --git a/include/hw/fsi/lbus.h b/include/hw/fsi/lbus.h +index 558268c013..12519073cd 100644 +--- a/include/hw/fsi/lbus.h ++++ b/include/hw/fsi/lbus.h +@@ -9,7 +9,7 @@ + + #include "hw/qdev-core.h" + #include "qemu/units.h" +-#include "exec/memory.h" ++#include "system/memory.h" + + #define TYPE_FSI_LBUS_DEVICE "fsi.lbus.device" + OBJECT_DECLARE_SIMPLE_TYPE(FSILBusDevice, FSI_LBUS_DEVICE) +diff --git a/include/hw/gpio/npcm7xx_gpio.h b/include/hw/gpio/npcm7xx_gpio.h +index b1d771bd77..7c0bf61a96 100644 +--- a/include/hw/gpio/npcm7xx_gpio.h ++++ b/include/hw/gpio/npcm7xx_gpio.h +@@ -15,7 +15,7 @@ + #ifndef NPCM7XX_GPIO_H + #define NPCM7XX_GPIO_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/sysbus.h" + + /* Number of pins managed by each controller. */ +diff --git a/include/hw/i2c/npcm7xx_smbus.h b/include/hw/i2c/npcm7xx_smbus.h +index dc45963c0e..9c544c561b 100644 +--- a/include/hw/i2c/npcm7xx_smbus.h ++++ b/include/hw/i2c/npcm7xx_smbus.h +@@ -16,7 +16,7 @@ + #ifndef NPCM7XX_SMBUS_H + #define NPCM7XX_SMBUS_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/i2c/i2c.h" + #include "hw/irq.h" + #include "hw/sysbus.h" +diff --git a/include/hw/i2c/pm_smbus.h b/include/hw/i2c/pm_smbus.h +index 0d74207efb..dafe0df4f6 100644 +--- a/include/hw/i2c/pm_smbus.h ++++ b/include/hw/i2c/pm_smbus.h +@@ -1,7 +1,7 @@ + #ifndef PM_SMBUS_H + #define PM_SMBUS_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/i2c/smbus_master.h" + + #define PM_SMBUS_MAX_MSG_SIZE 32 +diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h +index d6e85833da..429278da61 100644 +--- a/include/hw/i386/apic_internal.h ++++ b/include/hw/i386/apic_internal.h +@@ -22,7 +22,7 @@ + #define QEMU_APIC_INTERNAL_H + + #include "cpu.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/timer.h" + #include "target/i386/cpu-qom.h" + #include "qom/object.h" +diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h +index d43cb3908e..258b1343a1 100644 +--- a/include/hw/i386/x86.h ++++ b/include/hw/i386/x86.h +@@ -18,7 +18,7 @@ + #define HW_I386_X86_H + + #include "exec/hwaddr.h" +-#include "exec/memory.h" ++#include "system/memory.h" + + #include "hw/boards.h" + #include "hw/i386/topology.h" +diff --git a/include/hw/ide/ahci.h b/include/hw/ide/ahci.h +index ac0292c634..cd07b87811 100644 +--- a/include/hw/ide/ahci.h ++++ b/include/hw/ide/ahci.h +@@ -24,7 +24,7 @@ + #ifndef HW_IDE_AHCI_H + #define HW_IDE_AHCI_H + +-#include "exec/memory.h" ++#include "system/memory.h" + + typedef struct AHCIDevice AHCIDevice; + +diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h +index 77a7213ed9..2882eb7f3d 100644 +--- a/include/hw/ipmi/ipmi.h ++++ b/include/hw/ipmi/ipmi.h +@@ -25,7 +25,7 @@ + #ifndef HW_IPMI_H + #define HW_IPMI_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/qdev-core.h" + #include "qom/object.h" + +diff --git a/include/hw/isa/apm.h b/include/hw/isa/apm.h +index b6e070c00e..0834539045 100644 +--- a/include/hw/isa/apm.h ++++ b/include/hw/isa/apm.h +@@ -1,7 +1,7 @@ + #ifndef APM_H + #define APM_H + +-#include "exec/memory.h" ++#include "system/memory.h" + + #define APM_CNT_IOPORT 0xb2 + #define ACPI_PORT_SMI_CMD APM_CNT_IOPORT +diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h +index 40d6224a4e..1d852011b3 100644 +--- a/include/hw/isa/isa.h ++++ b/include/hw/isa/isa.h +@@ -3,7 +3,7 @@ + + /* ISA bus */ + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/ioport.h" + #include "hw/qdev-core.h" + #include "qom/object.h" +diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h +index 34365c9860..9caaed9692 100644 +--- a/include/hw/m68k/q800.h ++++ b/include/hw/m68k/q800.h +@@ -26,7 +26,7 @@ + #include "hw/boards.h" + #include "qom/object.h" + #include "target/m68k/cpu-qom.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/m68k/q800-glue.h" + #include "hw/misc/mac_via.h" + #include "hw/net/dp8393x.h" +diff --git a/include/hw/mem/npcm7xx_mc.h b/include/hw/mem/npcm7xx_mc.h +index 7ed38be243..568cc35fdd 100644 +--- a/include/hw/mem/npcm7xx_mc.h ++++ b/include/hw/mem/npcm7xx_mc.h +@@ -16,7 +16,7 @@ + #ifndef NPCM7XX_MC_H + #define NPCM7XX_MC_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/sysbus.h" + + /** +diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h +index fe0f3ea963..e0dbdd43dc 100644 +--- a/include/hw/mem/pc-dimm.h ++++ b/include/hw/mem/pc-dimm.h +@@ -16,7 +16,7 @@ + #ifndef QEMU_PC_DIMM_H + #define QEMU_PC_DIMM_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/qdev-core.h" + #include "qom/object.h" + +diff --git a/include/hw/mips/mips.h b/include/hw/mips/mips.h +index 101799f7d3..1f3672ba5f 100644 +--- a/include/hw/mips/mips.h ++++ b/include/hw/mips/mips.h +@@ -7,7 +7,7 @@ + /* Kernels can be configured with 64KB pages */ + #define INITRD_PAGE_SIZE (64 * KiB) + +-#include "exec/memory.h" ++#include "system/memory.h" + + /* bonito.c */ + PCIBus *bonito_init(qemu_irq *pic); +diff --git a/include/hw/misc/auxbus.h b/include/hw/misc/auxbus.h +index 03cacdee42..ccd18ce209 100644 +--- a/include/hw/misc/auxbus.h ++++ b/include/hw/misc/auxbus.h +@@ -25,7 +25,7 @@ + #ifndef HW_MISC_AUXBUS_H + #define HW_MISC_AUXBUS_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/qdev-core.h" + #include "qom/object.h" + +diff --git a/include/hw/misc/ivshmem-flat.h b/include/hw/misc/ivshmem-flat.h +index 0c2b015781..09bc3abcad 100644 +--- a/include/hw/misc/ivshmem-flat.h ++++ b/include/hw/misc/ivshmem-flat.h +@@ -14,7 +14,7 @@ + #include "qemu/queue.h" + #include "qemu/event_notifier.h" + #include "chardev/char-fe.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qom/object.h" + #include "hw/sysbus.h" + +diff --git a/include/hw/misc/mac_via.h b/include/hw/misc/mac_via.h +index 63cdcf7c69..6a15228150 100644 +--- a/include/hw/misc/mac_via.h ++++ b/include/hw/misc/mac_via.h +@@ -9,7 +9,7 @@ + #ifndef HW_MISC_MAC_VIA_H + #define HW_MISC_MAC_VIA_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/sysbus.h" + #include "hw/misc/mos6522.h" + #include "hw/input/adb.h" +diff --git a/include/hw/misc/npcm7xx_mft.h b/include/hw/misc/npcm7xx_mft.h +index d6384382ce..e4b997a6ad 100644 +--- a/include/hw/misc/npcm7xx_mft.h ++++ b/include/hw/misc/npcm7xx_mft.h +@@ -16,7 +16,7 @@ + #ifndef NPCM7XX_MFT_H + #define NPCM7XX_MFT_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/clock.h" + #include "hw/irq.h" + #include "hw/sysbus.h" +diff --git a/include/hw/misc/npcm_clk.h b/include/hw/misc/npcm_clk.h +index 8fa1e14bdd..52e972f460 100644 +--- a/include/hw/misc/npcm_clk.h ++++ b/include/hw/misc/npcm_clk.h +@@ -16,7 +16,7 @@ + #ifndef NPCM_CLK_H + #define NPCM_CLK_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/clock.h" + #include "hw/sysbus.h" + +diff --git a/include/hw/misc/npcm_gcr.h b/include/hw/misc/npcm_gcr.h +index d81bb9afb2..702e7fddb1 100644 +--- a/include/hw/misc/npcm_gcr.h ++++ b/include/hw/misc/npcm_gcr.h +@@ -16,7 +16,7 @@ + #ifndef NPCM_GCR_H + #define NPCM_GCR_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/sysbus.h" + #include "qom/object.h" + +diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h +index 049a94c112..5098693437 100644 +--- a/include/hw/misc/pvpanic.h ++++ b/include/hw/misc/pvpanic.h +@@ -15,7 +15,7 @@ + #ifndef HW_MISC_PVPANIC_H + #define HW_MISC_PVPANIC_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qom/object.h" + + #include "standard-headers/misc/pvpanic.h" +diff --git a/include/hw/net/dp8393x.h b/include/hw/net/dp8393x.h +index 4a3f7478be..24273dc1f4 100644 +--- a/include/hw/net/dp8393x.h ++++ b/include/hw/net/dp8393x.h +@@ -22,7 +22,7 @@ + + #include "hw/sysbus.h" + #include "net/net.h" +-#include "exec/memory.h" ++#include "system/memory.h" + + #define SONIC_REG_COUNT 0x40 + +diff --git a/include/hw/net/msf2-emac.h b/include/hw/net/msf2-emac.h +index 846ba6e6dc..b5d9127e46 100644 +--- a/include/hw/net/msf2-emac.h ++++ b/include/hw/net/msf2-emac.h +@@ -23,7 +23,7 @@ + */ + + #include "hw/sysbus.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "net/net.h" + #include "net/eth.h" + #include "qom/object.h" +diff --git a/include/hw/nvram/mac_nvram.h b/include/hw/nvram/mac_nvram.h +index 0c4dfaeff6..e9d8398f84 100644 +--- a/include/hw/nvram/mac_nvram.h ++++ b/include/hw/nvram/mac_nvram.h +@@ -26,7 +26,7 @@ + #ifndef MAC_NVRAM_H + #define MAC_NVRAM_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/sysbus.h" + + #define MACIO_NVRAM_SIZE 0x2000 +diff --git a/include/hw/nvram/npcm7xx_otp.h b/include/hw/nvram/npcm7xx_otp.h +index ea4b5d0731..77b05f8b82 100644 +--- a/include/hw/nvram/npcm7xx_otp.h ++++ b/include/hw/nvram/npcm7xx_otp.h +@@ -16,7 +16,7 @@ + #ifndef NPCM7XX_OTP_H + #define NPCM7XX_OTP_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/sysbus.h" + + /* Each OTP module holds 8192 bits of one-time programmable storage */ +diff --git a/include/hw/pci-host/fsl_imx8m_phy.h b/include/hw/pci-host/fsl_imx8m_phy.h +index 4f4875b37d..5f1b212fd9 100644 +--- a/include/hw/pci-host/fsl_imx8m_phy.h ++++ b/include/hw/pci-host/fsl_imx8m_phy.h +@@ -11,7 +11,7 @@ + + #include "hw/sysbus.h" + #include "qom/object.h" +-#include "exec/memory.h" ++#include "system/memory.h" + + #define TYPE_FSL_IMX8M_PCIE_PHY "fsl-imx8m-pcie-phy" + OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mPciePhyState, FSL_IMX8M_PCIE_PHY) +diff --git a/include/hw/pci-host/pam.h b/include/hw/pci-host/pam.h +index 005916f826..44f3908160 100644 +--- a/include/hw/pci-host/pam.h ++++ b/include/hw/pci-host/pam.h +@@ -50,7 +50,7 @@ + * 0xf0000 - 0xfffff System BIOS Area Memory Segments + */ + +-#include "exec/memory.h" ++#include "system/memory.h" + + #define SMRAM_C_BASE 0xa0000 + #define SMRAM_C_END 0xc0000 +diff --git a/include/hw/pci-host/remote.h b/include/hw/pci-host/remote.h +index 690a01f0fe..5264c35936 100644 +--- a/include/hw/pci-host/remote.h ++++ b/include/hw/pci-host/remote.h +@@ -11,7 +11,7 @@ + #ifndef PCI_HOST_REMOTE_H + #define PCI_HOST_REMOTE_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/pci/pcie_host.h" + + #define TYPE_REMOTE_PCIHOST "remote-pcihost" +diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h +index 822fbacdf0..c2fe6caa2c 100644 +--- a/include/hw/pci/pci.h ++++ b/include/hw/pci/pci.h +@@ -1,7 +1,7 @@ + #ifndef QEMU_PCI_H + #define QEMU_PCI_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "system/dma.h" + #include "system/host_iommu_device.h" + +diff --git a/include/hw/pci/pcie_host.h b/include/hw/pci/pcie_host.h +index 82d92177da..f09de76bfe 100644 +--- a/include/hw/pci/pcie_host.h ++++ b/include/hw/pci/pcie_host.h +@@ -22,7 +22,7 @@ + #define PCIE_HOST_H + + #include "hw/pci/pci_host.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qom/object.h" + + #define TYPE_PCIE_HOST_BRIDGE "pcie-host-bridge" +diff --git a/include/hw/pci/shpc.h b/include/hw/pci/shpc.h +index a0789df153..ad1089567a 100644 +--- a/include/hw/pci/shpc.h ++++ b/include/hw/pci/shpc.h +@@ -1,7 +1,7 @@ + #ifndef SHPC_H + #define SHPC_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/hotplug.h" + #include "hw/pci/pci_device.h" + #include "migration/vmstate.h" +diff --git a/include/hw/ppc/mac_dbdma.h b/include/hw/ppc/mac_dbdma.h +index 672c2be471..896ee4a2b1 100644 +--- a/include/hw/ppc/mac_dbdma.h ++++ b/include/hw/ppc/mac_dbdma.h +@@ -23,7 +23,7 @@ + #ifndef HW_MAC_DBDMA_H + #define HW_MAC_DBDMA_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/iov.h" + #include "system/dma.h" + #include "hw/sysbus.h" +diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h +index 174add4c53..266d56214f 100644 +--- a/include/hw/ppc/pnv_lpc.h ++++ b/include/hw/ppc/pnv_lpc.h +@@ -20,7 +20,7 @@ + #ifndef PPC_PNV_LPC_H + #define PPC_PNV_LPC_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/ppc/pnv.h" + #include "hw/qdev-core.h" + #include "hw/isa/isa.h" /* For ISA_NUM_IRQS */ +diff --git a/include/hw/ppc/pnv_occ.h b/include/hw/ppc/pnv_occ.h +index 3ec42de0ff..013ea2e53e 100644 +--- a/include/hw/ppc/pnv_occ.h ++++ b/include/hw/ppc/pnv_occ.h +@@ -20,7 +20,7 @@ + #ifndef PPC_PNV_OCC_H + #define PPC_PNV_OCC_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/qdev-core.h" + + #define TYPE_PNV_OCC "pnv-occ" +diff --git a/include/hw/ppc/pnv_sbe.h b/include/hw/ppc/pnv_sbe.h +index b6b378ad14..48a8b86a80 100644 +--- a/include/hw/ppc/pnv_sbe.h ++++ b/include/hw/ppc/pnv_sbe.h +@@ -20,7 +20,7 @@ + #ifndef PPC_PNV_SBE_H + #define PPC_PNV_SBE_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/qdev-core.h" + + #define TYPE_PNV_SBE "pnv-sbe" +diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h +index a927aea1c0..b14549db70 100644 +--- a/include/hw/ppc/pnv_xscom.h ++++ b/include/hw/ppc/pnv_xscom.h +@@ -20,7 +20,7 @@ + #ifndef PPC_PNV_XSCOM_H + #define PPC_PNV_XSCOM_H + +-#include "exec/memory.h" ++#include "system/memory.h" + + typedef struct PnvXScomInterface PnvXScomInterface; + typedef struct PnvChip PnvChip; +diff --git a/include/hw/ppc/ppc4xx.h b/include/hw/ppc/ppc4xx.h +index 1bd9b8821b..2e94b00673 100644 +--- a/include/hw/ppc/ppc4xx.h ++++ b/include/hw/ppc/ppc4xx.h +@@ -26,7 +26,7 @@ + #define PPC4XX_H + + #include "hw/ppc/ppc.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/sysbus.h" + + /* +diff --git a/include/hw/ppc/vof.h b/include/hw/ppc/vof.h +index d3f293da8b..2918aaab12 100644 +--- a/include/hw/ppc/vof.h ++++ b/include/hw/ppc/vof.h +@@ -8,7 +8,7 @@ + + #include "qom/object.h" + #include "exec/address-spaces.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/cpu-defs.h" + + typedef struct Vof { +diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h +index e94d53405f..097fcdf00f 100644 +--- a/include/hw/ppc/xics.h ++++ b/include/hw/ppc/xics.h +@@ -28,7 +28,7 @@ + #ifndef XICS_H + #define XICS_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/qdev-core.h" + #include "qom/object.h" + +diff --git a/include/hw/register.h b/include/hw/register.h +index 6a076cfcdf..a913c52aee 100644 +--- a/include/hw/register.h ++++ b/include/hw/register.h +@@ -12,7 +12,7 @@ + #define REGISTER_H + + #include "hw/qdev-core.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/registerfields.h" + #include "qom/object.h" + +diff --git a/include/hw/remote/proxy-memory-listener.h b/include/hw/remote/proxy-memory-listener.h +index c4f3efb928..ec516d8267 100644 +--- a/include/hw/remote/proxy-memory-listener.h ++++ b/include/hw/remote/proxy-memory-listener.h +@@ -9,7 +9,7 @@ + #ifndef PROXY_MEMORY_LISTENER_H + #define PROXY_MEMORY_LISTENER_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "io/channel.h" + + typedef struct ProxyMemoryListener { +diff --git a/include/hw/sh4/sh_intc.h b/include/hw/sh4/sh_intc.h +index f62d5c5e13..94f183121e 100644 +--- a/include/hw/sh4/sh_intc.h ++++ b/include/hw/sh4/sh_intc.h +@@ -1,7 +1,7 @@ + #ifndef SH_INTC_H + #define SH_INTC_H + +-#include "exec/memory.h" ++#include "system/memory.h" + + typedef unsigned char intc_enum; + +diff --git a/include/hw/southbridge/ich9.h b/include/hw/southbridge/ich9.h +index 6c60017024..1e231e89c9 100644 +--- a/include/hw/southbridge/ich9.h ++++ b/include/hw/southbridge/ich9.h +@@ -7,7 +7,7 @@ + #include "hw/pci/pci.h" + #include "hw/pci/pci_device.h" + #include "hw/rtc/mc146818rtc.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/notify.h" + #include "qom/object.h" + +diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h +index 81bbda10d3..7dc88aaa27 100644 +--- a/include/hw/sysbus.h ++++ b/include/hw/sysbus.h +@@ -4,7 +4,7 @@ + /* Devices attached directly to the main system bus. */ + + #include "hw/qdev-core.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qom/object.h" + + #define QDEV_MAX_MMIO 32 +diff --git a/include/hw/timer/npcm7xx_timer.h b/include/hw/timer/npcm7xx_timer.h +index d45c051b56..e287375dce 100644 +--- a/include/hw/timer/npcm7xx_timer.h ++++ b/include/hw/timer/npcm7xx_timer.h +@@ -16,7 +16,7 @@ + #ifndef NPCM7XX_TIMER_H + #define NPCM7XX_TIMER_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/sysbus.h" + #include "qemu/timer.h" + +diff --git a/include/hw/tricore/tricore.h b/include/hw/tricore/tricore.h +index c19ed3f013..4ffc0fe1d6 100644 +--- a/include/hw/tricore/tricore.h ++++ b/include/hw/tricore/tricore.h +@@ -1,7 +1,7 @@ + #ifndef HW_TRICORE_H + #define HW_TRICORE_H + +-#include "exec/memory.h" ++#include "system/memory.h" + + struct tricore_boot_info { + uint64_t ram_size; +diff --git a/include/hw/usb.h b/include/hw/usb.h +index e410693d0c..26a9f3ecde 100644 +--- a/include/hw/usb.h ++++ b/include/hw/usb.h +@@ -25,7 +25,7 @@ + * THE SOFTWARE. + */ + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/qdev-core.h" + #include "qemu/iov.h" + #include "qemu/queue.h" +diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h +index 04b123a6c9..f5b3f45a43 100644 +--- a/include/hw/vfio/vfio-common.h ++++ b/include/hw/vfio/vfio-common.h +@@ -21,7 +21,7 @@ + #ifndef HW_VFIO_VFIO_COMMON_H + #define HW_VFIO_VFIO_COMMON_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/queue.h" + #include "qemu/notify.h" + #include "ui/console.h" +diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h +index 4cff9943ab..6aca02fb3d 100644 +--- a/include/hw/vfio/vfio-container-base.h ++++ b/include/hw/vfio/vfio-container-base.h +@@ -13,7 +13,7 @@ + #ifndef HW_VFIO_VFIO_CONTAINER_BASE_H + #define HW_VFIO_VFIO_CONTAINER_BASE_H + +-#include "exec/memory.h" ++#include "system/memory.h" + + typedef struct VFIODevice VFIODevice; + typedef struct VFIOIOMMUClass VFIOIOMMUClass; +diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h +index 70c2e8ffee..d6df209a2f 100644 +--- a/include/hw/virtio/vhost-backend.h ++++ b/include/hw/virtio/vhost-backend.h +@@ -11,7 +11,7 @@ + #ifndef VHOST_BACKEND_H + #define VHOST_BACKEND_H + +-#include "exec/memory.h" ++#include "system/memory.h" + + typedef enum VhostBackendType { + VHOST_BACKEND_TYPE_NONE = 0, +diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h +index a9469d50bc..bb4b58e115 100644 +--- a/include/hw/virtio/vhost.h ++++ b/include/hw/virtio/vhost.h +@@ -3,7 +3,7 @@ + + #include "hw/virtio/vhost-backend.h" + #include "hw/virtio/virtio.h" +-#include "exec/memory.h" ++#include "system/memory.h" + + #define VHOST_F_DEVICE_IOTLB 63 + #define VHOST_USER_F_PROTOCOL_FEATURES 30 +diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h +index 6386910280..7e0c471ea4 100644 +--- a/include/hw/virtio/virtio.h ++++ b/include/hw/virtio/virtio.h +@@ -14,7 +14,7 @@ + #ifndef QEMU_VIRTIO_H + #define QEMU_VIRTIO_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "hw/qdev-core.h" + #include "net/net.h" + #include "migration/vmstate.h" +diff --git a/include/hw/xen/xen-pvh-common.h b/include/hw/xen/xen-pvh-common.h +index 17c5a58a5a..5db83d88ec 100644 +--- a/include/hw/xen/xen-pvh-common.h ++++ b/include/hw/xen/xen-pvh-common.h +@@ -9,7 +9,7 @@ + #ifndef XEN_PVH_COMMON_H__ + #define XEN_PVH_COMMON_H__ + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qom/object.h" + #include "hw/boards.h" + #include "hw/pci-host/gpex.h" +diff --git a/include/hw/xtensa/mx_pic.h b/include/hw/xtensa/mx_pic.h +index 500424c8d3..cd316d86eb 100644 +--- a/include/hw/xtensa/mx_pic.h ++++ b/include/hw/xtensa/mx_pic.h +@@ -28,7 +28,7 @@ + #ifndef XTENSA_MX_PIC_H + #define XTENSA_MX_PIC_H + +-#include "exec/memory.h" ++#include "system/memory.h" + + struct XtensaMxPic; + typedef struct XtensaMxPic XtensaMxPic; +diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h +index 16d354a814..14e82a22d5 100644 +--- a/include/qemu/iova-tree.h ++++ b/include/qemu/iova-tree.h +@@ -23,7 +23,7 @@ + * for the thread safety issue. + */ + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/hwaddr.h" + + #define IOVA_OK (0) +diff --git a/include/qemu/reserved-region.h b/include/qemu/reserved-region.h +index 8e6f0a97e2..9026cf08fd 100644 +--- a/include/qemu/reserved-region.h ++++ b/include/qemu/reserved-region.h +@@ -20,7 +20,7 @@ + #ifndef QEMU_RESERVED_REGION_H + #define QEMU_RESERVED_REGION_H + +-#include "exec/memory.h" ++#include "system/memory.h" + + /* + * Insert a new region into a sorted list of reserved regions. In case +diff --git a/include/system/dma.h b/include/system/dma.h +index e142f7efa6..aaa03b9711 100644 +--- a/include/system/dma.h ++++ b/include/system/dma.h +@@ -10,7 +10,7 @@ + #ifndef DMA_H + #define DMA_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/address-spaces.h" + #include "block/block.h" + #include "block/accounting.h" +diff --git a/include/system/hostmem.h b/include/system/hostmem.h +index 62642e602c..88fa791ac7 100644 +--- a/include/system/hostmem.h ++++ b/include/system/hostmem.h +@@ -16,7 +16,7 @@ + #include "system/numa.h" + #include "qapi/qapi-types-machine.h" + #include "qom/object.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/bitmap.h" + #include "qemu/thread-context.h" + +diff --git a/include/system/kvm_int.h b/include/system/kvm_int.h +index 4de6106869..756a3c0a25 100644 +--- a/include/system/kvm_int.h ++++ b/include/system/kvm_int.h +@@ -9,7 +9,7 @@ + #ifndef QEMU_KVM_INT_H + #define QEMU_KVM_INT_H + +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qapi/qapi-types-common.h" + #include "qemu/accel.h" + #include "qemu/queue.h" +diff --git a/include/exec/memory.h b/include/system/memory.h +similarity index 99% +rename from include/exec/memory.h +rename to include/system/memory.h +index e1c196a0c2..8c0590cd7b 100644 +--- a/include/exec/memory.h ++++ b/include/system/memory.h +@@ -11,10 +11,8 @@ + * + */ + +-#ifndef MEMORY_H +-#define MEMORY_H +- +-#ifndef CONFIG_USER_ONLY ++#ifndef SYSTEM_MEMORY_H ++#define SYSTEM_MEMORY_H + + #include "exec/cpu-common.h" + #include "exec/hwaddr.h" +@@ -3207,5 +3205,3 @@ void ram_block_add_cpr_blocker(RAMBlock *rb, Error **errp); + void ram_block_del_cpr_blocker(RAMBlock *rb); + + #endif +- +-#endif +diff --git a/include/system/vhost-user-backend.h b/include/system/vhost-user-backend.h +index 327b0b84f1..5ed953cd53 100644 +--- a/include/system/vhost-user-backend.h ++++ b/include/system/vhost-user-backend.h +@@ -13,7 +13,7 @@ + #define QEMU_VHOST_USER_BACKEND_H + + #include "qom/object.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/option.h" + #include "qemu/bitmap.h" + #include "hw/virtio/vhost.h" +diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c +index 4cd14779d6..09caf92f87 100644 +--- a/migration/dirtyrate.c ++++ b/migration/dirtyrate.c +@@ -27,7 +27,7 @@ + #include "qobject/qdict.h" + #include "system/kvm.h" + #include "system/runstate.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/xxhash.h" + #include "migration.h" + +diff --git a/migration/rdma.c b/migration/rdma.c +index 76fb034923..d9603ab603 100644 +--- a/migration/rdma.c ++++ b/migration/rdma.c +@@ -30,7 +30,7 @@ + #include "qemu/sockets.h" + #include "qemu/bitmap.h" + #include "qemu/coroutine.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include + #include + #include +diff --git a/migration/rdma.h b/migration/rdma.h +index f55f28bbed..4d3386b84a 100644 +--- a/migration/rdma.h ++++ b/migration/rdma.h +@@ -19,7 +19,7 @@ + #ifndef QEMU_MIGRATION_RDMA_H + #define QEMU_MIGRATION_RDMA_H + +-#include "exec/memory.h" ++#include "system/memory.h" + + void rdma_start_outgoing_migration(void *opaque, InetSocketAddress *host_port, + Error **errp); +diff --git a/migration/savevm.c b/migration/savevm.c +index 23ef4c7dc9..4319b86b8e 100644 +--- a/migration/savevm.c ++++ b/migration/savevm.c +@@ -48,7 +48,7 @@ + #include "qapi/qapi-builtin-visit.h" + #include "qemu/error-report.h" + #include "system/cpus.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/target_page.h" + #include "trace.h" + #include "qemu/iov.h" +diff --git a/monitor/hmp-cmds-target.c b/monitor/hmp-cmds-target.c +index 239c2a61a4..6654d31406 100644 +--- a/monitor/hmp-cmds-target.c ++++ b/monitor/hmp-cmds-target.c +@@ -25,7 +25,7 @@ + #include "qemu/osdep.h" + #include "disas/disas.h" + #include "exec/address-spaces.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "monitor/hmp-target.h" + #include "monitor/monitor-internal.h" + #include "qapi/error.h" +diff --git a/rust/wrapper.h b/rust/wrapper.h +index d4fec54657..94866b7e32 100644 +--- a/rust/wrapper.h ++++ b/rust/wrapper.h +@@ -52,7 +52,7 @@ typedef enum memory_order { + #include "qemu-io.h" + #include "system/system.h" + #include "hw/sysbus.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "chardev/char-fe.h" + #include "hw/clock.h" + #include "hw/qdev-clock.h" +diff --git a/scripts/analyze-inclusions b/scripts/analyze-inclusions +index b6280f25c8..d2c566667d 100644 +--- a/scripts/analyze-inclusions ++++ b/scripts/analyze-inclusions +@@ -53,7 +53,7 @@ echo $(grep_include -F 'trace/generated-tracers.h') files include generated-trac + echo $(grep_include -F 'qapi/error.h') files include qapi/error.h + echo $(grep_include -F 'qom/object.h') files include qom/object.h + echo $(grep_include -F 'block/aio.h') files include block/aio.h +-echo $(grep_include -F 'exec/memory.h') files include exec/memory.h ++echo $(grep_include -F 'system/memory.h') files include system/memory.h + echo $(grep_include -F 'fpu/softfloat.h') files include fpu/softfloat.h + echo $(grep_include -F 'qemu/bswap.h') files include qemu/bswap.h + echo +diff --git a/stubs/ram-block.c b/stubs/ram-block.c +index 108197683b..e88fab31a5 100644 +--- a/stubs/ram-block.c ++++ b/stubs/ram-block.c +@@ -1,7 +1,7 @@ + #include "qemu/osdep.h" + #include "exec/ramlist.h" + #include "exec/cpu-common.h" +-#include "exec/memory.h" ++#include "system/memory.h" + + void *qemu_ram_get_host_addr(RAMBlock *rb) + { +diff --git a/system/dirtylimit.c b/system/dirtylimit.c +index 7dedef8dd4..30cd09f3d1 100644 +--- a/system/dirtylimit.c ++++ b/system/dirtylimit.c +@@ -19,7 +19,7 @@ + #include "system/dirtylimit.h" + #include "monitor/hmp.h" + #include "monitor/monitor.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/target_page.h" + #include "hw/boards.h" + #include "system/kvm.h" +diff --git a/system/ioport.c b/system/ioport.c +index 55c2a75239..5f8718486c 100644 +--- a/system/ioport.c ++++ b/system/ioport.c +@@ -28,7 +28,7 @@ + #include "qemu/osdep.h" + #include "cpu.h" + #include "exec/ioport.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/address-spaces.h" + #include "trace.h" + +diff --git a/system/memory.c b/system/memory.c +index 4c829793a0..6d6b33b366 100644 +--- a/system/memory.c ++++ b/system/memory.c +@@ -16,7 +16,7 @@ + #include "qemu/osdep.h" + #include "qemu/log.h" + #include "qapi/error.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qapi/visitor.h" + #include "qemu/bitops.h" + #include "qemu/error-report.h" +diff --git a/system/memory_mapping.c b/system/memory_mapping.c +index 37d3325f77..8538a8241e 100644 +--- a/system/memory_mapping.c ++++ b/system/memory_mapping.c +@@ -16,7 +16,7 @@ + #include "qapi/error.h" + + #include "system/memory_mapping.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/address-spaces.h" + #include "hw/core/cpu.h" + +diff --git a/system/physmem.c b/system/physmem.c +index 333a5eb94d..e61fea41b5 100644 +--- a/system/physmem.c ++++ b/system/physmem.c +@@ -50,7 +50,7 @@ + #include "qemu/log.h" + #include "qemu/memalign.h" + #include "qemu/memfd.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/ioport.h" + #include "system/dma.h" + #include "system/hostmem.h" +diff --git a/system/qtest.c b/system/qtest.c +index 12152efbcd..5407289154 100644 +--- a/system/qtest.c ++++ b/system/qtest.c +@@ -17,7 +17,7 @@ + #include "system/runstate.h" + #include "chardev/char-fe.h" + #include "exec/ioport.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/tswap.h" + #include "hw/qdev-core.h" + #include "hw/irq.h" +diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h +index 254e4fbdcd..02ef6ddecb 100644 +--- a/target/loongarch/cpu.h ++++ b/target/loongarch/cpu.h +@@ -14,7 +14,7 @@ + #include "hw/registerfields.h" + #include "qemu/timer.h" + #ifndef CONFIG_USER_ONLY +-#include "exec/memory.h" ++#include "system/memory.h" + #endif + #include "cpu-csr.h" + #include "cpu-qom.h" +diff --git a/target/mips/cpu.h b/target/mips/cpu.h +index f6877ece8b..9ef72a95d7 100644 +--- a/target/mips/cpu.h ++++ b/target/mips/cpu.h +@@ -4,7 +4,7 @@ + #include "cpu-qom.h" + #include "exec/cpu-defs.h" + #ifndef CONFIG_USER_ONLY +-#include "exec/memory.h" ++#include "system/memory.h" + #endif + #include "fpu/softfloat-types.h" + #include "hw/clock.h" +diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c +index 7663b62d01..ec6a0a8b66 100644 +--- a/target/xtensa/cpu.c ++++ b/target/xtensa/cpu.c +@@ -36,7 +36,7 @@ + #include "migration/vmstate.h" + #include "hw/qdev-clock.h" + #ifndef CONFIG_USER_ONLY +-#include "exec/memory.h" ++#include "system/memory.h" + #endif + + +diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c +index d107a496da..239be9372d 100644 +--- a/tests/qtest/fuzz/generic_fuzz.c ++++ b/tests/qtest/fuzz/generic_fuzz.c +@@ -20,7 +20,7 @@ + #include "tests/qtest/libqos/pci-pc.h" + #include "fuzz.h" + #include "string.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "exec/ramblock.h" + #include "hw/qdev-core.h" + #include "hw/pci/pci.h" +diff --git a/tests/qtest/fuzz/qos_fuzz.c b/tests/qtest/fuzz/qos_fuzz.c +index d3839bf999..9afe8bf6d8 100644 +--- a/tests/qtest/fuzz/qos_fuzz.c ++++ b/tests/qtest/fuzz/qos_fuzz.c +@@ -19,7 +19,7 @@ + #include "qemu/osdep.h" + #include "qemu/units.h" + #include "qapi/error.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/main-loop.h" + + #include "tests/qtest/libqtest.h" +diff --git a/tests/unit/test-resv-mem.c b/tests/unit/test-resv-mem.c +index cd8f7318cc..4de2d042d1 100644 +--- a/tests/unit/test-resv-mem.c ++++ b/tests/unit/test-resv-mem.c +@@ -10,7 +10,7 @@ + + #include "qemu/osdep.h" + #include "qemu/range.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qemu/reserved-region.h" + + #define DEBUG 0 +diff --git a/ui/console.c b/ui/console.c +index 6456e8dd90..6cd122cf40 100644 +--- a/ui/console.c ++++ b/ui/console.c +@@ -35,7 +35,7 @@ + #include "qemu/option.h" + #include "chardev/char.h" + #include "trace.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "qom/object.h" + #include "qemu/memfd.h" + +diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c +index f8bab46c68..fdff042ab4 100644 +--- a/util/vfio-helpers.c ++++ b/util/vfio-helpers.c +@@ -16,7 +16,7 @@ + #include "qapi/error.h" + #include "exec/ramlist.h" + #include "exec/cpu-common.h" +-#include "exec/memory.h" ++#include "system/memory.h" + #include "trace.h" + #include "qemu/error-report.h" + #include "standard-headers/linux/pci_regs.h" +-- +2.47.3 + diff --git a/kvm-include-system-Move-exec-ram_addr.h-to-system-ram_ad.patch b/kvm-include-system-Move-exec-ram_addr.h-to-system-ram_ad.patch new file mode 100644 index 0000000..f04d892 --- /dev/null +++ b/kvm-include-system-Move-exec-ram_addr.h-to-system-ram_ad.patch @@ -0,0 +1,362 @@ +From 938de067b15a76a87f1ffb9c323168d5110e7d13 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 25 Jul 2025 16:39:48 +0200 +Subject: [PATCH 010/100] include/system: Move exec/ram_addr.h to + system/ram_addr.h +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Convert the existing includes with sed. + +Reviewed-by: Philippe Mathieu-DaudĂ© +Reviewed-by: Pierrick Bouvier +Signed-off-by: Richard Henderson +(cherry picked from commit 4705a71db5909ac5586e87397b2dece132b9e330) +Signed-off-by: Paolo Bonzini + +Conflicts: trivial in include/system/ram_addr.h +--- + MAINTAINERS | 2 +- + accel/kvm/kvm-all.c | 2 +- + accel/tcg/cputlb.c | 2 +- + accel/tcg/translate-all.c | 2 +- + hw/ppc/spapr.c | 2 +- + hw/ppc/spapr_caps.c | 2 +- + hw/ppc/spapr_pci.c | 2 +- + hw/remote/memory.c | 2 +- + hw/remote/proxy-memory-listener.c | 2 +- + hw/s390x/s390-stattrib-kvm.c | 2 +- + hw/s390x/s390-stattrib.c | 2 +- + hw/s390x/s390-virtio-ccw.c | 2 +- + hw/vfio/common.c | 3 +-- + hw/vfio/container.c | 2 +- + hw/vfio/spapr.c | 2 +- + hw/virtio/virtio-mem.c | 2 +- + include/{exec => system}/ram_addr.h | 7 +++---- + migration/ram.c | 2 +- + system/memory.c | 2 +- + system/physmem.c | 2 +- + target/arm/tcg/mte_helper.c | 2 +- + target/ppc/kvm.c | 2 +- + target/s390x/kvm/kvm.c | 2 +- + 23 files changed, 25 insertions(+), 27 deletions(-) + rename include/{exec => system}/ram_addr.h (99%) + +diff --git a/MAINTAINERS b/MAINTAINERS +index b7efd609c2..86df4aa512 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -3108,7 +3108,7 @@ S: Supported + F: include/system/ioport.h + F: include/exec/memop.h + F: include/system/memory.h +-F: include/exec/ram_addr.h ++F: include/system/ram_addr.h + F: include/exec/ramblock.h + F: include/system/memory_mapping.h + F: system/dma-helpers.c +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index 0d47bb0d9b..0723a3933b 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -34,7 +34,7 @@ + #include "system/accel-blocker.h" + #include "qemu/bswap.h" + #include "system/memory.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "qemu/event_notifier.h" + #include "qemu/main-loop.h" + #include "trace.h" +diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c +index 2bf21348b0..ca8fe313ef 100644 +--- a/accel/tcg/cputlb.c ++++ b/accel/tcg/cputlb.c +@@ -27,7 +27,7 @@ + #include "exec/cputlb.h" + #include "exec/tb-flush.h" + #include "exec/memory-internal.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "exec/mmu-access-type.h" + #include "exec/tlb-common.h" + #include "exec/vaddr.h" +diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c +index 82bc16bd53..dd08734fdf 100644 +--- a/accel/tcg/translate-all.c ++++ b/accel/tcg/translate-all.c +@@ -40,7 +40,7 @@ + #endif + #endif + #else +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #endif + + #include "exec/cputlb.h" +diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c +index b0a0f8c689..e0e7509c59 100644 +--- a/hw/ppc/spapr.c ++++ b/hw/ppc/spapr.c +@@ -77,7 +77,7 @@ + #include "hw/virtio/virtio-scsi.h" + #include "hw/virtio/vhost-scsi-common.h" + +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "system/confidential-guest-support.h" + #include "hw/usb.h" + #include "qemu/config-file.h" +diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c +index 815c94ed2f..f2f5722d8a 100644 +--- a/hw/ppc/spapr_caps.c ++++ b/hw/ppc/spapr_caps.c +@@ -27,7 +27,7 @@ + #include "qapi/error.h" + #include "qapi/visitor.h" + #include "system/hw_accel.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "target/ppc/cpu.h" + #include "target/ppc/mmu-hash64.h" + #include "cpu-models.h" +diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c +index e0a9d50edc..384269b831 100644 +--- a/hw/ppc/spapr_pci.c ++++ b/hw/ppc/spapr_pci.c +@@ -34,7 +34,7 @@ + #include "hw/pci/pci_host.h" + #include "hw/ppc/spapr.h" + #include "hw/pci-host/spapr.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include + #include "trace.h" + #include "qemu/error-report.h" +diff --git a/hw/remote/memory.c b/hw/remote/memory.c +index 6d60da91e0..00193a552f 100644 +--- a/hw/remote/memory.c ++++ b/hw/remote/memory.c +@@ -11,7 +11,7 @@ + #include "qemu/osdep.h" + + #include "hw/remote/memory.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "qapi/error.h" + + static void remote_sysmem_reset(void) +diff --git a/hw/remote/proxy-memory-listener.c b/hw/remote/proxy-memory-listener.c +index ce7f5b9bfb..30ac74961d 100644 +--- a/hw/remote/proxy-memory-listener.c ++++ b/hw/remote/proxy-memory-listener.c +@@ -12,7 +12,7 @@ + #include "qemu/range.h" + #include "system/memory.h" + #include "exec/cpu-common.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "qapi/error.h" + #include "qemu/error-report.h" + #include "hw/remote/mpqemu-link.h" +diff --git a/hw/s390x/s390-stattrib-kvm.c b/hw/s390x/s390-stattrib-kvm.c +index 2a8e31718b..f5695b0e53 100644 +--- a/hw/s390x/s390-stattrib-kvm.c ++++ b/hw/s390x/s390-stattrib-kvm.c +@@ -16,7 +16,7 @@ + #include "qemu/error-report.h" + #include "system/kvm.h" + #include "system/memory_mapping.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "kvm/kvm_s390x.h" + #include "qapi/error.h" + +diff --git a/hw/s390x/s390-stattrib.c b/hw/s390x/s390-stattrib.c +index be07c28c6e..d95b58a8a8 100644 +--- a/hw/s390x/s390-stattrib.c ++++ b/hw/s390x/s390-stattrib.c +@@ -16,7 +16,7 @@ + #include "hw/qdev-properties.h" + #include "hw/s390x/storage-attributes.h" + #include "qemu/error-report.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "qapi/error.h" + #include "qobject/qdict.h" + #include "cpu.h" +diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c +index dd3fc13683..ca7cea850a 100644 +--- a/hw/s390x/s390-virtio-ccw.c ++++ b/hw/s390x/s390-virtio-ccw.c +@@ -13,7 +13,7 @@ + + #include "qemu/osdep.h" + #include "qapi/error.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "system/confidential-guest-support.h" + #include "hw/boards.h" + #include "hw/s390x/sclp.h" +diff --git a/hw/vfio/common.c b/hw/vfio/common.c +index 98832af88d..bae0633c3d 100644 +--- a/hw/vfio/common.c ++++ b/hw/vfio/common.c +@@ -29,8 +29,7 @@ + #include "hw/vfio/pci.h" + #include "system/address-spaces.h" + #include "system/memory.h" +-#include "exec/ram_addr.h" +-#include "exec/target_page.h" ++#include "system/ram_addr.h" + #include "hw/hw.h" + #include "qemu/error-report.h" + #include "qemu/main-loop.h" +diff --git a/hw/vfio/container.c b/hw/vfio/container.c +index 2e993c7e73..812d5edbcf 100644 +--- a/hw/vfio/container.c ++++ b/hw/vfio/container.c +@@ -25,7 +25,7 @@ + #include "hw/vfio/vfio-common.h" + #include "system/address-spaces.h" + #include "system/memory.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "qemu/error-report.h" + #include "qemu/range.h" + #include "system/reset.h" +diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c +index c9a7dd8d68..66a2d2bb0d 100644 +--- a/hw/vfio/spapr.c ++++ b/hw/vfio/spapr.c +@@ -17,7 +17,7 @@ + + #include "hw/vfio/vfio-common.h" + #include "hw/hw.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "qemu/error-report.h" + #include "qapi/error.h" + #include "trace.h" +diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c +index 391d85c652..cefb43aca2 100644 +--- a/hw/virtio/virtio-mem.c ++++ b/hw/virtio/virtio-mem.c +@@ -24,7 +24,7 @@ + #include "hw/virtio/virtio-mem.h" + #include "qapi/error.h" + #include "qapi/visitor.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "migration/misc.h" + #include "hw/boards.h" + #include "hw/qdev-properties.h" +diff --git a/include/exec/ram_addr.h b/include/system/ram_addr.h +similarity index 99% +rename from include/exec/ram_addr.h +rename to include/system/ram_addr.h +index e4c28fbec9..3550a5df7c 100644 +--- a/include/exec/ram_addr.h ++++ b/include/system/ram_addr.h +@@ -16,10 +16,9 @@ + * The functions declared here will be removed soon. + */ + +-#ifndef RAM_ADDR_H +-#define RAM_ADDR_H ++#ifndef SYSTEM_RAM_ADDR_H ++#define SYSTEM_RAM_ADDR_H + +-#ifndef CONFIG_USER_ONLY + #include "cpu.h" + #include "system/xen.h" + #include "system/tcg.h" +@@ -554,5 +553,5 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb, + + return num_dirty; + } +-#endif ++ + #endif +diff --git a/migration/ram.c b/migration/ram.c +index 6f390b28d9..e0468210bd 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -48,7 +48,7 @@ + #include "qapi/qapi-commands-migration.h" + #include "qapi/qmp/qerror.h" + #include "trace.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "exec/target_page.h" + #include "qemu/rcu_queue.h" + #include "migration/colo.h" +diff --git a/system/memory.c b/system/memory.c +index 050bffdbf8..faddcbfd8a 100644 +--- a/system/memory.c ++++ b/system/memory.c +@@ -26,7 +26,7 @@ + #include "trace.h" + + #include "exec/memory-internal.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "system/kvm.h" + #include "system/runstate.h" + #include "system/tcg.h" +diff --git a/system/physmem.c b/system/physmem.c +index 234e489199..307d0764b6 100644 +--- a/system/physmem.c ++++ b/system/physmem.c +@@ -67,7 +67,7 @@ + #include "system/replay.h" + + #include "exec/memory-internal.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + + #include "qemu/pmem.h" + +diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c +index 5d6d8a17ae..80164a8050 100644 +--- a/target/arm/tcg/mte_helper.c ++++ b/target/arm/tcg/mte_helper.c +@@ -27,7 +27,7 @@ + #include "user/cpu_loop.h" + #include "user/page-protection.h" + #else +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #endif + #include "exec/cpu_ldst.h" + #include "exec/helper-proto.h" +diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c +index 992356cb75..8b12b8e7d2 100644 +--- a/target/ppc/kvm.c ++++ b/target/ppc/kvm.c +@@ -41,7 +41,7 @@ + #include "trace.h" + #include "gdbstub/enums.h" + #include "exec/memattrs.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "system/hostmem.h" + #include "qemu/cutils.h" + #include "qemu/main-loop.h" +diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c +index 4d56e653dd..b9f1422197 100644 +--- a/target/s390x/kvm/kvm.c ++++ b/target/s390x/kvm/kvm.c +@@ -41,7 +41,7 @@ + #include "system/runstate.h" + #include "system/device_tree.h" + #include "gdbstub/enums.h" +-#include "exec/ram_addr.h" ++#include "system/ram_addr.h" + #include "trace.h" + #include "hw/s390x/s390-pci-inst.h" + #include "hw/s390x/s390-pci-bus.h" +-- +2.47.3 + diff --git a/kvm-include-system-Move-exec-ramblock.h-to-system-ramblo.patch b/kvm-include-system-Move-exec-ramblock.h-to-system-ramblo.patch new file mode 100644 index 0000000..5f9c4c4 --- /dev/null +++ b/kvm-include-system-Move-exec-ramblock.h-to-system-ramblo.patch @@ -0,0 +1,291 @@ +From 1d5c95eaddcfd7f9c2764597a4e89a9e8a3e4beb Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 25 Jul 2025 16:43:16 +0200 +Subject: [PATCH 011/100] include/system: Move exec/ramblock.h to + system/ramblock.h +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Convert the existing includes with sed. + +Reviewed-by: Philippe Mathieu-DaudĂ© +Reviewed-by: Pierrick Bouvier +Signed-off-by: Richard Henderson +(cherry picked from commit 548a01650c9be153b352406cd4afb86cb350788e) +Signed-off-by: Paolo Bonzini +--- + MAINTAINERS | 2 +- + hw/display/virtio-gpu-udmabuf.c | 2 +- + hw/hyperv/hv-balloon.c | 2 +- + hw/virtio/vhost-user.c | 2 +- + include/system/ram_addr.h | 2 +- + include/{exec => system}/ramblock.h | 9 ++++----- + migration/dirtyrate.c | 2 +- + migration/file.c | 2 +- + migration/multifd-nocomp.c | 2 +- + migration/multifd-qatzip.c | 2 +- + migration/multifd-qpl.c | 2 +- + migration/multifd-uadk.c | 2 +- + migration/multifd-zero-page.c | 2 +- + migration/multifd-zlib.c | 2 +- + migration/multifd-zstd.c | 2 +- + migration/multifd.c | 2 +- + migration/postcopy-ram.c | 2 +- + tests/qtest/fuzz/generic_fuzz.c | 2 +- + 18 files changed, 21 insertions(+), 22 deletions(-) + rename include/{exec => system}/ramblock.h (96%) + +diff --git a/MAINTAINERS b/MAINTAINERS +index 86df4aa512..9016c2ede2 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -3109,7 +3109,7 @@ F: include/system/ioport.h + F: include/exec/memop.h + F: include/system/memory.h + F: include/system/ram_addr.h +-F: include/exec/ramblock.h ++F: include/system/ramblock.h + F: include/system/memory_mapping.h + F: system/dma-helpers.c + F: system/ioport.c +diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c +index 85ca23cb32..0510577475 100644 +--- a/hw/display/virtio-gpu-udmabuf.c ++++ b/hw/display/virtio-gpu-udmabuf.c +@@ -19,7 +19,7 @@ + #include "hw/virtio/virtio-gpu.h" + #include "hw/virtio/virtio-gpu-pixman.h" + #include "trace.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + #include "system/hostmem.h" + #include + #include +diff --git a/hw/hyperv/hv-balloon.c b/hw/hyperv/hv-balloon.c +index 0b1da723c8..acabff2c4a 100644 +--- a/hw/hyperv/hv-balloon.c ++++ b/hw/hyperv/hv-balloon.c +@@ -12,7 +12,7 @@ + + #include "system/address-spaces.h" + #include "exec/cpu-common.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + #include "hw/boards.h" + #include "hw/hyperv/dynmem-proto.h" + #include "hw/hyperv/hv-balloon.h" +diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c +index 267b612587..48561d3c74 100644 +--- a/hw/virtio/vhost-user.c ++++ b/hw/virtio/vhost-user.c +@@ -28,7 +28,7 @@ + #include "system/cryptodev.h" + #include "migration/postcopy-ram.h" + #include "trace.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + + #include + #include +diff --git a/include/system/ram_addr.h b/include/system/ram_addr.h +index 3550a5df7c..e5ba4f086f 100644 +--- a/include/system/ram_addr.h ++++ b/include/system/ram_addr.h +@@ -24,7 +24,7 @@ + #include "system/tcg.h" + #include "exec/cputlb.h" + #include "exec/ramlist.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + #include "exec/exec-all.h" + #include "qemu/rcu.h" + +diff --git a/include/exec/ramblock.h b/include/system/ramblock.h +similarity index 96% +rename from include/exec/ramblock.h +rename to include/system/ramblock.h +index 64484cd821..d8a116ba99 100644 +--- a/include/exec/ramblock.h ++++ b/include/system/ramblock.h +@@ -16,11 +16,10 @@ + * The functions declared here will be removed soon. + */ + +-#ifndef QEMU_EXEC_RAMBLOCK_H +-#define QEMU_EXEC_RAMBLOCK_H ++#ifndef SYSTEM_RAMBLOCK_H ++#define SYSTEM_RAMBLOCK_H + +-#ifndef CONFIG_USER_ONLY +-#include "cpu-common.h" ++#include "exec/cpu-common.h" + #include "qemu/rcu.h" + #include "exec/ramlist.h" + +@@ -91,5 +90,5 @@ struct RAMBlock { + */ + ram_addr_t postcopy_length; + }; +-#endif ++ + #endif +diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c +index 09caf92f87..986624c79a 100644 +--- a/migration/dirtyrate.c ++++ b/migration/dirtyrate.c +@@ -14,7 +14,7 @@ + #include "qemu/error-report.h" + #include "hw/core/cpu.h" + #include "qapi/error.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + #include "exec/target_page.h" + #include "qemu/rcu_queue.h" + #include "qemu/main-loop.h" +diff --git a/migration/file.c b/migration/file.c +index 7f11e26f5c..bb8031e3c7 100644 +--- a/migration/file.c ++++ b/migration/file.c +@@ -6,7 +6,7 @@ + */ + + #include "qemu/osdep.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + #include "qemu/cutils.h" + #include "qemu/error-report.h" + #include "qapi/error.h" +diff --git a/migration/multifd-nocomp.c b/migration/multifd-nocomp.c +index 02f8bf8ce8..03497f035e 100644 +--- a/migration/multifd-nocomp.c ++++ b/migration/multifd-nocomp.c +@@ -11,7 +11,7 @@ + */ + + #include "qemu/osdep.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + #include "exec/target_page.h" + #include "file.h" + #include "migration-stats.h" +diff --git a/migration/multifd-qatzip.c b/migration/multifd-qatzip.c +index 6a0e989fae..7419e5dc0d 100644 +--- a/migration/multifd-qatzip.c ++++ b/migration/multifd-qatzip.c +@@ -13,7 +13,7 @@ + */ + + #include "qemu/osdep.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + #include "qapi/error.h" + #include "qemu/error-report.h" + #include "qapi/qapi-types-migration.h" +diff --git a/migration/multifd-qpl.c b/migration/multifd-qpl.c +index 88e2344af2..52902eb00c 100644 +--- a/migration/multifd-qpl.c ++++ b/migration/multifd-qpl.c +@@ -14,7 +14,7 @@ + #include "qemu/module.h" + #include "qapi/error.h" + #include "qapi/qapi-types-migration.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + #include "multifd.h" + #include "qpl/qpl.h" + +diff --git a/migration/multifd-uadk.c b/migration/multifd-uadk.c +index 6895c1f65a..fd7cd9b5e8 100644 +--- a/migration/multifd-uadk.c ++++ b/migration/multifd-uadk.c +@@ -13,7 +13,7 @@ + #include "qemu/osdep.h" + #include "qemu/module.h" + #include "qapi/error.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + #include "migration.h" + #include "multifd.h" + #include "options.h" +diff --git a/migration/multifd-zero-page.c b/migration/multifd-zero-page.c +index 3e0a04f2b5..4cde868159 100644 +--- a/migration/multifd-zero-page.c ++++ b/migration/multifd-zero-page.c +@@ -12,7 +12,7 @@ + + #include "qemu/osdep.h" + #include "qemu/cutils.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + #include "migration.h" + #include "migration-stats.h" + #include "multifd.h" +diff --git a/migration/multifd-zlib.c b/migration/multifd-zlib.c +index 8cf8a26bb4..8820b2a787 100644 +--- a/migration/multifd-zlib.c ++++ b/migration/multifd-zlib.c +@@ -13,7 +13,7 @@ + #include "qemu/osdep.h" + #include + #include "qemu/rcu.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + #include "exec/target_page.h" + #include "qapi/error.h" + #include "migration.h" +diff --git a/migration/multifd-zstd.c b/migration/multifd-zstd.c +index abed140855..3c2dcf76b0 100644 +--- a/migration/multifd-zstd.c ++++ b/migration/multifd-zstd.c +@@ -13,7 +13,7 @@ + #include "qemu/osdep.h" + #include + #include "qemu/rcu.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + #include "exec/target_page.h" + #include "qapi/error.h" + #include "migration.h" +diff --git a/migration/multifd.c b/migration/multifd.c +index 074d16d07d..f18b166bcf 100644 +--- a/migration/multifd.c ++++ b/migration/multifd.c +@@ -16,7 +16,7 @@ + #include "qemu/rcu.h" + #include "exec/target_page.h" + #include "system/system.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + #include "qemu/error-report.h" + #include "qapi/error.h" + #include "file.h" +diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c +index 5d3edfcfec..995614b38c 100644 +--- a/migration/postcopy-ram.c ++++ b/migration/postcopy-ram.c +@@ -31,7 +31,7 @@ + #include "qemu/error-report.h" + #include "trace.h" + #include "hw/boards.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + #include "socket.h" + #include "yank_functions.h" + #include "tls.h" +diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c +index 239be9372d..507de74806 100644 +--- a/tests/qtest/fuzz/generic_fuzz.c ++++ b/tests/qtest/fuzz/generic_fuzz.c +@@ -21,7 +21,7 @@ + #include "fuzz.h" + #include "string.h" + #include "system/memory.h" +-#include "exec/ramblock.h" ++#include "system/ramblock.h" + #include "hw/qdev-core.h" + #include "hw/pci/pci.h" + #include "hw/pci/pci_device.h" +-- +2.47.3 + diff --git a/kvm-io-Fix-partial-struct-copy-in-qio_dns_resolver_looku.patch b/kvm-io-Fix-partial-struct-copy-in-qio_dns_resolver_looku.patch new file mode 100644 index 0000000..d22cb95 --- /dev/null +++ b/kvm-io-Fix-partial-struct-copy-in-qio_dns_resolver_looku.patch @@ -0,0 +1,73 @@ +From dcf18bc367aac87def0b03e2f4450d14b6dd53a5 Mon Sep 17 00:00:00 2001 +From: Juraj Marcin +Date: Wed, 21 May 2025 15:52:30 +0200 +Subject: [PATCH 3/9] io: Fix partial struct copy in + qio_dns_resolver_lookup_sync_inet() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Juraj Marcin +RH-MergeRequest: 368: util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive +RH-Jira: RHEL-67706 +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/7] 157425de9a5bcab4a63f84cceb35eb4954e7ed8b (JurajMarcin/centos-src-qemu-kvm) + +Commit aec21d3175 (qapi: Add InetSocketAddress member keep-alive) +introduces the keep-alive flag, but this flag is not copied together +with other options in qio_dns_resolver_lookup_sync_inet(). + +This patch fixes this issue and also prevents future ones by copying the +entire structure first and only then overriding a few attributes that +need to be different. + +Fixes: aec21d31756c (qapi: Add InetSocketAddress member keep-alive) +Signed-off-by: Juraj Marcin +Reviewed-by: Daniel P. BerrangĂ© +Signed-off-by: Daniel P. BerrangĂ© + +(cherry picked from commit 0dc051aa85e1bd68d5c5110fa8af69204e6dbd3d) + +JIRA: https://issues.redhat.com/browse/RHEL-67706 + +Signed-off-by: Juraj Marcin +--- + io/dns-resolver.c | 21 +++++---------------- + 1 file changed, 5 insertions(+), 16 deletions(-) + +diff --git a/io/dns-resolver.c b/io/dns-resolver.c +index 53b0e8407a..3712438f82 100644 +--- a/io/dns-resolver.c ++++ b/io/dns-resolver.c +@@ -111,22 +111,11 @@ static int qio_dns_resolver_lookup_sync_inet(QIODNSResolver *resolver, + uaddr, INET6_ADDRSTRLEN, uport, 32, + NI_NUMERICHOST | NI_NUMERICSERV); + +- newaddr->u.inet = (InetSocketAddress){ +- .host = g_strdup(uaddr), +- .port = g_strdup(uport), +- .has_numeric = true, +- .numeric = true, +- .has_to = iaddr->has_to, +- .to = iaddr->to, +- .has_ipv4 = iaddr->has_ipv4, +- .ipv4 = iaddr->ipv4, +- .has_ipv6 = iaddr->has_ipv6, +- .ipv6 = iaddr->ipv6, +-#ifdef HAVE_IPPROTO_MPTCP +- .has_mptcp = iaddr->has_mptcp, +- .mptcp = iaddr->mptcp, +-#endif +- }; ++ newaddr->u.inet = *iaddr; ++ newaddr->u.inet.host = g_strdup(uaddr), ++ newaddr->u.inet.port = g_strdup(uport), ++ newaddr->u.inet.has_numeric = true, ++ newaddr->u.inet.numeric = true, + + (*addrs)[i] = newaddr; + } +-- +2.39.3 + diff --git a/kvm-iotests-Add-NBD-based-tests-for-inactive-nodes.patch b/kvm-iotests-Add-NBD-based-tests-for-inactive-nodes.patch deleted file mode 100644 index d1911fc..0000000 --- a/kvm-iotests-Add-NBD-based-tests-for-inactive-nodes.patch +++ /dev/null @@ -1,609 +0,0 @@ -From 693f96281609b133244802fbb77f8e35061a1648 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Tue, 4 Feb 2025 22:14:07 +0100 -Subject: [PATCH 22/22] iotests: Add (NBD-based) tests for inactive nodes - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [22/22] 4715b88d95aefc8b7fdf74f3acb4a45811faea39 (kmwolf/centos-qemu-kvm) - -This tests different types of operations on inactive block nodes -(including graph changes, block jobs and NBD exports) to make sure that -users manually activating and inactivating nodes doesn't break things. - -Support for inactive nodes in other export types will have to come with -separate test cases because they have different dependencies like blkio -or root permissions and we don't want to disable this basic test when -they are not fulfilled. - -Signed-off-by: Kevin Wolf -Acked-by: Fabiano Rosas -Message-ID: <20250204211407.381505-17-kwolf@redhat.com> -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Kevin Wolf -(cherry picked from commit bbf105ef3cc48fff282789e9bf56b7a81e1407bd) -Signed-off-by: Kevin Wolf ---- - tests/qemu-iotests/iotests.py | 4 + - tests/qemu-iotests/tests/inactive-node-nbd | 303 ++++++++++++++++++ - .../qemu-iotests/tests/inactive-node-nbd.out | 239 ++++++++++++++ - 3 files changed, 546 insertions(+) - create mode 100755 tests/qemu-iotests/tests/inactive-node-nbd - create mode 100644 tests/qemu-iotests/tests/inactive-node-nbd.out - -diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py -index 1a42aa1416..c8cb028c2d 100644 ---- a/tests/qemu-iotests/iotests.py -+++ b/tests/qemu-iotests/iotests.py -@@ -913,6 +913,10 @@ def add_incoming(self, addr): - self._args.append(addr) - return self - -+ def add_paused(self): -+ self._args.append('-S') -+ return self -+ - def hmp(self, command_line: str, use_log: bool = False) -> QMPMessage: - cmd = 'human-monitor-command' - kwargs: Dict[str, Any] = {'command-line': command_line} -diff --git a/tests/qemu-iotests/tests/inactive-node-nbd b/tests/qemu-iotests/tests/inactive-node-nbd -new file mode 100755 -index 0000000000..a95b37e796 ---- /dev/null -+++ b/tests/qemu-iotests/tests/inactive-node-nbd -@@ -0,0 +1,303 @@ -+#!/usr/bin/env python3 -+# group: rw quick -+# -+# Copyright (C) Red Hat, Inc. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+# -+# Creator/Owner: Kevin Wolf -+ -+import iotests -+ -+from iotests import QemuIoInteractive -+from iotests import filter_qemu_io, filter_qtest, filter_qmp_testfiles -+ -+iotests.script_initialize(supported_fmts=['generic'], -+ supported_protocols=['file'], -+ supported_platforms=['linux']) -+ -+def get_export(node_name='disk-fmt', allow_inactive=None): -+ exp = { -+ 'id': 'exp0', -+ 'type': 'nbd', -+ 'node-name': node_name, -+ 'writable': True, -+ } -+ -+ if allow_inactive is not None: -+ exp['allow-inactive'] = allow_inactive -+ -+ return exp -+ -+def node_is_active(_vm, node_name): -+ nodes = _vm.cmd('query-named-block-nodes', flat=True) -+ node = next(n for n in nodes if n['node-name'] == node_name) -+ return node['active'] -+ -+with iotests.FilePath('disk.img') as path, \ -+ iotests.FilePath('snap.qcow2') as snap_path, \ -+ iotests.FilePath('snap2.qcow2') as snap2_path, \ -+ iotests.FilePath('target.img') as target_path, \ -+ iotests.FilePath('nbd.sock', base_dir=iotests.sock_dir) as nbd_sock, \ -+ iotests.VM() as vm: -+ -+ img_size = '10M' -+ -+ iotests.log('Preparing disk...') -+ iotests.qemu_img_create('-f', iotests.imgfmt, path, img_size) -+ iotests.qemu_img_create('-f', iotests.imgfmt, target_path, img_size) -+ -+ iotests.qemu_img_create('-f', 'qcow2', '-b', path, '-F', iotests.imgfmt, -+ snap_path) -+ iotests.qemu_img_create('-f', 'qcow2', '-b', snap_path, '-F', 'qcow2', -+ snap2_path) -+ -+ iotests.log('Launching VM...') -+ vm.add_blockdev(f'file,node-name=disk-file,filename={path}') -+ vm.add_blockdev(f'{iotests.imgfmt},file=disk-file,node-name=disk-fmt,' -+ 'active=off') -+ vm.add_blockdev(f'file,node-name=target-file,filename={target_path}') -+ vm.add_blockdev(f'{iotests.imgfmt},file=target-file,node-name=target-fmt') -+ vm.add_blockdev(f'file,node-name=snap-file,filename={snap_path}') -+ vm.add_blockdev(f'file,node-name=snap2-file,filename={snap2_path}') -+ -+ # Actually running the VM activates all images -+ vm.add_paused() -+ -+ vm.launch() -+ vm.qmp_log('nbd-server-start', -+ addr={'type': 'unix', 'data':{'path': nbd_sock}}, -+ filters=[filter_qmp_testfiles]) -+ -+ iotests.log('\n=== Creating export of inactive node ===') -+ -+ iotests.log('\nExports activate nodes without allow-inactive') -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ vm.qmp_log('block-export-add', **get_export()) -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ vm.qmp_log('query-block-exports') -+ vm.qmp_log('block-export-del', id='exp0') -+ vm.event_wait('BLOCK_EXPORT_DELETED') -+ vm.qmp_log('query-block-exports') -+ -+ iotests.log('\nExports activate nodes with allow-inactive=false') -+ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ vm.qmp_log('block-export-add', **get_export(allow_inactive=False)) -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ vm.qmp_log('query-block-exports') -+ vm.qmp_log('block-export-del', id='exp0') -+ vm.event_wait('BLOCK_EXPORT_DELETED') -+ vm.qmp_log('query-block-exports') -+ -+ iotests.log('\nExport leaves nodes inactive with allow-inactive=true') -+ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ vm.qmp_log('block-export-add', **get_export(allow_inactive=True)) -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ vm.qmp_log('query-block-exports') -+ vm.qmp_log('block-export-del', id='exp0') -+ vm.event_wait('BLOCK_EXPORT_DELETED') -+ vm.qmp_log('query-block-exports') -+ -+ iotests.log('\n=== Inactivating node with existing export ===') -+ -+ iotests.log('\nInactivating nodes with an export fails without ' -+ 'allow-inactive') -+ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=True) -+ vm.qmp_log('block-export-add', **get_export(node_name='disk-fmt')) -+ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ vm.qmp_log('query-block-exports') -+ vm.qmp_log('block-export-del', id='exp0') -+ vm.event_wait('BLOCK_EXPORT_DELETED') -+ vm.qmp_log('query-block-exports') -+ -+ iotests.log('\nInactivating nodes with an export fails with ' -+ 'allow-inactive=false') -+ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=True) -+ vm.qmp_log('block-export-add', -+ **get_export(node_name='disk-fmt', allow_inactive=False)) -+ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ vm.qmp_log('query-block-exports') -+ vm.qmp_log('block-export-del', id='exp0') -+ vm.event_wait('BLOCK_EXPORT_DELETED') -+ vm.qmp_log('query-block-exports') -+ -+ iotests.log('\nInactivating nodes with an export works with ' -+ 'allow-inactive=true') -+ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=True) -+ vm.qmp_log('block-export-add', -+ **get_export(node_name='disk-fmt', allow_inactive=True)) -+ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ vm.qmp_log('query-block-exports') -+ vm.qmp_log('block-export-del', id='exp0') -+ vm.event_wait('BLOCK_EXPORT_DELETED') -+ vm.qmp_log('query-block-exports') -+ -+ iotests.log('\n=== Inactive nodes with parent ===') -+ -+ iotests.log('\nInactivating nodes with an active parent fails') -+ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=True) -+ vm.qmp_log('blockdev-set-active', node_name='disk-file', active=False) -+ iotests.log('disk-file active: %s' % node_is_active(vm, 'disk-file')) -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ -+ iotests.log('\nInactivating nodes with an inactive parent works') -+ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) -+ vm.qmp_log('blockdev-set-active', node_name='disk-file', active=False) -+ iotests.log('disk-file active: %s' % node_is_active(vm, 'disk-file')) -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ -+ iotests.log('\nCreating active parent node with an inactive child fails') -+ vm.qmp_log('blockdev-add', driver='raw', file='disk-fmt', -+ node_name='disk-filter') -+ vm.qmp_log('blockdev-add', driver='raw', file='disk-fmt', -+ node_name='disk-filter', active=True) -+ -+ iotests.log('\nCreating inactive parent node with an inactive child works') -+ vm.qmp_log('blockdev-add', driver='raw', file='disk-fmt', -+ node_name='disk-filter', active=False) -+ vm.qmp_log('blockdev-del', node_name='disk-filter') -+ -+ iotests.log('\n=== Resizing an inactive node ===') -+ vm.qmp_log('block_resize', node_name='disk-fmt', size=16*1024*1024) -+ -+ iotests.log('\n=== Taking a snapshot of an inactive node ===') -+ -+ iotests.log('\nActive overlay over inactive backing file automatically ' -+ 'makes both inactive for compatibility') -+ vm.qmp_log('blockdev-add', driver='qcow2', node_name='snap-fmt', -+ file='snap-file', backing=None) -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) -+ vm.qmp_log('blockdev-snapshot', node='disk-fmt', overlay='snap-fmt') -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) -+ vm.qmp_log('blockdev-del', node_name='snap-fmt') -+ -+ iotests.log('\nInactive overlay over inactive backing file just works') -+ vm.qmp_log('blockdev-add', driver='qcow2', node_name='snap-fmt', -+ file='snap-file', backing=None, active=False) -+ vm.qmp_log('blockdev-snapshot', node='disk-fmt', overlay='snap-fmt') -+ -+ iotests.log('\n=== Block jobs with inactive nodes ===') -+ -+ iotests.log('\nStreaming into an inactive node') -+ vm.qmp_log('block-stream', device='snap-fmt', -+ filters=[iotests.filter_qmp_generated_node_ids]) -+ -+ iotests.log('\nCommitting an inactive root node (active commit)') -+ vm.qmp_log('block-commit', job_id='job0', device='snap-fmt', -+ filters=[iotests.filter_qmp_generated_node_ids]) -+ -+ iotests.log('\nCommitting an inactive intermediate node to inactive base') -+ vm.qmp_log('blockdev-add', driver='qcow2', node_name='snap2-fmt', -+ file='snap2-file', backing='snap-fmt', active=False) -+ -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) -+ iotests.log('snap2-fmt active: %s' % node_is_active(vm, 'snap2-fmt')) -+ -+ vm.qmp_log('block-commit', job_id='job0', device='snap2-fmt', -+ top_node='snap-fmt', -+ filters=[iotests.filter_qmp_generated_node_ids]) -+ -+ iotests.log('\nCommitting an inactive intermediate node to active base') -+ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=True) -+ vm.qmp_log('block-commit', job_id='job0', device='snap2-fmt', -+ top_node='snap-fmt', -+ filters=[iotests.filter_qmp_generated_node_ids]) -+ -+ iotests.log('\nMirror from inactive source to active target') -+ vm.qmp_log('blockdev-mirror', job_id='job0', device='snap2-fmt', -+ target='target-fmt', sync='full', -+ filters=[iotests.filter_qmp_generated_node_ids]) -+ -+ iotests.log('\nMirror from active source to inactive target') -+ -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) -+ iotests.log('snap2-fmt active: %s' % node_is_active(vm, 'snap2-fmt')) -+ iotests.log('target-fmt active: %s' % node_is_active(vm, 'target-fmt')) -+ -+ # Activating snap2-fmt recursively activates the whole backing chain -+ vm.qmp_log('blockdev-set-active', node_name='snap2-fmt', active=True) -+ vm.qmp_log('blockdev-set-active', node_name='target-fmt', active=False) -+ -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) -+ iotests.log('snap2-fmt active: %s' % node_is_active(vm, 'snap2-fmt')) -+ iotests.log('target-fmt active: %s' % node_is_active(vm, 'target-fmt')) -+ -+ vm.qmp_log('blockdev-mirror', job_id='job0', device='snap2-fmt', -+ target='target-fmt', sync='full', -+ filters=[iotests.filter_qmp_generated_node_ids]) -+ -+ iotests.log('\nBackup from active source to inactive target') -+ -+ vm.qmp_log('blockdev-backup', job_id='job0', device='snap2-fmt', -+ target='target-fmt', sync='full', -+ filters=[iotests.filter_qmp_generated_node_ids]) -+ -+ iotests.log('\nBackup from inactive source to active target') -+ -+ # Inactivating snap2-fmt recursively inactivates the whole backing chain -+ vm.qmp_log('blockdev-set-active', node_name='snap2-fmt', active=False) -+ vm.qmp_log('blockdev-set-active', node_name='target-fmt', active=True) -+ -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) -+ iotests.log('snap2-fmt active: %s' % node_is_active(vm, 'snap2-fmt')) -+ iotests.log('target-fmt active: %s' % node_is_active(vm, 'target-fmt')) -+ -+ vm.qmp_log('blockdev-backup', job_id='job0', device='snap2-fmt', -+ target='target-fmt', sync='full', -+ filters=[iotests.filter_qmp_generated_node_ids]) -+ -+ iotests.log('\n=== Accessing export on inactive node ===') -+ -+ # Use the target node because it has the right image format and isn't the -+ # (read-only) backing file of a qcow2 node -+ vm.qmp_log('blockdev-set-active', node_name='target-fmt', active=False) -+ vm.qmp_log('block-export-add', -+ **get_export(node_name='target-fmt', allow_inactive=True)) -+ -+ # The read should succeed, everything else should fail gracefully -+ qemu_io = QemuIoInteractive('-f', 'raw', -+ f'nbd+unix:///target-fmt?socket={nbd_sock}') -+ iotests.log(qemu_io.cmd('read 0 64k'), filters=[filter_qemu_io]) -+ iotests.log(qemu_io.cmd('write 0 64k'), filters=[filter_qemu_io]) -+ iotests.log(qemu_io.cmd('write -z 0 64k'), filters=[filter_qemu_io]) -+ iotests.log(qemu_io.cmd('write -zu 0 64k'), filters=[filter_qemu_io]) -+ iotests.log(qemu_io.cmd('discard 0 64k'), filters=[filter_qemu_io]) -+ iotests.log(qemu_io.cmd('flush'), filters=[filter_qemu_io]) -+ iotests.log(qemu_io.cmd('map'), filters=[filter_qemu_io]) -+ qemu_io.close() -+ -+ iotests.log('\n=== Resuming VM activates all images ===') -+ vm.qmp_log('cont') -+ -+ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) -+ iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) -+ iotests.log('snap2-fmt active: %s' % node_is_active(vm, 'snap2-fmt')) -+ iotests.log('target-fmt active: %s' % node_is_active(vm, 'target-fmt')) -+ -+ iotests.log('\nShutting down...') -+ vm.shutdown() -+ log = vm.get_log() -+ if log: -+ iotests.log(log, [filter_qtest, filter_qemu_io]) -diff --git a/tests/qemu-iotests/tests/inactive-node-nbd.out b/tests/qemu-iotests/tests/inactive-node-nbd.out -new file mode 100644 -index 0000000000..a458b4fc05 ---- /dev/null -+++ b/tests/qemu-iotests/tests/inactive-node-nbd.out -@@ -0,0 +1,239 @@ -+Preparing disk... -+Launching VM... -+{"execute": "nbd-server-start", "arguments": {"addr": {"data": {"path": "SOCK_DIR/PID-nbd.sock"}, "type": "unix"}}} -+{"return": {}} -+ -+=== Creating export of inactive node === -+ -+Exports activate nodes without allow-inactive -+disk-fmt active: False -+{"execute": "block-export-add", "arguments": {"id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} -+{"return": {}} -+disk-fmt active: True -+{"execute": "query-block-exports", "arguments": {}} -+{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} -+{"execute": "block-export-del", "arguments": {"id": "exp0"}} -+{"return": {}} -+{"execute": "query-block-exports", "arguments": {}} -+{"return": []} -+ -+Exports activate nodes with allow-inactive=false -+{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} -+{"return": {}} -+disk-fmt active: False -+{"execute": "block-export-add", "arguments": {"allow-inactive": false, "id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} -+{"return": {}} -+disk-fmt active: True -+{"execute": "query-block-exports", "arguments": {}} -+{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} -+{"execute": "block-export-del", "arguments": {"id": "exp0"}} -+{"return": {}} -+{"execute": "query-block-exports", "arguments": {}} -+{"return": []} -+ -+Export leaves nodes inactive with allow-inactive=true -+{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} -+{"return": {}} -+disk-fmt active: False -+{"execute": "block-export-add", "arguments": {"allow-inactive": true, "id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} -+{"return": {}} -+disk-fmt active: False -+{"execute": "query-block-exports", "arguments": {}} -+{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} -+{"execute": "block-export-del", "arguments": {"id": "exp0"}} -+{"return": {}} -+{"execute": "query-block-exports", "arguments": {}} -+{"return": []} -+ -+=== Inactivating node with existing export === -+ -+Inactivating nodes with an export fails without allow-inactive -+{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "disk-fmt"}} -+{"return": {}} -+{"execute": "block-export-add", "arguments": {"id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} -+{"return": {}} -+{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} -+{"error": {"class": "GenericError", "desc": "Failed to inactivate node: Operation not permitted"}} -+disk-fmt active: True -+{"execute": "query-block-exports", "arguments": {}} -+{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} -+{"execute": "block-export-del", "arguments": {"id": "exp0"}} -+{"return": {}} -+{"execute": "query-block-exports", "arguments": {}} -+{"return": []} -+ -+Inactivating nodes with an export fails with allow-inactive=false -+{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "disk-fmt"}} -+{"return": {}} -+{"execute": "block-export-add", "arguments": {"allow-inactive": false, "id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} -+{"return": {}} -+{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} -+{"error": {"class": "GenericError", "desc": "Failed to inactivate node: Operation not permitted"}} -+disk-fmt active: True -+{"execute": "query-block-exports", "arguments": {}} -+{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} -+{"execute": "block-export-del", "arguments": {"id": "exp0"}} -+{"return": {}} -+{"execute": "query-block-exports", "arguments": {}} -+{"return": []} -+ -+Inactivating nodes with an export works with allow-inactive=true -+{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "disk-fmt"}} -+{"return": {}} -+{"execute": "block-export-add", "arguments": {"allow-inactive": true, "id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} -+{"return": {}} -+{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} -+{"return": {}} -+disk-fmt active: False -+{"execute": "query-block-exports", "arguments": {}} -+{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} -+{"execute": "block-export-del", "arguments": {"id": "exp0"}} -+{"return": {}} -+{"execute": "query-block-exports", "arguments": {}} -+{"return": []} -+ -+=== Inactive nodes with parent === -+ -+Inactivating nodes with an active parent fails -+{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "disk-fmt"}} -+{"return": {}} -+{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-file"}} -+{"error": {"class": "GenericError", "desc": "Node has active parent node"}} -+disk-file active: True -+disk-fmt active: True -+ -+Inactivating nodes with an inactive parent works -+{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} -+{"return": {}} -+{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-file"}} -+{"return": {}} -+disk-file active: False -+disk-fmt active: False -+ -+Creating active parent node with an inactive child fails -+{"execute": "blockdev-add", "arguments": {"driver": "raw", "file": "disk-fmt", "node-name": "disk-filter"}} -+{"error": {"class": "GenericError", "desc": "Inactive 'disk-fmt' can't be a file child of active 'disk-filter'"}} -+{"execute": "blockdev-add", "arguments": {"active": true, "driver": "raw", "file": "disk-fmt", "node-name": "disk-filter"}} -+{"error": {"class": "GenericError", "desc": "Inactive 'disk-fmt' can't be a file child of active 'disk-filter'"}} -+ -+Creating inactive parent node with an inactive child works -+{"execute": "blockdev-add", "arguments": {"active": false, "driver": "raw", "file": "disk-fmt", "node-name": "disk-filter"}} -+{"return": {}} -+{"execute": "blockdev-del", "arguments": {"node-name": "disk-filter"}} -+{"return": {}} -+ -+=== Resizing an inactive node === -+{"execute": "block_resize", "arguments": {"node-name": "disk-fmt", "size": 16777216}} -+{"error": {"class": "GenericError", "desc": "Permission 'resize' unavailable on inactive node"}} -+ -+=== Taking a snapshot of an inactive node === -+ -+Active overlay over inactive backing file automatically makes both inactive for compatibility -+{"execute": "blockdev-add", "arguments": {"backing": null, "driver": "qcow2", "file": "snap-file", "node-name": "snap-fmt"}} -+{"return": {}} -+disk-fmt active: False -+snap-fmt active: True -+{"execute": "blockdev-snapshot", "arguments": {"node": "disk-fmt", "overlay": "snap-fmt"}} -+{"return": {}} -+disk-fmt active: False -+snap-fmt active: False -+{"execute": "blockdev-del", "arguments": {"node-name": "snap-fmt"}} -+{"return": {}} -+ -+Inactive overlay over inactive backing file just works -+{"execute": "blockdev-add", "arguments": {"active": false, "backing": null, "driver": "qcow2", "file": "snap-file", "node-name": "snap-fmt"}} -+{"return": {}} -+{"execute": "blockdev-snapshot", "arguments": {"node": "disk-fmt", "overlay": "snap-fmt"}} -+{"return": {}} -+ -+=== Block jobs with inactive nodes === -+ -+Streaming into an inactive node -+{"execute": "block-stream", "arguments": {"device": "snap-fmt"}} -+{"error": {"class": "GenericError", "desc": "Could not create node: Inactive 'snap-fmt' can't be a file child of active 'NODE_NAME'"}} -+ -+Committing an inactive root node (active commit) -+{"execute": "block-commit", "arguments": {"device": "snap-fmt", "job-id": "job0"}} -+{"error": {"class": "GenericError", "desc": "Inactive 'snap-fmt' can't be a backing child of active 'NODE_NAME'"}} -+ -+Committing an inactive intermediate node to inactive base -+{"execute": "blockdev-add", "arguments": {"active": false, "backing": "snap-fmt", "driver": "qcow2", "file": "snap2-file", "node-name": "snap2-fmt"}} -+{"return": {}} -+disk-fmt active: False -+snap-fmt active: False -+snap2-fmt active: False -+{"execute": "block-commit", "arguments": {"device": "snap2-fmt", "job-id": "job0", "top-node": "snap-fmt"}} -+{"error": {"class": "GenericError", "desc": "Inactive 'snap-fmt' can't be a backing child of active 'NODE_NAME'"}} -+ -+Committing an inactive intermediate node to active base -+{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "disk-fmt"}} -+{"return": {}} -+{"execute": "block-commit", "arguments": {"device": "snap2-fmt", "job-id": "job0", "top-node": "snap-fmt"}} -+{"error": {"class": "GenericError", "desc": "Inactive 'snap-fmt' can't be a backing child of active 'NODE_NAME'"}} -+ -+Mirror from inactive source to active target -+{"execute": "blockdev-mirror", "arguments": {"device": "snap2-fmt", "job-id": "job0", "sync": "full", "target": "target-fmt"}} -+{"error": {"class": "GenericError", "desc": "Inactive 'snap2-fmt' can't be a backing child of active 'NODE_NAME'"}} -+ -+Mirror from active source to inactive target -+disk-fmt active: True -+snap-fmt active: False -+snap2-fmt active: False -+target-fmt active: True -+{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "snap2-fmt"}} -+{"return": {}} -+{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "target-fmt"}} -+{"return": {}} -+disk-fmt active: True -+snap-fmt active: True -+snap2-fmt active: True -+target-fmt active: False -+{"execute": "blockdev-mirror", "arguments": {"device": "snap2-fmt", "job-id": "job0", "sync": "full", "target": "target-fmt"}} -+{"error": {"class": "GenericError", "desc": "Permission 'write' unavailable on inactive node"}} -+ -+Backup from active source to inactive target -+{"execute": "blockdev-backup", "arguments": {"device": "snap2-fmt", "job-id": "job0", "sync": "full", "target": "target-fmt"}} -+{"error": {"class": "GenericError", "desc": "Could not create node: Inactive 'target-fmt' can't be a target child of active 'NODE_NAME'"}} -+ -+Backup from inactive source to active target -+{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "snap2-fmt"}} -+{"return": {}} -+{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "target-fmt"}} -+{"return": {}} -+disk-fmt active: False -+snap-fmt active: False -+snap2-fmt active: False -+target-fmt active: True -+{"execute": "blockdev-backup", "arguments": {"device": "snap2-fmt", "job-id": "job0", "sync": "full", "target": "target-fmt"}} -+{"error": {"class": "GenericError", "desc": "Could not create node: Inactive 'snap2-fmt' can't be a file child of active 'NODE_NAME'"}} -+ -+=== Accessing export on inactive node === -+{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "target-fmt"}} -+{"return": {}} -+{"execute": "block-export-add", "arguments": {"allow-inactive": true, "id": "exp0", "node-name": "target-fmt", "type": "nbd", "writable": true}} -+{"return": {}} -+read 65536/65536 bytes at offset 0 -+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -+ -+write failed: Operation not permitted -+ -+write failed: Operation not permitted -+ -+write failed: Operation not permitted -+ -+discard failed: Operation not permitted -+ -+ -+qemu-io: Failed to get allocation status: Operation not permitted -+ -+ -+=== Resuming VM activates all images === -+{"execute": "cont", "arguments": {}} -+{"return": {}} -+disk-fmt active: True -+snap-fmt active: True -+snap2-fmt active: True -+target-fmt active: True -+ -+Shutting down... -+ --- -2.39.3 - diff --git a/kvm-iotests-Add-filter_qtest.patch b/kvm-iotests-Add-filter_qtest.patch deleted file mode 100644 index 3b2d259..0000000 --- a/kvm-iotests-Add-filter_qtest.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 30350ce735c55c416d98a566370bc43b7358ee1d Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Tue, 4 Feb 2025 22:14:05 +0100 -Subject: [PATCH 20/22] iotests: Add filter_qtest() - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [20/22] 46aecb1c268dcf666c8c7ef8e0d2f3fecaa934e2 (kmwolf/centos-qemu-kvm) - -The open-coded form of this filter has been copied into enough tests -that it's better to move it into iotests.py. - -Signed-off-by: Kevin Wolf -Acked-by: Fabiano Rosas -Reviewed-by: Eric Blake -Message-ID: <20250204211407.381505-15-kwolf@redhat.com> -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Kevin Wolf -(cherry picked from commit ed26db83673f4a190332d2a378e2f6e342b8904d) -Signed-off-by: Kevin Wolf ---- - tests/qemu-iotests/041 | 4 +--- - tests/qemu-iotests/165 | 4 +--- - tests/qemu-iotests/iotests.py | 4 ++++ - tests/qemu-iotests/tests/copy-before-write | 3 +-- - tests/qemu-iotests/tests/migrate-bitmaps-test | 7 +++---- - 5 files changed, 10 insertions(+), 12 deletions(-) - -diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 -index 98d17b1388..8452845f44 100755 ---- a/tests/qemu-iotests/041 -+++ b/tests/qemu-iotests/041 -@@ -1100,10 +1100,8 @@ class TestRepairQuorum(iotests.QMPTestCase): - - # Check the full error message now - self.vm.shutdown() -- log = self.vm.get_log() -- log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) -+ log = iotests.filter_qtest(self.vm.get_log()) - log = re.sub(r'^Formatting.*\n', '', log) -- log = re.sub(r'\n\[I \+\d+\.\d+\] CLOSED\n?$', '', log) - log = re.sub(r'^%s: ' % os.path.basename(iotests.qemu_prog), '', log) - - self.assertEqual(log, -diff --git a/tests/qemu-iotests/165 b/tests/qemu-iotests/165 -index b24907a62f..b3b1709d71 100755 ---- a/tests/qemu-iotests/165 -+++ b/tests/qemu-iotests/165 -@@ -82,9 +82,7 @@ class TestPersistentDirtyBitmap(iotests.QMPTestCase): - self.vm.shutdown() - - #catch 'Persistent bitmaps are lost' possible error -- log = self.vm.get_log() -- log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) -- log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log) -+ log = iotests.filter_qtest(self.vm.get_log()) - if log: - print(log) - -diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py -index ea48af4a7b..1a42aa1416 100644 ---- a/tests/qemu-iotests/iotests.py -+++ b/tests/qemu-iotests/iotests.py -@@ -701,6 +701,10 @@ def _filter(_key, value): - def filter_nbd_exports(output: str) -> str: - return re.sub(r'((min|opt|max) block): [0-9]+', r'\1: XXX', output) - -+def filter_qtest(output: str) -> str: -+ output = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', output) -+ output = re.sub(r'\n?\[I \+\d+\.\d+\] CLOSED\n?$', '', output) -+ return output - - Msg = TypeVar('Msg', Dict[str, Any], List[Any], str) - -diff --git a/tests/qemu-iotests/tests/copy-before-write b/tests/qemu-iotests/tests/copy-before-write -index d33bea577d..498c558008 100755 ---- a/tests/qemu-iotests/tests/copy-before-write -+++ b/tests/qemu-iotests/tests/copy-before-write -@@ -95,8 +95,7 @@ class TestCbwError(iotests.QMPTestCase): - - self.vm.shutdown() - log = self.vm.get_log() -- log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) -- log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log) -+ log = iotests.filter_qtest(log) - log = iotests.filter_qemu_io(log) - return log - -diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-test b/tests/qemu-iotests/tests/migrate-bitmaps-test -index f98e721e97..8fb4099201 100755 ---- a/tests/qemu-iotests/tests/migrate-bitmaps-test -+++ b/tests/qemu-iotests/tests/migrate-bitmaps-test -@@ -122,11 +122,10 @@ class TestDirtyBitmapMigration(iotests.QMPTestCase): - - # catch 'Could not reopen qcow2 layer: Bitmap already exists' - # possible error -- log = self.vm_a.get_log() -- log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) -- log = re.sub(r'^(wrote .* bytes at offset .*\n.*KiB.*ops.*sec.*\n){3}', -+ log = iotests.filter_qtest(self.vm_a.get_log()) -+ log = re.sub(r'^(wrote .* bytes at offset .*\n' -+ r'.*KiB.*ops.*sec.*\n?){3}', - '', log) -- log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log) - self.assertEqual(log, '') - - # test that bitmap is still persistent --- -2.39.3 - diff --git a/kvm-iotests-Add-qsd-migrate-case.patch b/kvm-iotests-Add-qsd-migrate-case.patch deleted file mode 100644 index 67eca02..0000000 --- a/kvm-iotests-Add-qsd-migrate-case.patch +++ /dev/null @@ -1,244 +0,0 @@ -From 10bfceb42fa5a7cb0cd0286e85f63da3bed3d806 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Tue, 4 Feb 2025 22:14:06 +0100 -Subject: [PATCH 21/22] iotests: Add qsd-migrate case - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [21/22] 50e7160617762ec15cc63f4062d47d65268c551a (kmwolf/centos-qemu-kvm) - -Test that it's possible to migrate a VM that uses an image on shared -storage through qemu-storage-daemon. - -Signed-off-by: Kevin Wolf -Acked-by: Fabiano Rosas -Reviewed-by: Eric Blake -Message-ID: <20250204211407.381505-16-kwolf@redhat.com> -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Kevin Wolf -(cherry picked from commit 3ea437ab3d561ca79b95a34c5128e370de4738e3) -Signed-off-by: Kevin Wolf ---- - tests/qemu-iotests/tests/qsd-migrate | 140 +++++++++++++++++++++++ - tests/qemu-iotests/tests/qsd-migrate.out | 59 ++++++++++ - 2 files changed, 199 insertions(+) - create mode 100755 tests/qemu-iotests/tests/qsd-migrate - create mode 100644 tests/qemu-iotests/tests/qsd-migrate.out - -diff --git a/tests/qemu-iotests/tests/qsd-migrate b/tests/qemu-iotests/tests/qsd-migrate -new file mode 100755 -index 0000000000..de17562cb0 ---- /dev/null -+++ b/tests/qemu-iotests/tests/qsd-migrate -@@ -0,0 +1,140 @@ -+#!/usr/bin/env python3 -+# group: rw quick -+# -+# Copyright (C) Red Hat, Inc. -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+# -+# Creator/Owner: Kevin Wolf -+ -+import iotests -+ -+from iotests import filter_qemu_io, filter_qtest -+ -+iotests.script_initialize(supported_fmts=['generic'], -+ supported_protocols=['file'], -+ supported_platforms=['linux']) -+ -+with iotests.FilePath('disk.img') as path, \ -+ iotests.FilePath('nbd-src.sock', base_dir=iotests.sock_dir) as nbd_src, \ -+ iotests.FilePath('nbd-dst.sock', base_dir=iotests.sock_dir) as nbd_dst, \ -+ iotests.FilePath('migrate.sock', base_dir=iotests.sock_dir) as mig_sock, \ -+ iotests.VM(path_suffix="-src") as vm_src, \ -+ iotests.VM(path_suffix="-dst") as vm_dst: -+ -+ img_size = '10M' -+ -+ iotests.log('Preparing disk...') -+ iotests.qemu_img_create('-f', iotests.imgfmt, path, img_size) -+ -+ iotests.log('Launching source QSD...') -+ qsd_src = iotests.QemuStorageDaemon( -+ '--blockdev', f'file,node-name=disk-file,filename={path}', -+ '--blockdev', f'{iotests.imgfmt},file=disk-file,node-name=disk-fmt', -+ '--nbd-server', f'addr.type=unix,addr.path={nbd_src}', -+ '--export', 'nbd,id=exp0,node-name=disk-fmt,writable=true,' -+ 'allow-inactive=true', -+ qmp=True, -+ ) -+ -+ iotests.log('Launching source VM...') -+ vm_src.add_args('-blockdev', f'nbd,node-name=disk,server.type=unix,' -+ f'server.path={nbd_src},export=disk-fmt') -+ vm_src.add_args('-device', 'virtio-blk,drive=disk,id=virtio0') -+ vm_src.launch() -+ -+ iotests.log('Launching destination QSD...') -+ qsd_dst = iotests.QemuStorageDaemon( -+ '--blockdev', f'file,node-name=disk-file,filename={path},active=off', -+ '--blockdev', f'{iotests.imgfmt},file=disk-file,node-name=disk-fmt,' -+ f'active=off', -+ '--nbd-server', f'addr.type=unix,addr.path={nbd_dst}', -+ '--export', 'nbd,id=exp0,node-name=disk-fmt,writable=true,' -+ 'allow-inactive=true', -+ qmp=True, -+ instance_id='b', -+ ) -+ -+ iotests.log('Launching destination VM...') -+ vm_dst.add_args('-blockdev', f'nbd,node-name=disk,server.type=unix,' -+ f'server.path={nbd_dst},export=disk-fmt') -+ vm_dst.add_args('-device', 'virtio-blk,drive=disk,id=virtio0') -+ vm_dst.add_args('-incoming', f'unix:{mig_sock}') -+ vm_dst.launch() -+ -+ iotests.log('\nTest I/O on the source') -+ vm_src.hmp_qemu_io('virtio0/virtio-backend', 'write -P 0x11 0 4k', -+ use_log=True, qdev=True) -+ vm_src.hmp_qemu_io('virtio0/virtio-backend', 'read -P 0x11 0 4k', -+ use_log=True, qdev=True) -+ -+ iotests.log('\nStarting migration...') -+ -+ mig_caps = [ -+ {'capability': 'events', 'state': True}, -+ {'capability': 'pause-before-switchover', 'state': True}, -+ ] -+ vm_src.qmp_log('migrate-set-capabilities', capabilities=mig_caps) -+ vm_dst.qmp_log('migrate-set-capabilities', capabilities=mig_caps) -+ vm_src.qmp_log('migrate', uri=f'unix:{mig_sock}', -+ filters=[iotests.filter_qmp_testfiles]) -+ -+ vm_src.event_wait('MIGRATION', -+ match={'data': {'status': 'pre-switchover'}}) -+ -+ iotests.log('\nPre-switchover: Reconfigure QSD instances') -+ -+ iotests.log(qsd_src.qmp('blockdev-set-active', {'active': False})) -+ -+ # Reading is okay from both sides while the image is inactive. Note that -+ # the destination may have stale data until it activates the image, though. -+ vm_src.hmp_qemu_io('virtio0/virtio-backend', 'read -P 0x11 0 4k', -+ use_log=True, qdev=True) -+ vm_dst.hmp_qemu_io('virtio0/virtio-backend', 'read 0 4k', -+ use_log=True, qdev=True) -+ -+ iotests.log(qsd_dst.qmp('blockdev-set-active', {'active': True})) -+ -+ iotests.log('\nCompleting migration...') -+ -+ vm_src.qmp_log('migrate-continue', state='pre-switchover') -+ vm_dst.event_wait('MIGRATION', match={'data': {'status': 'completed'}}) -+ -+ iotests.log('\nTest I/O on the destination') -+ -+ # Now the destination must see what the source wrote -+ vm_dst.hmp_qemu_io('virtio0/virtio-backend', 'read -P 0x11 0 4k', -+ use_log=True, qdev=True) -+ -+ # And be able to overwrite it -+ vm_dst.hmp_qemu_io('virtio0/virtio-backend', 'write -P 0x22 0 4k', -+ use_log=True, qdev=True) -+ vm_dst.hmp_qemu_io('virtio0/virtio-backend', 'read -P 0x22 0 4k', -+ use_log=True, qdev=True) -+ -+ iotests.log('\nDone') -+ -+ vm_src.shutdown() -+ iotests.log('\n--- vm_src log ---') -+ log = vm_src.get_log() -+ if log: -+ iotests.log(log, [filter_qtest, filter_qemu_io]) -+ qsd_src.stop() -+ -+ vm_dst.shutdown() -+ iotests.log('\n--- vm_dst log ---') -+ log = vm_dst.get_log() -+ if log: -+ iotests.log(log, [filter_qtest, filter_qemu_io]) -+ qsd_dst.stop() -diff --git a/tests/qemu-iotests/tests/qsd-migrate.out b/tests/qemu-iotests/tests/qsd-migrate.out -new file mode 100644 -index 0000000000..4a5241e5d4 ---- /dev/null -+++ b/tests/qemu-iotests/tests/qsd-migrate.out -@@ -0,0 +1,59 @@ -+Preparing disk... -+Launching source QSD... -+Launching source VM... -+Launching destination QSD... -+Launching destination VM... -+ -+Test I/O on the source -+{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"write -P 0x11 0 4k\""}} -+{"return": ""} -+{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"read -P 0x11 0 4k\""}} -+{"return": ""} -+ -+Starting migration... -+{"execute": "migrate-set-capabilities", "arguments": {"capabilities": [{"capability": "events", "state": true}, {"capability": "pause-before-switchover", "state": true}]}} -+{"return": {}} -+{"execute": "migrate-set-capabilities", "arguments": {"capabilities": [{"capability": "events", "state": true}, {"capability": "pause-before-switchover", "state": true}]}} -+{"return": {}} -+{"execute": "migrate", "arguments": {"uri": "unix:SOCK_DIR/PID-migrate.sock"}} -+{"return": {}} -+ -+Pre-switchover: Reconfigure QSD instances -+{"return": {}} -+{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"read -P 0x11 0 4k\""}} -+{"return": ""} -+{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"read 0 4k\""}} -+{"return": ""} -+{"return": {}} -+ -+Completing migration... -+{"execute": "migrate-continue", "arguments": {"state": "pre-switchover"}} -+{"return": {}} -+ -+Test I/O on the destination -+{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"read -P 0x11 0 4k\""}} -+{"return": ""} -+{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"write -P 0x22 0 4k\""}} -+{"return": ""} -+{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"read -P 0x22 0 4k\""}} -+{"return": ""} -+ -+Done -+ -+--- vm_src log --- -+wrote 4096/4096 bytes at offset 0 -+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -+read 4096/4096 bytes at offset 0 -+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -+read 4096/4096 bytes at offset 0 -+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -+ -+--- vm_dst log --- -+read 4096/4096 bytes at offset 0 -+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -+read 4096/4096 bytes at offset 0 -+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -+wrote 4096/4096 bytes at offset 0 -+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -+read 4096/4096 bytes at offset 0 -+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) --- -2.39.3 - diff --git a/kvm-iotests-Improve-iotest-194-to-mirror-data.patch b/kvm-iotests-Improve-iotest-194-to-mirror-data.patch new file mode 100644 index 0000000..caeec40 --- /dev/null +++ b/kvm-iotests-Improve-iotest-194-to-mirror-data.patch @@ -0,0 +1,42 @@ +From 11b46a271d73631177f59ff581a408f967c30fb9 Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Fri, 9 May 2025 15:40:22 -0500 +Subject: [PATCH 05/14] iotests: Improve iotest 194 to mirror data + +RH-Author: Eric Blake +RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors +RH-Jira: RHEL-88435 RHEL-88437 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +RH-Commit: [5/14] 9f1fd3c7d4332ac310af4eb37e8f2122f6324294 (ebblake/centos-qemu-kvm) + +Mirroring a completely sparse image to a sparse destination should be +practically instantaneous. It isn't yet, but the test will be more +realistic if it has some non-zero to mirror as well as the holes. + +Signed-off-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-ID: <20250509204341.3553601-20-eblake@redhat.com> +(cherry picked from commit eb89627899bb84148d272394e885725eff456ae9) +Jira: https://issues.redhat.com/browse/RHEL-88435 +Jira: https://issues.redhat.com/browse/RHEL-88437 +Signed-off-by: Eric Blake +--- + tests/qemu-iotests/194 | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/qemu-iotests/194 b/tests/qemu-iotests/194 +index c0ce82dd25..d0b9c084f5 100755 +--- a/tests/qemu-iotests/194 ++++ b/tests/qemu-iotests/194 +@@ -34,6 +34,7 @@ with iotests.FilePath('source.img') as source_img_path, \ + + img_size = '1G' + iotests.qemu_img_create('-f', iotests.imgfmt, source_img_path, img_size) ++ iotests.qemu_io('-f', iotests.imgfmt, '-c', 'write 512M 1M', source_img_path) + iotests.qemu_img_create('-f', iotests.imgfmt, dest_img_path, img_size) + + iotests.log('Launching VMs...') +-- +2.39.3 + diff --git a/kvm-iotests-common.rc-add-disk_usage-function.patch b/kvm-iotests-common.rc-add-disk_usage-function.patch new file mode 100644 index 0000000..02fc97a --- /dev/null +++ b/kvm-iotests-common.rc-add-disk_usage-function.patch @@ -0,0 +1,68 @@ +From d8ed5039981b1eb81d229d8ee672d5ee28862e92 Mon Sep 17 00:00:00 2001 +From: Andrey Drobyshev +Date: Fri, 9 May 2025 15:40:29 -0500 +Subject: [PATCH 12/14] iotests/common.rc: add disk_usage function + +RH-Author: Eric Blake +RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors +RH-Jira: RHEL-88435 RHEL-88437 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +RH-Commit: [12/14] 0a007f9d09f01b50cf4edeb8ac8217356b2cb5d2 (ebblake/centos-qemu-kvm) + +Move the definition from iotests/250 to common.rc. This is used to +detect real disk usage of sparse files. In particular, we want to use +it for checking subclusters-based discards. + +Signed-off-by: Andrey Drobyshev +Reviewed-by: Alexander Ivanov +Reviewed-by: Alberto Garcia +Message-ID: <20240913163942.423050-6-andrey.drobyshev@virtuozzo.com> +Signed-off-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-ID: <20250509204341.3553601-27-eblake@redhat.com> +(cherry picked from commit be9bac072ede6e6aa27079f59efcf17b56bd7b26) +Jira: https://issues.redhat.com/browse/RHEL-88435 +Jira: https://issues.redhat.com/browse/RHEL-88437 +Signed-off-by: Eric Blake +--- + tests/qemu-iotests/250 | 5 ----- + tests/qemu-iotests/common.rc | 6 ++++++ + 2 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/tests/qemu-iotests/250 b/tests/qemu-iotests/250 +index af48f83aba..c0a0dbc0ff 100755 +--- a/tests/qemu-iotests/250 ++++ b/tests/qemu-iotests/250 +@@ -52,11 +52,6 @@ _unsupported_imgopts data_file + # bdrv_co_truncate(bs->file) call in qcow2_co_truncate(), which might succeed + # anyway. + +-disk_usage() +-{ +- du --block-size=1 $1 | awk '{print $1}' +-} +- + size=2100M + + _make_test_img -o "cluster_size=1M,preallocation=metadata" $size +diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc +index 95c12577dd..237f746af8 100644 +--- a/tests/qemu-iotests/common.rc ++++ b/tests/qemu-iotests/common.rc +@@ -140,6 +140,12 @@ _optstr_add() + fi + } + ++# report real disk usage for sparse files ++disk_usage() ++{ ++ du --block-size=1 "$1" | awk '{print $1}' ++} ++ + # Set the variables to the empty string to turn Valgrind off + # for specific processes, e.g. + # $ VALGRIND_QEMU_IO= ./check -qcow2 -valgrind 015 +-- +2.39.3 + diff --git a/kvm-iotests-graph-changes-while-io-add-test-case-with-re.patch b/kvm-iotests-graph-changes-while-io-add-test-case-with-re.patch new file mode 100644 index 0000000..4ec2cc5 --- /dev/null +++ b/kvm-iotests-graph-changes-while-io-add-test-case-with-re.patch @@ -0,0 +1,176 @@ +From 19aa4d70aa02db7183997cfb2e6086a125ee2cdd Mon Sep 17 00:00:00 2001 +From: Andrey Drobyshev +Date: Fri, 30 May 2025 17:10:58 +0200 +Subject: [PATCH 33/33] iotests/graph-changes-while-io: add test case with + removal of lower snapshot + +RH-Author: Kevin Wolf +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +RH-Commit: [21/21] 2382d5d35e99a8d2dc481e1ddf89b475d13a620f (kmwolf/centos-qemu-kvm) + +This case is catching potential deadlock which takes place when job-dismiss +is issued when I/O requests are processed in a separate iothread. + +See https://mail.gnu.org/archive/html/qemu-devel/2025-04/msg04421.html + +Signed-off-by: Andrey Drobyshev +[FE: re-use top image and rename snap1->mid as suggested by Kevin Wolf + remove image file after test as suggested by Kevin Wolf + add type annotation for function argument to make mypy happy] +Signed-off-by: Fiona Ebner +Message-ID: <20250530151125.955508-22-f.ebner@proxmox.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit 09d98a018e1fd2db0bb73bbe9b4a7110c8ae354f) +Signed-off-by: Kevin Wolf +--- + .../qemu-iotests/tests/graph-changes-while-io | 101 ++++++++++++++++-- + .../tests/graph-changes-while-io.out | 4 +- + 2 files changed, 96 insertions(+), 9 deletions(-) + +diff --git a/tests/qemu-iotests/tests/graph-changes-while-io b/tests/qemu-iotests/tests/graph-changes-while-io +index 35489e3b5e..dca1167b6d 100755 +--- a/tests/qemu-iotests/tests/graph-changes-while-io ++++ b/tests/qemu-iotests/tests/graph-changes-while-io +@@ -27,6 +27,7 @@ from iotests import imgfmt, qemu_img, qemu_img_create, qemu_io, \ + + + top = os.path.join(iotests.test_dir, 'top.img') ++mid = os.path.join(iotests.test_dir, 'mid.img') + nbd_sock = os.path.join(iotests.sock_dir, 'nbd.sock') + + +@@ -59,6 +60,15 @@ class TestGraphChangesWhileIO(QMPTestCase): + self.qsd.stop() + os.remove(top) + ++ def _wait_for_blockjob(self, status: str) -> None: ++ done = False ++ while not done: ++ for event in self.qsd.get_qmp().get_events(wait=10.0): ++ if event['event'] != 'JOB_STATUS_CHANGE': ++ continue ++ if event['data']['status'] == status: ++ done = True ++ + def test_blockdev_add_while_io(self) -> None: + # Run qemu-img bench in the background + bench_thr = Thread(target=do_qemu_img_bench) +@@ -117,15 +127,92 @@ class TestGraphChangesWhileIO(QMPTestCase): + 'device': 'job0', + }) + +- cancelled = False +- while not cancelled: +- for event in self.qsd.get_qmp().get_events(wait=10.0): +- if event['event'] != 'JOB_STATUS_CHANGE': +- continue +- if event['data']['status'] == 'null': +- cancelled = True ++ self._wait_for_blockjob('null') ++ ++ bench_thr.join() ++ ++ def test_remove_lower_snapshot_while_io(self) -> None: ++ # Run qemu-img bench in the background ++ bench_thr = Thread(target=do_qemu_img_bench, args=(100000, )) ++ bench_thr.start() ++ ++ # While I/O is performed on 'node0' node, consequently add 2 snapshots ++ # on top of it, then remove (commit) them starting from lower one. ++ while bench_thr.is_alive(): ++ # Recreate snapshot images on every iteration ++ qemu_img_create('-f', imgfmt, mid, '1G') ++ qemu_img_create('-f', imgfmt, top, '1G') ++ ++ self.qsd.cmd('blockdev-add', { ++ 'driver': imgfmt, ++ 'node-name': 'mid', ++ 'file': { ++ 'driver': 'file', ++ 'filename': mid ++ } ++ }) ++ ++ self.qsd.cmd('blockdev-snapshot', { ++ 'node': 'node0', ++ 'overlay': 'mid', ++ }) ++ ++ self.qsd.cmd('blockdev-add', { ++ 'driver': imgfmt, ++ 'node-name': 'top', ++ 'file': { ++ 'driver': 'file', ++ 'filename': top ++ } ++ }) ++ ++ self.qsd.cmd('blockdev-snapshot', { ++ 'node': 'mid', ++ 'overlay': 'top', ++ }) ++ ++ self.qsd.cmd('block-commit', { ++ 'job-id': 'commit-mid', ++ 'device': 'top', ++ 'top-node': 'mid', ++ 'base-node': 'node0', ++ 'auto-finalize': True, ++ 'auto-dismiss': False, ++ }) ++ ++ self._wait_for_blockjob('concluded') ++ self.qsd.cmd('job-dismiss', { ++ 'id': 'commit-mid', ++ }) ++ ++ self.qsd.cmd('block-commit', { ++ 'job-id': 'commit-top', ++ 'device': 'top', ++ 'top-node': 'top', ++ 'base-node': 'node0', ++ 'auto-finalize': True, ++ 'auto-dismiss': False, ++ }) ++ ++ self._wait_for_blockjob('ready') ++ self.qsd.cmd('job-complete', { ++ 'id': 'commit-top', ++ }) ++ ++ self._wait_for_blockjob('concluded') ++ self.qsd.cmd('job-dismiss', { ++ 'id': 'commit-top', ++ }) ++ ++ self.qsd.cmd('blockdev-del', { ++ 'node-name': 'mid' ++ }) ++ self.qsd.cmd('blockdev-del', { ++ 'node-name': 'top' ++ }) + + bench_thr.join() ++ os.remove(mid) + + if __name__ == '__main__': + # Format must support raw backing files +diff --git a/tests/qemu-iotests/tests/graph-changes-while-io.out b/tests/qemu-iotests/tests/graph-changes-while-io.out +index fbc63e62f8..8d7e996700 100644 +--- a/tests/qemu-iotests/tests/graph-changes-while-io.out ++++ b/tests/qemu-iotests/tests/graph-changes-while-io.out +@@ -1,5 +1,5 @@ +-.. ++... + ---------------------------------------------------------------------- +-Ran 2 tests ++Ran 3 tests + + OK +-- +2.39.3 + diff --git a/kvm-iotests-graph-changes-while-io-remove-image-file-aft.patch b/kvm-iotests-graph-changes-while-io-remove-image-file-aft.patch new file mode 100644 index 0000000..af0c52f --- /dev/null +++ b/kvm-iotests-graph-changes-while-io-remove-image-file-aft.patch @@ -0,0 +1,39 @@ +From 727fb4bf3409e170fbab697981f5f57b6ee2f93b Mon Sep 17 00:00:00 2001 +From: Fiona Ebner +Date: Fri, 30 May 2025 17:10:57 +0200 +Subject: [PATCH 32/33] iotests/graph-changes-while-io: remove image file after + test + +RH-Author: Kevin Wolf +RH-MergeRequest: 393: block: do not drain while holding the graph lock +RH-Jira: RHEL-88561 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Czenczek +RH-Commit: [20/21] b7c8fe57ca9058829b6c959ca2305420261d99f5 (kmwolf/centos-qemu-kvm) + +Suggested-by: Kevin Wolf +Signed-off-by: Fiona Ebner +Message-ID: <20250530151125.955508-21-f.ebner@proxmox.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit ed8c62927e8facebb1e41b417daee3109e398712) +Signed-off-by: Kevin Wolf +--- + tests/qemu-iotests/tests/graph-changes-while-io | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/qemu-iotests/tests/graph-changes-while-io b/tests/qemu-iotests/tests/graph-changes-while-io +index 194fda500e..35489e3b5e 100755 +--- a/tests/qemu-iotests/tests/graph-changes-while-io ++++ b/tests/qemu-iotests/tests/graph-changes-while-io +@@ -57,6 +57,7 @@ class TestGraphChangesWhileIO(QMPTestCase): + + def tearDown(self) -> None: + self.qsd.stop() ++ os.remove(top) + + def test_blockdev_add_while_io(self) -> None: + # Run qemu-img bench in the background +-- +2.39.3 + diff --git a/kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch b/kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch deleted file mode 100644 index f6eb21f..0000000 --- a/kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch +++ /dev/null @@ -1,287 +0,0 @@ -From 74964784ffb9a0ad307eddafddd6b47f596ca3c1 Mon Sep 17 00:00:00 2001 -From: Julia Suvorova -Date: Fri, 27 Sep 2024 12:47:40 +0200 -Subject: [PATCH 28/38] kvm: Allow kvm_arch_get/put_registers to accept Error** - -RH-Author: Julia Suvorova -RH-MergeRequest: 287: kvm: Allow kvm_arch_get/put_registers to accept Error** -RH-Jira: RHEL-20574 -RH-Acked-by: Juraj Marcin -RH-Acked-by: Peter Xu -RH-Commit: [1/2] 7b1d8bf84339f908358f3fe3e392b1950aaa881d - -This is necessary to provide discernible error messages to the caller. - -Signed-off-by: Julia Suvorova -Reviewed-by: Peter Xu -Link: https://lore.kernel.org/r/20240927104743.218468-2-jusual@redhat.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit a1676bb3047f28b292ecbce3a378ccc0b4721d47) ---- - accel/kvm/kvm-all.c | 41 +++++++++++++++++++++++++++++--------- - include/sysemu/kvm.h | 4 ++-- - target/arm/kvm.c | 4 ++-- - target/i386/kvm/kvm.c | 4 ++-- - target/loongarch/kvm/kvm.c | 4 ++-- - target/mips/kvm.c | 4 ++-- - target/ppc/kvm.c | 4 ++-- - target/riscv/kvm/kvm-cpu.c | 4 ++-- - target/s390x/kvm/kvm.c | 4 ++-- - 9 files changed, 48 insertions(+), 25 deletions(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index acc23092e7..c7f1cc64b6 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2766,9 +2766,15 @@ void kvm_flush_coalesced_mmio_buffer(void) - static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg) - { - if (!cpu->vcpu_dirty && !kvm_state->guest_state_protected) { -- int ret = kvm_arch_get_registers(cpu); -+ Error *err = NULL; -+ int ret = kvm_arch_get_registers(cpu, &err); - if (ret) { -- error_report("Failed to get registers: %s", strerror(-ret)); -+ if (err) { -+ error_reportf_err(err, "Failed to synchronize CPU state: "); -+ } else { -+ error_report("Failed to get registers: %s", strerror(-ret)); -+ } -+ - cpu_dump_state(cpu, stderr, CPU_DUMP_CODE); - vm_stop(RUN_STATE_INTERNAL_ERROR); - } -@@ -2786,9 +2792,15 @@ void kvm_cpu_synchronize_state(CPUState *cpu) - - static void do_kvm_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg) - { -- int ret = kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE); -+ Error *err = NULL; -+ int ret = kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE, &err); - if (ret) { -- error_report("Failed to put registers after reset: %s", strerror(-ret)); -+ if (err) { -+ error_reportf_err(err, "Restoring resisters after reset: "); -+ } else { -+ error_report("Failed to put registers after reset: %s", -+ strerror(-ret)); -+ } - cpu_dump_state(cpu, stderr, CPU_DUMP_CODE); - vm_stop(RUN_STATE_INTERNAL_ERROR); - } -@@ -2803,9 +2815,15 @@ void kvm_cpu_synchronize_post_reset(CPUState *cpu) - - static void do_kvm_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg) - { -- int ret = kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE); -+ Error *err = NULL; -+ int ret = kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE, &err); - if (ret) { -- error_report("Failed to put registers after init: %s", strerror(-ret)); -+ if (err) { -+ error_reportf_err(err, "Putting registers after init: "); -+ } else { -+ error_report("Failed to put registers after init: %s", -+ strerror(-ret)); -+ } - exit(1); - } - -@@ -2995,10 +3013,15 @@ int kvm_cpu_exec(CPUState *cpu) - MemTxAttrs attrs; - - if (cpu->vcpu_dirty) { -- ret = kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE); -+ Error *err = NULL; -+ ret = kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE, &err); - if (ret) { -- error_report("Failed to put registers after init: %s", -- strerror(-ret)); -+ if (err) { -+ error_reportf_err(err, "Putting registers after init: "); -+ } else { -+ error_report("Failed to put registers after init: %s", -+ strerror(-ret)); -+ } - ret = -1; - break; - } -diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h -index 9cf14ca3d5..d9ad723f78 100644 ---- a/include/sysemu/kvm.h -+++ b/include/sysemu/kvm.h -@@ -359,7 +359,7 @@ int kvm_arch_handle_exit(CPUState *cpu, struct kvm_run *run); - - int kvm_arch_process_async_events(CPUState *cpu); - --int kvm_arch_get_registers(CPUState *cpu); -+int kvm_arch_get_registers(CPUState *cpu, Error **errp); - - /* state subset only touched by the VCPU itself during runtime */ - #define KVM_PUT_RUNTIME_STATE 1 -@@ -368,7 +368,7 @@ int kvm_arch_get_registers(CPUState *cpu); - /* full state set, modified during initialization or on vmload */ - #define KVM_PUT_FULL_STATE 3 - --int kvm_arch_put_registers(CPUState *cpu, int level); -+int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp); - - int kvm_arch_get_default_type(MachineState *ms); - -diff --git a/target/arm/kvm.c b/target/arm/kvm.c -index 849e2e21b3..f1f1b5b375 100644 ---- a/target/arm/kvm.c -+++ b/target/arm/kvm.c -@@ -2042,7 +2042,7 @@ static int kvm_arch_put_sve(CPUState *cs) - return 0; - } - --int kvm_arch_put_registers(CPUState *cs, int level) -+int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) - { - uint64_t val; - uint32_t fpr; -@@ -2226,7 +2226,7 @@ static int kvm_arch_get_sve(CPUState *cs) - return 0; - } - --int kvm_arch_get_registers(CPUState *cs) -+int kvm_arch_get_registers(CPUState *cs, Error **errp) - { - uint64_t val; - unsigned int el; -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 2b28c18693..423e6922d8 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -5121,7 +5121,7 @@ static int kvm_get_nested_state(X86CPU *cpu) - return ret; - } - --int kvm_arch_put_registers(CPUState *cpu, int level) -+int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp) - { - X86CPU *x86_cpu = X86_CPU(cpu); - int ret; -@@ -5209,7 +5209,7 @@ int kvm_arch_put_registers(CPUState *cpu, int level) - return 0; - } - --int kvm_arch_get_registers(CPUState *cs) -+int kvm_arch_get_registers(CPUState *cs, Error **errp) - { - X86CPU *cpu = X86_CPU(cs); - int ret; -diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c -index e1be6a6959..9204d4295d 100644 ---- a/target/loongarch/kvm/kvm.c -+++ b/target/loongarch/kvm/kvm.c -@@ -585,7 +585,7 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs) - return ret; - } - --int kvm_arch_get_registers(CPUState *cs) -+int kvm_arch_get_registers(CPUState *cs, Error **errp) - { - int ret; - -@@ -613,7 +613,7 @@ int kvm_arch_get_registers(CPUState *cs) - return ret; - } - --int kvm_arch_put_registers(CPUState *cs, int level) -+int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) - { - int ret; - -diff --git a/target/mips/kvm.c b/target/mips/kvm.c -index a631ab544f..a98798c669 100644 ---- a/target/mips/kvm.c -+++ b/target/mips/kvm.c -@@ -1172,7 +1172,7 @@ static int kvm_mips_get_cp0_registers(CPUState *cs) - return ret; - } - --int kvm_arch_put_registers(CPUState *cs, int level) -+int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) - { - CPUMIPSState *env = cpu_env(cs); - struct kvm_regs regs; -@@ -1207,7 +1207,7 @@ int kvm_arch_put_registers(CPUState *cs, int level) - return ret; - } - --int kvm_arch_get_registers(CPUState *cs) -+int kvm_arch_get_registers(CPUState *cs, Error **errp) - { - CPUMIPSState *env = cpu_env(cs); - int ret = 0; -diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c -index 907dba60d1..3efc28f18b 100644 ---- a/target/ppc/kvm.c -+++ b/target/ppc/kvm.c -@@ -900,7 +900,7 @@ int kvmppc_put_books_sregs(PowerPCCPU *cpu) - return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_SREGS, &sregs); - } - --int kvm_arch_put_registers(CPUState *cs, int level) -+int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) - { - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; -@@ -1205,7 +1205,7 @@ static int kvmppc_get_books_sregs(PowerPCCPU *cpu) - return 0; - } - --int kvm_arch_get_registers(CPUState *cs) -+int kvm_arch_get_registers(CPUState *cs, Error **errp) - { - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; -diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c -index f6e3156b8d..2bfb112be0 100644 ---- a/target/riscv/kvm/kvm-cpu.c -+++ b/target/riscv/kvm/kvm-cpu.c -@@ -1192,7 +1192,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { - KVM_CAP_LAST_INFO - }; - --int kvm_arch_get_registers(CPUState *cs) -+int kvm_arch_get_registers(CPUState *cs, Error **errp) - { - int ret = 0; - -@@ -1237,7 +1237,7 @@ int kvm_riscv_sync_mpstate_to_kvm(RISCVCPU *cpu, int state) - return 0; - } - --int kvm_arch_put_registers(CPUState *cs, int level) -+int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) - { - int ret = 0; - -diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c -index 94181d9281..8ffe0159d8 100644 ---- a/target/s390x/kvm/kvm.c -+++ b/target/s390x/kvm/kvm.c -@@ -472,7 +472,7 @@ static int can_sync_regs(CPUState *cs, int regs) - #define KVM_SYNC_REQUIRED_REGS (KVM_SYNC_GPRS | KVM_SYNC_ACRS | \ - KVM_SYNC_CRS | KVM_SYNC_PREFIX) - --int kvm_arch_put_registers(CPUState *cs, int level) -+int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) - { - CPUS390XState *env = cpu_env(cs); - struct kvm_fpu fpu = {}; -@@ -598,7 +598,7 @@ int kvm_arch_put_registers(CPUState *cs, int level) - return 0; - } - --int kvm_arch_get_registers(CPUState *cs) -+int kvm_arch_get_registers(CPUState *cs, Error **errp) - { - CPUS390XState *env = cpu_env(cs); - struct kvm_fpu fpu; --- -2.39.3 - diff --git a/kvm-kvm-Check-KVM_CAP_MAX_VCPUS-at-vm-level.patch b/kvm-kvm-Check-KVM_CAP_MAX_VCPUS-at-vm-level.patch new file mode 100644 index 0000000..c1292a2 --- /dev/null +++ b/kvm-kvm-Check-KVM_CAP_MAX_VCPUS-at-vm-level.patch @@ -0,0 +1,37 @@ +From 12b987964bc5314f26d33583d5033fe9d54112e4 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:47 +0200 +Subject: [PATCH 044/100] kvm: Check KVM_CAP_MAX_VCPUS at vm level + +KVM with TDX support starts to report different KVM_CAP_MAX_VCPUS per +different VM types. So switch to check the KVM_CAP_MAX_VCPUS at vm level. + +KVM still returns the global KVM_CAP_MAX_VCPUS when the KVM is old that +doesn't report different value at vm level. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-31-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 77b5403a0298a5460554f768a2098fd21588e555) +Signed-off-by: Paolo Bonzini +--- + 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 1655c21f91..696abf2cea 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -2425,7 +2425,7 @@ static int kvm_recommended_vcpus(KVMState *s) + + static int kvm_max_vcpus(KVMState *s) + { +- int ret = kvm_check_extension(s, KVM_CAP_MAX_VCPUS); ++ int ret = kvm_vm_check_extension(s, KVM_CAP_MAX_VCPUS); + return (ret) ? ret : kvm_recommended_vcpus(s); + } + +-- +2.47.3 + diff --git a/kvm-kvm-Introduce-kvm_arch_pre_create_vcpu.patch b/kvm-kvm-Introduce-kvm_arch_pre_create_vcpu.patch new file mode 100644 index 0000000..31f3e20 --- /dev/null +++ b/kvm-kvm-Introduce-kvm_arch_pre_create_vcpu.patch @@ -0,0 +1,177 @@ +From 6d5f21436f28a488124f558a5bf96472615de027 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 25 Jul 2025 16:28:19 +0200 +Subject: [PATCH 021/100] kvm: Introduce kvm_arch_pre_create_vcpu() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduce kvm_arch_pre_create_vcpu(), to perform arch-dependent +work prior to create any vcpu. This is for i386 TDX because it needs +call TDX_INIT_VM before creating any vcpu. + +The specific implementation for i386 will be added in the future patch. + +Signed-off-by: Xiaoyao Li +Acked-by: Gerd Hoffmann +Reviewed-by: Daniel P. BerrangĂ© +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20250508150002.689633-8-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit a668268dc08f7f4d30cecd513054bb38ce48c0d6) +Signed-off-by: Paolo Bonzini +--- + accel/kvm/kvm-all.c | 5 +++++ + include/system/kvm.h | 1 + + target/arm/kvm.c | 5 +++++ + target/i386/kvm/kvm.c | 5 +++++ + target/loongarch/kvm/kvm.c | 5 +++++ + target/mips/kvm.c | 5 +++++ + target/ppc/kvm.c | 5 +++++ + target/riscv/kvm/kvm-cpu.c | 5 +++++ + target/s390x/kvm/kvm.c | 5 +++++ + 9 files changed, 41 insertions(+) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index 0723a3933b..1655c21f91 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -540,6 +540,11 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp) + + trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu)); + ++ ret = kvm_arch_pre_create_vcpu(cpu, errp); ++ if (ret < 0) { ++ goto err; ++ } ++ + ret = kvm_create_vcpu(cpu); + if (ret < 0) { + error_setg_errno(errp, -ret, +diff --git a/include/system/kvm.h b/include/system/kvm.h +index ab17c09a55..d7dfa25493 100644 +--- a/include/system/kvm.h ++++ b/include/system/kvm.h +@@ -374,6 +374,7 @@ int kvm_arch_get_default_type(MachineState *ms); + + int kvm_arch_init(MachineState *ms, KVMState *s); + ++int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp); + int kvm_arch_init_vcpu(CPUState *cpu); + int kvm_arch_destroy_vcpu(CPUState *cpu); + +diff --git a/target/arm/kvm.c b/target/arm/kvm.c +index 97de8c7e93..d53ac64bf1 100644 +--- a/target/arm/kvm.c ++++ b/target/arm/kvm.c +@@ -1874,6 +1874,11 @@ static int kvm_arm_sve_set_vls(ARMCPU *cpu) + + #define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5 + ++int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp) ++{ ++ return 0; ++} ++ + int kvm_arch_init_vcpu(CPUState *cs) + { + int ret; +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index dcb432cb48..3affc7193b 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -2050,6 +2050,11 @@ full: + abort(); + } + ++int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp) ++{ ++ return 0; ++} ++ + int kvm_arch_init_vcpu(CPUState *cs) + { + struct { +diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c +index 1bda570482..c6cc05356e 100644 +--- a/target/loongarch/kvm/kvm.c ++++ b/target/loongarch/kvm/kvm.c +@@ -838,6 +838,11 @@ static void kvm_loongarch_vm_stage_change(void *opaque, bool running, + } + } + ++int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp) ++{ ++ return 0; ++} ++ + static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature) + { + int ret; +diff --git a/target/mips/kvm.c b/target/mips/kvm.c +index d67b7c1a8e..ec53acb51a 100644 +--- a/target/mips/kvm.c ++++ b/target/mips/kvm.c +@@ -61,6 +61,11 @@ int kvm_arch_irqchip_create(KVMState *s) + return 0; + } + ++int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp) ++{ ++ return 0; ++} ++ + int kvm_arch_init_vcpu(CPUState *cs) + { + CPUMIPSState *env = cpu_env(cs); +diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c +index 8b12b8e7d2..13e72ec4cb 100644 +--- a/target/ppc/kvm.c ++++ b/target/ppc/kvm.c +@@ -479,6 +479,11 @@ static void kvmppc_hw_debug_points_init(CPUPPCState *cenv) + } + } + ++int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp) ++{ ++ return 0; ++} ++ + int kvm_arch_init_vcpu(CPUState *cs) + { + PowerPCCPU *cpu = POWERPC_CPU(cs); +diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c +index 5315134e08..cdeee58484 100644 +--- a/target/riscv/kvm/kvm-cpu.c ++++ b/target/riscv/kvm/kvm-cpu.c +@@ -1383,6 +1383,11 @@ static int kvm_vcpu_enable_sbi_dbcn(RISCVCPU *cpu, CPUState *cs) + return kvm_set_one_reg(cs, kvm_sbi_dbcn.kvm_reg_id, ®); + } + ++int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp) ++{ ++ return 0; ++} ++ + int kvm_arch_init_vcpu(CPUState *cs) + { + int ret = 0; +diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c +index b9f1422197..8946f5a806 100644 +--- a/target/s390x/kvm/kvm.c ++++ b/target/s390x/kvm/kvm.c +@@ -404,6 +404,11 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu) + return cpu->cpu_index; + } + ++int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp) ++{ ++ return 0; ++} ++ + int kvm_arch_init_vcpu(CPUState *cs) + { + unsigned int max_cpus = MACHINE(qdev_get_machine())->smp.max_cpus; +-- +2.47.3 + diff --git a/kvm-kvm-refactor-core-virtual-machine-creation-into-its-.patch b/kvm-kvm-refactor-core-virtual-machine-creation-into-its-.patch deleted file mode 100644 index fa633bb..0000000 --- a/kvm-kvm-refactor-core-virtual-machine-creation-into-its-.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 67180363bdc1898462f90e16c1909db7331cc5e2 Mon Sep 17 00:00:00 2001 -From: Ani Sinha -Date: Thu, 8 Aug 2024 17:08:38 +0530 -Subject: [PATCH 3/9] kvm: refactor core virtual machine creation into its own - function - -RH-Author: Peter Xu -RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array -RH-Jira: RHEL-57685 -RH-Acked-by: Juraj Marcin -RH-Acked-by: Miroslav Rezanina -RH-Commit: [2/7] a783111d9a2ef6590103543f1bd103bf90052872 (peterx/qemu-kvm) - -Refactoring the core logic around KVM_CREATE_VM into its own separate function -so that it can be called from other functions in subsequent patches. There is -no functional change in this patch. - -CC: pbonzini@redhat.com -CC: zhao1.liu@intel.com -Signed-off-by: Ani Sinha -Link: https://lore.kernel.org/r/20240808113838.1697366-1-anisinha@redhat.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit 67388078da1cf6dac89e5a7c748cca3444d49690) -Signed-off-by: Peter Xu ---- - accel/kvm/kvm-all.c | 89 ++++++++++++++++++++++++++++----------------- - 1 file changed, 56 insertions(+), 33 deletions(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 7432a54f39..d86d1b515a 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2385,6 +2385,60 @@ uint32_t kvm_dirty_ring_size(void) - return kvm_state->kvm_dirty_ring_size; - } - -+static int do_kvm_create_vm(MachineState *ms, int type) -+{ -+ KVMState *s; -+ int ret; -+ -+ s = KVM_STATE(ms->accelerator); -+ -+ do { -+ ret = kvm_ioctl(s, KVM_CREATE_VM, type); -+ } while (ret == -EINTR); -+ -+ if (ret < 0) { -+ error_report("ioctl(KVM_CREATE_VM) failed: %s", strerror(-ret)); -+ -+#ifdef TARGET_S390X -+ if (ret == -EINVAL) { -+ error_printf("Host kernel setup problem detected." -+ " Please verify:\n"); -+ error_printf("- for kernels supporting the" -+ " switch_amode or user_mode parameters, whether"); -+ error_printf(" user space is running in primary address space\n"); -+ error_printf("- for kernels supporting the vm.allocate_pgste" -+ " sysctl, whether it is enabled\n"); -+ } -+#elif defined(TARGET_PPC) -+ if (ret == -EINVAL) { -+ error_printf("PPC KVM module is not loaded. Try modprobe kvm_%s.\n", -+ (type == 2) ? "pr" : "hv"); -+ } -+#endif -+ } -+ -+ return ret; -+} -+ -+static int find_kvm_machine_type(MachineState *ms) -+{ -+ MachineClass *mc = MACHINE_GET_CLASS(ms); -+ int type; -+ -+ if (object_property_find(OBJECT(current_machine), "kvm-type")) { -+ g_autofree char *kvm_type; -+ kvm_type = object_property_get_str(OBJECT(current_machine), -+ "kvm-type", -+ &error_abort); -+ type = mc->kvm_type(ms, kvm_type); -+ } else if (mc->kvm_type) { -+ type = mc->kvm_type(ms, NULL); -+ } else { -+ type = kvm_arch_get_default_type(ms); -+ } -+ return type; -+} -+ - static int kvm_init(MachineState *ms) - { - MachineClass *mc = MACHINE_GET_CLASS(ms); -@@ -2467,45 +2521,14 @@ static int kvm_init(MachineState *ms) - } - s->as = g_new0(struct KVMAs, s->nr_as); - -- if (object_property_find(OBJECT(current_machine), "kvm-type")) { -- g_autofree char *kvm_type = object_property_get_str(OBJECT(current_machine), -- "kvm-type", -- &error_abort); -- type = mc->kvm_type(ms, kvm_type); -- } else if (mc->kvm_type) { -- type = mc->kvm_type(ms, NULL); -- } else { -- type = kvm_arch_get_default_type(ms); -- } -- -+ type = find_kvm_machine_type(ms); - if (type < 0) { - ret = -EINVAL; - goto err; - } - -- do { -- ret = kvm_ioctl(s, KVM_CREATE_VM, type); -- } while (ret == -EINTR); -- -+ ret = do_kvm_create_vm(ms, type); - if (ret < 0) { -- error_report("ioctl(KVM_CREATE_VM) failed: %s", strerror(-ret)); -- --#ifdef TARGET_S390X -- if (ret == -EINVAL) { -- error_printf("Host kernel setup problem detected." -- " Please verify:\n"); -- error_printf("- for kernels supporting the" -- " switch_amode or user_mode parameters, whether"); -- error_printf(" user space is running in primary address space\n"); -- error_printf("- for kernels supporting the vm.allocate_pgste" -- " sysctl, whether it is enabled\n"); -- } --#elif defined(TARGET_PPC) -- if (ret == -EINVAL) { -- error_printf("PPC KVM module is not loaded. Try modprobe kvm_%s.\n", -- (type == 2) ? "pr" : "hv"); -- } --#endif - goto err; - } - --- -2.39.3 - diff --git a/kvm-kvm-replace-fprintf-with-error_report-printf-in-kvm_.patch b/kvm-kvm-replace-fprintf-with-error_report-printf-in-kvm_.patch deleted file mode 100644 index 7f7a756..0000000 --- a/kvm-kvm-replace-fprintf-with-error_report-printf-in-kvm_.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 522e19dd84eb5c4d88b3b70193ee104f67a5b89d Mon Sep 17 00:00:00 2001 -From: Ani Sinha -Date: Wed, 28 Aug 2024 18:15:39 +0530 -Subject: [PATCH 2/9] kvm: replace fprintf with error_report()/printf() in - kvm_init() - -RH-Author: Peter Xu -RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array -RH-Jira: RHEL-57685 -RH-Acked-by: Juraj Marcin -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/7] 6c1230a6d5033d928817df9458938a675058e995 (peterx/qemu-kvm) - -error_report() is more appropriate for error situations. Replace fprintf with -error_report() and error_printf() as appropriate. Some improvement in error -reporting also happens as a part of this change. For example: - -From: -$ ./qemu-system-x86_64 --accel kvm -Could not access KVM kernel module: No such file or directory - -To: -$ ./qemu-system-x86_64 --accel kvm -qemu-system-x86_64: --accel kvm: Could not access KVM kernel module: No such file or directory - -CC: qemu-trivial@nongnu.org -CC: zhao1.liu@intel.com -CC: armbru@redhat.com -Reviewed-by: Zhao Liu -Reviewed-by: Markus Armbruster -Signed-off-by: Ani Sinha -Link: https://lore.kernel.org/r/20240828124539.62672-1-anisinha@redhat.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit 804dfbe3ef5e950328b162ae85741be2e228544f) -Signed-off-by: Peter Xu ---- - accel/kvm/kvm-all.c | 40 ++++++++++++++++++---------------------- - 1 file changed, 18 insertions(+), 22 deletions(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index c7f1cc64b6..7432a54f39 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2427,7 +2427,7 @@ static int kvm_init(MachineState *ms) - QLIST_INIT(&s->kvm_parked_vcpus); - s->fd = qemu_open_old(s->device ?: "/dev/kvm", O_RDWR); - if (s->fd == -1) { -- fprintf(stderr, "Could not access KVM kernel module: %m\n"); -+ error_report("Could not access KVM kernel module: %m"); - ret = -errno; - goto err; - } -@@ -2437,13 +2437,13 @@ static int kvm_init(MachineState *ms) - if (ret >= 0) { - ret = -EINVAL; - } -- fprintf(stderr, "kvm version too old\n"); -+ error_report("kvm version too old"); - goto err; - } - - if (ret > KVM_API_VERSION) { - ret = -EINVAL; -- fprintf(stderr, "kvm version not supported\n"); -+ error_report("kvm version not supported"); - goto err; - } - -@@ -2488,26 +2488,22 @@ static int kvm_init(MachineState *ms) - } while (ret == -EINTR); - - if (ret < 0) { -- fprintf(stderr, "ioctl(KVM_CREATE_VM) failed: %d %s\n", -ret, -- strerror(-ret)); -+ error_report("ioctl(KVM_CREATE_VM) failed: %s", strerror(-ret)); - - #ifdef TARGET_S390X - if (ret == -EINVAL) { -- fprintf(stderr, -- "Host kernel setup problem detected. Please verify:\n"); -- fprintf(stderr, "- for kernels supporting the switch_amode or" -- " user_mode parameters, whether\n"); -- fprintf(stderr, -- " user space is running in primary address space\n"); -- fprintf(stderr, -- "- for kernels supporting the vm.allocate_pgste sysctl, " -- "whether it is enabled\n"); -+ error_printf("Host kernel setup problem detected." -+ " Please verify:\n"); -+ error_printf("- for kernels supporting the" -+ " switch_amode or user_mode parameters, whether"); -+ error_printf(" user space is running in primary address space\n"); -+ error_printf("- for kernels supporting the vm.allocate_pgste" -+ " sysctl, whether it is enabled\n"); - } - #elif defined(TARGET_PPC) - if (ret == -EINVAL) { -- fprintf(stderr, -- "PPC KVM module is not loaded. Try modprobe kvm_%s.\n", -- (type == 2) ? "pr" : "hv"); -+ error_printf("PPC KVM module is not loaded. Try modprobe kvm_%s.\n", -+ (type == 2) ? "pr" : "hv"); - } - #endif - goto err; -@@ -2526,9 +2522,9 @@ static int kvm_init(MachineState *ms) - nc->name, nc->num, soft_vcpus_limit); - - if (nc->num > hard_vcpus_limit) { -- fprintf(stderr, "Number of %s cpus requested (%d) exceeds " -- "the maximum cpus supported by KVM (%d)\n", -- nc->name, nc->num, hard_vcpus_limit); -+ error_report("Number of %s cpus requested (%d) exceeds " -+ "the maximum cpus supported by KVM (%d)", -+ nc->name, nc->num, hard_vcpus_limit); - exit(1); - } - } -@@ -2542,8 +2538,8 @@ static int kvm_init(MachineState *ms) - } - if (missing_cap) { - ret = -EINVAL; -- fprintf(stderr, "kvm does not support %s\n%s", -- missing_cap->name, upgrade_note); -+ error_report("kvm does not support %s", missing_cap->name); -+ error_printf("%s", upgrade_note); - goto err; - } - --- -2.39.3 - diff --git a/kvm-linux-headers-Update-to-Linux-6.13-rc1.patch b/kvm-linux-headers-Update-to-Linux-6.13-rc1.patch deleted file mode 100644 index f6f6574..0000000 --- a/kvm-linux-headers-Update-to-Linux-6.13-rc1.patch +++ /dev/null @@ -1,1099 +0,0 @@ -From 46aeae3bd6fad36c985dbd1a7cb2dde613fbc60b Mon Sep 17 00:00:00 2001 -From: Hendrik Brueckner -Date: Fri, 6 Dec 2024 13:27:42 +0100 -Subject: [PATCH 07/18] linux-headers: Update to Linux 6.13-rc1 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [7/16] f729f38c4bcd5eb773d8387f45292a6f7aa26c5c (thuth/qemu-kvm-cs9) - -This linux headers update includes required changes for -the gen17 CPU model. - -Signed-off-by: Hendrik Brueckner -Suggested-by: Thomas Huth -Message-ID: <20241206122751.189721-7-brueckner@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 44fe383c274174405da79f5fcb028e39fe688036) ---- - include/standard-headers/drm/drm_fourcc.h | 1 + - include/standard-headers/linux/ethtool.h | 5 + - include/standard-headers/linux/pci_regs.h | 38 ++- - .../standard-headers/linux/virtio_crypto.h | 1 + - include/standard-headers/linux/virtio_pci.h | 131 ++++++++++ - linux-headers/asm-arm64/kvm.h | 6 + - linux-headers/asm-arm64/unistd_64.h | 4 + - linux-headers/asm-generic/mman-common.h | 3 + - linux-headers/asm-generic/mman.h | 4 + - linux-headers/asm-generic/unistd.h | 11 +- - linux-headers/asm-loongarch/kvm.h | 20 ++ - linux-headers/asm-loongarch/unistd_64.h | 4 + - linux-headers/asm-mips/mman.h | 3 + - linux-headers/asm-mips/unistd_n32.h | 4 + - linux-headers/asm-mips/unistd_n64.h | 4 + - linux-headers/asm-mips/unistd_o32.h | 4 + - linux-headers/asm-powerpc/unistd_32.h | 4 + - linux-headers/asm-powerpc/unistd_64.h | 4 + - linux-headers/asm-riscv/kvm.h | 4 + - linux-headers/asm-riscv/unistd_32.h | 4 + - linux-headers/asm-riscv/unistd_64.h | 4 + - linux-headers/asm-s390/kvm.h | 3 +- - linux-headers/asm-s390/unistd_32.h | 4 + - linux-headers/asm-s390/unistd_64.h | 4 + - linux-headers/asm-x86/kvm.h | 1 + - linux-headers/asm-x86/mman.h | 3 - - linux-headers/asm-x86/unistd_32.h | 4 + - linux-headers/asm-x86/unistd_64.h | 4 + - linux-headers/asm-x86/unistd_x32.h | 4 + - linux-headers/linux/iommufd.h | 224 +++++++++++++++++- - linux-headers/linux/kvm.h | 8 + - linux-headers/linux/psci.h | 5 + - linux-headers/linux/vfio.h | 2 +- - 33 files changed, 506 insertions(+), 23 deletions(-) - -diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h -index d4a2231306..708647776f 100644 ---- a/include/standard-headers/drm/drm_fourcc.h -+++ b/include/standard-headers/drm/drm_fourcc.h -@@ -1515,6 +1515,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) - * 64K_D_2D on GFX12 is identical to 64K_D on GFX11. - */ - #define AMD_FMT_MOD_TILE_GFX9_64K_D 10 -+#define AMD_FMT_MOD_TILE_GFX9_4K_D_X 22 - #define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25 - #define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26 - #define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27 -diff --git a/include/standard-headers/linux/ethtool.h b/include/standard-headers/linux/ethtool.h -index b05e84825b..67c47912e5 100644 ---- a/include/standard-headers/linux/ethtool.h -+++ b/include/standard-headers/linux/ethtool.h -@@ -2526,6 +2526,11 @@ struct ethtool_link_settings { - uint8_t master_slave_state; - uint8_t rate_matching; - uint32_t reserved[7]; -+ /* Linux builds with -Wflex-array-member-not-at-end but does -+ * not use the "link_mode_masks" member. Leave it defined for -+ * userspace for now, and when userspace wants to start using -+ * -Wfamnae, we'll need a new solution. -+ */ - uint32_t link_mode_masks[]; - /* layout of link_mode_masks fields: - * uint32_t map_supported[link_mode_masks_nwords]; -diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h -index 12323b3334..1601c7ed5f 100644 ---- a/include/standard-headers/linux/pci_regs.h -+++ b/include/standard-headers/linux/pci_regs.h -@@ -340,7 +340,8 @@ - #define PCI_MSIX_ENTRY_UPPER_ADDR 0x4 /* Message Upper Address */ - #define PCI_MSIX_ENTRY_DATA 0x8 /* Message Data */ - #define PCI_MSIX_ENTRY_VECTOR_CTRL 0xc /* Vector Control */ --#define PCI_MSIX_ENTRY_CTRL_MASKBIT 0x00000001 -+#define PCI_MSIX_ENTRY_CTRL_MASKBIT 0x00000001 /* Mask Bit */ -+#define PCI_MSIX_ENTRY_CTRL_ST 0xffff0000 /* Steering Tag */ - - /* CompactPCI Hotswap Register */ - -@@ -659,6 +660,7 @@ - #define PCI_EXP_DEVCAP2_ATOMIC_COMP64 0x00000100 /* 64b AtomicOp completion */ - #define PCI_EXP_DEVCAP2_ATOMIC_COMP128 0x00000200 /* 128b AtomicOp completion */ - #define PCI_EXP_DEVCAP2_LTR 0x00000800 /* Latency tolerance reporting */ -+#define PCI_EXP_DEVCAP2_TPH_COMP_MASK 0x00003000 /* TPH completer support */ - #define PCI_EXP_DEVCAP2_OBFF_MASK 0x000c0000 /* OBFF support mechanism */ - #define PCI_EXP_DEVCAP2_OBFF_MSG 0x00040000 /* New message signaling */ - #define PCI_EXP_DEVCAP2_OBFF_WAKE 0x00080000 /* Re-use WAKE# for OBFF */ -@@ -678,6 +680,7 @@ - #define PCI_EXP_DEVSTA2 0x2a /* Device Status 2 */ - #define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V2 0x2c /* end of v2 EPs w/o link */ - #define PCI_EXP_LNKCAP2 0x2c /* Link Capabilities 2 */ -+#define PCI_EXP_LNKCAP2_SLS 0x000000fe /* Supported Link Speeds Vector */ - #define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002 /* Supported Speed 2.5GT/s */ - #define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004 /* Supported Speed 5GT/s */ - #define PCI_EXP_LNKCAP2_SLS_8_0GB 0x00000008 /* Supported Speed 8GT/s */ -@@ -1023,15 +1026,34 @@ - #define PCI_DPA_CAP_SUBSTATE_MASK 0x1F /* # substates - 1 */ - #define PCI_DPA_BASE_SIZEOF 16 /* size with 0 substates */ - -+/* TPH Completer Support */ -+#define PCI_EXP_DEVCAP2_TPH_COMP_NONE 0x0 /* None */ -+#define PCI_EXP_DEVCAP2_TPH_COMP_TPH_ONLY 0x1 /* TPH only */ -+#define PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH 0x3 /* TPH and Extended TPH */ -+ - /* TPH Requester */ - #define PCI_TPH_CAP 4 /* capability register */ --#define PCI_TPH_CAP_LOC_MASK 0x600 /* location mask */ --#define PCI_TPH_LOC_NONE 0x000 /* no location */ --#define PCI_TPH_LOC_CAP 0x200 /* in capability */ --#define PCI_TPH_LOC_MSIX 0x400 /* in MSI-X */ --#define PCI_TPH_CAP_ST_MASK 0x07FF0000 /* ST table mask */ --#define PCI_TPH_CAP_ST_SHIFT 16 /* ST table shift */ --#define PCI_TPH_BASE_SIZEOF 0xc /* size with no ST table */ -+#define PCI_TPH_CAP_ST_NS 0x00000001 /* No ST Mode Supported */ -+#define PCI_TPH_CAP_ST_IV 0x00000002 /* Interrupt Vector Mode Supported */ -+#define PCI_TPH_CAP_ST_DS 0x00000004 /* Device Specific Mode Supported */ -+#define PCI_TPH_CAP_EXT_TPH 0x00000100 /* Ext TPH Requester Supported */ -+#define PCI_TPH_CAP_LOC_MASK 0x00000600 /* ST Table Location */ -+#define PCI_TPH_LOC_NONE 0x00000000 /* Not present */ -+#define PCI_TPH_LOC_CAP 0x00000200 /* In capability */ -+#define PCI_TPH_LOC_MSIX 0x00000400 /* In MSI-X */ -+#define PCI_TPH_CAP_ST_MASK 0x07FF0000 /* ST Table Size */ -+#define PCI_TPH_CAP_ST_SHIFT 16 /* ST Table Size shift */ -+#define PCI_TPH_BASE_SIZEOF 0xc /* Size with no ST table */ -+ -+#define PCI_TPH_CTRL 8 /* control register */ -+#define PCI_TPH_CTRL_MODE_SEL_MASK 0x00000007 /* ST Mode Select */ -+#define PCI_TPH_ST_NS_MODE 0x0 /* No ST Mode */ -+#define PCI_TPH_ST_IV_MODE 0x1 /* Interrupt Vector Mode */ -+#define PCI_TPH_ST_DS_MODE 0x2 /* Device Specific Mode */ -+#define PCI_TPH_CTRL_REQ_EN_MASK 0x00000300 /* TPH Requester Enable */ -+#define PCI_TPH_REQ_DISABLE 0x0 /* No TPH requests allowed */ -+#define PCI_TPH_REQ_TPH_ONLY 0x1 /* TPH only requests allowed */ -+#define PCI_TPH_REQ_EXT_TPH 0x3 /* Extended TPH requests allowed */ - - /* Downstream Port Containment */ - #define PCI_EXP_DPC_CAP 0x04 /* DPC Capability */ -diff --git a/include/standard-headers/linux/virtio_crypto.h b/include/standard-headers/linux/virtio_crypto.h -index 68066dafb6..4d350ae595 100644 ---- a/include/standard-headers/linux/virtio_crypto.h -+++ b/include/standard-headers/linux/virtio_crypto.h -@@ -329,6 +329,7 @@ struct virtio_crypto_op_header { - VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x00) - #define VIRTIO_CRYPTO_AKCIPHER_DECRYPT \ - VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x01) -+ /* akcipher sign/verify opcodes are deprecated */ - #define VIRTIO_CRYPTO_AKCIPHER_SIGN \ - VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x02) - #define VIRTIO_CRYPTO_AKCIPHER_VERIFY \ -diff --git a/include/standard-headers/linux/virtio_pci.h b/include/standard-headers/linux/virtio_pci.h -index 4010216103..b177ed8972 100644 ---- a/include/standard-headers/linux/virtio_pci.h -+++ b/include/standard-headers/linux/virtio_pci.h -@@ -40,6 +40,7 @@ - #define _LINUX_VIRTIO_PCI_H - - #include "standard-headers/linux/types.h" -+#include "standard-headers/linux/kernel.h" - - #ifndef VIRTIO_PCI_NO_LEGACY - -@@ -240,6 +241,17 @@ struct virtio_pci_cfg_cap { - #define VIRTIO_ADMIN_CMD_LEGACY_DEV_CFG_READ 0x5 - #define VIRTIO_ADMIN_CMD_LEGACY_NOTIFY_INFO 0x6 - -+/* Device parts access commands. */ -+#define VIRTIO_ADMIN_CMD_CAP_ID_LIST_QUERY 0x7 -+#define VIRTIO_ADMIN_CMD_DEVICE_CAP_GET 0x8 -+#define VIRTIO_ADMIN_CMD_DRIVER_CAP_SET 0x9 -+#define VIRTIO_ADMIN_CMD_RESOURCE_OBJ_CREATE 0xa -+#define VIRTIO_ADMIN_CMD_RESOURCE_OBJ_DESTROY 0xd -+#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_GET 0xe -+#define VIRTIO_ADMIN_CMD_DEV_PARTS_GET 0xf -+#define VIRTIO_ADMIN_CMD_DEV_PARTS_SET 0x10 -+#define VIRTIO_ADMIN_CMD_DEV_MODE_SET 0x11 -+ - struct virtio_admin_cmd_hdr { - uint16_t opcode; - /* -@@ -286,4 +298,123 @@ struct virtio_admin_cmd_notify_info_result { - struct virtio_admin_cmd_notify_info_data entries[VIRTIO_ADMIN_CMD_MAX_NOTIFY_INFO]; - }; - -+#define VIRTIO_DEV_PARTS_CAP 0x0000 -+ -+struct virtio_dev_parts_cap { -+ uint8_t get_parts_resource_objects_limit; -+ uint8_t set_parts_resource_objects_limit; -+}; -+ -+#define MAX_CAP_ID __KERNEL_DIV_ROUND_UP(VIRTIO_DEV_PARTS_CAP + 1, 64) -+ -+struct virtio_admin_cmd_query_cap_id_result { -+ uint64_t supported_caps[MAX_CAP_ID]; -+}; -+ -+struct virtio_admin_cmd_cap_get_data { -+ uint16_t id; -+ uint8_t reserved[6]; -+}; -+ -+struct virtio_admin_cmd_cap_set_data { -+ uint16_t id; -+ uint8_t reserved[6]; -+ uint8_t cap_specific_data[]; -+}; -+ -+struct virtio_admin_cmd_resource_obj_cmd_hdr { -+ uint16_t type; -+ uint8_t reserved[2]; -+ uint32_t id; /* Indicates unique resource object id per resource object type */ -+}; -+ -+struct virtio_admin_cmd_resource_obj_create_data { -+ struct virtio_admin_cmd_resource_obj_cmd_hdr hdr; -+ uint64_t flags; -+ uint8_t resource_obj_specific_data[]; -+}; -+ -+#define VIRTIO_RESOURCE_OBJ_DEV_PARTS 0 -+ -+#define VIRTIO_RESOURCE_OBJ_DEV_PARTS_TYPE_GET 0 -+#define VIRTIO_RESOURCE_OBJ_DEV_PARTS_TYPE_SET 1 -+ -+struct virtio_resource_obj_dev_parts { -+ uint8_t type; -+ uint8_t reserved[7]; -+}; -+ -+#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_TYPE_SIZE 0 -+#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_TYPE_COUNT 1 -+#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_TYPE_LIST 2 -+ -+struct virtio_admin_cmd_dev_parts_metadata_data { -+ struct virtio_admin_cmd_resource_obj_cmd_hdr hdr; -+ uint8_t type; -+ uint8_t reserved[7]; -+}; -+ -+#define VIRTIO_DEV_PART_F_OPTIONAL 0 -+ -+struct virtio_dev_part_hdr { -+ uint16_t part_type; -+ uint8_t flags; -+ uint8_t reserved; -+ union { -+ struct { -+ uint32_t offset; -+ uint32_t reserved; -+ } pci_common_cfg; -+ struct { -+ uint16_t index; -+ uint8_t reserved[6]; -+ } vq_index; -+ } selector; -+ uint32_t length; -+}; -+ -+struct virtio_dev_part { -+ struct virtio_dev_part_hdr hdr; -+ uint8_t value[]; -+}; -+ -+struct virtio_admin_cmd_dev_parts_metadata_result { -+ union { -+ struct { -+ uint32_t size; -+ uint32_t reserved; -+ } parts_size; -+ struct { -+ uint32_t count; -+ uint32_t reserved; -+ } hdr_list_count; -+ struct { -+ uint32_t count; -+ uint32_t reserved; -+ struct virtio_dev_part_hdr hdrs[]; -+ } hdr_list; -+ }; -+}; -+ -+#define VIRTIO_ADMIN_CMD_DEV_PARTS_GET_TYPE_SELECTED 0 -+#define VIRTIO_ADMIN_CMD_DEV_PARTS_GET_TYPE_ALL 1 -+ -+struct virtio_admin_cmd_dev_parts_get_data { -+ struct virtio_admin_cmd_resource_obj_cmd_hdr hdr; -+ uint8_t type; -+ uint8_t reserved[7]; -+ struct virtio_dev_part_hdr hdr_list[]; -+}; -+ -+struct virtio_admin_cmd_dev_parts_set_data { -+ struct virtio_admin_cmd_resource_obj_cmd_hdr hdr; -+ struct virtio_dev_part parts[]; -+}; -+ -+#define VIRTIO_ADMIN_CMD_DEV_MODE_F_STOPPED 0 -+ -+struct virtio_admin_cmd_dev_mode_set_data { -+ uint8_t flags; -+}; -+ - #endif -diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h -index 2af9931ae9..dccd5d965f 100644 ---- a/linux-headers/asm-arm64/kvm.h -+++ b/linux-headers/asm-arm64/kvm.h -@@ -473,6 +473,12 @@ enum { - */ - #define KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2 (1ULL << 0) - -+/* -+ * Shutdown caused by a PSCI v1.3 SYSTEM_OFF2 call. -+ * Valid only when the system event has a type of KVM_SYSTEM_EVENT_SHUTDOWN. -+ */ -+#define KVM_SYSTEM_EVENT_SHUTDOWN_FLAG_PSCI_OFF2 (1ULL << 0) -+ - /* run->fail_entry.hardware_entry_failure_reason codes. */ - #define KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED (1ULL << 0) - -diff --git a/linux-headers/asm-arm64/unistd_64.h b/linux-headers/asm-arm64/unistd_64.h -index 99a1d70459..d4e90fff76 100644 ---- a/linux-headers/asm-arm64/unistd_64.h -+++ b/linux-headers/asm-arm64/unistd_64.h -@@ -319,6 +319,10 @@ - #define __NR_lsm_set_self_attr 460 - #define __NR_lsm_list_modules 461 - #define __NR_mseal 462 -+#define __NR_setxattrat 463 -+#define __NR_getxattrat 464 -+#define __NR_listxattrat 465 -+#define __NR_removexattrat 466 - - - #endif /* _ASM_UNISTD_64_H */ -diff --git a/linux-headers/asm-generic/mman-common.h b/linux-headers/asm-generic/mman-common.h -index 6ce1f1ceb4..1ea2c4c33b 100644 ---- a/linux-headers/asm-generic/mman-common.h -+++ b/linux-headers/asm-generic/mman-common.h -@@ -79,6 +79,9 @@ - - #define MADV_COLLAPSE 25 /* Synchronous hugepage collapse */ - -+#define MADV_GUARD_INSTALL 102 /* fatal signal on access to range */ -+#define MADV_GUARD_REMOVE 103 /* unguard range */ -+ - /* compatibility flags */ - #define MAP_FILE 0 - -diff --git a/linux-headers/asm-generic/mman.h b/linux-headers/asm-generic/mman.h -index 57e8195d0b..5e3d61ddbd 100644 ---- a/linux-headers/asm-generic/mman.h -+++ b/linux-headers/asm-generic/mman.h -@@ -19,4 +19,8 @@ - #define MCL_FUTURE 2 /* lock all future mappings */ - #define MCL_ONFAULT 4 /* lock all pages that are faulted in */ - -+#define SHADOW_STACK_SET_TOKEN (1ULL << 0) /* Set up a restore token in the shadow stack */ -+#define SHADOW_STACK_SET_MARKER (1ULL << 1) /* Set up a top of stack marker in the shadow stack */ -+ -+ - #endif /* __ASM_GENERIC_MMAN_H */ -diff --git a/linux-headers/asm-generic/unistd.h b/linux-headers/asm-generic/unistd.h -index 5bf6148cac..88dc393c2b 100644 ---- a/linux-headers/asm-generic/unistd.h -+++ b/linux-headers/asm-generic/unistd.h -@@ -841,8 +841,17 @@ __SYSCALL(__NR_lsm_list_modules, sys_lsm_list_modules) - #define __NR_mseal 462 - __SYSCALL(__NR_mseal, sys_mseal) - -+#define __NR_setxattrat 463 -+__SYSCALL(__NR_setxattrat, sys_setxattrat) -+#define __NR_getxattrat 464 -+__SYSCALL(__NR_getxattrat, sys_getxattrat) -+#define __NR_listxattrat 465 -+__SYSCALL(__NR_listxattrat, sys_listxattrat) -+#define __NR_removexattrat 466 -+__SYSCALL(__NR_removexattrat, sys_removexattrat) -+ - #undef __NR_syscalls --#define __NR_syscalls 463 -+#define __NR_syscalls 467 - - /* - * 32 bit systems traditionally used different -diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h -index 70d89070bf..5f354f5c68 100644 ---- a/linux-headers/asm-loongarch/kvm.h -+++ b/linux-headers/asm-loongarch/kvm.h -@@ -8,6 +8,8 @@ - - #include - -+#define __KVM_HAVE_IRQ_LINE -+ - /* - * KVM LoongArch specific structures and definitions. - * -@@ -132,4 +134,22 @@ struct kvm_iocsr_entry { - #define KVM_IRQCHIP_NUM_PINS 64 - #define KVM_MAX_CORES 256 - -+#define KVM_DEV_LOONGARCH_IPI_GRP_REGS 0x40000001 -+ -+#define KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS 0x40000002 -+ -+#define KVM_DEV_LOONGARCH_EXTIOI_GRP_SW_STATUS 0x40000003 -+#define KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_NUM_CPU 0x0 -+#define KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_FEATURE 0x1 -+#define KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_STATE 0x2 -+ -+#define KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL 0x40000004 -+#define KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU 0x0 -+#define KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_FEATURE 0x1 -+#define KVM_DEV_LOONGARCH_EXTIOI_CTRL_LOAD_FINISHED 0x3 -+ -+#define KVM_DEV_LOONGARCH_PCH_PIC_GRP_REGS 0x40000005 -+#define KVM_DEV_LOONGARCH_PCH_PIC_GRP_CTRL 0x40000006 -+#define KVM_DEV_LOONGARCH_PCH_PIC_CTRL_INIT 0 -+ - #endif /* __UAPI_ASM_LOONGARCH_KVM_H */ -diff --git a/linux-headers/asm-loongarch/unistd_64.h b/linux-headers/asm-loongarch/unistd_64.h -index 887ea50cca..23fb96a8a7 100644 ---- a/linux-headers/asm-loongarch/unistd_64.h -+++ b/linux-headers/asm-loongarch/unistd_64.h -@@ -315,6 +315,10 @@ - #define __NR_lsm_set_self_attr 460 - #define __NR_lsm_list_modules 461 - #define __NR_mseal 462 -+#define __NR_setxattrat 463 -+#define __NR_getxattrat 464 -+#define __NR_listxattrat 465 -+#define __NR_removexattrat 466 - - - #endif /* _ASM_UNISTD_64_H */ -diff --git a/linux-headers/asm-mips/mman.h b/linux-headers/asm-mips/mman.h -index 9c48d9a21a..b700dae28c 100644 ---- a/linux-headers/asm-mips/mman.h -+++ b/linux-headers/asm-mips/mman.h -@@ -105,6 +105,9 @@ - - #define MADV_COLLAPSE 25 /* Synchronous hugepage collapse */ - -+#define MADV_GUARD_INSTALL 102 /* fatal signal on access to range */ -+#define MADV_GUARD_REMOVE 103 /* unguard range */ -+ - /* compatibility flags */ - #define MAP_FILE 0 - -diff --git a/linux-headers/asm-mips/unistd_n32.h b/linux-headers/asm-mips/unistd_n32.h -index fc93b3be30..9a75719644 100644 ---- a/linux-headers/asm-mips/unistd_n32.h -+++ b/linux-headers/asm-mips/unistd_n32.h -@@ -391,5 +391,9 @@ - #define __NR_lsm_set_self_attr (__NR_Linux + 460) - #define __NR_lsm_list_modules (__NR_Linux + 461) - #define __NR_mseal (__NR_Linux + 462) -+#define __NR_setxattrat (__NR_Linux + 463) -+#define __NR_getxattrat (__NR_Linux + 464) -+#define __NR_listxattrat (__NR_Linux + 465) -+#define __NR_removexattrat (__NR_Linux + 466) - - #endif /* _ASM_UNISTD_N32_H */ -diff --git a/linux-headers/asm-mips/unistd_n64.h b/linux-headers/asm-mips/unistd_n64.h -index e72a3eb2c9..7086783b0c 100644 ---- a/linux-headers/asm-mips/unistd_n64.h -+++ b/linux-headers/asm-mips/unistd_n64.h -@@ -367,5 +367,9 @@ - #define __NR_lsm_set_self_attr (__NR_Linux + 460) - #define __NR_lsm_list_modules (__NR_Linux + 461) - #define __NR_mseal (__NR_Linux + 462) -+#define __NR_setxattrat (__NR_Linux + 463) -+#define __NR_getxattrat (__NR_Linux + 464) -+#define __NR_listxattrat (__NR_Linux + 465) -+#define __NR_removexattrat (__NR_Linux + 466) - - #endif /* _ASM_UNISTD_N64_H */ -diff --git a/linux-headers/asm-mips/unistd_o32.h b/linux-headers/asm-mips/unistd_o32.h -index b86eb0786c..b3825823e4 100644 ---- a/linux-headers/asm-mips/unistd_o32.h -+++ b/linux-headers/asm-mips/unistd_o32.h -@@ -437,5 +437,9 @@ - #define __NR_lsm_set_self_attr (__NR_Linux + 460) - #define __NR_lsm_list_modules (__NR_Linux + 461) - #define __NR_mseal (__NR_Linux + 462) -+#define __NR_setxattrat (__NR_Linux + 463) -+#define __NR_getxattrat (__NR_Linux + 464) -+#define __NR_listxattrat (__NR_Linux + 465) -+#define __NR_removexattrat (__NR_Linux + 466) - - #endif /* _ASM_UNISTD_O32_H */ -diff --git a/linux-headers/asm-powerpc/unistd_32.h b/linux-headers/asm-powerpc/unistd_32.h -index 28627b6546..38ee4dc35d 100644 ---- a/linux-headers/asm-powerpc/unistd_32.h -+++ b/linux-headers/asm-powerpc/unistd_32.h -@@ -444,6 +444,10 @@ - #define __NR_lsm_set_self_attr 460 - #define __NR_lsm_list_modules 461 - #define __NR_mseal 462 -+#define __NR_setxattrat 463 -+#define __NR_getxattrat 464 -+#define __NR_listxattrat 465 -+#define __NR_removexattrat 466 - - - #endif /* _ASM_UNISTD_32_H */ -diff --git a/linux-headers/asm-powerpc/unistd_64.h b/linux-headers/asm-powerpc/unistd_64.h -index 1fc42a8300..5e5f156834 100644 ---- a/linux-headers/asm-powerpc/unistd_64.h -+++ b/linux-headers/asm-powerpc/unistd_64.h -@@ -416,6 +416,10 @@ - #define __NR_lsm_set_self_attr 460 - #define __NR_lsm_list_modules 461 - #define __NR_mseal 462 -+#define __NR_setxattrat 463 -+#define __NR_getxattrat 464 -+#define __NR_listxattrat 465 -+#define __NR_removexattrat 466 - - - #endif /* _ASM_UNISTD_64_H */ -diff --git a/linux-headers/asm-riscv/kvm.h b/linux-headers/asm-riscv/kvm.h -index e97db32964..3482c9a73d 100644 ---- a/linux-headers/asm-riscv/kvm.h -+++ b/linux-headers/asm-riscv/kvm.h -@@ -175,6 +175,10 @@ enum KVM_RISCV_ISA_EXT_ID { - KVM_RISCV_ISA_EXT_ZCF, - KVM_RISCV_ISA_EXT_ZCMOP, - KVM_RISCV_ISA_EXT_ZAWRS, -+ KVM_RISCV_ISA_EXT_SMNPM, -+ KVM_RISCV_ISA_EXT_SSNPM, -+ KVM_RISCV_ISA_EXT_SVADE, -+ KVM_RISCV_ISA_EXT_SVADU, - KVM_RISCV_ISA_EXT_MAX, - }; - -diff --git a/linux-headers/asm-riscv/unistd_32.h b/linux-headers/asm-riscv/unistd_32.h -index 9625743dfd..74f6127aed 100644 ---- a/linux-headers/asm-riscv/unistd_32.h -+++ b/linux-headers/asm-riscv/unistd_32.h -@@ -310,6 +310,10 @@ - #define __NR_lsm_set_self_attr 460 - #define __NR_lsm_list_modules 461 - #define __NR_mseal 462 -+#define __NR_setxattrat 463 -+#define __NR_getxattrat 464 -+#define __NR_listxattrat 465 -+#define __NR_removexattrat 466 - - - #endif /* _ASM_UNISTD_32_H */ -diff --git a/linux-headers/asm-riscv/unistd_64.h b/linux-headers/asm-riscv/unistd_64.h -index 95bca8ae81..bb6a15a2ec 100644 ---- a/linux-headers/asm-riscv/unistd_64.h -+++ b/linux-headers/asm-riscv/unistd_64.h -@@ -320,6 +320,10 @@ - #define __NR_lsm_set_self_attr 460 - #define __NR_lsm_list_modules 461 - #define __NR_mseal 462 -+#define __NR_setxattrat 463 -+#define __NR_getxattrat 464 -+#define __NR_listxattrat 465 -+#define __NR_removexattrat 466 - - - #endif /* _ASM_UNISTD_64_H */ -diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h -index 684c4e1205..ab5a6bce59 100644 ---- a/linux-headers/asm-s390/kvm.h -+++ b/linux-headers/asm-s390/kvm.h -@@ -469,7 +469,8 @@ struct kvm_s390_vm_cpu_subfunc { - __u8 kdsa[16]; /* with MSA9 */ - __u8 sortl[32]; /* with STFLE.150 */ - __u8 dfltcc[32]; /* with STFLE.151 */ -- __u8 reserved[1728]; -+ __u8 pfcr[16]; /* with STFLE.201 */ -+ __u8 reserved[1712]; - }; - - #define KVM_S390_VM_CPU_PROCESSOR_UV_FEAT_GUEST 6 -diff --git a/linux-headers/asm-s390/unistd_32.h b/linux-headers/asm-s390/unistd_32.h -index 7706c21b87..620201cb36 100644 ---- a/linux-headers/asm-s390/unistd_32.h -+++ b/linux-headers/asm-s390/unistd_32.h -@@ -435,5 +435,9 @@ - #define __NR_lsm_set_self_attr 460 - #define __NR_lsm_list_modules 461 - #define __NR_mseal 462 -+#define __NR_setxattrat 463 -+#define __NR_getxattrat 464 -+#define __NR_listxattrat 465 -+#define __NR_removexattrat 466 - - #endif /* _ASM_S390_UNISTD_32_H */ -diff --git a/linux-headers/asm-s390/unistd_64.h b/linux-headers/asm-s390/unistd_64.h -index 62082d592d..e7e4a10aaf 100644 ---- a/linux-headers/asm-s390/unistd_64.h -+++ b/linux-headers/asm-s390/unistd_64.h -@@ -383,5 +383,9 @@ - #define __NR_lsm_set_self_attr 460 - #define __NR_lsm_list_modules 461 - #define __NR_mseal 462 -+#define __NR_setxattrat 463 -+#define __NR_getxattrat 464 -+#define __NR_listxattrat 465 -+#define __NR_removexattrat 466 - - #endif /* _ASM_S390_UNISTD_64_H */ -diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h -index 4711ef2c3d..96589490c4 100644 ---- a/linux-headers/asm-x86/kvm.h -+++ b/linux-headers/asm-x86/kvm.h -@@ -438,6 +438,7 @@ struct kvm_sync_regs { - #define KVM_X86_QUIRK_FIX_HYPERCALL_INSN (1 << 5) - #define KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS (1 << 6) - #define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7) -+#define KVM_X86_QUIRK_STUFF_FEATURE_MSRS (1 << 8) - - #define KVM_STATE_NESTED_FORMAT_VMX 0 - #define KVM_STATE_NESTED_FORMAT_SVM 1 -diff --git a/linux-headers/asm-x86/mman.h b/linux-headers/asm-x86/mman.h -index 46cdc941f9..ac1e627721 100644 ---- a/linux-headers/asm-x86/mman.h -+++ b/linux-headers/asm-x86/mman.h -@@ -5,9 +5,6 @@ - #define MAP_32BIT 0x40 /* only give out 32bit addresses */ - #define MAP_ABOVE4G 0x80 /* only map above 4GB */ - --/* Flags for map_shadow_stack(2) */ --#define SHADOW_STACK_SET_TOKEN (1ULL << 0) /* Set up a restore token in the shadow stack */ -- - #include - - #endif /* _ASM_X86_MMAN_H */ -diff --git a/linux-headers/asm-x86/unistd_32.h b/linux-headers/asm-x86/unistd_32.h -index fb7b8b169b..a2eb492a75 100644 ---- a/linux-headers/asm-x86/unistd_32.h -+++ b/linux-headers/asm-x86/unistd_32.h -@@ -453,6 +453,10 @@ - #define __NR_lsm_set_self_attr 460 - #define __NR_lsm_list_modules 461 - #define __NR_mseal 462 -+#define __NR_setxattrat 463 -+#define __NR_getxattrat 464 -+#define __NR_listxattrat 465 -+#define __NR_removexattrat 466 - - - #endif /* _ASM_UNISTD_32_H */ -diff --git a/linux-headers/asm-x86/unistd_64.h b/linux-headers/asm-x86/unistd_64.h -index 24c979be54..2f5fc400f5 100644 ---- a/linux-headers/asm-x86/unistd_64.h -+++ b/linux-headers/asm-x86/unistd_64.h -@@ -376,6 +376,10 @@ - #define __NR_lsm_set_self_attr 460 - #define __NR_lsm_list_modules 461 - #define __NR_mseal 462 -+#define __NR_setxattrat 463 -+#define __NR_getxattrat 464 -+#define __NR_listxattrat 465 -+#define __NR_removexattrat 466 - - - #endif /* _ASM_UNISTD_64_H */ -diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h -index c23dd21a2d..fecd832e7f 100644 ---- a/linux-headers/asm-x86/unistd_x32.h -+++ b/linux-headers/asm-x86/unistd_x32.h -@@ -329,6 +329,10 @@ - #define __NR_lsm_set_self_attr (__X32_SYSCALL_BIT + 460) - #define __NR_lsm_list_modules (__X32_SYSCALL_BIT + 461) - #define __NR_mseal (__X32_SYSCALL_BIT + 462) -+#define __NR_setxattrat (__X32_SYSCALL_BIT + 463) -+#define __NR_getxattrat (__X32_SYSCALL_BIT + 464) -+#define __NR_listxattrat (__X32_SYSCALL_BIT + 465) -+#define __NR_removexattrat (__X32_SYSCALL_BIT + 466) - #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512) - #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513) - #define __NR_ioctl (__X32_SYSCALL_BIT + 514) -diff --git a/linux-headers/linux/iommufd.h b/linux-headers/linux/iommufd.h -index 782baf477f..37aae16502 100644 ---- a/linux-headers/linux/iommufd.h -+++ b/linux-headers/linux/iommufd.h -@@ -51,6 +51,10 @@ enum { - IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP = 0x8c, - IOMMUFD_CMD_HWPT_INVALIDATE = 0x8d, - IOMMUFD_CMD_FAULT_QUEUE_ALLOC = 0x8e, -+ IOMMUFD_CMD_IOAS_MAP_FILE = 0x8f, -+ IOMMUFD_CMD_VIOMMU_ALLOC = 0x90, -+ IOMMUFD_CMD_VDEVICE_ALLOC = 0x91, -+ IOMMUFD_CMD_IOAS_CHANGE_PROCESS = 0x92, - }; - - /** -@@ -213,6 +217,30 @@ struct iommu_ioas_map { - }; - #define IOMMU_IOAS_MAP _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_MAP) - -+/** -+ * struct iommu_ioas_map_file - ioctl(IOMMU_IOAS_MAP_FILE) -+ * @size: sizeof(struct iommu_ioas_map_file) -+ * @flags: same as for iommu_ioas_map -+ * @ioas_id: same as for iommu_ioas_map -+ * @fd: the memfd to map -+ * @start: byte offset from start of file to map from -+ * @length: same as for iommu_ioas_map -+ * @iova: same as for iommu_ioas_map -+ * -+ * Set an IOVA mapping from a memfd file. All other arguments and semantics -+ * match those of IOMMU_IOAS_MAP. -+ */ -+struct iommu_ioas_map_file { -+ __u32 size; -+ __u32 flags; -+ __u32 ioas_id; -+ __s32 fd; -+ __aligned_u64 start; -+ __aligned_u64 length; -+ __aligned_u64 iova; -+}; -+#define IOMMU_IOAS_MAP_FILE _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_MAP_FILE) -+ - /** - * struct iommu_ioas_copy - ioctl(IOMMU_IOAS_COPY) - * @size: sizeof(struct iommu_ioas_copy) -@@ -359,11 +387,19 @@ struct iommu_vfio_ioas { - * enforced on device attachment - * @IOMMU_HWPT_FAULT_ID_VALID: The fault_id field of hwpt allocation data is - * valid. -+ * @IOMMU_HWPT_ALLOC_PASID: Requests a domain that can be used with PASID. The -+ * domain can be attached to any PASID on the device. -+ * Any domain attached to the non-PASID part of the -+ * device must also be flaged, otherwise attaching a -+ * PASID will blocked. -+ * If IOMMU does not support PASID it will return -+ * error (-EOPNOTSUPP). - */ - enum iommufd_hwpt_alloc_flags { - IOMMU_HWPT_ALLOC_NEST_PARENT = 1 << 0, - IOMMU_HWPT_ALLOC_DIRTY_TRACKING = 1 << 1, - IOMMU_HWPT_FAULT_ID_VALID = 1 << 2, -+ IOMMU_HWPT_ALLOC_PASID = 1 << 3, - }; - - /** -@@ -394,14 +430,36 @@ struct iommu_hwpt_vtd_s1 { - __u32 __reserved; - }; - -+/** -+ * struct iommu_hwpt_arm_smmuv3 - ARM SMMUv3 nested STE -+ * (IOMMU_HWPT_DATA_ARM_SMMUV3) -+ * -+ * @ste: The first two double words of the user space Stream Table Entry for -+ * the translation. Must be little-endian. -+ * Allowed fields: (Refer to "5.2 Stream Table Entry" in SMMUv3 HW Spec) -+ * - word-0: V, Cfg, S1Fmt, S1ContextPtr, S1CDMax -+ * - word-1: EATS, S1DSS, S1CIR, S1COR, S1CSH, S1STALLD -+ * -+ * -EIO will be returned if @ste is not legal or contains any non-allowed field. -+ * Cfg can be used to select a S1, Bypass or Abort configuration. A Bypass -+ * nested domain will translate the same as the nesting parent. The S1 will -+ * install a Context Descriptor Table pointing at userspace memory translated -+ * by the nesting parent. -+ */ -+struct iommu_hwpt_arm_smmuv3 { -+ __aligned_le64 ste[2]; -+}; -+ - /** - * enum iommu_hwpt_data_type - IOMMU HWPT Data Type - * @IOMMU_HWPT_DATA_NONE: no data - * @IOMMU_HWPT_DATA_VTD_S1: Intel VT-d stage-1 page table -+ * @IOMMU_HWPT_DATA_ARM_SMMUV3: ARM SMMUv3 Context Descriptor Table - */ - enum iommu_hwpt_data_type { - IOMMU_HWPT_DATA_NONE = 0, - IOMMU_HWPT_DATA_VTD_S1 = 1, -+ IOMMU_HWPT_DATA_ARM_SMMUV3 = 2, - }; - - /** -@@ -409,7 +467,7 @@ enum iommu_hwpt_data_type { - * @size: sizeof(struct iommu_hwpt_alloc) - * @flags: Combination of enum iommufd_hwpt_alloc_flags - * @dev_id: The device to allocate this HWPT for -- * @pt_id: The IOAS or HWPT to connect this HWPT to -+ * @pt_id: The IOAS or HWPT or vIOMMU to connect this HWPT to - * @out_hwpt_id: The ID of the new HWPT - * @__reserved: Must be 0 - * @data_type: One of enum iommu_hwpt_data_type -@@ -428,11 +486,13 @@ enum iommu_hwpt_data_type { - * IOMMU_HWPT_DATA_NONE. The HWPT can be allocated as a parent HWPT for a - * nesting configuration by passing IOMMU_HWPT_ALLOC_NEST_PARENT via @flags. - * -- * A user-managed nested HWPT will be created from a given parent HWPT via -- * @pt_id, in which the parent HWPT must be allocated previously via the -- * same ioctl from a given IOAS (@pt_id). In this case, the @data_type -- * must be set to a pre-defined type corresponding to an I/O page table -- * type supported by the underlying IOMMU hardware. -+ * A user-managed nested HWPT will be created from a given vIOMMU (wrapping a -+ * parent HWPT) or a parent HWPT via @pt_id, in which the parent HWPT must be -+ * allocated previously via the same ioctl from a given IOAS (@pt_id). In this -+ * case, the @data_type must be set to a pre-defined type corresponding to an -+ * I/O page table type supported by the underlying IOMMU hardware. The device -+ * via @dev_id and the vIOMMU via @pt_id must be associated to the same IOMMU -+ * instance. - * - * If the @data_type is set to IOMMU_HWPT_DATA_NONE, @data_len and - * @data_uptr should be zero. Otherwise, both @data_len and @data_uptr -@@ -484,15 +544,50 @@ struct iommu_hw_info_vtd { - __aligned_u64 ecap_reg; - }; - -+/** -+ * struct iommu_hw_info_arm_smmuv3 - ARM SMMUv3 hardware information -+ * (IOMMU_HW_INFO_TYPE_ARM_SMMUV3) -+ * -+ * @flags: Must be set to 0 -+ * @__reserved: Must be 0 -+ * @idr: Implemented features for ARM SMMU Non-secure programming interface -+ * @iidr: Information about the implementation and implementer of ARM SMMU, -+ * and architecture version supported -+ * @aidr: ARM SMMU architecture version -+ * -+ * For the details of @idr, @iidr and @aidr, please refer to the chapters -+ * from 6.3.1 to 6.3.6 in the SMMUv3 Spec. -+ * -+ * User space should read the underlying ARM SMMUv3 hardware information for -+ * the list of supported features. -+ * -+ * Note that these values reflect the raw HW capability, without any insight if -+ * any required kernel driver support is present. Bits may be set indicating the -+ * HW has functionality that is lacking kernel software support, such as BTM. If -+ * a VMM is using this information to construct emulated copies of these -+ * registers it should only forward bits that it knows it can support. -+ * -+ * In future, presence of required kernel support will be indicated in flags. -+ */ -+struct iommu_hw_info_arm_smmuv3 { -+ __u32 flags; -+ __u32 __reserved; -+ __u32 idr[6]; -+ __u32 iidr; -+ __u32 aidr; -+}; -+ - /** - * enum iommu_hw_info_type - IOMMU Hardware Info Types - * @IOMMU_HW_INFO_TYPE_NONE: Used by the drivers that do not report hardware - * info - * @IOMMU_HW_INFO_TYPE_INTEL_VTD: Intel VT-d iommu info type -+ * @IOMMU_HW_INFO_TYPE_ARM_SMMUV3: ARM SMMUv3 iommu info type - */ - enum iommu_hw_info_type { - IOMMU_HW_INFO_TYPE_NONE = 0, - IOMMU_HW_INFO_TYPE_INTEL_VTD = 1, -+ IOMMU_HW_INFO_TYPE_ARM_SMMUV3 = 2, - }; - - /** -@@ -627,9 +722,11 @@ struct iommu_hwpt_get_dirty_bitmap { - * enum iommu_hwpt_invalidate_data_type - IOMMU HWPT Cache Invalidation - * Data Type - * @IOMMU_HWPT_INVALIDATE_DATA_VTD_S1: Invalidation data for VTD_S1 -+ * @IOMMU_VIOMMU_INVALIDATE_DATA_ARM_SMMUV3: Invalidation data for ARM SMMUv3 - */ - enum iommu_hwpt_invalidate_data_type { - IOMMU_HWPT_INVALIDATE_DATA_VTD_S1 = 0, -+ IOMMU_VIOMMU_INVALIDATE_DATA_ARM_SMMUV3 = 1, - }; - - /** -@@ -668,10 +765,32 @@ struct iommu_hwpt_vtd_s1_invalidate { - __u32 __reserved; - }; - -+/** -+ * struct iommu_viommu_arm_smmuv3_invalidate - ARM SMMUv3 cahce invalidation -+ * (IOMMU_VIOMMU_INVALIDATE_DATA_ARM_SMMUV3) -+ * @cmd: 128-bit cache invalidation command that runs in SMMU CMDQ. -+ * Must be little-endian. -+ * -+ * Supported command list only when passing in a vIOMMU via @hwpt_id: -+ * CMDQ_OP_TLBI_NSNH_ALL -+ * CMDQ_OP_TLBI_NH_VA -+ * CMDQ_OP_TLBI_NH_VAA -+ * CMDQ_OP_TLBI_NH_ALL -+ * CMDQ_OP_TLBI_NH_ASID -+ * CMDQ_OP_ATC_INV -+ * CMDQ_OP_CFGI_CD -+ * CMDQ_OP_CFGI_CD_ALL -+ * -+ * -EIO will be returned if the command is not supported. -+ */ -+struct iommu_viommu_arm_smmuv3_invalidate { -+ __aligned_le64 cmd[2]; -+}; -+ - /** - * struct iommu_hwpt_invalidate - ioctl(IOMMU_HWPT_INVALIDATE) - * @size: sizeof(struct iommu_hwpt_invalidate) -- * @hwpt_id: ID of a nested HWPT for cache invalidation -+ * @hwpt_id: ID of a nested HWPT or a vIOMMU, for cache invalidation - * @data_uptr: User pointer to an array of driver-specific cache invalidation - * data. - * @data_type: One of enum iommu_hwpt_invalidate_data_type, defining the data -@@ -682,8 +801,11 @@ struct iommu_hwpt_vtd_s1_invalidate { - * Output the number of requests successfully handled by kernel. - * @__reserved: Must be 0. - * -- * Invalidate the iommu cache for user-managed page table. Modifications on a -- * user-managed page table should be followed by this operation to sync cache. -+ * Invalidate iommu cache for user-managed page table or vIOMMU. Modifications -+ * on a user-managed page table should be followed by this operation, if a HWPT -+ * is passed in via @hwpt_id. Other caches, such as device cache or descriptor -+ * cache can be flushed if a vIOMMU is passed in via the @hwpt_id field. -+ * - * Each ioctl can support one or more cache invalidation requests in the array - * that has a total size of @entry_len * @entry_num. - * -@@ -797,4 +919,88 @@ struct iommu_fault_alloc { - __u32 out_fault_fd; - }; - #define IOMMU_FAULT_QUEUE_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_FAULT_QUEUE_ALLOC) -+ -+/** -+ * enum iommu_viommu_type - Virtual IOMMU Type -+ * @IOMMU_VIOMMU_TYPE_DEFAULT: Reserved for future use -+ * @IOMMU_VIOMMU_TYPE_ARM_SMMUV3: ARM SMMUv3 driver specific type -+ */ -+enum iommu_viommu_type { -+ IOMMU_VIOMMU_TYPE_DEFAULT = 0, -+ IOMMU_VIOMMU_TYPE_ARM_SMMUV3 = 1, -+}; -+ -+/** -+ * struct iommu_viommu_alloc - ioctl(IOMMU_VIOMMU_ALLOC) -+ * @size: sizeof(struct iommu_viommu_alloc) -+ * @flags: Must be 0 -+ * @type: Type of the virtual IOMMU. Must be defined in enum iommu_viommu_type -+ * @dev_id: The device's physical IOMMU will be used to back the virtual IOMMU -+ * @hwpt_id: ID of a nesting parent HWPT to associate to -+ * @out_viommu_id: Output virtual IOMMU ID for the allocated object -+ * -+ * Allocate a virtual IOMMU object, representing the underlying physical IOMMU's -+ * virtualization support that is a security-isolated slice of the real IOMMU HW -+ * that is unique to a specific VM. Operations global to the IOMMU are connected -+ * to the vIOMMU, such as: -+ * - Security namespace for guest owned ID, e.g. guest-controlled cache tags -+ * - Non-device-affiliated event reporting, e.g. invalidation queue errors -+ * - Access to a sharable nesting parent pagetable across physical IOMMUs -+ * - Virtualization of various platforms IDs, e.g. RIDs and others -+ * - Delivery of paravirtualized invalidation -+ * - Direct assigned invalidation queues -+ * - Direct assigned interrupts -+ */ -+struct iommu_viommu_alloc { -+ __u32 size; -+ __u32 flags; -+ __u32 type; -+ __u32 dev_id; -+ __u32 hwpt_id; -+ __u32 out_viommu_id; -+}; -+#define IOMMU_VIOMMU_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VIOMMU_ALLOC) -+ -+/** -+ * struct iommu_vdevice_alloc - ioctl(IOMMU_VDEVICE_ALLOC) -+ * @size: sizeof(struct iommu_vdevice_alloc) -+ * @viommu_id: vIOMMU ID to associate with the virtual device -+ * @dev_id: The physical device to allocate a virtual instance on the vIOMMU -+ * @out_vdevice_id: Object handle for the vDevice. Pass to IOMMU_DESTORY -+ * @virt_id: Virtual device ID per vIOMMU, e.g. vSID of ARM SMMUv3, vDeviceID -+ * of AMD IOMMU, and vRID of a nested Intel VT-d to a Context Table -+ * -+ * Allocate a virtual device instance (for a physical device) against a vIOMMU. -+ * This instance holds the device's information (related to its vIOMMU) in a VM. -+ */ -+struct iommu_vdevice_alloc { -+ __u32 size; -+ __u32 viommu_id; -+ __u32 dev_id; -+ __u32 out_vdevice_id; -+ __aligned_u64 virt_id; -+}; -+#define IOMMU_VDEVICE_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VDEVICE_ALLOC) -+ -+/** -+ * struct iommu_ioas_change_process - ioctl(VFIO_IOAS_CHANGE_PROCESS) -+ * @size: sizeof(struct iommu_ioas_change_process) -+ * @__reserved: Must be 0 -+ * -+ * This transfers pinned memory counts for every memory map in every IOAS -+ * in the context to the current process. This only supports maps created -+ * with IOMMU_IOAS_MAP_FILE, and returns EINVAL if other maps are present. -+ * If the ioctl returns a failure status, then nothing is changed. -+ * -+ * This API is useful for transferring operation of a device from one process -+ * to another, such as during userland live update. -+ */ -+struct iommu_ioas_change_process { -+ __u32 size; -+ __u32 __reserved; -+}; -+ -+#define IOMMU_IOAS_CHANGE_PROCESS \ -+ _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_CHANGE_PROCESS) -+ - #endif -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 49dd1b30ce..3bcd4eabe3 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1150,7 +1150,15 @@ enum kvm_device_type { - #define KVM_DEV_TYPE_ARM_PV_TIME KVM_DEV_TYPE_ARM_PV_TIME - KVM_DEV_TYPE_RISCV_AIA, - #define KVM_DEV_TYPE_RISCV_AIA KVM_DEV_TYPE_RISCV_AIA -+ KVM_DEV_TYPE_LOONGARCH_IPI, -+#define KVM_DEV_TYPE_LOONGARCH_IPI KVM_DEV_TYPE_LOONGARCH_IPI -+ KVM_DEV_TYPE_LOONGARCH_EIOINTC, -+#define KVM_DEV_TYPE_LOONGARCH_EIOINTC KVM_DEV_TYPE_LOONGARCH_EIOINTC -+ KVM_DEV_TYPE_LOONGARCH_PCHPIC, -+#define KVM_DEV_TYPE_LOONGARCH_PCHPIC KVM_DEV_TYPE_LOONGARCH_PCHPIC -+ - KVM_DEV_TYPE_MAX, -+ - }; - - struct kvm_vfio_spapr_tce { -diff --git a/linux-headers/linux/psci.h b/linux-headers/linux/psci.h -index 74f3cb5007..a982afd498 100644 ---- a/linux-headers/linux/psci.h -+++ b/linux-headers/linux/psci.h -@@ -59,6 +59,7 @@ - #define PSCI_1_1_FN_SYSTEM_RESET2 PSCI_0_2_FN(18) - #define PSCI_1_1_FN_MEM_PROTECT PSCI_0_2_FN(19) - #define PSCI_1_1_FN_MEM_PROTECT_CHECK_RANGE PSCI_0_2_FN(20) -+#define PSCI_1_3_FN_SYSTEM_OFF2 PSCI_0_2_FN(21) - - #define PSCI_1_0_FN64_CPU_DEFAULT_SUSPEND PSCI_0_2_FN64(12) - #define PSCI_1_0_FN64_NODE_HW_STATE PSCI_0_2_FN64(13) -@@ -68,6 +69,7 @@ - - #define PSCI_1_1_FN64_SYSTEM_RESET2 PSCI_0_2_FN64(18) - #define PSCI_1_1_FN64_MEM_PROTECT_CHECK_RANGE PSCI_0_2_FN64(20) -+#define PSCI_1_3_FN64_SYSTEM_OFF2 PSCI_0_2_FN64(21) - - /* PSCI v0.2 power state encoding for CPU_SUSPEND function */ - #define PSCI_0_2_POWER_STATE_ID_MASK 0xffff -@@ -100,6 +102,9 @@ - #define PSCI_1_1_RESET_TYPE_SYSTEM_WARM_RESET 0 - #define PSCI_1_1_RESET_TYPE_VENDOR_START 0x80000000U - -+/* PSCI v1.3 hibernate type for SYSTEM_OFF2 */ -+#define PSCI_1_3_OFF_TYPE_HIBERNATE_OFF BIT(0) -+ - /* PSCI version decoding (independent of PSCI version) */ - #define PSCI_VERSION_MAJOR_SHIFT 16 - #define PSCI_VERSION_MINOR_MASK \ -diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h -index b4be37b225..1b5e254d6a 100644 ---- a/linux-headers/linux/vfio.h -+++ b/linux-headers/linux/vfio.h -@@ -35,7 +35,7 @@ - #define VFIO_EEH 5 - - /* Two-stage IOMMU */ --#define VFIO_TYPE1_NESTING_IOMMU 6 /* Implies v2 */ -+#define __VFIO_RESERVED_TYPE1_NESTING_IOMMU 6 /* Implies v2 */ - - #define VFIO_SPAPR_TCE_v2_IOMMU 7 - --- -2.39.3 - diff --git a/kvm-linux-headers-Update-to-Linux-v6.12-rc5.patch b/kvm-linux-headers-Update-to-Linux-v6.12-rc5.patch deleted file mode 100644 index b548ab3..0000000 --- a/kvm-linux-headers-Update-to-Linux-v6.12-rc5.patch +++ /dev/null @@ -1,2559 +0,0 @@ -From d49c6a77649755fac29dce957795338942f58ac4 Mon Sep 17 00:00:00 2001 -From: Bibo Mao -Date: Mon, 28 Oct 2024 10:38:09 +0800 -Subject: [PATCH 01/18] linux-headers: Update to Linux v6.12-rc5 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [1/16] b28ecec9551a4850d48d48522088ef4eef6f30ad (thuth/qemu-kvm-cs9) - -update linux-headers to v6.12-rc5. Pass to compile on aarch64, arm, -loongarch64, x86_64, i386, riscv64,riscv32 softmmu and linux-user. - -Signed-off-by: Bibo Mao -Acked-by: Song Gao -Message-Id: <20241028023809.1554405-4-maobibo@loongson.cn> -Signed-off-by: Song Gao -(cherry picked from commit 0d2eeef77a33315187df8519491a900bde4a3d83) -Signed-off-by: Thomas Huth ---- - include/standard-headers/drm/drm_fourcc.h | 43 +++ - include/standard-headers/linux/const.h | 17 + - include/standard-headers/linux/ethtool.h | 226 ++++++++++++ - include/standard-headers/linux/fuse.h | 22 +- - .../linux/input-event-codes.h | 2 + - include/standard-headers/linux/pci_regs.h | 41 ++- - .../standard-headers/linux/virtio_balloon.h | 16 +- - include/standard-headers/linux/virtio_gpu.h | 1 + - linux-headers/asm-arm64/mman.h | 9 + - linux-headers/asm-arm64/unistd.h | 25 +- - linux-headers/asm-arm64/unistd_64.h | 324 +++++++++++++++++ - linux-headers/asm-generic/unistd.h | 6 +- - linux-headers/asm-loongarch/kvm.h | 24 ++ - linux-headers/asm-loongarch/kvm_para.h | 21 ++ - linux-headers/asm-loongarch/unistd.h | 4 +- - linux-headers/asm-loongarch/unistd_64.h | 320 +++++++++++++++++ - linux-headers/asm-riscv/kvm.h | 7 + - linux-headers/asm-riscv/unistd.h | 41 +-- - linux-headers/asm-riscv/unistd_32.h | 315 +++++++++++++++++ - linux-headers/asm-riscv/unistd_64.h | 325 ++++++++++++++++++ - linux-headers/asm-x86/kvm.h | 2 + - linux-headers/asm-x86/unistd_64.h | 1 + - linux-headers/asm-x86/unistd_x32.h | 1 + - linux-headers/linux/bits.h | 3 + - linux-headers/linux/const.h | 17 + - linux-headers/linux/iommufd.h | 143 +++++++- - linux-headers/linux/kvm.h | 23 +- - linux-headers/linux/mman.h | 1 + - linux-headers/linux/psp-sev.h | 28 ++ - 29 files changed, 1915 insertions(+), 93 deletions(-) - create mode 100644 linux-headers/asm-arm64/unistd_64.h - create mode 100644 linux-headers/asm-loongarch/kvm_para.h - create mode 100644 linux-headers/asm-loongarch/unistd_64.h - create mode 100644 linux-headers/asm-riscv/unistd_32.h - create mode 100644 linux-headers/asm-riscv/unistd_64.h - -diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h -index b72917073d..d4a2231306 100644 ---- a/include/standard-headers/drm/drm_fourcc.h -+++ b/include/standard-headers/drm/drm_fourcc.h -@@ -701,6 +701,31 @@ extern "C" { - */ - #define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC fourcc_mod_code(INTEL, 15) - -+/* -+ * Intel Color Control Surfaces (CCS) for graphics ver. 20 unified compression -+ * on integrated graphics -+ * -+ * The main surface is Tile 4 and at plane index 0. For semi-planar formats -+ * like NV12, the Y and UV planes are Tile 4 and are located at plane indices -+ * 0 and 1, respectively. The CCS for all planes are stored outside of the -+ * GEM object in a reserved memory area dedicated for the storage of the -+ * CCS data for all compressible GEM objects. -+ */ -+#define I915_FORMAT_MOD_4_TILED_LNL_CCS fourcc_mod_code(INTEL, 16) -+ -+/* -+ * Intel Color Control Surfaces (CCS) for graphics ver. 20 unified compression -+ * on discrete graphics -+ * -+ * The main surface is Tile 4 and at plane index 0. For semi-planar formats -+ * like NV12, the Y and UV planes are Tile 4 and are located at plane indices -+ * 0 and 1, respectively. The CCS for all planes are stored outside of the -+ * GEM object in a reserved memory area dedicated for the storage of the -+ * CCS data for all compressible GEM objects. The GEM object must be stored in -+ * contiguous memory with a size aligned to 64KB -+ */ -+#define I915_FORMAT_MOD_4_TILED_BMG_CCS fourcc_mod_code(INTEL, 17) -+ - /* - * Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks - * -@@ -1475,6 +1500,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) - #define AMD_FMT_MOD_TILE_VER_GFX10 2 - #define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3 - #define AMD_FMT_MOD_TILE_VER_GFX11 4 -+#define AMD_FMT_MOD_TILE_VER_GFX12 5 - - /* - * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical -@@ -1485,6 +1511,8 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) - /* - * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has - * GFX9 as canonical version. -+ * -+ * 64K_D_2D on GFX12 is identical to 64K_D on GFX11. - */ - #define AMD_FMT_MOD_TILE_GFX9_64K_D 10 - #define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25 -@@ -1492,6 +1520,21 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) - #define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27 - #define AMD_FMT_MOD_TILE_GFX11_256K_R_X 31 - -+/* Gfx12 swizzle modes: -+ * 0 - LINEAR -+ * 1 - 256B_2D - 2D block dimensions -+ * 2 - 4KB_2D -+ * 3 - 64KB_2D -+ * 4 - 256KB_2D -+ * 5 - 4KB_3D - 3D block dimensions -+ * 6 - 64KB_3D -+ * 7 - 256KB_3D -+ */ -+#define AMD_FMT_MOD_TILE_GFX12_256B_2D 1 -+#define AMD_FMT_MOD_TILE_GFX12_4K_2D 2 -+#define AMD_FMT_MOD_TILE_GFX12_64K_2D 3 -+#define AMD_FMT_MOD_TILE_GFX12_256K_2D 4 -+ - #define AMD_FMT_MOD_DCC_BLOCK_64B 0 - #define AMD_FMT_MOD_DCC_BLOCK_128B 1 - #define AMD_FMT_MOD_DCC_BLOCK_256B 2 -diff --git a/include/standard-headers/linux/const.h b/include/standard-headers/linux/const.h -index 1eb84b5087..2122610de7 100644 ---- a/include/standard-headers/linux/const.h -+++ b/include/standard-headers/linux/const.h -@@ -28,6 +28,23 @@ - #define _BITUL(x) (_UL(1) << (x)) - #define _BITULL(x) (_ULL(1) << (x)) - -+#if !defined(__ASSEMBLY__) -+/* -+ * Missing __asm__ support -+ * -+ * __BIT128() would not work in the __asm__ code, as it shifts an -+ * 'unsigned __init128' data type as direct representation of -+ * 128 bit constants is not supported in the gcc compiler, as -+ * they get silently truncated. -+ * -+ * TODO: Please revisit this implementation when gcc compiler -+ * starts representing 128 bit constants directly like long -+ * and unsigned long etc. Subsequently drop the comment for -+ * GENMASK_U128() which would then start supporting __asm__ code. -+ */ -+#define _BIT128(x) ((unsigned __int128)(1) << (x)) -+#endif -+ - #define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (__typeof__(x))(a) - 1) - #define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) - -diff --git a/include/standard-headers/linux/ethtool.h b/include/standard-headers/linux/ethtool.h -index b0b4b68410..b05e84825b 100644 ---- a/include/standard-headers/linux/ethtool.h -+++ b/include/standard-headers/linux/ethtool.h -@@ -752,6 +752,197 @@ enum ethtool_module_power_mode { - ETHTOOL_MODULE_POWER_MODE_HIGH, - }; - -+/** -+ * enum ethtool_c33_pse_ext_state - groups of PSE extended states -+ * functions. IEEE 802.3-2022 33.2.4.4 Variables -+ * -+ * @ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION: Group of error_condition states -+ * @ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID: Group of mr_mps_valid states -+ * @ETHTOOL_C33_PSE_EXT_STATE_MR_PSE_ENABLE: Group of mr_pse_enable states -+ * @ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED: Group of option_detect_ted -+ * states -+ * @ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM: Group of option_vport_lim states -+ * @ETHTOOL_C33_PSE_EXT_STATE_OVLD_DETECTED: Group of ovld_detected states -+ * @ETHTOOL_C33_PSE_EXT_STATE_PD_DLL_POWER_TYPE: Group of pd_dll_power_type -+ * states -+ * @ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE: Group of power_not_available -+ * states -+ * @ETHTOOL_C33_PSE_EXT_STATE_SHORT_DETECTED: Group of short_detected states -+ */ -+enum ethtool_c33_pse_ext_state { -+ ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION = 1, -+ ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID, -+ ETHTOOL_C33_PSE_EXT_STATE_MR_PSE_ENABLE, -+ ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED, -+ ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM, -+ ETHTOOL_C33_PSE_EXT_STATE_OVLD_DETECTED, -+ ETHTOOL_C33_PSE_EXT_STATE_PD_DLL_POWER_TYPE, -+ ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE, -+ ETHTOOL_C33_PSE_EXT_STATE_SHORT_DETECTED, -+}; -+ -+/** -+ * enum ethtool_c33_pse_ext_substate_mr_mps_valid - mr_mps_valid states -+ * functions. IEEE 802.3-2022 33.2.4.4 Variables -+ * -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_DETECTED_UNDERLOAD: Underload -+ * state -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_CONNECTION_OPEN: Port is not -+ * connected -+ * -+ * The PSE monitors either the DC or AC Maintain Power Signature -+ * (MPS, see 33.2.9.1). This variable indicates the presence or absence of -+ * a valid MPS. -+ */ -+enum ethtool_c33_pse_ext_substate_mr_mps_valid { -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_DETECTED_UNDERLOAD = 1, -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_CONNECTION_OPEN, -+}; -+ -+/** -+ * enum ethtool_c33_pse_ext_substate_error_condition - error_condition states -+ * functions. IEEE 802.3-2022 33.2.4.4 Variables -+ * -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_NON_EXISTING_PORT: Non-existing -+ * port number -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNDEFINED_PORT: Undefined port -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT: Internal -+ * hardware fault -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_COMM_ERROR_AFTER_FORCE_ON: -+ * Communication error after force on -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS: Unknown -+ * port status -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_TURN_OFF: Host -+ * crash turn off -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_FORCE_SHUTDOWN: -+ * Host crash force shutdown -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_CONFIG_CHANGE: Configuration -+ * change -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP: Over -+ * temperature detected -+ * -+ * error_condition is a variable indicating the status of -+ * implementation-specific fault conditions or optionally other system faults -+ * that prevent the PSE from meeting the specifications in Table 33–11 and that -+ * require the PSE not to source power. These error conditions are different -+ * from those monitored by the state diagrams in Figure 33–10. -+ */ -+enum ethtool_c33_pse_ext_substate_error_condition { -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_NON_EXISTING_PORT = 1, -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNDEFINED_PORT, -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT, -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_COMM_ERROR_AFTER_FORCE_ON, -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS, -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_TURN_OFF, -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_FORCE_SHUTDOWN, -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_CONFIG_CHANGE, -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP, -+}; -+ -+/** -+ * enum ethtool_c33_pse_ext_substate_mr_pse_enable - mr_pse_enable states -+ * functions. IEEE 802.3-2022 33.2.4.4 Variables -+ * -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PIN_ACTIVE: Disable -+ * pin active -+ * -+ * mr_pse_enable is control variable that selects PSE operation and test -+ * functions. -+ */ -+enum ethtool_c33_pse_ext_substate_mr_pse_enable { -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PIN_ACTIVE = 1, -+}; -+ -+/** -+ * enum ethtool_c33_pse_ext_substate_option_detect_ted - option_detect_ted -+ * states functions. IEEE 802.3-2022 33.2.4.4 Variables -+ * -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_DET_IN_PROCESS: Detection -+ * in process -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_CONNECTION_CHECK_ERROR: -+ * Connection check error -+ * -+ * option_detect_ted is a variable indicating if detection can be performed -+ * by the PSE during the ted_timer interval. -+ */ -+enum ethtool_c33_pse_ext_substate_option_detect_ted { -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_DET_IN_PROCESS = 1, -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_CONNECTION_CHECK_ERROR, -+}; -+ -+/** -+ * enum ethtool_c33_pse_ext_substate_option_vport_lim - option_vport_lim states -+ * functions. IEEE 802.3-2022 33.2.4.4 Variables -+ * -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE: Main supply -+ * voltage is high -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE: Main supply -+ * voltage is low -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_VOLTAGE_INJECTION: Voltage -+ * injection into the port -+ * -+ * option_vport_lim is an optional variable indicates if VPSE is out of the -+ * operating range during normal operating state. -+ */ -+enum ethtool_c33_pse_ext_substate_option_vport_lim { -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE = 1, -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE, -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_VOLTAGE_INJECTION, -+}; -+ -+/** -+ * enum ethtool_c33_pse_ext_substate_ovld_detected - ovld_detected states -+ * functions. IEEE 802.3-2022 33.2.4.4 Variables -+ * -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD: Overload state -+ * -+ * ovld_detected is a variable indicating if the PSE output current has been -+ * in an overload condition (see 33.2.7.6) for at least TCUT of a one-second -+ * sliding time. -+ */ -+enum ethtool_c33_pse_ext_substate_ovld_detected { -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD = 1, -+}; -+ -+/** -+ * enum ethtool_c33_pse_ext_substate_power_not_available - power_not_available -+ * states functions. IEEE 802.3-2022 33.2.4.4 Variables -+ * -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_BUDGET_EXCEEDED: Power -+ * budget exceeded for the controller -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PORT_PW_LIMIT_EXCEEDS_CONTROLLER_BUDGET: -+ * Configured port power limit exceeded controller power budget -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PD_REQUEST_EXCEEDS_PORT_LIMIT: -+ * Power request from PD exceeds port limit -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_HW_PW_LIMIT: Power -+ * denied due to Hardware power limit -+ * -+ * power_not_available is a variable that is asserted in an -+ * implementation-dependent manner when the PSE is no longer capable of -+ * sourcing sufficient power to support the attached PD. Sufficient power -+ * is defined by classification; see 33.2.6. -+ */ -+enum ethtool_c33_pse_ext_substate_power_not_available { -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_BUDGET_EXCEEDED = 1, -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PORT_PW_LIMIT_EXCEEDS_CONTROLLER_BUDGET, -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PD_REQUEST_EXCEEDS_PORT_LIMIT, -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_HW_PW_LIMIT, -+}; -+ -+/** -+ * enum ethtool_c33_pse_ext_substate_short_detected - short_detected states -+ * functions. IEEE 802.3-2022 33.2.4.4 Variables -+ * -+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_SHORT_CONDITION: Short -+ * condition was detected -+ * -+ * short_detected is a variable indicating if the PSE output current has been -+ * in a short circuit condition for TLIM within a sliding window (see 33.2.7.7). -+ */ -+enum ethtool_c33_pse_ext_substate_short_detected { -+ ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_SHORT_CONDITION = 1, -+}; -+ - /** - * enum ethtool_pse_types - Types of PSE controller. - * @ETHTOOL_PSE_UNKNOWN: Type of PSE controller is unknown -@@ -877,6 +1068,24 @@ enum ethtool_mm_verify_status { - ETHTOOL_MM_VERIFY_STATUS_DISABLED, - }; - -+/** -+ * enum ethtool_module_fw_flash_status - plug-in module firmware flashing status -+ * @ETHTOOL_MODULE_FW_FLASH_STATUS_STARTED: The firmware flashing process has -+ * started. -+ * @ETHTOOL_MODULE_FW_FLASH_STATUS_IN_PROGRESS: The firmware flashing process -+ * is in progress. -+ * @ETHTOOL_MODULE_FW_FLASH_STATUS_COMPLETED: The firmware flashing process was -+ * completed successfully. -+ * @ETHTOOL_MODULE_FW_FLASH_STATUS_ERROR: The firmware flashing process was -+ * stopped due to an error. -+ */ -+enum ethtool_module_fw_flash_status { -+ ETHTOOL_MODULE_FW_FLASH_STATUS_STARTED = 1, -+ ETHTOOL_MODULE_FW_FLASH_STATUS_IN_PROGRESS, -+ ETHTOOL_MODULE_FW_FLASH_STATUS_COMPLETED, -+ ETHTOOL_MODULE_FW_FLASH_STATUS_ERROR, -+}; -+ - /** - * struct ethtool_gstrings - string set for data tagging - * @cmd: Command number = %ETHTOOL_GSTRINGS -@@ -1845,6 +2054,7 @@ enum ethtool_link_mode_bit_indices { - ETHTOOL_LINK_MODE_10baseT1S_Full_BIT = 99, - ETHTOOL_LINK_MODE_10baseT1S_Half_BIT = 100, - ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT = 101, -+ ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT = 102, - - /* must be last entry */ - __ETHTOOL_LINK_MODE_MASK_NBITS -@@ -2323,4 +2533,20 @@ struct ethtool_link_settings { - * uint32_t map_lp_advertising[link_mode_masks_nwords]; - */ - }; -+ -+/** -+ * enum phy_upstream - Represents the upstream component a given PHY device -+ * is connected to, as in what is on the other end of the MII bus. Most PHYs -+ * will be attached to an Ethernet MAC controller, but in some cases, there's -+ * an intermediate PHY used as a media-converter, which will driver another -+ * MII interface as its output. -+ * @PHY_UPSTREAM_MAC: Upstream component is a MAC (a switch port, -+ * or ethernet controller) -+ * @PHY_UPSTREAM_PHY: Upstream component is a PHY (likely a media converter) -+ */ -+enum phy_upstream { -+ PHY_UPSTREAM_MAC, -+ PHY_UPSTREAM_PHY, -+}; -+ - #endif /* _LINUX_ETHTOOL_H */ -diff --git a/include/standard-headers/linux/fuse.h b/include/standard-headers/linux/fuse.h -index bac9dbc49f..889e12ad15 100644 ---- a/include/standard-headers/linux/fuse.h -+++ b/include/standard-headers/linux/fuse.h -@@ -217,6 +217,9 @@ - * - add backing_id to fuse_open_out, add FOPEN_PASSTHROUGH open flag - * - add FUSE_NO_EXPORT_SUPPORT init flag - * - add FUSE_NOTIFY_RESEND, add FUSE_HAS_RESEND init flag -+ * -+ * 7.41 -+ * - add FUSE_ALLOW_IDMAP - */ - - #ifndef _LINUX_FUSE_H -@@ -248,7 +251,7 @@ - #define FUSE_KERNEL_VERSION 7 - - /** Minor version number of this interface */ --#define FUSE_KERNEL_MINOR_VERSION 40 -+#define FUSE_KERNEL_MINOR_VERSION 41 - - /** The node ID of the root inode */ - #define FUSE_ROOT_ID 1 -@@ -417,6 +420,7 @@ struct fuse_file_lock { - * FUSE_NO_EXPORT_SUPPORT: explicitly disable export support - * FUSE_HAS_RESEND: kernel supports resending pending requests, and the high bit - * of the request ID indicates resend requests -+ * FUSE_ALLOW_IDMAP: allow creation of idmapped mounts - */ - #define FUSE_ASYNC_READ (1 << 0) - #define FUSE_POSIX_LOCKS (1 << 1) -@@ -462,6 +466,7 @@ struct fuse_file_lock { - - /* Obsolete alias for FUSE_DIRECT_IO_ALLOW_MMAP */ - #define FUSE_DIRECT_IO_RELAX FUSE_DIRECT_IO_ALLOW_MMAP -+#define FUSE_ALLOW_IDMAP (1ULL << 40) - - /** - * CUSE INIT request/reply flags -@@ -980,6 +985,21 @@ struct fuse_fallocate_in { - */ - #define FUSE_UNIQUE_RESEND (1ULL << 63) - -+/** -+ * This value will be set by the kernel to -+ * (struct fuse_in_header).{uid,gid} fields in -+ * case when: -+ * - fuse daemon enabled FUSE_ALLOW_IDMAP -+ * - idmapping information is not available and uid/gid -+ * can not be mapped in accordance with an idmapping. -+ * -+ * Note: an idmapping information always available -+ * for inode creation operations like: -+ * FUSE_MKNOD, FUSE_SYMLINK, FUSE_MKDIR, FUSE_TMPFILE, -+ * FUSE_CREATE and FUSE_RENAME2 (with RENAME_WHITEOUT). -+ */ -+#define FUSE_INVALID_UIDGID ((uint32_t)(-1)) -+ - struct fuse_in_header { - uint32_t len; - uint32_t opcode; -diff --git a/include/standard-headers/linux/input-event-codes.h b/include/standard-headers/linux/input-event-codes.h -index 2221b0c383..50b2b7497e 100644 ---- a/include/standard-headers/linux/input-event-codes.h -+++ b/include/standard-headers/linux/input-event-codes.h -@@ -618,6 +618,8 @@ - #define KEY_CAMERA_ACCESS_ENABLE 0x24b /* Enables programmatic access to camera devices. (HUTRR72) */ - #define KEY_CAMERA_ACCESS_DISABLE 0x24c /* Disables programmatic access to camera devices. (HUTRR72) */ - #define KEY_CAMERA_ACCESS_TOGGLE 0x24d /* Toggles the current state of the camera access control. (HUTRR72) */ -+#define KEY_ACCESSIBILITY 0x24e /* Toggles the system bound accessibility UI/command (HUTRR116) */ -+#define KEY_DO_NOT_DISTURB 0x24f /* Toggles the system-wide "Do Not Disturb" control (HUTRR94)*/ - - #define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */ - #define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */ -diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h -index 94c00996e6..12323b3334 100644 ---- a/include/standard-headers/linux/pci_regs.h -+++ b/include/standard-headers/linux/pci_regs.h -@@ -634,9 +634,11 @@ - #define PCI_EXP_RTCTL_SENFEE 0x0002 /* System Error on Non-Fatal Error */ - #define PCI_EXP_RTCTL_SEFEE 0x0004 /* System Error on Fatal Error */ - #define PCI_EXP_RTCTL_PMEIE 0x0008 /* PME Interrupt Enable */ --#define PCI_EXP_RTCTL_CRSSVE 0x0010 /* CRS Software Visibility Enable */ -+#define PCI_EXP_RTCTL_RRS_SVE 0x0010 /* Config RRS Software Visibility Enable */ -+#define PCI_EXP_RTCTL_CRSSVE PCI_EXP_RTCTL_RRS_SVE /* compatibility */ - #define PCI_EXP_RTCAP 0x1e /* Root Capabilities */ --#define PCI_EXP_RTCAP_CRSVIS 0x0001 /* CRS Software Visibility capability */ -+#define PCI_EXP_RTCAP_RRS_SV 0x0001 /* Config RRS Software Visibility */ -+#define PCI_EXP_RTCAP_CRSVIS PCI_EXP_RTCAP_RRS_SV /* compatibility */ - #define PCI_EXP_RTSTA 0x20 /* Root Status */ - #define PCI_EXP_RTSTA_PME_RQ_ID 0x0000ffff /* PME Requester ID */ - #define PCI_EXP_RTSTA_PME 0x00010000 /* PME status */ -@@ -740,6 +742,7 @@ - #define PCI_EXT_CAP_ID_DVSEC 0x23 /* Designated Vendor-Specific */ - #define PCI_EXT_CAP_ID_DLF 0x25 /* Data Link Feature */ - #define PCI_EXT_CAP_ID_PL_16GT 0x26 /* Physical Layer 16.0 GT/s */ -+#define PCI_EXT_CAP_ID_NPEM 0x29 /* Native PCIe Enclosure Management */ - #define PCI_EXT_CAP_ID_PL_32GT 0x2A /* Physical Layer 32.0 GT/s */ - #define PCI_EXT_CAP_ID_DOE 0x2E /* Data Object Exchange */ - #define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_DOE -@@ -1121,6 +1124,40 @@ - #define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_MASK 0x000000F0 - #define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_SHIFT 4 - -+/* Native PCIe Enclosure Management */ -+#define PCI_NPEM_CAP 0x04 /* NPEM capability register */ -+#define PCI_NPEM_CAP_CAPABLE 0x00000001 /* NPEM Capable */ -+ -+#define PCI_NPEM_CTRL 0x08 /* NPEM control register */ -+#define PCI_NPEM_CTRL_ENABLE 0x00000001 /* NPEM Enable */ -+ -+/* -+ * Native PCIe Enclosure Management indication bits and Reset command bit -+ * are corresponding for capability and control registers. -+ */ -+#define PCI_NPEM_CMD_RESET 0x00000002 /* Reset Command */ -+#define PCI_NPEM_IND_OK 0x00000004 /* OK */ -+#define PCI_NPEM_IND_LOCATE 0x00000008 /* Locate */ -+#define PCI_NPEM_IND_FAIL 0x00000010 /* Fail */ -+#define PCI_NPEM_IND_REBUILD 0x00000020 /* Rebuild */ -+#define PCI_NPEM_IND_PFA 0x00000040 /* Predicted Failure Analysis */ -+#define PCI_NPEM_IND_HOTSPARE 0x00000080 /* Hot Spare */ -+#define PCI_NPEM_IND_ICA 0x00000100 /* In Critical Array */ -+#define PCI_NPEM_IND_IFA 0x00000200 /* In Failed Array */ -+#define PCI_NPEM_IND_IDT 0x00000400 /* Device Type */ -+#define PCI_NPEM_IND_DISABLED 0x00000800 /* Disabled */ -+#define PCI_NPEM_IND_SPEC_0 0x01000000 -+#define PCI_NPEM_IND_SPEC_1 0x02000000 -+#define PCI_NPEM_IND_SPEC_2 0x04000000 -+#define PCI_NPEM_IND_SPEC_3 0x08000000 -+#define PCI_NPEM_IND_SPEC_4 0x10000000 -+#define PCI_NPEM_IND_SPEC_5 0x20000000 -+#define PCI_NPEM_IND_SPEC_6 0x40000000 -+#define PCI_NPEM_IND_SPEC_7 0x80000000 -+ -+#define PCI_NPEM_STATUS 0x0c /* NPEM status register */ -+#define PCI_NPEM_STATUS_CC 0x00000001 /* Command Completed */ -+ - /* Data Object Exchange */ - #define PCI_DOE_CAP 0x04 /* DOE Capabilities Register */ - #define PCI_DOE_CAP_INT_SUP 0x00000001 /* Interrupt Support */ -diff --git a/include/standard-headers/linux/virtio_balloon.h b/include/standard-headers/linux/virtio_balloon.h -index f343bfefd8..3121cd2e0e 100644 ---- a/include/standard-headers/linux/virtio_balloon.h -+++ b/include/standard-headers/linux/virtio_balloon.h -@@ -71,7 +71,13 @@ struct virtio_balloon_config { - #define VIRTIO_BALLOON_S_CACHES 7 /* Disk caches */ - #define VIRTIO_BALLOON_S_HTLB_PGALLOC 8 /* Hugetlb page allocations */ - #define VIRTIO_BALLOON_S_HTLB_PGFAIL 9 /* Hugetlb page allocation failures */ --#define VIRTIO_BALLOON_S_NR 10 -+#define VIRTIO_BALLOON_S_OOM_KILL 10 /* OOM killer invocations */ -+#define VIRTIO_BALLOON_S_ALLOC_STALL 11 /* Stall count of memory allocatoin */ -+#define VIRTIO_BALLOON_S_ASYNC_SCAN 12 /* Amount of memory scanned asynchronously */ -+#define VIRTIO_BALLOON_S_DIRECT_SCAN 13 /* Amount of memory scanned directly */ -+#define VIRTIO_BALLOON_S_ASYNC_RECLAIM 14 /* Amount of memory reclaimed asynchronously */ -+#define VIRTIO_BALLOON_S_DIRECT_RECLAIM 15 /* Amount of memory reclaimed directly */ -+#define VIRTIO_BALLOON_S_NR 16 - - #define VIRTIO_BALLOON_S_NAMES_WITH_PREFIX(VIRTIO_BALLOON_S_NAMES_prefix) { \ - VIRTIO_BALLOON_S_NAMES_prefix "swap-in", \ -@@ -83,7 +89,13 @@ struct virtio_balloon_config { - VIRTIO_BALLOON_S_NAMES_prefix "available-memory", \ - VIRTIO_BALLOON_S_NAMES_prefix "disk-caches", \ - VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-allocations", \ -- VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-failures" \ -+ VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-failures", \ -+ VIRTIO_BALLOON_S_NAMES_prefix "oom-kills", \ -+ VIRTIO_BALLOON_S_NAMES_prefix "alloc-stalls", \ -+ VIRTIO_BALLOON_S_NAMES_prefix "async-scans", \ -+ VIRTIO_BALLOON_S_NAMES_prefix "direct-scans", \ -+ VIRTIO_BALLOON_S_NAMES_prefix "async-reclaims", \ -+ VIRTIO_BALLOON_S_NAMES_prefix "direct-reclaims" \ - } - - #define VIRTIO_BALLOON_S_NAMES VIRTIO_BALLOON_S_NAMES_WITH_PREFIX("") -diff --git a/include/standard-headers/linux/virtio_gpu.h b/include/standard-headers/linux/virtio_gpu.h -index 2db643ed8f..6459fdb9fb 100644 ---- a/include/standard-headers/linux/virtio_gpu.h -+++ b/include/standard-headers/linux/virtio_gpu.h -@@ -311,6 +311,7 @@ struct virtio_gpu_cmd_submit { - #define VIRTIO_GPU_CAPSET_VIRGL2 2 - /* 3 is reserved for gfxstream */ - #define VIRTIO_GPU_CAPSET_VENUS 4 -+#define VIRTIO_GPU_CAPSET_DRM 6 - - /* VIRTIO_GPU_CMD_GET_CAPSET_INFO */ - struct virtio_gpu_get_capset_info { -diff --git a/linux-headers/asm-arm64/mman.h b/linux-headers/asm-arm64/mman.h -index d0dbfe9587..7b500a3a7b 100644 ---- a/linux-headers/asm-arm64/mman.h -+++ b/linux-headers/asm-arm64/mman.h -@@ -7,4 +7,13 @@ - #define PROT_BTI 0x10 /* BTI guarded page */ - #define PROT_MTE 0x20 /* Normal Tagged mapping */ - -+/* Override any generic PKEY permission defines */ -+#define PKEY_DISABLE_EXECUTE 0x4 -+#define PKEY_DISABLE_READ 0x8 -+#undef PKEY_ACCESS_MASK -+#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ -+ PKEY_DISABLE_WRITE |\ -+ PKEY_DISABLE_READ |\ -+ PKEY_DISABLE_EXECUTE) -+ - #endif /* ! _UAPI__ASM_MMAN_H */ -diff --git a/linux-headers/asm-arm64/unistd.h b/linux-headers/asm-arm64/unistd.h -index ce2ee8f1e3..df36f23876 100644 ---- a/linux-headers/asm-arm64/unistd.h -+++ b/linux-headers/asm-arm64/unistd.h -@@ -1,25 +1,2 @@ - /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ --/* -- * Copyright (C) 2012 ARM Ltd. -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . -- */ -- --#define __ARCH_WANT_RENAMEAT --#define __ARCH_WANT_NEW_STAT --#define __ARCH_WANT_SET_GET_RLIMIT --#define __ARCH_WANT_TIME32_SYSCALLS --#define __ARCH_WANT_SYS_CLONE3 --#define __ARCH_WANT_MEMFD_SECRET -- --#include -+#include -diff --git a/linux-headers/asm-arm64/unistd_64.h b/linux-headers/asm-arm64/unistd_64.h -new file mode 100644 -index 0000000000..99a1d70459 ---- /dev/null -+++ b/linux-headers/asm-arm64/unistd_64.h -@@ -0,0 +1,324 @@ -+#ifndef _ASM_UNISTD_64_H -+#define _ASM_UNISTD_64_H -+ -+#define __NR_io_setup 0 -+#define __NR_io_destroy 1 -+#define __NR_io_submit 2 -+#define __NR_io_cancel 3 -+#define __NR_io_getevents 4 -+#define __NR_setxattr 5 -+#define __NR_lsetxattr 6 -+#define __NR_fsetxattr 7 -+#define __NR_getxattr 8 -+#define __NR_lgetxattr 9 -+#define __NR_fgetxattr 10 -+#define __NR_listxattr 11 -+#define __NR_llistxattr 12 -+#define __NR_flistxattr 13 -+#define __NR_removexattr 14 -+#define __NR_lremovexattr 15 -+#define __NR_fremovexattr 16 -+#define __NR_getcwd 17 -+#define __NR_lookup_dcookie 18 -+#define __NR_eventfd2 19 -+#define __NR_epoll_create1 20 -+#define __NR_epoll_ctl 21 -+#define __NR_epoll_pwait 22 -+#define __NR_dup 23 -+#define __NR_dup3 24 -+#define __NR_fcntl 25 -+#define __NR_inotify_init1 26 -+#define __NR_inotify_add_watch 27 -+#define __NR_inotify_rm_watch 28 -+#define __NR_ioctl 29 -+#define __NR_ioprio_set 30 -+#define __NR_ioprio_get 31 -+#define __NR_flock 32 -+#define __NR_mknodat 33 -+#define __NR_mkdirat 34 -+#define __NR_unlinkat 35 -+#define __NR_symlinkat 36 -+#define __NR_linkat 37 -+#define __NR_renameat 38 -+#define __NR_umount2 39 -+#define __NR_mount 40 -+#define __NR_pivot_root 41 -+#define __NR_nfsservctl 42 -+#define __NR_statfs 43 -+#define __NR_fstatfs 44 -+#define __NR_truncate 45 -+#define __NR_ftruncate 46 -+#define __NR_fallocate 47 -+#define __NR_faccessat 48 -+#define __NR_chdir 49 -+#define __NR_fchdir 50 -+#define __NR_chroot 51 -+#define __NR_fchmod 52 -+#define __NR_fchmodat 53 -+#define __NR_fchownat 54 -+#define __NR_fchown 55 -+#define __NR_openat 56 -+#define __NR_close 57 -+#define __NR_vhangup 58 -+#define __NR_pipe2 59 -+#define __NR_quotactl 60 -+#define __NR_getdents64 61 -+#define __NR_lseek 62 -+#define __NR_read 63 -+#define __NR_write 64 -+#define __NR_readv 65 -+#define __NR_writev 66 -+#define __NR_pread64 67 -+#define __NR_pwrite64 68 -+#define __NR_preadv 69 -+#define __NR_pwritev 70 -+#define __NR_sendfile 71 -+#define __NR_pselect6 72 -+#define __NR_ppoll 73 -+#define __NR_signalfd4 74 -+#define __NR_vmsplice 75 -+#define __NR_splice 76 -+#define __NR_tee 77 -+#define __NR_readlinkat 78 -+#define __NR_newfstatat 79 -+#define __NR_fstat 80 -+#define __NR_sync 81 -+#define __NR_fsync 82 -+#define __NR_fdatasync 83 -+#define __NR_sync_file_range 84 -+#define __NR_timerfd_create 85 -+#define __NR_timerfd_settime 86 -+#define __NR_timerfd_gettime 87 -+#define __NR_utimensat 88 -+#define __NR_acct 89 -+#define __NR_capget 90 -+#define __NR_capset 91 -+#define __NR_personality 92 -+#define __NR_exit 93 -+#define __NR_exit_group 94 -+#define __NR_waitid 95 -+#define __NR_set_tid_address 96 -+#define __NR_unshare 97 -+#define __NR_futex 98 -+#define __NR_set_robust_list 99 -+#define __NR_get_robust_list 100 -+#define __NR_nanosleep 101 -+#define __NR_getitimer 102 -+#define __NR_setitimer 103 -+#define __NR_kexec_load 104 -+#define __NR_init_module 105 -+#define __NR_delete_module 106 -+#define __NR_timer_create 107 -+#define __NR_timer_gettime 108 -+#define __NR_timer_getoverrun 109 -+#define __NR_timer_settime 110 -+#define __NR_timer_delete 111 -+#define __NR_clock_settime 112 -+#define __NR_clock_gettime 113 -+#define __NR_clock_getres 114 -+#define __NR_clock_nanosleep 115 -+#define __NR_syslog 116 -+#define __NR_ptrace 117 -+#define __NR_sched_setparam 118 -+#define __NR_sched_setscheduler 119 -+#define __NR_sched_getscheduler 120 -+#define __NR_sched_getparam 121 -+#define __NR_sched_setaffinity 122 -+#define __NR_sched_getaffinity 123 -+#define __NR_sched_yield 124 -+#define __NR_sched_get_priority_max 125 -+#define __NR_sched_get_priority_min 126 -+#define __NR_sched_rr_get_interval 127 -+#define __NR_restart_syscall 128 -+#define __NR_kill 129 -+#define __NR_tkill 130 -+#define __NR_tgkill 131 -+#define __NR_sigaltstack 132 -+#define __NR_rt_sigsuspend 133 -+#define __NR_rt_sigaction 134 -+#define __NR_rt_sigprocmask 135 -+#define __NR_rt_sigpending 136 -+#define __NR_rt_sigtimedwait 137 -+#define __NR_rt_sigqueueinfo 138 -+#define __NR_rt_sigreturn 139 -+#define __NR_setpriority 140 -+#define __NR_getpriority 141 -+#define __NR_reboot 142 -+#define __NR_setregid 143 -+#define __NR_setgid 144 -+#define __NR_setreuid 145 -+#define __NR_setuid 146 -+#define __NR_setresuid 147 -+#define __NR_getresuid 148 -+#define __NR_setresgid 149 -+#define __NR_getresgid 150 -+#define __NR_setfsuid 151 -+#define __NR_setfsgid 152 -+#define __NR_times 153 -+#define __NR_setpgid 154 -+#define __NR_getpgid 155 -+#define __NR_getsid 156 -+#define __NR_setsid 157 -+#define __NR_getgroups 158 -+#define __NR_setgroups 159 -+#define __NR_uname 160 -+#define __NR_sethostname 161 -+#define __NR_setdomainname 162 -+#define __NR_getrlimit 163 -+#define __NR_setrlimit 164 -+#define __NR_getrusage 165 -+#define __NR_umask 166 -+#define __NR_prctl 167 -+#define __NR_getcpu 168 -+#define __NR_gettimeofday 169 -+#define __NR_settimeofday 170 -+#define __NR_adjtimex 171 -+#define __NR_getpid 172 -+#define __NR_getppid 173 -+#define __NR_getuid 174 -+#define __NR_geteuid 175 -+#define __NR_getgid 176 -+#define __NR_getegid 177 -+#define __NR_gettid 178 -+#define __NR_sysinfo 179 -+#define __NR_mq_open 180 -+#define __NR_mq_unlink 181 -+#define __NR_mq_timedsend 182 -+#define __NR_mq_timedreceive 183 -+#define __NR_mq_notify 184 -+#define __NR_mq_getsetattr 185 -+#define __NR_msgget 186 -+#define __NR_msgctl 187 -+#define __NR_msgrcv 188 -+#define __NR_msgsnd 189 -+#define __NR_semget 190 -+#define __NR_semctl 191 -+#define __NR_semtimedop 192 -+#define __NR_semop 193 -+#define __NR_shmget 194 -+#define __NR_shmctl 195 -+#define __NR_shmat 196 -+#define __NR_shmdt 197 -+#define __NR_socket 198 -+#define __NR_socketpair 199 -+#define __NR_bind 200 -+#define __NR_listen 201 -+#define __NR_accept 202 -+#define __NR_connect 203 -+#define __NR_getsockname 204 -+#define __NR_getpeername 205 -+#define __NR_sendto 206 -+#define __NR_recvfrom 207 -+#define __NR_setsockopt 208 -+#define __NR_getsockopt 209 -+#define __NR_shutdown 210 -+#define __NR_sendmsg 211 -+#define __NR_recvmsg 212 -+#define __NR_readahead 213 -+#define __NR_brk 214 -+#define __NR_munmap 215 -+#define __NR_mremap 216 -+#define __NR_add_key 217 -+#define __NR_request_key 218 -+#define __NR_keyctl 219 -+#define __NR_clone 220 -+#define __NR_execve 221 -+#define __NR_mmap 222 -+#define __NR_fadvise64 223 -+#define __NR_swapon 224 -+#define __NR_swapoff 225 -+#define __NR_mprotect 226 -+#define __NR_msync 227 -+#define __NR_mlock 228 -+#define __NR_munlock 229 -+#define __NR_mlockall 230 -+#define __NR_munlockall 231 -+#define __NR_mincore 232 -+#define __NR_madvise 233 -+#define __NR_remap_file_pages 234 -+#define __NR_mbind 235 -+#define __NR_get_mempolicy 236 -+#define __NR_set_mempolicy 237 -+#define __NR_migrate_pages 238 -+#define __NR_move_pages 239 -+#define __NR_rt_tgsigqueueinfo 240 -+#define __NR_perf_event_open 241 -+#define __NR_accept4 242 -+#define __NR_recvmmsg 243 -+#define __NR_wait4 260 -+#define __NR_prlimit64 261 -+#define __NR_fanotify_init 262 -+#define __NR_fanotify_mark 263 -+#define __NR_name_to_handle_at 264 -+#define __NR_open_by_handle_at 265 -+#define __NR_clock_adjtime 266 -+#define __NR_syncfs 267 -+#define __NR_setns 268 -+#define __NR_sendmmsg 269 -+#define __NR_process_vm_readv 270 -+#define __NR_process_vm_writev 271 -+#define __NR_kcmp 272 -+#define __NR_finit_module 273 -+#define __NR_sched_setattr 274 -+#define __NR_sched_getattr 275 -+#define __NR_renameat2 276 -+#define __NR_seccomp 277 -+#define __NR_getrandom 278 -+#define __NR_memfd_create 279 -+#define __NR_bpf 280 -+#define __NR_execveat 281 -+#define __NR_userfaultfd 282 -+#define __NR_membarrier 283 -+#define __NR_mlock2 284 -+#define __NR_copy_file_range 285 -+#define __NR_preadv2 286 -+#define __NR_pwritev2 287 -+#define __NR_pkey_mprotect 288 -+#define __NR_pkey_alloc 289 -+#define __NR_pkey_free 290 -+#define __NR_statx 291 -+#define __NR_io_pgetevents 292 -+#define __NR_rseq 293 -+#define __NR_kexec_file_load 294 -+#define __NR_pidfd_send_signal 424 -+#define __NR_io_uring_setup 425 -+#define __NR_io_uring_enter 426 -+#define __NR_io_uring_register 427 -+#define __NR_open_tree 428 -+#define __NR_move_mount 429 -+#define __NR_fsopen 430 -+#define __NR_fsconfig 431 -+#define __NR_fsmount 432 -+#define __NR_fspick 433 -+#define __NR_pidfd_open 434 -+#define __NR_clone3 435 -+#define __NR_close_range 436 -+#define __NR_openat2 437 -+#define __NR_pidfd_getfd 438 -+#define __NR_faccessat2 439 -+#define __NR_process_madvise 440 -+#define __NR_epoll_pwait2 441 -+#define __NR_mount_setattr 442 -+#define __NR_quotactl_fd 443 -+#define __NR_landlock_create_ruleset 444 -+#define __NR_landlock_add_rule 445 -+#define __NR_landlock_restrict_self 446 -+#define __NR_memfd_secret 447 -+#define __NR_process_mrelease 448 -+#define __NR_futex_waitv 449 -+#define __NR_set_mempolicy_home_node 450 -+#define __NR_cachestat 451 -+#define __NR_fchmodat2 452 -+#define __NR_map_shadow_stack 453 -+#define __NR_futex_wake 454 -+#define __NR_futex_wait 455 -+#define __NR_futex_requeue 456 -+#define __NR_statmount 457 -+#define __NR_listmount 458 -+#define __NR_lsm_get_self_attr 459 -+#define __NR_lsm_set_self_attr 460 -+#define __NR_lsm_list_modules 461 -+#define __NR_mseal 462 -+ -+ -+#endif /* _ASM_UNISTD_64_H */ -diff --git a/linux-headers/asm-generic/unistd.h b/linux-headers/asm-generic/unistd.h -index d983c48a3b..5bf6148cac 100644 ---- a/linux-headers/asm-generic/unistd.h -+++ b/linux-headers/asm-generic/unistd.h -@@ -737,7 +737,7 @@ __SC_COMP(__NR_pselect6_time64, sys_pselect6, compat_sys_pselect6_time64) - #define __NR_ppoll_time64 414 - __SC_COMP(__NR_ppoll_time64, sys_ppoll, compat_sys_ppoll_time64) - #define __NR_io_pgetevents_time64 416 --__SYSCALL(__NR_io_pgetevents_time64, sys_io_pgetevents) -+__SC_COMP(__NR_io_pgetevents_time64, sys_io_pgetevents, compat_sys_io_pgetevents_time64) - #define __NR_recvmmsg_time64 417 - __SC_COMP(__NR_recvmmsg_time64, sys_recvmmsg, compat_sys_recvmmsg_time64) - #define __NR_mq_timedsend_time64 418 -@@ -776,12 +776,8 @@ __SYSCALL(__NR_fsmount, sys_fsmount) - __SYSCALL(__NR_fspick, sys_fspick) - #define __NR_pidfd_open 434 - __SYSCALL(__NR_pidfd_open, sys_pidfd_open) -- --#ifdef __ARCH_WANT_SYS_CLONE3 - #define __NR_clone3 435 - __SYSCALL(__NR_clone3, sys_clone3) --#endif -- - #define __NR_close_range 436 - __SYSCALL(__NR_close_range, sys_close_range) - #define __NR_openat2 437 -diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h -index f9abef3823..70d89070bf 100644 ---- a/linux-headers/asm-loongarch/kvm.h -+++ b/linux-headers/asm-loongarch/kvm.h -@@ -64,6 +64,7 @@ struct kvm_fpu { - #define KVM_REG_LOONGARCH_KVM (KVM_REG_LOONGARCH | 0x20000ULL) - #define KVM_REG_LOONGARCH_FPSIMD (KVM_REG_LOONGARCH | 0x30000ULL) - #define KVM_REG_LOONGARCH_CPUCFG (KVM_REG_LOONGARCH | 0x40000ULL) -+#define KVM_REG_LOONGARCH_LBT (KVM_REG_LOONGARCH | 0x50000ULL) - #define KVM_REG_LOONGARCH_MASK (KVM_REG_LOONGARCH | 0x70000ULL) - #define KVM_CSR_IDX_MASK 0x7fff - #define KVM_CPUCFG_IDX_MASK 0x7fff -@@ -77,11 +78,34 @@ struct kvm_fpu { - /* Debugging: Special instruction for software breakpoint */ - #define KVM_REG_LOONGARCH_DEBUG_INST (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 3) - -+/* LBT registers */ -+#define KVM_REG_LOONGARCH_LBT_SCR0 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 1) -+#define KVM_REG_LOONGARCH_LBT_SCR1 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 2) -+#define KVM_REG_LOONGARCH_LBT_SCR2 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 3) -+#define KVM_REG_LOONGARCH_LBT_SCR3 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 4) -+#define KVM_REG_LOONGARCH_LBT_EFLAGS (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 5) -+#define KVM_REG_LOONGARCH_LBT_FTOP (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 6) -+ - #define LOONGARCH_REG_SHIFT 3 - #define LOONGARCH_REG_64(TYPE, REG) (TYPE | KVM_REG_SIZE_U64 | (REG << LOONGARCH_REG_SHIFT)) - #define KVM_IOC_CSRID(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, REG) - #define KVM_IOC_CPUCFG(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG) -+ -+/* Device Control API on vm fd */ -+#define KVM_LOONGARCH_VM_FEAT_CTRL 0 -+#define KVM_LOONGARCH_VM_FEAT_LSX 0 -+#define KVM_LOONGARCH_VM_FEAT_LASX 1 -+#define KVM_LOONGARCH_VM_FEAT_X86BT 2 -+#define KVM_LOONGARCH_VM_FEAT_ARMBT 3 -+#define KVM_LOONGARCH_VM_FEAT_MIPSBT 4 -+#define KVM_LOONGARCH_VM_FEAT_PMU 5 -+#define KVM_LOONGARCH_VM_FEAT_PV_IPI 6 -+#define KVM_LOONGARCH_VM_FEAT_PV_STEALTIME 7 -+ -+/* Device Control API on vcpu fd */ - #define KVM_LOONGARCH_VCPU_CPUCFG 0 -+#define KVM_LOONGARCH_VCPU_PVTIME_CTRL 1 -+#define KVM_LOONGARCH_VCPU_PVTIME_GPA 0 - - struct kvm_debug_exit_arch { - }; -diff --git a/linux-headers/asm-loongarch/kvm_para.h b/linux-headers/asm-loongarch/kvm_para.h -new file mode 100644 -index 0000000000..4ba4ad8db1 ---- /dev/null -+++ b/linux-headers/asm-loongarch/kvm_para.h -@@ -0,0 +1,21 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+#ifndef _ASM_KVM_PARA_H -+#define _ASM_KVM_PARA_H -+ -+#include -+ -+/* -+ * CPUCFG index area: 0x40000000 -- 0x400000ff -+ * SW emulation for KVM hypervirsor -+ */ -+#define CPUCFG_KVM_BASE 0x40000000 -+#define CPUCFG_KVM_SIZE 0x100 -+#define CPUCFG_KVM_SIG (CPUCFG_KVM_BASE + 0) -+#define KVM_SIGNATURE "KVM\0" -+#define CPUCFG_KVM_FEATURE (CPUCFG_KVM_BASE + 4) -+#define KVM_FEATURE_IPI 1 -+#define KVM_FEATURE_STEAL_TIME 2 -+/* BIT 24 - 31 are features configurable by user space vmm */ -+#define KVM_FEATURE_VIRT_EXTIOI 24 -+ -+#endif /* _ASM_KVM_PARA_H */ -diff --git a/linux-headers/asm-loongarch/unistd.h b/linux-headers/asm-loongarch/unistd.h -index fcb668984f..1f01980f9c 100644 ---- a/linux-headers/asm-loongarch/unistd.h -+++ b/linux-headers/asm-loongarch/unistd.h -@@ -1,5 +1,3 @@ - /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ --#define __ARCH_WANT_SYS_CLONE --#define __ARCH_WANT_SYS_CLONE3 - --#include -+#include -diff --git a/linux-headers/asm-loongarch/unistd_64.h b/linux-headers/asm-loongarch/unistd_64.h -new file mode 100644 -index 0000000000..887ea50cca ---- /dev/null -+++ b/linux-headers/asm-loongarch/unistd_64.h -@@ -0,0 +1,320 @@ -+#ifndef _ASM_UNISTD_64_H -+#define _ASM_UNISTD_64_H -+ -+#define __NR_io_setup 0 -+#define __NR_io_destroy 1 -+#define __NR_io_submit 2 -+#define __NR_io_cancel 3 -+#define __NR_io_getevents 4 -+#define __NR_setxattr 5 -+#define __NR_lsetxattr 6 -+#define __NR_fsetxattr 7 -+#define __NR_getxattr 8 -+#define __NR_lgetxattr 9 -+#define __NR_fgetxattr 10 -+#define __NR_listxattr 11 -+#define __NR_llistxattr 12 -+#define __NR_flistxattr 13 -+#define __NR_removexattr 14 -+#define __NR_lremovexattr 15 -+#define __NR_fremovexattr 16 -+#define __NR_getcwd 17 -+#define __NR_lookup_dcookie 18 -+#define __NR_eventfd2 19 -+#define __NR_epoll_create1 20 -+#define __NR_epoll_ctl 21 -+#define __NR_epoll_pwait 22 -+#define __NR_dup 23 -+#define __NR_dup3 24 -+#define __NR_fcntl 25 -+#define __NR_inotify_init1 26 -+#define __NR_inotify_add_watch 27 -+#define __NR_inotify_rm_watch 28 -+#define __NR_ioctl 29 -+#define __NR_ioprio_set 30 -+#define __NR_ioprio_get 31 -+#define __NR_flock 32 -+#define __NR_mknodat 33 -+#define __NR_mkdirat 34 -+#define __NR_unlinkat 35 -+#define __NR_symlinkat 36 -+#define __NR_linkat 37 -+#define __NR_umount2 39 -+#define __NR_mount 40 -+#define __NR_pivot_root 41 -+#define __NR_nfsservctl 42 -+#define __NR_statfs 43 -+#define __NR_fstatfs 44 -+#define __NR_truncate 45 -+#define __NR_ftruncate 46 -+#define __NR_fallocate 47 -+#define __NR_faccessat 48 -+#define __NR_chdir 49 -+#define __NR_fchdir 50 -+#define __NR_chroot 51 -+#define __NR_fchmod 52 -+#define __NR_fchmodat 53 -+#define __NR_fchownat 54 -+#define __NR_fchown 55 -+#define __NR_openat 56 -+#define __NR_close 57 -+#define __NR_vhangup 58 -+#define __NR_pipe2 59 -+#define __NR_quotactl 60 -+#define __NR_getdents64 61 -+#define __NR_lseek 62 -+#define __NR_read 63 -+#define __NR_write 64 -+#define __NR_readv 65 -+#define __NR_writev 66 -+#define __NR_pread64 67 -+#define __NR_pwrite64 68 -+#define __NR_preadv 69 -+#define __NR_pwritev 70 -+#define __NR_sendfile 71 -+#define __NR_pselect6 72 -+#define __NR_ppoll 73 -+#define __NR_signalfd4 74 -+#define __NR_vmsplice 75 -+#define __NR_splice 76 -+#define __NR_tee 77 -+#define __NR_readlinkat 78 -+#define __NR_newfstatat 79 -+#define __NR_fstat 80 -+#define __NR_sync 81 -+#define __NR_fsync 82 -+#define __NR_fdatasync 83 -+#define __NR_sync_file_range 84 -+#define __NR_timerfd_create 85 -+#define __NR_timerfd_settime 86 -+#define __NR_timerfd_gettime 87 -+#define __NR_utimensat 88 -+#define __NR_acct 89 -+#define __NR_capget 90 -+#define __NR_capset 91 -+#define __NR_personality 92 -+#define __NR_exit 93 -+#define __NR_exit_group 94 -+#define __NR_waitid 95 -+#define __NR_set_tid_address 96 -+#define __NR_unshare 97 -+#define __NR_futex 98 -+#define __NR_set_robust_list 99 -+#define __NR_get_robust_list 100 -+#define __NR_nanosleep 101 -+#define __NR_getitimer 102 -+#define __NR_setitimer 103 -+#define __NR_kexec_load 104 -+#define __NR_init_module 105 -+#define __NR_delete_module 106 -+#define __NR_timer_create 107 -+#define __NR_timer_gettime 108 -+#define __NR_timer_getoverrun 109 -+#define __NR_timer_settime 110 -+#define __NR_timer_delete 111 -+#define __NR_clock_settime 112 -+#define __NR_clock_gettime 113 -+#define __NR_clock_getres 114 -+#define __NR_clock_nanosleep 115 -+#define __NR_syslog 116 -+#define __NR_ptrace 117 -+#define __NR_sched_setparam 118 -+#define __NR_sched_setscheduler 119 -+#define __NR_sched_getscheduler 120 -+#define __NR_sched_getparam 121 -+#define __NR_sched_setaffinity 122 -+#define __NR_sched_getaffinity 123 -+#define __NR_sched_yield 124 -+#define __NR_sched_get_priority_max 125 -+#define __NR_sched_get_priority_min 126 -+#define __NR_sched_rr_get_interval 127 -+#define __NR_restart_syscall 128 -+#define __NR_kill 129 -+#define __NR_tkill 130 -+#define __NR_tgkill 131 -+#define __NR_sigaltstack 132 -+#define __NR_rt_sigsuspend 133 -+#define __NR_rt_sigaction 134 -+#define __NR_rt_sigprocmask 135 -+#define __NR_rt_sigpending 136 -+#define __NR_rt_sigtimedwait 137 -+#define __NR_rt_sigqueueinfo 138 -+#define __NR_rt_sigreturn 139 -+#define __NR_setpriority 140 -+#define __NR_getpriority 141 -+#define __NR_reboot 142 -+#define __NR_setregid 143 -+#define __NR_setgid 144 -+#define __NR_setreuid 145 -+#define __NR_setuid 146 -+#define __NR_setresuid 147 -+#define __NR_getresuid 148 -+#define __NR_setresgid 149 -+#define __NR_getresgid 150 -+#define __NR_setfsuid 151 -+#define __NR_setfsgid 152 -+#define __NR_times 153 -+#define __NR_setpgid 154 -+#define __NR_getpgid 155 -+#define __NR_getsid 156 -+#define __NR_setsid 157 -+#define __NR_getgroups 158 -+#define __NR_setgroups 159 -+#define __NR_uname 160 -+#define __NR_sethostname 161 -+#define __NR_setdomainname 162 -+#define __NR_getrusage 165 -+#define __NR_umask 166 -+#define __NR_prctl 167 -+#define __NR_getcpu 168 -+#define __NR_gettimeofday 169 -+#define __NR_settimeofday 170 -+#define __NR_adjtimex 171 -+#define __NR_getpid 172 -+#define __NR_getppid 173 -+#define __NR_getuid 174 -+#define __NR_geteuid 175 -+#define __NR_getgid 176 -+#define __NR_getegid 177 -+#define __NR_gettid 178 -+#define __NR_sysinfo 179 -+#define __NR_mq_open 180 -+#define __NR_mq_unlink 181 -+#define __NR_mq_timedsend 182 -+#define __NR_mq_timedreceive 183 -+#define __NR_mq_notify 184 -+#define __NR_mq_getsetattr 185 -+#define __NR_msgget 186 -+#define __NR_msgctl 187 -+#define __NR_msgrcv 188 -+#define __NR_msgsnd 189 -+#define __NR_semget 190 -+#define __NR_semctl 191 -+#define __NR_semtimedop 192 -+#define __NR_semop 193 -+#define __NR_shmget 194 -+#define __NR_shmctl 195 -+#define __NR_shmat 196 -+#define __NR_shmdt 197 -+#define __NR_socket 198 -+#define __NR_socketpair 199 -+#define __NR_bind 200 -+#define __NR_listen 201 -+#define __NR_accept 202 -+#define __NR_connect 203 -+#define __NR_getsockname 204 -+#define __NR_getpeername 205 -+#define __NR_sendto 206 -+#define __NR_recvfrom 207 -+#define __NR_setsockopt 208 -+#define __NR_getsockopt 209 -+#define __NR_shutdown 210 -+#define __NR_sendmsg 211 -+#define __NR_recvmsg 212 -+#define __NR_readahead 213 -+#define __NR_brk 214 -+#define __NR_munmap 215 -+#define __NR_mremap 216 -+#define __NR_add_key 217 -+#define __NR_request_key 218 -+#define __NR_keyctl 219 -+#define __NR_clone 220 -+#define __NR_execve 221 -+#define __NR_mmap 222 -+#define __NR_fadvise64 223 -+#define __NR_swapon 224 -+#define __NR_swapoff 225 -+#define __NR_mprotect 226 -+#define __NR_msync 227 -+#define __NR_mlock 228 -+#define __NR_munlock 229 -+#define __NR_mlockall 230 -+#define __NR_munlockall 231 -+#define __NR_mincore 232 -+#define __NR_madvise 233 -+#define __NR_remap_file_pages 234 -+#define __NR_mbind 235 -+#define __NR_get_mempolicy 236 -+#define __NR_set_mempolicy 237 -+#define __NR_migrate_pages 238 -+#define __NR_move_pages 239 -+#define __NR_rt_tgsigqueueinfo 240 -+#define __NR_perf_event_open 241 -+#define __NR_accept4 242 -+#define __NR_recvmmsg 243 -+#define __NR_wait4 260 -+#define __NR_prlimit64 261 -+#define __NR_fanotify_init 262 -+#define __NR_fanotify_mark 263 -+#define __NR_name_to_handle_at 264 -+#define __NR_open_by_handle_at 265 -+#define __NR_clock_adjtime 266 -+#define __NR_syncfs 267 -+#define __NR_setns 268 -+#define __NR_sendmmsg 269 -+#define __NR_process_vm_readv 270 -+#define __NR_process_vm_writev 271 -+#define __NR_kcmp 272 -+#define __NR_finit_module 273 -+#define __NR_sched_setattr 274 -+#define __NR_sched_getattr 275 -+#define __NR_renameat2 276 -+#define __NR_seccomp 277 -+#define __NR_getrandom 278 -+#define __NR_memfd_create 279 -+#define __NR_bpf 280 -+#define __NR_execveat 281 -+#define __NR_userfaultfd 282 -+#define __NR_membarrier 283 -+#define __NR_mlock2 284 -+#define __NR_copy_file_range 285 -+#define __NR_preadv2 286 -+#define __NR_pwritev2 287 -+#define __NR_pkey_mprotect 288 -+#define __NR_pkey_alloc 289 -+#define __NR_pkey_free 290 -+#define __NR_statx 291 -+#define __NR_io_pgetevents 292 -+#define __NR_rseq 293 -+#define __NR_kexec_file_load 294 -+#define __NR_pidfd_send_signal 424 -+#define __NR_io_uring_setup 425 -+#define __NR_io_uring_enter 426 -+#define __NR_io_uring_register 427 -+#define __NR_open_tree 428 -+#define __NR_move_mount 429 -+#define __NR_fsopen 430 -+#define __NR_fsconfig 431 -+#define __NR_fsmount 432 -+#define __NR_fspick 433 -+#define __NR_pidfd_open 434 -+#define __NR_clone3 435 -+#define __NR_close_range 436 -+#define __NR_openat2 437 -+#define __NR_pidfd_getfd 438 -+#define __NR_faccessat2 439 -+#define __NR_process_madvise 440 -+#define __NR_epoll_pwait2 441 -+#define __NR_mount_setattr 442 -+#define __NR_quotactl_fd 443 -+#define __NR_landlock_create_ruleset 444 -+#define __NR_landlock_add_rule 445 -+#define __NR_landlock_restrict_self 446 -+#define __NR_process_mrelease 448 -+#define __NR_futex_waitv 449 -+#define __NR_set_mempolicy_home_node 450 -+#define __NR_cachestat 451 -+#define __NR_fchmodat2 452 -+#define __NR_map_shadow_stack 453 -+#define __NR_futex_wake 454 -+#define __NR_futex_wait 455 -+#define __NR_futex_requeue 456 -+#define __NR_statmount 457 -+#define __NR_listmount 458 -+#define __NR_lsm_get_self_attr 459 -+#define __NR_lsm_set_self_attr 460 -+#define __NR_lsm_list_modules 461 -+#define __NR_mseal 462 -+ -+ -+#endif /* _ASM_UNISTD_64_H */ -diff --git a/linux-headers/asm-riscv/kvm.h b/linux-headers/asm-riscv/kvm.h -index e878e7cc39..e97db32964 100644 ---- a/linux-headers/asm-riscv/kvm.h -+++ b/linux-headers/asm-riscv/kvm.h -@@ -168,6 +168,13 @@ enum KVM_RISCV_ISA_EXT_ID { - KVM_RISCV_ISA_EXT_ZTSO, - KVM_RISCV_ISA_EXT_ZACAS, - KVM_RISCV_ISA_EXT_SSCOFPMF, -+ KVM_RISCV_ISA_EXT_ZIMOP, -+ KVM_RISCV_ISA_EXT_ZCA, -+ KVM_RISCV_ISA_EXT_ZCB, -+ KVM_RISCV_ISA_EXT_ZCD, -+ KVM_RISCV_ISA_EXT_ZCF, -+ KVM_RISCV_ISA_EXT_ZCMOP, -+ KVM_RISCV_ISA_EXT_ZAWRS, - KVM_RISCV_ISA_EXT_MAX, - }; - -diff --git a/linux-headers/asm-riscv/unistd.h b/linux-headers/asm-riscv/unistd.h -index 950ab3fd44..81896bbbf7 100644 ---- a/linux-headers/asm-riscv/unistd.h -+++ b/linux-headers/asm-riscv/unistd.h -@@ -14,41 +14,10 @@ - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -+#include - --#if defined(__LP64__) && !defined(__SYSCALL_COMPAT) --#define __ARCH_WANT_NEW_STAT --#define __ARCH_WANT_SET_GET_RLIMIT --#endif /* __LP64__ */ -- --#define __ARCH_WANT_SYS_CLONE3 --#define __ARCH_WANT_MEMFD_SECRET -- --#include -- --/* -- * Allows the instruction cache to be flushed from userspace. Despite RISC-V -- * having a direct 'fence.i' instruction available to userspace (which we -- * can't trap!), that's not actually viable when running on Linux because the -- * kernel might schedule a process on another hart. There is no way for -- * userspace to handle this without invoking the kernel (as it doesn't know the -- * thread->hart mappings), so we've defined a RISC-V specific system call to -- * flush the instruction cache. -- * -- * __NR_riscv_flush_icache is defined to flush the instruction cache over an -- * address range, with the flush applying to either all threads or just the -- * caller. We don't currently do anything with the address range, that's just -- * in there for forwards compatibility. -- */ --#ifndef __NR_riscv_flush_icache --#define __NR_riscv_flush_icache (__NR_arch_specific_syscall + 15) --#endif --__SYSCALL(__NR_riscv_flush_icache, sys_riscv_flush_icache) -- --/* -- * Allows userspace to query the kernel for CPU architecture and -- * microarchitecture details across a given set of CPUs. -- */ --#ifndef __NR_riscv_hwprobe --#define __NR_riscv_hwprobe (__NR_arch_specific_syscall + 14) -+#if __BITS_PER_LONG == 64 -+#include -+#else -+#include - #endif --__SYSCALL(__NR_riscv_hwprobe, sys_riscv_hwprobe) -diff --git a/linux-headers/asm-riscv/unistd_32.h b/linux-headers/asm-riscv/unistd_32.h -new file mode 100644 -index 0000000000..9625743dfd ---- /dev/null -+++ b/linux-headers/asm-riscv/unistd_32.h -@@ -0,0 +1,315 @@ -+#ifndef _ASM_UNISTD_32_H -+#define _ASM_UNISTD_32_H -+ -+#define __NR_io_setup 0 -+#define __NR_io_destroy 1 -+#define __NR_io_submit 2 -+#define __NR_io_cancel 3 -+#define __NR_setxattr 5 -+#define __NR_lsetxattr 6 -+#define __NR_fsetxattr 7 -+#define __NR_getxattr 8 -+#define __NR_lgetxattr 9 -+#define __NR_fgetxattr 10 -+#define __NR_listxattr 11 -+#define __NR_llistxattr 12 -+#define __NR_flistxattr 13 -+#define __NR_removexattr 14 -+#define __NR_lremovexattr 15 -+#define __NR_fremovexattr 16 -+#define __NR_getcwd 17 -+#define __NR_lookup_dcookie 18 -+#define __NR_eventfd2 19 -+#define __NR_epoll_create1 20 -+#define __NR_epoll_ctl 21 -+#define __NR_epoll_pwait 22 -+#define __NR_dup 23 -+#define __NR_dup3 24 -+#define __NR_fcntl64 25 -+#define __NR_inotify_init1 26 -+#define __NR_inotify_add_watch 27 -+#define __NR_inotify_rm_watch 28 -+#define __NR_ioctl 29 -+#define __NR_ioprio_set 30 -+#define __NR_ioprio_get 31 -+#define __NR_flock 32 -+#define __NR_mknodat 33 -+#define __NR_mkdirat 34 -+#define __NR_unlinkat 35 -+#define __NR_symlinkat 36 -+#define __NR_linkat 37 -+#define __NR_umount2 39 -+#define __NR_mount 40 -+#define __NR_pivot_root 41 -+#define __NR_nfsservctl 42 -+#define __NR_statfs64 43 -+#define __NR_fstatfs64 44 -+#define __NR_truncate64 45 -+#define __NR_ftruncate64 46 -+#define __NR_fallocate 47 -+#define __NR_faccessat 48 -+#define __NR_chdir 49 -+#define __NR_fchdir 50 -+#define __NR_chroot 51 -+#define __NR_fchmod 52 -+#define __NR_fchmodat 53 -+#define __NR_fchownat 54 -+#define __NR_fchown 55 -+#define __NR_openat 56 -+#define __NR_close 57 -+#define __NR_vhangup 58 -+#define __NR_pipe2 59 -+#define __NR_quotactl 60 -+#define __NR_getdents64 61 -+#define __NR_llseek 62 -+#define __NR_read 63 -+#define __NR_write 64 -+#define __NR_readv 65 -+#define __NR_writev 66 -+#define __NR_pread64 67 -+#define __NR_pwrite64 68 -+#define __NR_preadv 69 -+#define __NR_pwritev 70 -+#define __NR_sendfile64 71 -+#define __NR_signalfd4 74 -+#define __NR_vmsplice 75 -+#define __NR_splice 76 -+#define __NR_tee 77 -+#define __NR_readlinkat 78 -+#define __NR_sync 81 -+#define __NR_fsync 82 -+#define __NR_fdatasync 83 -+#define __NR_sync_file_range 84 -+#define __NR_timerfd_create 85 -+#define __NR_acct 89 -+#define __NR_capget 90 -+#define __NR_capset 91 -+#define __NR_personality 92 -+#define __NR_exit 93 -+#define __NR_exit_group 94 -+#define __NR_waitid 95 -+#define __NR_set_tid_address 96 -+#define __NR_unshare 97 -+#define __NR_set_robust_list 99 -+#define __NR_get_robust_list 100 -+#define __NR_getitimer 102 -+#define __NR_setitimer 103 -+#define __NR_kexec_load 104 -+#define __NR_init_module 105 -+#define __NR_delete_module 106 -+#define __NR_timer_create 107 -+#define __NR_timer_getoverrun 109 -+#define __NR_timer_delete 111 -+#define __NR_syslog 116 -+#define __NR_ptrace 117 -+#define __NR_sched_setparam 118 -+#define __NR_sched_setscheduler 119 -+#define __NR_sched_getscheduler 120 -+#define __NR_sched_getparam 121 -+#define __NR_sched_setaffinity 122 -+#define __NR_sched_getaffinity 123 -+#define __NR_sched_yield 124 -+#define __NR_sched_get_priority_max 125 -+#define __NR_sched_get_priority_min 126 -+#define __NR_restart_syscall 128 -+#define __NR_kill 129 -+#define __NR_tkill 130 -+#define __NR_tgkill 131 -+#define __NR_sigaltstack 132 -+#define __NR_rt_sigsuspend 133 -+#define __NR_rt_sigaction 134 -+#define __NR_rt_sigprocmask 135 -+#define __NR_rt_sigpending 136 -+#define __NR_rt_sigqueueinfo 138 -+#define __NR_rt_sigreturn 139 -+#define __NR_setpriority 140 -+#define __NR_getpriority 141 -+#define __NR_reboot 142 -+#define __NR_setregid 143 -+#define __NR_setgid 144 -+#define __NR_setreuid 145 -+#define __NR_setuid 146 -+#define __NR_setresuid 147 -+#define __NR_getresuid 148 -+#define __NR_setresgid 149 -+#define __NR_getresgid 150 -+#define __NR_setfsuid 151 -+#define __NR_setfsgid 152 -+#define __NR_times 153 -+#define __NR_setpgid 154 -+#define __NR_getpgid 155 -+#define __NR_getsid 156 -+#define __NR_setsid 157 -+#define __NR_getgroups 158 -+#define __NR_setgroups 159 -+#define __NR_uname 160 -+#define __NR_sethostname 161 -+#define __NR_setdomainname 162 -+#define __NR_getrusage 165 -+#define __NR_umask 166 -+#define __NR_prctl 167 -+#define __NR_getcpu 168 -+#define __NR_getpid 172 -+#define __NR_getppid 173 -+#define __NR_getuid 174 -+#define __NR_geteuid 175 -+#define __NR_getgid 176 -+#define __NR_getegid 177 -+#define __NR_gettid 178 -+#define __NR_sysinfo 179 -+#define __NR_mq_open 180 -+#define __NR_mq_unlink 181 -+#define __NR_mq_notify 184 -+#define __NR_mq_getsetattr 185 -+#define __NR_msgget 186 -+#define __NR_msgctl 187 -+#define __NR_msgrcv 188 -+#define __NR_msgsnd 189 -+#define __NR_semget 190 -+#define __NR_semctl 191 -+#define __NR_semop 193 -+#define __NR_shmget 194 -+#define __NR_shmctl 195 -+#define __NR_shmat 196 -+#define __NR_shmdt 197 -+#define __NR_socket 198 -+#define __NR_socketpair 199 -+#define __NR_bind 200 -+#define __NR_listen 201 -+#define __NR_accept 202 -+#define __NR_connect 203 -+#define __NR_getsockname 204 -+#define __NR_getpeername 205 -+#define __NR_sendto 206 -+#define __NR_recvfrom 207 -+#define __NR_setsockopt 208 -+#define __NR_getsockopt 209 -+#define __NR_shutdown 210 -+#define __NR_sendmsg 211 -+#define __NR_recvmsg 212 -+#define __NR_readahead 213 -+#define __NR_brk 214 -+#define __NR_munmap 215 -+#define __NR_mremap 216 -+#define __NR_add_key 217 -+#define __NR_request_key 218 -+#define __NR_keyctl 219 -+#define __NR_clone 220 -+#define __NR_execve 221 -+#define __NR_mmap2 222 -+#define __NR_fadvise64_64 223 -+#define __NR_swapon 224 -+#define __NR_swapoff 225 -+#define __NR_mprotect 226 -+#define __NR_msync 227 -+#define __NR_mlock 228 -+#define __NR_munlock 229 -+#define __NR_mlockall 230 -+#define __NR_munlockall 231 -+#define __NR_mincore 232 -+#define __NR_madvise 233 -+#define __NR_remap_file_pages 234 -+#define __NR_mbind 235 -+#define __NR_get_mempolicy 236 -+#define __NR_set_mempolicy 237 -+#define __NR_migrate_pages 238 -+#define __NR_move_pages 239 -+#define __NR_rt_tgsigqueueinfo 240 -+#define __NR_perf_event_open 241 -+#define __NR_accept4 242 -+#define __NR_riscv_hwprobe 258 -+#define __NR_riscv_flush_icache 259 -+#define __NR_prlimit64 261 -+#define __NR_fanotify_init 262 -+#define __NR_fanotify_mark 263 -+#define __NR_name_to_handle_at 264 -+#define __NR_open_by_handle_at 265 -+#define __NR_syncfs 267 -+#define __NR_setns 268 -+#define __NR_sendmmsg 269 -+#define __NR_process_vm_readv 270 -+#define __NR_process_vm_writev 271 -+#define __NR_kcmp 272 -+#define __NR_finit_module 273 -+#define __NR_sched_setattr 274 -+#define __NR_sched_getattr 275 -+#define __NR_renameat2 276 -+#define __NR_seccomp 277 -+#define __NR_getrandom 278 -+#define __NR_memfd_create 279 -+#define __NR_bpf 280 -+#define __NR_execveat 281 -+#define __NR_userfaultfd 282 -+#define __NR_membarrier 283 -+#define __NR_mlock2 284 -+#define __NR_copy_file_range 285 -+#define __NR_preadv2 286 -+#define __NR_pwritev2 287 -+#define __NR_pkey_mprotect 288 -+#define __NR_pkey_alloc 289 -+#define __NR_pkey_free 290 -+#define __NR_statx 291 -+#define __NR_rseq 293 -+#define __NR_kexec_file_load 294 -+#define __NR_clock_gettime64 403 -+#define __NR_clock_settime64 404 -+#define __NR_clock_adjtime64 405 -+#define __NR_clock_getres_time64 406 -+#define __NR_clock_nanosleep_time64 407 -+#define __NR_timer_gettime64 408 -+#define __NR_timer_settime64 409 -+#define __NR_timerfd_gettime64 410 -+#define __NR_timerfd_settime64 411 -+#define __NR_utimensat_time64 412 -+#define __NR_pselect6_time64 413 -+#define __NR_ppoll_time64 414 -+#define __NR_io_pgetevents_time64 416 -+#define __NR_recvmmsg_time64 417 -+#define __NR_mq_timedsend_time64 418 -+#define __NR_mq_timedreceive_time64 419 -+#define __NR_semtimedop_time64 420 -+#define __NR_rt_sigtimedwait_time64 421 -+#define __NR_futex_time64 422 -+#define __NR_sched_rr_get_interval_time64 423 -+#define __NR_pidfd_send_signal 424 -+#define __NR_io_uring_setup 425 -+#define __NR_io_uring_enter 426 -+#define __NR_io_uring_register 427 -+#define __NR_open_tree 428 -+#define __NR_move_mount 429 -+#define __NR_fsopen 430 -+#define __NR_fsconfig 431 -+#define __NR_fsmount 432 -+#define __NR_fspick 433 -+#define __NR_pidfd_open 434 -+#define __NR_clone3 435 -+#define __NR_close_range 436 -+#define __NR_openat2 437 -+#define __NR_pidfd_getfd 438 -+#define __NR_faccessat2 439 -+#define __NR_process_madvise 440 -+#define __NR_epoll_pwait2 441 -+#define __NR_mount_setattr 442 -+#define __NR_quotactl_fd 443 -+#define __NR_landlock_create_ruleset 444 -+#define __NR_landlock_add_rule 445 -+#define __NR_landlock_restrict_self 446 -+#define __NR_memfd_secret 447 -+#define __NR_process_mrelease 448 -+#define __NR_futex_waitv 449 -+#define __NR_set_mempolicy_home_node 450 -+#define __NR_cachestat 451 -+#define __NR_fchmodat2 452 -+#define __NR_map_shadow_stack 453 -+#define __NR_futex_wake 454 -+#define __NR_futex_wait 455 -+#define __NR_futex_requeue 456 -+#define __NR_statmount 457 -+#define __NR_listmount 458 -+#define __NR_lsm_get_self_attr 459 -+#define __NR_lsm_set_self_attr 460 -+#define __NR_lsm_list_modules 461 -+#define __NR_mseal 462 -+ -+ -+#endif /* _ASM_UNISTD_32_H */ -diff --git a/linux-headers/asm-riscv/unistd_64.h b/linux-headers/asm-riscv/unistd_64.h -new file mode 100644 -index 0000000000..95bca8ae81 ---- /dev/null -+++ b/linux-headers/asm-riscv/unistd_64.h -@@ -0,0 +1,325 @@ -+#ifndef _ASM_UNISTD_64_H -+#define _ASM_UNISTD_64_H -+ -+#define __NR_io_setup 0 -+#define __NR_io_destroy 1 -+#define __NR_io_submit 2 -+#define __NR_io_cancel 3 -+#define __NR_io_getevents 4 -+#define __NR_setxattr 5 -+#define __NR_lsetxattr 6 -+#define __NR_fsetxattr 7 -+#define __NR_getxattr 8 -+#define __NR_lgetxattr 9 -+#define __NR_fgetxattr 10 -+#define __NR_listxattr 11 -+#define __NR_llistxattr 12 -+#define __NR_flistxattr 13 -+#define __NR_removexattr 14 -+#define __NR_lremovexattr 15 -+#define __NR_fremovexattr 16 -+#define __NR_getcwd 17 -+#define __NR_lookup_dcookie 18 -+#define __NR_eventfd2 19 -+#define __NR_epoll_create1 20 -+#define __NR_epoll_ctl 21 -+#define __NR_epoll_pwait 22 -+#define __NR_dup 23 -+#define __NR_dup3 24 -+#define __NR_fcntl 25 -+#define __NR_inotify_init1 26 -+#define __NR_inotify_add_watch 27 -+#define __NR_inotify_rm_watch 28 -+#define __NR_ioctl 29 -+#define __NR_ioprio_set 30 -+#define __NR_ioprio_get 31 -+#define __NR_flock 32 -+#define __NR_mknodat 33 -+#define __NR_mkdirat 34 -+#define __NR_unlinkat 35 -+#define __NR_symlinkat 36 -+#define __NR_linkat 37 -+#define __NR_umount2 39 -+#define __NR_mount 40 -+#define __NR_pivot_root 41 -+#define __NR_nfsservctl 42 -+#define __NR_statfs 43 -+#define __NR_fstatfs 44 -+#define __NR_truncate 45 -+#define __NR_ftruncate 46 -+#define __NR_fallocate 47 -+#define __NR_faccessat 48 -+#define __NR_chdir 49 -+#define __NR_fchdir 50 -+#define __NR_chroot 51 -+#define __NR_fchmod 52 -+#define __NR_fchmodat 53 -+#define __NR_fchownat 54 -+#define __NR_fchown 55 -+#define __NR_openat 56 -+#define __NR_close 57 -+#define __NR_vhangup 58 -+#define __NR_pipe2 59 -+#define __NR_quotactl 60 -+#define __NR_getdents64 61 -+#define __NR_lseek 62 -+#define __NR_read 63 -+#define __NR_write 64 -+#define __NR_readv 65 -+#define __NR_writev 66 -+#define __NR_pread64 67 -+#define __NR_pwrite64 68 -+#define __NR_preadv 69 -+#define __NR_pwritev 70 -+#define __NR_sendfile 71 -+#define __NR_pselect6 72 -+#define __NR_ppoll 73 -+#define __NR_signalfd4 74 -+#define __NR_vmsplice 75 -+#define __NR_splice 76 -+#define __NR_tee 77 -+#define __NR_readlinkat 78 -+#define __NR_newfstatat 79 -+#define __NR_fstat 80 -+#define __NR_sync 81 -+#define __NR_fsync 82 -+#define __NR_fdatasync 83 -+#define __NR_sync_file_range 84 -+#define __NR_timerfd_create 85 -+#define __NR_timerfd_settime 86 -+#define __NR_timerfd_gettime 87 -+#define __NR_utimensat 88 -+#define __NR_acct 89 -+#define __NR_capget 90 -+#define __NR_capset 91 -+#define __NR_personality 92 -+#define __NR_exit 93 -+#define __NR_exit_group 94 -+#define __NR_waitid 95 -+#define __NR_set_tid_address 96 -+#define __NR_unshare 97 -+#define __NR_futex 98 -+#define __NR_set_robust_list 99 -+#define __NR_get_robust_list 100 -+#define __NR_nanosleep 101 -+#define __NR_getitimer 102 -+#define __NR_setitimer 103 -+#define __NR_kexec_load 104 -+#define __NR_init_module 105 -+#define __NR_delete_module 106 -+#define __NR_timer_create 107 -+#define __NR_timer_gettime 108 -+#define __NR_timer_getoverrun 109 -+#define __NR_timer_settime 110 -+#define __NR_timer_delete 111 -+#define __NR_clock_settime 112 -+#define __NR_clock_gettime 113 -+#define __NR_clock_getres 114 -+#define __NR_clock_nanosleep 115 -+#define __NR_syslog 116 -+#define __NR_ptrace 117 -+#define __NR_sched_setparam 118 -+#define __NR_sched_setscheduler 119 -+#define __NR_sched_getscheduler 120 -+#define __NR_sched_getparam 121 -+#define __NR_sched_setaffinity 122 -+#define __NR_sched_getaffinity 123 -+#define __NR_sched_yield 124 -+#define __NR_sched_get_priority_max 125 -+#define __NR_sched_get_priority_min 126 -+#define __NR_sched_rr_get_interval 127 -+#define __NR_restart_syscall 128 -+#define __NR_kill 129 -+#define __NR_tkill 130 -+#define __NR_tgkill 131 -+#define __NR_sigaltstack 132 -+#define __NR_rt_sigsuspend 133 -+#define __NR_rt_sigaction 134 -+#define __NR_rt_sigprocmask 135 -+#define __NR_rt_sigpending 136 -+#define __NR_rt_sigtimedwait 137 -+#define __NR_rt_sigqueueinfo 138 -+#define __NR_rt_sigreturn 139 -+#define __NR_setpriority 140 -+#define __NR_getpriority 141 -+#define __NR_reboot 142 -+#define __NR_setregid 143 -+#define __NR_setgid 144 -+#define __NR_setreuid 145 -+#define __NR_setuid 146 -+#define __NR_setresuid 147 -+#define __NR_getresuid 148 -+#define __NR_setresgid 149 -+#define __NR_getresgid 150 -+#define __NR_setfsuid 151 -+#define __NR_setfsgid 152 -+#define __NR_times 153 -+#define __NR_setpgid 154 -+#define __NR_getpgid 155 -+#define __NR_getsid 156 -+#define __NR_setsid 157 -+#define __NR_getgroups 158 -+#define __NR_setgroups 159 -+#define __NR_uname 160 -+#define __NR_sethostname 161 -+#define __NR_setdomainname 162 -+#define __NR_getrlimit 163 -+#define __NR_setrlimit 164 -+#define __NR_getrusage 165 -+#define __NR_umask 166 -+#define __NR_prctl 167 -+#define __NR_getcpu 168 -+#define __NR_gettimeofday 169 -+#define __NR_settimeofday 170 -+#define __NR_adjtimex 171 -+#define __NR_getpid 172 -+#define __NR_getppid 173 -+#define __NR_getuid 174 -+#define __NR_geteuid 175 -+#define __NR_getgid 176 -+#define __NR_getegid 177 -+#define __NR_gettid 178 -+#define __NR_sysinfo 179 -+#define __NR_mq_open 180 -+#define __NR_mq_unlink 181 -+#define __NR_mq_timedsend 182 -+#define __NR_mq_timedreceive 183 -+#define __NR_mq_notify 184 -+#define __NR_mq_getsetattr 185 -+#define __NR_msgget 186 -+#define __NR_msgctl 187 -+#define __NR_msgrcv 188 -+#define __NR_msgsnd 189 -+#define __NR_semget 190 -+#define __NR_semctl 191 -+#define __NR_semtimedop 192 -+#define __NR_semop 193 -+#define __NR_shmget 194 -+#define __NR_shmctl 195 -+#define __NR_shmat 196 -+#define __NR_shmdt 197 -+#define __NR_socket 198 -+#define __NR_socketpair 199 -+#define __NR_bind 200 -+#define __NR_listen 201 -+#define __NR_accept 202 -+#define __NR_connect 203 -+#define __NR_getsockname 204 -+#define __NR_getpeername 205 -+#define __NR_sendto 206 -+#define __NR_recvfrom 207 -+#define __NR_setsockopt 208 -+#define __NR_getsockopt 209 -+#define __NR_shutdown 210 -+#define __NR_sendmsg 211 -+#define __NR_recvmsg 212 -+#define __NR_readahead 213 -+#define __NR_brk 214 -+#define __NR_munmap 215 -+#define __NR_mremap 216 -+#define __NR_add_key 217 -+#define __NR_request_key 218 -+#define __NR_keyctl 219 -+#define __NR_clone 220 -+#define __NR_execve 221 -+#define __NR_mmap 222 -+#define __NR_fadvise64 223 -+#define __NR_swapon 224 -+#define __NR_swapoff 225 -+#define __NR_mprotect 226 -+#define __NR_msync 227 -+#define __NR_mlock 228 -+#define __NR_munlock 229 -+#define __NR_mlockall 230 -+#define __NR_munlockall 231 -+#define __NR_mincore 232 -+#define __NR_madvise 233 -+#define __NR_remap_file_pages 234 -+#define __NR_mbind 235 -+#define __NR_get_mempolicy 236 -+#define __NR_set_mempolicy 237 -+#define __NR_migrate_pages 238 -+#define __NR_move_pages 239 -+#define __NR_rt_tgsigqueueinfo 240 -+#define __NR_perf_event_open 241 -+#define __NR_accept4 242 -+#define __NR_recvmmsg 243 -+#define __NR_riscv_hwprobe 258 -+#define __NR_riscv_flush_icache 259 -+#define __NR_wait4 260 -+#define __NR_prlimit64 261 -+#define __NR_fanotify_init 262 -+#define __NR_fanotify_mark 263 -+#define __NR_name_to_handle_at 264 -+#define __NR_open_by_handle_at 265 -+#define __NR_clock_adjtime 266 -+#define __NR_syncfs 267 -+#define __NR_setns 268 -+#define __NR_sendmmsg 269 -+#define __NR_process_vm_readv 270 -+#define __NR_process_vm_writev 271 -+#define __NR_kcmp 272 -+#define __NR_finit_module 273 -+#define __NR_sched_setattr 274 -+#define __NR_sched_getattr 275 -+#define __NR_renameat2 276 -+#define __NR_seccomp 277 -+#define __NR_getrandom 278 -+#define __NR_memfd_create 279 -+#define __NR_bpf 280 -+#define __NR_execveat 281 -+#define __NR_userfaultfd 282 -+#define __NR_membarrier 283 -+#define __NR_mlock2 284 -+#define __NR_copy_file_range 285 -+#define __NR_preadv2 286 -+#define __NR_pwritev2 287 -+#define __NR_pkey_mprotect 288 -+#define __NR_pkey_alloc 289 -+#define __NR_pkey_free 290 -+#define __NR_statx 291 -+#define __NR_io_pgetevents 292 -+#define __NR_rseq 293 -+#define __NR_kexec_file_load 294 -+#define __NR_pidfd_send_signal 424 -+#define __NR_io_uring_setup 425 -+#define __NR_io_uring_enter 426 -+#define __NR_io_uring_register 427 -+#define __NR_open_tree 428 -+#define __NR_move_mount 429 -+#define __NR_fsopen 430 -+#define __NR_fsconfig 431 -+#define __NR_fsmount 432 -+#define __NR_fspick 433 -+#define __NR_pidfd_open 434 -+#define __NR_clone3 435 -+#define __NR_close_range 436 -+#define __NR_openat2 437 -+#define __NR_pidfd_getfd 438 -+#define __NR_faccessat2 439 -+#define __NR_process_madvise 440 -+#define __NR_epoll_pwait2 441 -+#define __NR_mount_setattr 442 -+#define __NR_quotactl_fd 443 -+#define __NR_landlock_create_ruleset 444 -+#define __NR_landlock_add_rule 445 -+#define __NR_landlock_restrict_self 446 -+#define __NR_memfd_secret 447 -+#define __NR_process_mrelease 448 -+#define __NR_futex_waitv 449 -+#define __NR_set_mempolicy_home_node 450 -+#define __NR_cachestat 451 -+#define __NR_fchmodat2 452 -+#define __NR_map_shadow_stack 453 -+#define __NR_futex_wake 454 -+#define __NR_futex_wait 455 -+#define __NR_futex_requeue 456 -+#define __NR_statmount 457 -+#define __NR_listmount 458 -+#define __NR_lsm_get_self_attr 459 -+#define __NR_lsm_set_self_attr 460 -+#define __NR_lsm_list_modules 461 -+#define __NR_mseal 462 -+ -+ -+#endif /* _ASM_UNISTD_64_H */ -diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h -index 1c8f918234..4711ef2c3d 100644 ---- a/linux-headers/asm-x86/kvm.h -+++ b/linux-headers/asm-x86/kvm.h -@@ -106,6 +106,7 @@ struct kvm_ioapic_state { - - #define KVM_RUN_X86_SMM (1 << 0) - #define KVM_RUN_X86_BUS_LOCK (1 << 1) -+#define KVM_RUN_X86_GUEST_MODE (1 << 2) - - /* for KVM_GET_REGS and KVM_SET_REGS */ - struct kvm_regs { -@@ -436,6 +437,7 @@ struct kvm_sync_regs { - #define KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT (1 << 4) - #define KVM_X86_QUIRK_FIX_HYPERCALL_INSN (1 << 5) - #define KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS (1 << 6) -+#define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7) - - #define KVM_STATE_NESTED_FORMAT_VMX 0 - #define KVM_STATE_NESTED_FORMAT_SVM 1 -diff --git a/linux-headers/asm-x86/unistd_64.h b/linux-headers/asm-x86/unistd_64.h -index da439afee1..24c979be54 100644 ---- a/linux-headers/asm-x86/unistd_64.h -+++ b/linux-headers/asm-x86/unistd_64.h -@@ -336,6 +336,7 @@ - #define __NR_statx 332 - #define __NR_io_pgetevents 333 - #define __NR_rseq 334 -+#define __NR_uretprobe 335 - #define __NR_pidfd_send_signal 424 - #define __NR_io_uring_setup 425 - #define __NR_io_uring_enter 426 -diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h -index 4fcb607c72..c23dd21a2d 100644 ---- a/linux-headers/asm-x86/unistd_x32.h -+++ b/linux-headers/asm-x86/unistd_x32.h -@@ -289,6 +289,7 @@ - #define __NR_statx (__X32_SYSCALL_BIT + 332) - #define __NR_io_pgetevents (__X32_SYSCALL_BIT + 333) - #define __NR_rseq (__X32_SYSCALL_BIT + 334) -+#define __NR_uretprobe (__X32_SYSCALL_BIT + 335) - #define __NR_pidfd_send_signal (__X32_SYSCALL_BIT + 424) - #define __NR_io_uring_setup (__X32_SYSCALL_BIT + 425) - #define __NR_io_uring_enter (__X32_SYSCALL_BIT + 426) -diff --git a/linux-headers/linux/bits.h b/linux-headers/linux/bits.h -index d9897771be..c0d00c0a98 100644 ---- a/linux-headers/linux/bits.h -+++ b/linux-headers/linux/bits.h -@@ -12,4 +12,7 @@ - (((~_ULL(0)) - (_ULL(1) << (l)) + 1) & \ - (~_ULL(0) >> (__BITS_PER_LONG_LONG - 1 - (h)))) - -+#define __GENMASK_U128(h, l) \ -+ ((_BIT128((h)) << 1) - (_BIT128(l))) -+ - #endif /* _LINUX_BITS_H */ -diff --git a/linux-headers/linux/const.h b/linux-headers/linux/const.h -index 1eb84b5087..2122610de7 100644 ---- a/linux-headers/linux/const.h -+++ b/linux-headers/linux/const.h -@@ -28,6 +28,23 @@ - #define _BITUL(x) (_UL(1) << (x)) - #define _BITULL(x) (_ULL(1) << (x)) - -+#if !defined(__ASSEMBLY__) -+/* -+ * Missing __asm__ support -+ * -+ * __BIT128() would not work in the __asm__ code, as it shifts an -+ * 'unsigned __init128' data type as direct representation of -+ * 128 bit constants is not supported in the gcc compiler, as -+ * they get silently truncated. -+ * -+ * TODO: Please revisit this implementation when gcc compiler -+ * starts representing 128 bit constants directly like long -+ * and unsigned long etc. Subsequently drop the comment for -+ * GENMASK_U128() which would then start supporting __asm__ code. -+ */ -+#define _BIT128(x) ((unsigned __int128)(1) << (x)) -+#endif -+ - #define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (__typeof__(x))(a) - 1) - #define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) - -diff --git a/linux-headers/linux/iommufd.h b/linux-headers/linux/iommufd.h -index 72e8f4b9dd..782baf477f 100644 ---- a/linux-headers/linux/iommufd.h -+++ b/linux-headers/linux/iommufd.h -@@ -4,8 +4,8 @@ - #ifndef _IOMMUFD_H - #define _IOMMUFD_H - --#include - #include -+#include - - #define IOMMUFD_TYPE (';') - -@@ -37,19 +37,20 @@ - enum { - IOMMUFD_CMD_BASE = 0x80, - IOMMUFD_CMD_DESTROY = IOMMUFD_CMD_BASE, -- IOMMUFD_CMD_IOAS_ALLOC, -- IOMMUFD_CMD_IOAS_ALLOW_IOVAS, -- IOMMUFD_CMD_IOAS_COPY, -- IOMMUFD_CMD_IOAS_IOVA_RANGES, -- IOMMUFD_CMD_IOAS_MAP, -- IOMMUFD_CMD_IOAS_UNMAP, -- IOMMUFD_CMD_OPTION, -- IOMMUFD_CMD_VFIO_IOAS, -- IOMMUFD_CMD_HWPT_ALLOC, -- IOMMUFD_CMD_GET_HW_INFO, -- IOMMUFD_CMD_HWPT_SET_DIRTY_TRACKING, -- IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP, -- IOMMUFD_CMD_HWPT_INVALIDATE, -+ IOMMUFD_CMD_IOAS_ALLOC = 0x81, -+ IOMMUFD_CMD_IOAS_ALLOW_IOVAS = 0x82, -+ IOMMUFD_CMD_IOAS_COPY = 0x83, -+ IOMMUFD_CMD_IOAS_IOVA_RANGES = 0x84, -+ IOMMUFD_CMD_IOAS_MAP = 0x85, -+ IOMMUFD_CMD_IOAS_UNMAP = 0x86, -+ IOMMUFD_CMD_OPTION = 0x87, -+ IOMMUFD_CMD_VFIO_IOAS = 0x88, -+ IOMMUFD_CMD_HWPT_ALLOC = 0x89, -+ IOMMUFD_CMD_GET_HW_INFO = 0x8a, -+ IOMMUFD_CMD_HWPT_SET_DIRTY_TRACKING = 0x8b, -+ IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP = 0x8c, -+ IOMMUFD_CMD_HWPT_INVALIDATE = 0x8d, -+ IOMMUFD_CMD_FAULT_QUEUE_ALLOC = 0x8e, - }; - - /** -@@ -356,10 +357,13 @@ struct iommu_vfio_ioas { - * the parent HWPT in a nesting configuration. - * @IOMMU_HWPT_ALLOC_DIRTY_TRACKING: Dirty tracking support for device IOMMU is - * enforced on device attachment -+ * @IOMMU_HWPT_FAULT_ID_VALID: The fault_id field of hwpt allocation data is -+ * valid. - */ - enum iommufd_hwpt_alloc_flags { - IOMMU_HWPT_ALLOC_NEST_PARENT = 1 << 0, - IOMMU_HWPT_ALLOC_DIRTY_TRACKING = 1 << 1, -+ IOMMU_HWPT_FAULT_ID_VALID = 1 << 2, - }; - - /** -@@ -396,8 +400,8 @@ struct iommu_hwpt_vtd_s1 { - * @IOMMU_HWPT_DATA_VTD_S1: Intel VT-d stage-1 page table - */ - enum iommu_hwpt_data_type { -- IOMMU_HWPT_DATA_NONE, -- IOMMU_HWPT_DATA_VTD_S1, -+ IOMMU_HWPT_DATA_NONE = 0, -+ IOMMU_HWPT_DATA_VTD_S1 = 1, - }; - - /** -@@ -411,6 +415,9 @@ enum iommu_hwpt_data_type { - * @data_type: One of enum iommu_hwpt_data_type - * @data_len: Length of the type specific data - * @data_uptr: User pointer to the type specific data -+ * @fault_id: The ID of IOMMUFD_FAULT object. Valid only if flags field of -+ * IOMMU_HWPT_FAULT_ID_VALID is set. -+ * @__reserved2: Padding to 64-bit alignment. Must be 0. - * - * Explicitly allocate a hardware page table object. This is the same object - * type that is returned by iommufd_device_attach() and represents the -@@ -441,6 +448,8 @@ struct iommu_hwpt_alloc { - __u32 data_type; - __u32 data_len; - __aligned_u64 data_uptr; -+ __u32 fault_id; -+ __u32 __reserved2; - }; - #define IOMMU_HWPT_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_ALLOC) - -@@ -482,8 +491,8 @@ struct iommu_hw_info_vtd { - * @IOMMU_HW_INFO_TYPE_INTEL_VTD: Intel VT-d iommu info type - */ - enum iommu_hw_info_type { -- IOMMU_HW_INFO_TYPE_NONE, -- IOMMU_HW_INFO_TYPE_INTEL_VTD, -+ IOMMU_HW_INFO_TYPE_NONE = 0, -+ IOMMU_HW_INFO_TYPE_INTEL_VTD = 1, - }; - - /** -@@ -620,7 +629,7 @@ struct iommu_hwpt_get_dirty_bitmap { - * @IOMMU_HWPT_INVALIDATE_DATA_VTD_S1: Invalidation data for VTD_S1 - */ - enum iommu_hwpt_invalidate_data_type { -- IOMMU_HWPT_INVALIDATE_DATA_VTD_S1, -+ IOMMU_HWPT_INVALIDATE_DATA_VTD_S1 = 0, - }; - - /** -@@ -692,4 +701,100 @@ struct iommu_hwpt_invalidate { - __u32 __reserved; - }; - #define IOMMU_HWPT_INVALIDATE _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_INVALIDATE) -+ -+/** -+ * enum iommu_hwpt_pgfault_flags - flags for struct iommu_hwpt_pgfault -+ * @IOMMU_PGFAULT_FLAGS_PASID_VALID: The pasid field of the fault data is -+ * valid. -+ * @IOMMU_PGFAULT_FLAGS_LAST_PAGE: It's the last fault of a fault group. -+ */ -+enum iommu_hwpt_pgfault_flags { -+ IOMMU_PGFAULT_FLAGS_PASID_VALID = (1 << 0), -+ IOMMU_PGFAULT_FLAGS_LAST_PAGE = (1 << 1), -+}; -+ -+/** -+ * enum iommu_hwpt_pgfault_perm - perm bits for struct iommu_hwpt_pgfault -+ * @IOMMU_PGFAULT_PERM_READ: request for read permission -+ * @IOMMU_PGFAULT_PERM_WRITE: request for write permission -+ * @IOMMU_PGFAULT_PERM_EXEC: (PCIE 10.4.1) request with a PASID that has the -+ * Execute Requested bit set in PASID TLP Prefix. -+ * @IOMMU_PGFAULT_PERM_PRIV: (PCIE 10.4.1) request with a PASID that has the -+ * Privileged Mode Requested bit set in PASID TLP -+ * Prefix. -+ */ -+enum iommu_hwpt_pgfault_perm { -+ IOMMU_PGFAULT_PERM_READ = (1 << 0), -+ IOMMU_PGFAULT_PERM_WRITE = (1 << 1), -+ IOMMU_PGFAULT_PERM_EXEC = (1 << 2), -+ IOMMU_PGFAULT_PERM_PRIV = (1 << 3), -+}; -+ -+/** -+ * struct iommu_hwpt_pgfault - iommu page fault data -+ * @flags: Combination of enum iommu_hwpt_pgfault_flags -+ * @dev_id: id of the originated device -+ * @pasid: Process Address Space ID -+ * @grpid: Page Request Group Index -+ * @perm: Combination of enum iommu_hwpt_pgfault_perm -+ * @addr: Fault address -+ * @length: a hint of how much data the requestor is expecting to fetch. For -+ * example, if the PRI initiator knows it is going to do a 10MB -+ * transfer, it could fill in 10MB and the OS could pre-fault in -+ * 10MB of IOVA. It's default to 0 if there's no such hint. -+ * @cookie: kernel-managed cookie identifying a group of fault messages. The -+ * cookie number encoded in the last page fault of the group should -+ * be echoed back in the response message. -+ */ -+struct iommu_hwpt_pgfault { -+ __u32 flags; -+ __u32 dev_id; -+ __u32 pasid; -+ __u32 grpid; -+ __u32 perm; -+ __u64 addr; -+ __u32 length; -+ __u32 cookie; -+}; -+ -+/** -+ * enum iommufd_page_response_code - Return status of fault handlers -+ * @IOMMUFD_PAGE_RESP_SUCCESS: Fault has been handled and the page tables -+ * populated, retry the access. This is the -+ * "Success" defined in PCI 10.4.2.1. -+ * @IOMMUFD_PAGE_RESP_INVALID: Could not handle this fault, don't retry the -+ * access. This is the "Invalid Request" in PCI -+ * 10.4.2.1. -+ */ -+enum iommufd_page_response_code { -+ IOMMUFD_PAGE_RESP_SUCCESS = 0, -+ IOMMUFD_PAGE_RESP_INVALID = 1, -+}; -+ -+/** -+ * struct iommu_hwpt_page_response - IOMMU page fault response -+ * @cookie: The kernel-managed cookie reported in the fault message. -+ * @code: One of response code in enum iommufd_page_response_code. -+ */ -+struct iommu_hwpt_page_response { -+ __u32 cookie; -+ __u32 code; -+}; -+ -+/** -+ * struct iommu_fault_alloc - ioctl(IOMMU_FAULT_QUEUE_ALLOC) -+ * @size: sizeof(struct iommu_fault_alloc) -+ * @flags: Must be 0 -+ * @out_fault_id: The ID of the new FAULT -+ * @out_fault_fd: The fd of the new FAULT -+ * -+ * Explicitly allocate a fault handling object. -+ */ -+struct iommu_fault_alloc { -+ __u32 size; -+ __u32 flags; -+ __u32 out_fault_id; -+ __u32 out_fault_fd; -+}; -+#define IOMMU_FAULT_QUEUE_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_FAULT_QUEUE_ALLOC) - #endif -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index c93876ca0b..49dd1b30ce 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -192,11 +192,20 @@ struct kvm_xen_exit { - /* Flags that describe what fields in emulation_failure hold valid data. */ - #define KVM_INTERNAL_ERROR_EMULATION_FLAG_INSTRUCTION_BYTES (1ULL << 0) - -+/* -+ * struct kvm_run can be modified by userspace at any time, so KVM must be -+ * careful to avoid TOCTOU bugs. In order to protect KVM, HINT_UNSAFE_IN_KVM() -+ * renames fields in struct kvm_run from to __unsafe when -+ * compiled into the kernel, ensuring that any use within KVM is obvious and -+ * gets extra scrutiny. -+ */ -+#define HINT_UNSAFE_IN_KVM(_symbol) _symbol -+ - /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ - struct kvm_run { - /* in */ - __u8 request_interrupt_window; -- __u8 immediate_exit; -+ __u8 HINT_UNSAFE_IN_KVM(immediate_exit); - __u8 padding1[6]; - - /* out */ -@@ -913,6 +922,9 @@ struct kvm_enable_cap { - #define KVM_CAP_MEMORY_ATTRIBUTES 233 - #define KVM_CAP_GUEST_MEMFD 234 - #define KVM_CAP_VM_TYPES 235 -+#define KVM_CAP_PRE_FAULT_MEMORY 236 -+#define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237 -+#define KVM_CAP_X86_GUEST_MODE 238 - - struct kvm_irq_routing_irqchip { - __u32 irqchip; -@@ -1544,4 +1556,13 @@ struct kvm_create_guest_memfd { - __u64 reserved[6]; - }; - -+#define KVM_PRE_FAULT_MEMORY _IOWR(KVMIO, 0xd5, struct kvm_pre_fault_memory) -+ -+struct kvm_pre_fault_memory { -+ __u64 gpa; -+ __u64 size; -+ __u64 flags; -+ __u64 padding[5]; -+}; -+ - #endif /* __LINUX_KVM_H */ -diff --git a/linux-headers/linux/mman.h b/linux-headers/linux/mman.h -index 4e8cb60780..2b83059586 100644 ---- a/linux-headers/linux/mman.h -+++ b/linux-headers/linux/mman.h -@@ -17,6 +17,7 @@ - #define MAP_SHARED 0x01 /* Share changes */ - #define MAP_PRIVATE 0x02 /* Changes are private */ - #define MAP_SHARED_VALIDATE 0x03 /* share + validate extension flags */ -+#define MAP_DROPPABLE 0x08 /* Zero memory under memory pressure. */ - - /* - * Huge page size encoding when MAP_HUGETLB is specified, and a huge page -diff --git a/linux-headers/linux/psp-sev.h b/linux-headers/linux/psp-sev.h -index c3046c6bff..17bf191573 100644 ---- a/linux-headers/linux/psp-sev.h -+++ b/linux-headers/linux/psp-sev.h -@@ -31,6 +31,7 @@ enum { - SNP_PLATFORM_STATUS, - SNP_COMMIT, - SNP_SET_CONFIG, -+ SNP_VLEK_LOAD, - - SEV_MAX, - }; -@@ -50,6 +51,7 @@ typedef enum { - SEV_RET_INVALID_PLATFORM_STATE, - SEV_RET_INVALID_GUEST_STATE, - SEV_RET_INAVLID_CONFIG, -+ SEV_RET_INVALID_CONFIG = SEV_RET_INAVLID_CONFIG, - SEV_RET_INVALID_LEN, - SEV_RET_ALREADY_OWNED, - SEV_RET_INVALID_CERTIFICATE, -@@ -214,6 +216,32 @@ struct sev_user_data_snp_config { - __u8 rsvd1[52]; - } __attribute__((packed)); - -+/** -+ * struct sev_data_snp_vlek_load - SNP_VLEK_LOAD structure -+ * -+ * @len: length of the command buffer read by the PSP -+ * @vlek_wrapped_version: version of wrapped VLEK hashstick (Must be 0h) -+ * @rsvd: reserved -+ * @vlek_wrapped_address: address of a wrapped VLEK hashstick -+ * (struct sev_user_data_snp_wrapped_vlek_hashstick) -+ */ -+struct sev_user_data_snp_vlek_load { -+ __u32 len; /* In */ -+ __u8 vlek_wrapped_version; /* In */ -+ __u8 rsvd[3]; /* In */ -+ __u64 vlek_wrapped_address; /* In */ -+} __attribute__((packed)); -+ -+/** -+ * struct sev_user_data_snp_vlek_wrapped_vlek_hashstick - Wrapped VLEK data -+ * -+ * @data: Opaque data provided by AMD KDS (as described in SEV-SNP Firmware ABI -+ * 1.54, SNP_VLEK_LOAD) -+ */ -+struct sev_user_data_snp_wrapped_vlek_hashstick { -+ __u8 data[432]; /* In */ -+} __attribute__((packed)); -+ - /** - * struct sev_issue_cmd - SEV ioctl parameters - * --- -2.39.3 - diff --git a/kvm-linux-headers-Update-to-Linux-v6.15-rc3.patch b/kvm-linux-headers-Update-to-Linux-v6.15-rc3.patch new file mode 100644 index 0000000..ac99e01 --- /dev/null +++ b/kvm-linux-headers-Update-to-Linux-v6.15-rc3.patch @@ -0,0 +1,941 @@ +From 3ede0386035f7ce77bdeef7145a902a79f6e1dfe Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:45 +0200 +Subject: [PATCH 012/100] linux-headers: Update to Linux v6.15-rc3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Update headers to retrieve uapi information for vfio-ap + +Signed-off-by: Rorie Reyes +Reviewed-by: CĂ©dric Le Goater +Link: https://lore.kernel.org/qemu-devel/20250425052401.8287-3-rreyes@linux.ibm.com +Signed-off-by: CĂ©dric Le Goater +(cherry picked from commit 1cab5a02ab8144aad2abd001835e49104e4aae0f) +Signed-off-by: Paolo Bonzini +--- + include/standard-headers/asm-x86/setup_data.h | 4 +- + include/standard-headers/drm/drm_fourcc.h | 41 ++++++ + include/standard-headers/linux/const.h | 2 +- + include/standard-headers/linux/ethtool.h | 22 +++ + include/standard-headers/linux/fuse.h | 12 +- + include/standard-headers/linux/pci_regs.h | 13 +- + include/standard-headers/linux/virtio_net.h | 13 ++ + include/standard-headers/linux/virtio_snd.h | 2 +- + linux-headers/asm-arm64/kvm.h | 11 ++ + linux-headers/asm-arm64/unistd_64.h | 1 + + linux-headers/asm-generic/mman-common.h | 1 + + linux-headers/asm-generic/unistd.h | 4 +- + linux-headers/asm-loongarch/unistd_64.h | 1 + + linux-headers/asm-mips/unistd_n32.h | 1 + + linux-headers/asm-mips/unistd_n64.h | 1 + + linux-headers/asm-mips/unistd_o32.h | 1 + + linux-headers/asm-powerpc/unistd_32.h | 1 + + linux-headers/asm-powerpc/unistd_64.h | 1 + + linux-headers/asm-riscv/kvm.h | 2 + + linux-headers/asm-riscv/unistd_32.h | 1 + + linux-headers/asm-riscv/unistd_64.h | 1 + + linux-headers/asm-s390/unistd_32.h | 1 + + linux-headers/asm-s390/unistd_64.h | 1 + + linux-headers/asm-x86/kvm.h | 3 + + linux-headers/asm-x86/unistd_32.h | 1 + + linux-headers/asm-x86/unistd_64.h | 1 + + linux-headers/asm-x86/unistd_x32.h | 1 + + linux-headers/linux/bits.h | 8 +- + linux-headers/linux/const.h | 2 +- + linux-headers/linux/iommufd.h | 129 +++++++++++++++++- + linux-headers/linux/kvm.h | 1 + + linux-headers/linux/psp-sev.h | 21 ++- + linux-headers/linux/stddef.h | 2 + + linux-headers/linux/vfio.h | 30 ++-- + 34 files changed, 301 insertions(+), 36 deletions(-) + +diff --git a/include/standard-headers/asm-x86/setup_data.h b/include/standard-headers/asm-x86/setup_data.h +index 09355f54c5..a483d72f42 100644 +--- a/include/standard-headers/asm-x86/setup_data.h ++++ b/include/standard-headers/asm-x86/setup_data.h +@@ -18,7 +18,7 @@ + #define SETUP_INDIRECT (1<<31) + #define SETUP_TYPE_MAX (SETUP_ENUM_MAX | SETUP_INDIRECT) + +-#ifndef __ASSEMBLY__ ++#ifndef __ASSEMBLER__ + + #include "standard-headers/linux/types.h" + +@@ -78,6 +78,6 @@ struct ima_setup_data { + uint64_t size; + } QEMU_PACKED; + +-#endif /* __ASSEMBLY__ */ ++#endif /* __ASSEMBLER__ */ + + #endif /* _ASM_X86_SETUP_DATA_H */ +diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h +index 708647776f..a8b759dcbc 100644 +--- a/include/standard-headers/drm/drm_fourcc.h ++++ b/include/standard-headers/drm/drm_fourcc.h +@@ -420,6 +420,7 @@ extern "C" { + #define DRM_FORMAT_MOD_VENDOR_ARM 0x08 + #define DRM_FORMAT_MOD_VENDOR_ALLWINNER 0x09 + #define DRM_FORMAT_MOD_VENDOR_AMLOGIC 0x0a ++#define DRM_FORMAT_MOD_VENDOR_MTK 0x0b + + /* add more to the end as needed */ + +@@ -1452,6 +1453,46 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) + */ + #define AMLOGIC_FBC_OPTION_MEM_SAVING (1ULL << 0) + ++/* MediaTek modifiers ++ * Bits Parameter Notes ++ * ----- ------------------------ --------------------------------------------- ++ * 7: 0 TILE LAYOUT Values are MTK_FMT_MOD_TILE_* ++ * 15: 8 COMPRESSION Values are MTK_FMT_MOD_COMPRESS_* ++ * 23:16 10 BIT LAYOUT Values are MTK_FMT_MOD_10BIT_LAYOUT_* ++ * ++ */ ++ ++#define DRM_FORMAT_MOD_MTK(__flags) fourcc_mod_code(MTK, __flags) ++ ++/* ++ * MediaTek Tiled Modifier ++ * The lowest 8 bits of the modifier is used to specify the tiling ++ * layout. Only the 16L_32S tiling is used for now, but we define an ++ * "untiled" version and leave room for future expansion. ++ */ ++#define MTK_FMT_MOD_TILE_MASK 0xf ++#define MTK_FMT_MOD_TILE_NONE 0x0 ++#define MTK_FMT_MOD_TILE_16L32S 0x1 ++ ++/* ++ * Bits 8-15 specify compression options ++ */ ++#define MTK_FMT_MOD_COMPRESS_MASK (0xf << 8) ++#define MTK_FMT_MOD_COMPRESS_NONE (0x0 << 8) ++#define MTK_FMT_MOD_COMPRESS_V1 (0x1 << 8) ++ ++/* ++ * Bits 16-23 specify how the bits of 10 bit formats are ++ * stored out in memory ++ */ ++#define MTK_FMT_MOD_10BIT_LAYOUT_MASK (0xf << 16) ++#define MTK_FMT_MOD_10BIT_LAYOUT_PACKED (0x0 << 16) ++#define MTK_FMT_MOD_10BIT_LAYOUT_LSBTILED (0x1 << 16) ++#define MTK_FMT_MOD_10BIT_LAYOUT_LSBRASTER (0x2 << 16) ++ ++/* alias for the most common tiling format */ ++#define DRM_FORMAT_MOD_MTK_16L_32S_TILE DRM_FORMAT_MOD_MTK(MTK_FMT_MOD_TILE_16L32S) ++ + /* + * AMD modifiers + * +diff --git a/include/standard-headers/linux/const.h b/include/standard-headers/linux/const.h +index 2122610de7..95ede23342 100644 +--- a/include/standard-headers/linux/const.h ++++ b/include/standard-headers/linux/const.h +@@ -33,7 +33,7 @@ + * Missing __asm__ support + * + * __BIT128() would not work in the __asm__ code, as it shifts an +- * 'unsigned __init128' data type as direct representation of ++ * 'unsigned __int128' data type as direct representation of + * 128 bit constants is not supported in the gcc compiler, as + * they get silently truncated. + * +diff --git a/include/standard-headers/linux/ethtool.h b/include/standard-headers/linux/ethtool.h +index e83382531c..5d1ad5fdea 100644 +--- a/include/standard-headers/linux/ethtool.h ++++ b/include/standard-headers/linux/ethtool.h +@@ -2059,6 +2059,24 @@ enum ethtool_link_mode_bit_indices { + ETHTOOL_LINK_MODE_10baseT1S_Half_BIT = 100, + ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT = 101, + ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT = 102, ++ ETHTOOL_LINK_MODE_200000baseCR_Full_BIT = 103, ++ ETHTOOL_LINK_MODE_200000baseKR_Full_BIT = 104, ++ ETHTOOL_LINK_MODE_200000baseDR_Full_BIT = 105, ++ ETHTOOL_LINK_MODE_200000baseDR_2_Full_BIT = 106, ++ ETHTOOL_LINK_MODE_200000baseSR_Full_BIT = 107, ++ ETHTOOL_LINK_MODE_200000baseVR_Full_BIT = 108, ++ ETHTOOL_LINK_MODE_400000baseCR2_Full_BIT = 109, ++ ETHTOOL_LINK_MODE_400000baseKR2_Full_BIT = 110, ++ ETHTOOL_LINK_MODE_400000baseDR2_Full_BIT = 111, ++ ETHTOOL_LINK_MODE_400000baseDR2_2_Full_BIT = 112, ++ ETHTOOL_LINK_MODE_400000baseSR2_Full_BIT = 113, ++ ETHTOOL_LINK_MODE_400000baseVR2_Full_BIT = 114, ++ ETHTOOL_LINK_MODE_800000baseCR4_Full_BIT = 115, ++ ETHTOOL_LINK_MODE_800000baseKR4_Full_BIT = 116, ++ ETHTOOL_LINK_MODE_800000baseDR4_Full_BIT = 117, ++ ETHTOOL_LINK_MODE_800000baseDR4_2_Full_BIT = 118, ++ ETHTOOL_LINK_MODE_800000baseSR4_Full_BIT = 119, ++ ETHTOOL_LINK_MODE_800000baseVR4_Full_BIT = 120, + + /* must be last entry */ + __ETHTOOL_LINK_MODE_MASK_NBITS +@@ -2271,6 +2289,10 @@ static inline int ethtool_validate_duplex(uint8_t duplex) + * be exploited to reduce the RSS queue spread. + */ + #define RXH_XFRM_SYM_XOR (1 << 0) ++/* Similar to SYM_XOR, except that one copy of the XOR'ed fields is replaced by ++ * an OR of the same fields ++ */ ++#define RXH_XFRM_SYM_OR_XOR (1 << 1) + #define RXH_XFRM_NO_CHANGE 0xff + + /* L2-L4 network traffic flow types */ +diff --git a/include/standard-headers/linux/fuse.h b/include/standard-headers/linux/fuse.h +index d303effb2a..a2b5815d89 100644 +--- a/include/standard-headers/linux/fuse.h ++++ b/include/standard-headers/linux/fuse.h +@@ -229,6 +229,9 @@ + * - FUSE_URING_IN_OUT_HEADER_SZ + * - FUSE_URING_OP_IN_OUT_SZ + * - enum fuse_uring_cmd ++ * ++ * 7.43 ++ * - add FUSE_REQUEST_TIMEOUT + */ + + #ifndef _LINUX_FUSE_H +@@ -260,7 +263,7 @@ + #define FUSE_KERNEL_VERSION 7 + + /** Minor version number of this interface */ +-#define FUSE_KERNEL_MINOR_VERSION 42 ++#define FUSE_KERNEL_MINOR_VERSION 43 + + /** The node ID of the root inode */ + #define FUSE_ROOT_ID 1 +@@ -431,6 +434,8 @@ struct fuse_file_lock { + * of the request ID indicates resend requests + * FUSE_ALLOW_IDMAP: allow creation of idmapped mounts + * FUSE_OVER_IO_URING: Indicate that client supports io-uring ++ * FUSE_REQUEST_TIMEOUT: kernel supports timing out requests. ++ * init_out.request_timeout contains the timeout (in secs) + */ + #define FUSE_ASYNC_READ (1 << 0) + #define FUSE_POSIX_LOCKS (1 << 1) +@@ -473,11 +478,11 @@ struct fuse_file_lock { + #define FUSE_PASSTHROUGH (1ULL << 37) + #define FUSE_NO_EXPORT_SUPPORT (1ULL << 38) + #define FUSE_HAS_RESEND (1ULL << 39) +- + /* Obsolete alias for FUSE_DIRECT_IO_ALLOW_MMAP */ + #define FUSE_DIRECT_IO_RELAX FUSE_DIRECT_IO_ALLOW_MMAP + #define FUSE_ALLOW_IDMAP (1ULL << 40) + #define FUSE_OVER_IO_URING (1ULL << 41) ++#define FUSE_REQUEST_TIMEOUT (1ULL << 42) + + /** + * CUSE INIT request/reply flags +@@ -905,7 +910,8 @@ struct fuse_init_out { + uint16_t map_alignment; + uint32_t flags2; + uint32_t max_stack_depth; +- uint32_t unused[6]; ++ uint16_t request_timeout; ++ uint16_t unused[11]; + }; + + #define CUSE_INIT_INFO_MAX 4096 +diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h +index 3445c4970e..ba326710f9 100644 +--- a/include/standard-headers/linux/pci_regs.h ++++ b/include/standard-headers/linux/pci_regs.h +@@ -486,6 +486,7 @@ + #define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */ + #define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */ + #define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */ ++#define PCI_EXP_FLAGS_FLIT 0x8000 /* Flit Mode Supported */ + #define PCI_EXP_DEVCAP 0x04 /* Device capabilities */ + #define PCI_EXP_DEVCAP_PAYLOAD 0x00000007 /* Max_Payload_Size */ + #define PCI_EXP_DEVCAP_PHANTOM 0x00000018 /* Phantom functions */ +@@ -795,6 +796,8 @@ + #define PCI_ERR_CAP_ECRC_CHKC 0x00000080 /* ECRC Check Capable */ + #define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */ + #define PCI_ERR_CAP_PREFIX_LOG_PRESENT 0x00000800 /* TLP Prefix Log Present */ ++#define PCI_ERR_CAP_TLP_LOG_FLIT 0x00040000 /* TLP was logged in Flit Mode */ ++#define PCI_ERR_CAP_TLP_LOG_SIZE 0x00f80000 /* Logged TLP Size (only in Flit mode) */ + #define PCI_ERR_HEADER_LOG 0x1c /* Header Log Register (16 bytes) */ + #define PCI_ERR_ROOT_COMMAND 0x2c /* Root Error Command */ + #define PCI_ERR_ROOT_CMD_COR_EN 0x00000001 /* Correctable Err Reporting Enable */ +@@ -1013,7 +1016,7 @@ + + /* Resizable BARs */ + #define PCI_REBAR_CAP 4 /* capability register */ +-#define PCI_REBAR_CAP_SIZES 0x00FFFFF0 /* supported BAR sizes */ ++#define PCI_REBAR_CAP_SIZES 0xFFFFFFF0 /* supported BAR sizes */ + #define PCI_REBAR_CTRL 8 /* control register */ + #define PCI_REBAR_CTRL_BAR_IDX 0x00000007 /* BAR index */ + #define PCI_REBAR_CTRL_NBAR_MASK 0x000000E0 /* # of resizable BARs */ +@@ -1061,8 +1064,9 @@ + #define PCI_EXP_DPC_CAP_RP_EXT 0x0020 /* Root Port Extensions */ + #define PCI_EXP_DPC_CAP_POISONED_TLP 0x0040 /* Poisoned TLP Egress Blocking Supported */ + #define PCI_EXP_DPC_CAP_SW_TRIGGER 0x0080 /* Software Triggering Supported */ +-#define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0x0F00 /* RP PIO Log Size */ ++#define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0x0F00 /* RP PIO Log Size [3:0] */ + #define PCI_EXP_DPC_CAP_DL_ACTIVE 0x1000 /* ERR_COR signal on DL_Active supported */ ++#define PCI_EXP_DPC_RP_PIO_LOG_SIZE4 0x2000 /* RP PIO Log Size [4] */ + + #define PCI_EXP_DPC_CTL 0x06 /* DPC control */ + #define PCI_EXP_DPC_CTL_EN_FATAL 0x0001 /* Enable trigger on ERR_FATAL message */ +@@ -1205,9 +1209,12 @@ + #define PCI_DOE_DATA_OBJECT_DISC_REQ_3_INDEX 0x000000ff + #define PCI_DOE_DATA_OBJECT_DISC_REQ_3_VER 0x0000ff00 + #define PCI_DOE_DATA_OBJECT_DISC_RSP_3_VID 0x0000ffff +-#define PCI_DOE_DATA_OBJECT_DISC_RSP_3_PROTOCOL 0x00ff0000 ++#define PCI_DOE_DATA_OBJECT_DISC_RSP_3_TYPE 0x00ff0000 + #define PCI_DOE_DATA_OBJECT_DISC_RSP_3_NEXT_INDEX 0xff000000 + ++/* Deprecated old name, replaced with PCI_DOE_DATA_OBJECT_DISC_RSP_3_TYPE */ ++#define PCI_DOE_DATA_OBJECT_DISC_RSP_3_PROTOCOL PCI_DOE_DATA_OBJECT_DISC_RSP_3_TYPE ++ + /* Compute Express Link (CXL r3.1, sec 8.1.5) */ + #define PCI_DVSEC_CXL_PORT 3 + #define PCI_DVSEC_CXL_PORT_CTL 0x0c +diff --git a/include/standard-headers/linux/virtio_net.h b/include/standard-headers/linux/virtio_net.h +index fc594fe5fc..982e854f14 100644 +--- a/include/standard-headers/linux/virtio_net.h ++++ b/include/standard-headers/linux/virtio_net.h +@@ -327,6 +327,19 @@ struct virtio_net_rss_config { + uint8_t hash_key_data[/* hash_key_length */]; + }; + ++struct virtio_net_rss_config_hdr { ++ uint32_t hash_types; ++ uint16_t indirection_table_mask; ++ uint16_t unclassified_queue; ++ uint16_t indirection_table[/* 1 + indirection_table_mask */]; ++}; ++ ++struct virtio_net_rss_config_trailer { ++ uint16_t max_tx_vq; ++ uint8_t hash_key_length; ++ uint8_t hash_key_data[/* hash_key_length */]; ++}; ++ + #define VIRTIO_NET_CTRL_MQ_RSS_CONFIG 1 + + /* +diff --git a/include/standard-headers/linux/virtio_snd.h b/include/standard-headers/linux/virtio_snd.h +index 860f12e0a4..160d57899f 100644 +--- a/include/standard-headers/linux/virtio_snd.h ++++ b/include/standard-headers/linux/virtio_snd.h +@@ -25,7 +25,7 @@ struct virtio_snd_config { + uint32_t streams; + /* # of available channel maps */ + uint32_t chmaps; +- /* # of available control elements */ ++ /* # of available control elements (if VIRTIO_SND_F_CTLS) */ + uint32_t controls; + }; + +diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h +index ec1e82bdc8..4e6aff08df 100644 +--- a/linux-headers/asm-arm64/kvm.h ++++ b/linux-headers/asm-arm64/kvm.h +@@ -105,6 +105,7 @@ struct kvm_regs { + #define KVM_ARM_VCPU_PTRAUTH_ADDRESS 5 /* VCPU uses address authentication */ + #define KVM_ARM_VCPU_PTRAUTH_GENERIC 6 /* VCPU uses generic authentication */ + #define KVM_ARM_VCPU_HAS_EL2 7 /* Support nested virtualization */ ++#define KVM_ARM_VCPU_HAS_EL2_E2H0 8 /* Limit NV support to E2H RES0 */ + + struct kvm_vcpu_init { + __u32 target; +@@ -365,6 +366,7 @@ enum { + KVM_REG_ARM_STD_HYP_BIT_PV_TIME = 0, + }; + ++/* Vendor hyper call function numbers 0-63 */ + #define KVM_REG_ARM_VENDOR_HYP_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(2) + + enum { +@@ -372,6 +374,14 @@ enum { + KVM_REG_ARM_VENDOR_HYP_BIT_PTP = 1, + }; + ++/* Vendor hyper call function numbers 64-127 */ ++#define KVM_REG_ARM_VENDOR_HYP_BMAP_2 KVM_REG_ARM_FW_FEAT_BMAP_REG(3) ++ ++enum { ++ KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_VER = 0, ++ KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_CPUS = 1, ++}; ++ + /* Device Control API on vm fd */ + #define KVM_ARM_VM_SMCCC_CTRL 0 + #define KVM_ARM_VM_SMCCC_FILTER 0 +@@ -394,6 +404,7 @@ enum { + #define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6 + #define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7 + #define KVM_DEV_ARM_VGIC_GRP_ITS_REGS 8 ++#define KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ 9 + #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT 10 + #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \ + (0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT) +diff --git a/linux-headers/asm-arm64/unistd_64.h b/linux-headers/asm-arm64/unistd_64.h +index d4e90fff76..ee9aaebdf3 100644 +--- a/linux-headers/asm-arm64/unistd_64.h ++++ b/linux-headers/asm-arm64/unistd_64.h +@@ -323,6 +323,7 @@ + #define __NR_getxattrat 464 + #define __NR_listxattrat 465 + #define __NR_removexattrat 466 ++#define __NR_open_tree_attr 467 + + + #endif /* _ASM_UNISTD_64_H */ +diff --git a/linux-headers/asm-generic/mman-common.h b/linux-headers/asm-generic/mman-common.h +index 1ea2c4c33b..ef1c27fa3c 100644 +--- a/linux-headers/asm-generic/mman-common.h ++++ b/linux-headers/asm-generic/mman-common.h +@@ -85,6 +85,7 @@ + /* compatibility flags */ + #define MAP_FILE 0 + ++#define PKEY_UNRESTRICTED 0x0 + #define PKEY_DISABLE_ACCESS 0x1 + #define PKEY_DISABLE_WRITE 0x2 + #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ +diff --git a/linux-headers/asm-generic/unistd.h b/linux-headers/asm-generic/unistd.h +index 88dc393c2b..2892a45023 100644 +--- a/linux-headers/asm-generic/unistd.h ++++ b/linux-headers/asm-generic/unistd.h +@@ -849,9 +849,11 @@ __SYSCALL(__NR_getxattrat, sys_getxattrat) + __SYSCALL(__NR_listxattrat, sys_listxattrat) + #define __NR_removexattrat 466 + __SYSCALL(__NR_removexattrat, sys_removexattrat) ++#define __NR_open_tree_attr 467 ++__SYSCALL(__NR_open_tree_attr, sys_open_tree_attr) + + #undef __NR_syscalls +-#define __NR_syscalls 467 ++#define __NR_syscalls 468 + + /* + * 32 bit systems traditionally used different +diff --git a/linux-headers/asm-loongarch/unistd_64.h b/linux-headers/asm-loongarch/unistd_64.h +index 23fb96a8a7..50d22df8f7 100644 +--- a/linux-headers/asm-loongarch/unistd_64.h ++++ b/linux-headers/asm-loongarch/unistd_64.h +@@ -319,6 +319,7 @@ + #define __NR_getxattrat 464 + #define __NR_listxattrat 465 + #define __NR_removexattrat 466 ++#define __NR_open_tree_attr 467 + + + #endif /* _ASM_UNISTD_64_H */ +diff --git a/linux-headers/asm-mips/unistd_n32.h b/linux-headers/asm-mips/unistd_n32.h +index 9a75719644..bdcc2f460b 100644 +--- a/linux-headers/asm-mips/unistd_n32.h ++++ b/linux-headers/asm-mips/unistd_n32.h +@@ -395,5 +395,6 @@ + #define __NR_getxattrat (__NR_Linux + 464) + #define __NR_listxattrat (__NR_Linux + 465) + #define __NR_removexattrat (__NR_Linux + 466) ++#define __NR_open_tree_attr (__NR_Linux + 467) + + #endif /* _ASM_UNISTD_N32_H */ +diff --git a/linux-headers/asm-mips/unistd_n64.h b/linux-headers/asm-mips/unistd_n64.h +index 7086783b0c..3b6b0193b6 100644 +--- a/linux-headers/asm-mips/unistd_n64.h ++++ b/linux-headers/asm-mips/unistd_n64.h +@@ -371,5 +371,6 @@ + #define __NR_getxattrat (__NR_Linux + 464) + #define __NR_listxattrat (__NR_Linux + 465) + #define __NR_removexattrat (__NR_Linux + 466) ++#define __NR_open_tree_attr (__NR_Linux + 467) + + #endif /* _ASM_UNISTD_N64_H */ +diff --git a/linux-headers/asm-mips/unistd_o32.h b/linux-headers/asm-mips/unistd_o32.h +index b3825823e4..4609a4b4d3 100644 +--- a/linux-headers/asm-mips/unistd_o32.h ++++ b/linux-headers/asm-mips/unistd_o32.h +@@ -441,5 +441,6 @@ + #define __NR_getxattrat (__NR_Linux + 464) + #define __NR_listxattrat (__NR_Linux + 465) + #define __NR_removexattrat (__NR_Linux + 466) ++#define __NR_open_tree_attr (__NR_Linux + 467) + + #endif /* _ASM_UNISTD_O32_H */ +diff --git a/linux-headers/asm-powerpc/unistd_32.h b/linux-headers/asm-powerpc/unistd_32.h +index 38ee4dc35d..5d38a427e0 100644 +--- a/linux-headers/asm-powerpc/unistd_32.h ++++ b/linux-headers/asm-powerpc/unistd_32.h +@@ -448,6 +448,7 @@ + #define __NR_getxattrat 464 + #define __NR_listxattrat 465 + #define __NR_removexattrat 466 ++#define __NR_open_tree_attr 467 + + + #endif /* _ASM_UNISTD_32_H */ +diff --git a/linux-headers/asm-powerpc/unistd_64.h b/linux-headers/asm-powerpc/unistd_64.h +index 5e5f156834..860a488e4d 100644 +--- a/linux-headers/asm-powerpc/unistd_64.h ++++ b/linux-headers/asm-powerpc/unistd_64.h +@@ -420,6 +420,7 @@ + #define __NR_getxattrat 464 + #define __NR_listxattrat 465 + #define __NR_removexattrat 466 ++#define __NR_open_tree_attr 467 + + + #endif /* _ASM_UNISTD_64_H */ +diff --git a/linux-headers/asm-riscv/kvm.h b/linux-headers/asm-riscv/kvm.h +index f06bc5efcd..5f59fd226c 100644 +--- a/linux-headers/asm-riscv/kvm.h ++++ b/linux-headers/asm-riscv/kvm.h +@@ -182,6 +182,8 @@ enum KVM_RISCV_ISA_EXT_ID { + KVM_RISCV_ISA_EXT_SVVPTC, + KVM_RISCV_ISA_EXT_ZABHA, + KVM_RISCV_ISA_EXT_ZICCRSE, ++ KVM_RISCV_ISA_EXT_ZAAMO, ++ KVM_RISCV_ISA_EXT_ZALRSC, + KVM_RISCV_ISA_EXT_MAX, + }; + +diff --git a/linux-headers/asm-riscv/unistd_32.h b/linux-headers/asm-riscv/unistd_32.h +index 74f6127aed..a5e769f1d9 100644 +--- a/linux-headers/asm-riscv/unistd_32.h ++++ b/linux-headers/asm-riscv/unistd_32.h +@@ -314,6 +314,7 @@ + #define __NR_getxattrat 464 + #define __NR_listxattrat 465 + #define __NR_removexattrat 466 ++#define __NR_open_tree_attr 467 + + + #endif /* _ASM_UNISTD_32_H */ +diff --git a/linux-headers/asm-riscv/unistd_64.h b/linux-headers/asm-riscv/unistd_64.h +index bb6a15a2ec..8df4d64841 100644 +--- a/linux-headers/asm-riscv/unistd_64.h ++++ b/linux-headers/asm-riscv/unistd_64.h +@@ -324,6 +324,7 @@ + #define __NR_getxattrat 464 + #define __NR_listxattrat 465 + #define __NR_removexattrat 466 ++#define __NR_open_tree_attr 467 + + + #endif /* _ASM_UNISTD_64_H */ +diff --git a/linux-headers/asm-s390/unistd_32.h b/linux-headers/asm-s390/unistd_32.h +index 620201cb36..85eedbd18e 100644 +--- a/linux-headers/asm-s390/unistd_32.h ++++ b/linux-headers/asm-s390/unistd_32.h +@@ -439,5 +439,6 @@ + #define __NR_getxattrat 464 + #define __NR_listxattrat 465 + #define __NR_removexattrat 466 ++#define __NR_open_tree_attr 467 + + #endif /* _ASM_S390_UNISTD_32_H */ +diff --git a/linux-headers/asm-s390/unistd_64.h b/linux-headers/asm-s390/unistd_64.h +index e7e4a10aaf..c03b1b9701 100644 +--- a/linux-headers/asm-s390/unistd_64.h ++++ b/linux-headers/asm-s390/unistd_64.h +@@ -387,5 +387,6 @@ + #define __NR_getxattrat 464 + #define __NR_listxattrat 465 + #define __NR_removexattrat 466 ++#define __NR_open_tree_attr 467 + + #endif /* _ASM_S390_UNISTD_64_H */ +diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h +index 86f2c34e7a..dc591fb17e 100644 +--- a/linux-headers/asm-x86/kvm.h ++++ b/linux-headers/asm-x86/kvm.h +@@ -557,6 +557,9 @@ struct kvm_x86_mce { + #define KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE (1 << 7) + #define KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA (1 << 8) + ++#define KVM_XEN_MSR_MIN_INDEX 0x40000000u ++#define KVM_XEN_MSR_MAX_INDEX 0x4fffffffu ++ + struct kvm_xen_hvm_config { + __u32 flags; + __u32 msr; +diff --git a/linux-headers/asm-x86/unistd_32.h b/linux-headers/asm-x86/unistd_32.h +index a2eb492a75..491d6b4eb6 100644 +--- a/linux-headers/asm-x86/unistd_32.h ++++ b/linux-headers/asm-x86/unistd_32.h +@@ -457,6 +457,7 @@ + #define __NR_getxattrat 464 + #define __NR_listxattrat 465 + #define __NR_removexattrat 466 ++#define __NR_open_tree_attr 467 + + + #endif /* _ASM_UNISTD_32_H */ +diff --git a/linux-headers/asm-x86/unistd_64.h b/linux-headers/asm-x86/unistd_64.h +index 2f5fc400f5..7cf88bf9bd 100644 +--- a/linux-headers/asm-x86/unistd_64.h ++++ b/linux-headers/asm-x86/unistd_64.h +@@ -380,6 +380,7 @@ + #define __NR_getxattrat 464 + #define __NR_listxattrat 465 + #define __NR_removexattrat 466 ++#define __NR_open_tree_attr 467 + + + #endif /* _ASM_UNISTD_64_H */ +diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h +index fecd832e7f..82959111e6 100644 +--- a/linux-headers/asm-x86/unistd_x32.h ++++ b/linux-headers/asm-x86/unistd_x32.h +@@ -333,6 +333,7 @@ + #define __NR_getxattrat (__X32_SYSCALL_BIT + 464) + #define __NR_listxattrat (__X32_SYSCALL_BIT + 465) + #define __NR_removexattrat (__X32_SYSCALL_BIT + 466) ++#define __NR_open_tree_attr (__X32_SYSCALL_BIT + 467) + #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512) + #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513) + #define __NR_ioctl (__X32_SYSCALL_BIT + 514) +diff --git a/linux-headers/linux/bits.h b/linux-headers/linux/bits.h +index c0d00c0a98..58596d18f4 100644 +--- a/linux-headers/linux/bits.h ++++ b/linux-headers/linux/bits.h +@@ -4,13 +4,9 @@ + #ifndef _LINUX_BITS_H + #define _LINUX_BITS_H + +-#define __GENMASK(h, l) \ +- (((~_UL(0)) - (_UL(1) << (l)) + 1) & \ +- (~_UL(0) >> (__BITS_PER_LONG - 1 - (h)))) ++#define __GENMASK(h, l) (((~_UL(0)) << (l)) & (~_UL(0) >> (BITS_PER_LONG - 1 - (h)))) + +-#define __GENMASK_ULL(h, l) \ +- (((~_ULL(0)) - (_ULL(1) << (l)) + 1) & \ +- (~_ULL(0) >> (__BITS_PER_LONG_LONG - 1 - (h)))) ++#define __GENMASK_ULL(h, l) (((~_ULL(0)) << (l)) & (~_ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h)))) + + #define __GENMASK_U128(h, l) \ + ((_BIT128((h)) << 1) - (_BIT128(l))) +diff --git a/linux-headers/linux/const.h b/linux-headers/linux/const.h +index 2122610de7..95ede23342 100644 +--- a/linux-headers/linux/const.h ++++ b/linux-headers/linux/const.h +@@ -33,7 +33,7 @@ + * Missing __asm__ support + * + * __BIT128() would not work in the __asm__ code, as it shifts an +- * 'unsigned __init128' data type as direct representation of ++ * 'unsigned __int128' data type as direct representation of + * 128 bit constants is not supported in the gcc compiler, as + * they get silently truncated. + * +diff --git a/linux-headers/linux/iommufd.h b/linux-headers/linux/iommufd.h +index ccbdca5e11..cb0f7d6b4d 100644 +--- a/linux-headers/linux/iommufd.h ++++ b/linux-headers/linux/iommufd.h +@@ -55,6 +55,7 @@ enum { + IOMMUFD_CMD_VIOMMU_ALLOC = 0x90, + IOMMUFD_CMD_VDEVICE_ALLOC = 0x91, + IOMMUFD_CMD_IOAS_CHANGE_PROCESS = 0x92, ++ IOMMUFD_CMD_VEVENTQ_ALLOC = 0x93, + }; + + /** +@@ -392,6 +393,9 @@ struct iommu_vfio_ioas { + * Any domain attached to the non-PASID part of the + * device must also be flagged, otherwise attaching a + * PASID will blocked. ++ * For the user that wants to attach PASID, ioas is ++ * not recommended for both the non-PASID part ++ * and PASID part of the device. + * If IOMMU does not support PASID it will return + * error (-EOPNOTSUPP). + */ +@@ -608,9 +612,17 @@ enum iommu_hw_info_type { + * IOMMU_HWPT_GET_DIRTY_BITMAP + * IOMMU_HWPT_SET_DIRTY_TRACKING + * ++ * @IOMMU_HW_CAP_PCI_PASID_EXEC: Execute Permission Supported, user ignores it ++ * when the struct ++ * iommu_hw_info::out_max_pasid_log2 is zero. ++ * @IOMMU_HW_CAP_PCI_PASID_PRIV: Privileged Mode Supported, user ignores it ++ * when the struct ++ * iommu_hw_info::out_max_pasid_log2 is zero. + */ + enum iommufd_hw_capabilities { + IOMMU_HW_CAP_DIRTY_TRACKING = 1 << 0, ++ IOMMU_HW_CAP_PCI_PASID_EXEC = 1 << 1, ++ IOMMU_HW_CAP_PCI_PASID_PRIV = 1 << 2, + }; + + /** +@@ -626,6 +638,9 @@ enum iommufd_hw_capabilities { + * iommu_hw_info_type. + * @out_capabilities: Output the generic iommu capability info type as defined + * in the enum iommu_hw_capabilities. ++ * @out_max_pasid_log2: Output the width of PASIDs. 0 means no PASID support. ++ * PCI devices turn to out_capabilities to check if the ++ * specific capabilities is supported or not. + * @__reserved: Must be 0 + * + * Query an iommu type specific hardware information data from an iommu behind +@@ -649,7 +664,8 @@ struct iommu_hw_info { + __u32 data_len; + __aligned_u64 data_uptr; + __u32 out_data_type; +- __u32 __reserved; ++ __u8 out_max_pasid_log2; ++ __u8 __reserved[3]; + __aligned_u64 out_capabilities; + }; + #define IOMMU_GET_HW_INFO _IO(IOMMUFD_TYPE, IOMMUFD_CMD_GET_HW_INFO) +@@ -1014,4 +1030,115 @@ struct iommu_ioas_change_process { + #define IOMMU_IOAS_CHANGE_PROCESS \ + _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_CHANGE_PROCESS) + ++/** ++ * enum iommu_veventq_flag - flag for struct iommufd_vevent_header ++ * @IOMMU_VEVENTQ_FLAG_LOST_EVENTS: vEVENTQ has lost vEVENTs ++ */ ++enum iommu_veventq_flag { ++ IOMMU_VEVENTQ_FLAG_LOST_EVENTS = (1U << 0), ++}; ++ ++/** ++ * struct iommufd_vevent_header - Virtual Event Header for a vEVENTQ Status ++ * @flags: Combination of enum iommu_veventq_flag ++ * @sequence: The sequence index of a vEVENT in the vEVENTQ, with a range of ++ * [0, INT_MAX] where the following index of INT_MAX is 0 ++ * ++ * Each iommufd_vevent_header reports a sequence index of the following vEVENT: ++ * ++ * +----------------------+-------+----------------------+-------+---+-------+ ++ * | header0 {sequence=0} | data0 | header1 {sequence=1} | data1 |...| dataN | ++ * +----------------------+-------+----------------------+-------+---+-------+ ++ * ++ * And this sequence index is expected to be monotonic to the sequence index of ++ * the previous vEVENT. If two adjacent sequence indexes has a delta larger than ++ * 1, it means that delta - 1 number of vEVENTs has lost, e.g. two lost vEVENTs: ++ * ++ * +-----+----------------------+-------+----------------------+-------+-----+ ++ * | ... | header3 {sequence=3} | data3 | header6 {sequence=6} | data6 | ... | ++ * +-----+----------------------+-------+----------------------+-------+-----+ ++ * ++ * If a vEVENT lost at the tail of the vEVENTQ and there is no following vEVENT ++ * providing the next sequence index, an IOMMU_VEVENTQ_FLAG_LOST_EVENTS header ++ * would be added to the tail, and no data would follow this header: ++ * ++ * +--+----------------------+-------+-----------------------------------------+ ++ * |..| header3 {sequence=3} | data3 | header4 {flags=LOST_EVENTS, sequence=4} | ++ * +--+----------------------+-------+-----------------------------------------+ ++ */ ++struct iommufd_vevent_header { ++ __u32 flags; ++ __u32 sequence; ++}; ++ ++/** ++ * enum iommu_veventq_type - Virtual Event Queue Type ++ * @IOMMU_VEVENTQ_TYPE_DEFAULT: Reserved for future use ++ * @IOMMU_VEVENTQ_TYPE_ARM_SMMUV3: ARM SMMUv3 Virtual Event Queue ++ */ ++enum iommu_veventq_type { ++ IOMMU_VEVENTQ_TYPE_DEFAULT = 0, ++ IOMMU_VEVENTQ_TYPE_ARM_SMMUV3 = 1, ++}; ++ ++/** ++ * struct iommu_vevent_arm_smmuv3 - ARM SMMUv3 Virtual Event ++ * (IOMMU_VEVENTQ_TYPE_ARM_SMMUV3) ++ * @evt: 256-bit ARM SMMUv3 Event record, little-endian. ++ * Reported event records: (Refer to "7.3 Event records" in SMMUv3 HW Spec) ++ * - 0x04 C_BAD_STE ++ * - 0x06 F_STREAM_DISABLED ++ * - 0x08 C_BAD_SUBSTREAMID ++ * - 0x0a C_BAD_CD ++ * - 0x10 F_TRANSLATION ++ * - 0x11 F_ADDR_SIZE ++ * - 0x12 F_ACCESS ++ * - 0x13 F_PERMISSION ++ * ++ * StreamID field reports a virtual device ID. To receive a virtual event for a ++ * device, a vDEVICE must be allocated via IOMMU_VDEVICE_ALLOC. ++ */ ++struct iommu_vevent_arm_smmuv3 { ++ __aligned_le64 evt[4]; ++}; ++ ++/** ++ * struct iommu_veventq_alloc - ioctl(IOMMU_VEVENTQ_ALLOC) ++ * @size: sizeof(struct iommu_veventq_alloc) ++ * @flags: Must be 0 ++ * @viommu_id: virtual IOMMU ID to associate the vEVENTQ with ++ * @type: Type of the vEVENTQ. Must be defined in enum iommu_veventq_type ++ * @veventq_depth: Maximum number of events in the vEVENTQ ++ * @out_veventq_id: The ID of the new vEVENTQ ++ * @out_veventq_fd: The fd of the new vEVENTQ. User space must close the ++ * successfully returned fd after using it ++ * @__reserved: Must be 0 ++ * ++ * Explicitly allocate a virtual event queue interface for a vIOMMU. A vIOMMU ++ * can have multiple FDs for different types, but is confined to one per @type. ++ * User space should open the @out_veventq_fd to read vEVENTs out of a vEVENTQ, ++ * if there are vEVENTs available. A vEVENTQ will lose events due to overflow, ++ * if the number of the vEVENTs hits @veventq_depth. ++ * ++ * Each vEVENT in a vEVENTQ encloses a struct iommufd_vevent_header followed by ++ * a type-specific data structure, in a normal case: ++ * ++ * +-+---------+-------+---------+-------+-----+---------+-------+-+ ++ * | | header0 | data0 | header1 | data1 | ... | headerN | dataN | | ++ * +-+---------+-------+---------+-------+-----+---------+-------+-+ ++ * ++ * unless a tailing IOMMU_VEVENTQ_FLAG_LOST_EVENTS header is logged (refer to ++ * struct iommufd_vevent_header). ++ */ ++struct iommu_veventq_alloc { ++ __u32 size; ++ __u32 flags; ++ __u32 viommu_id; ++ __u32 type; ++ __u32 veventq_depth; ++ __u32 out_veventq_id; ++ __u32 out_veventq_fd; ++ __u32 __reserved; ++}; ++#define IOMMU_VEVENTQ_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VEVENTQ_ALLOC) + #endif +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 27181b3dd8..e5f3e8b5a0 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -921,6 +921,7 @@ struct kvm_enable_cap { + #define KVM_CAP_PRE_FAULT_MEMORY 236 + #define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237 + #define KVM_CAP_X86_GUEST_MODE 238 ++#define KVM_CAP_ARM_WRITABLE_IMP_ID_REGS 239 + + struct kvm_irq_routing_irqchip { + __u32 irqchip; +diff --git a/linux-headers/linux/psp-sev.h b/linux-headers/linux/psp-sev.h +index 17bf191573..113c4ceb78 100644 +--- a/linux-headers/linux/psp-sev.h ++++ b/linux-headers/linux/psp-sev.h +@@ -73,13 +73,20 @@ typedef enum { + SEV_RET_INVALID_PARAM, + SEV_RET_RESOURCE_LIMIT, + SEV_RET_SECURE_DATA_INVALID, +- SEV_RET_INVALID_KEY = 0x27, +- SEV_RET_INVALID_PAGE_SIZE, +- SEV_RET_INVALID_PAGE_STATE, +- SEV_RET_INVALID_MDATA_ENTRY, +- SEV_RET_INVALID_PAGE_OWNER, +- SEV_RET_INVALID_PAGE_AEAD_OFLOW, +- SEV_RET_RMP_INIT_REQUIRED, ++ SEV_RET_INVALID_PAGE_SIZE = 0x0019, ++ SEV_RET_INVALID_PAGE_STATE = 0x001A, ++ SEV_RET_INVALID_MDATA_ENTRY = 0x001B, ++ SEV_RET_INVALID_PAGE_OWNER = 0x001C, ++ SEV_RET_AEAD_OFLOW = 0x001D, ++ SEV_RET_EXIT_RING_BUFFER = 0x001F, ++ SEV_RET_RMP_INIT_REQUIRED = 0x0020, ++ SEV_RET_BAD_SVN = 0x0021, ++ SEV_RET_BAD_VERSION = 0x0022, ++ SEV_RET_SHUTDOWN_REQUIRED = 0x0023, ++ SEV_RET_UPDATE_FAILED = 0x0024, ++ SEV_RET_RESTORE_REQUIRED = 0x0025, ++ SEV_RET_RMP_INITIALIZATION_FAILED = 0x0026, ++ SEV_RET_INVALID_KEY = 0x0027, + SEV_RET_MAX, + } sev_ret_code; + +diff --git a/linux-headers/linux/stddef.h b/linux-headers/linux/stddef.h +index e1416f7937..e1fcfcf3b3 100644 +--- a/linux-headers/linux/stddef.h ++++ b/linux-headers/linux/stddef.h +@@ -70,4 +70,6 @@ + #define __counted_by_be(m) + #endif + ++#define __kernel_nonstring ++ + #endif /* _LINUX_STDDEF_H */ +diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h +index 1b5e254d6a..79bf8c0cc5 100644 +--- a/linux-headers/linux/vfio.h ++++ b/linux-headers/linux/vfio.h +@@ -671,6 +671,7 @@ enum { + */ + enum { + VFIO_AP_REQ_IRQ_INDEX, ++ VFIO_AP_CFG_CHG_IRQ_INDEX, + VFIO_AP_NUM_IRQS + }; + +@@ -931,29 +932,34 @@ struct vfio_device_bind_iommufd { + * VFIO_DEVICE_ATTACH_IOMMUFD_PT - _IOW(VFIO_TYPE, VFIO_BASE + 19, + * struct vfio_device_attach_iommufd_pt) + * @argsz: User filled size of this data. +- * @flags: Must be 0. ++ * @flags: Flags for attach. + * @pt_id: Input the target id which can represent an ioas or a hwpt + * allocated via iommufd subsystem. + * Output the input ioas id or the attached hwpt id which could + * be the specified hwpt itself or a hwpt automatically created + * for the specified ioas by kernel during the attachment. ++ * @pasid: The pasid to be attached, only meaningful when ++ * VFIO_DEVICE_ATTACH_PASID is set in @flags + * + * Associate the device with an address space within the bound iommufd. + * Undo by VFIO_DEVICE_DETACH_IOMMUFD_PT or device fd close. This is only + * allowed on cdev fds. + * +- * If a vfio device is currently attached to a valid hw_pagetable, without doing +- * a VFIO_DEVICE_DETACH_IOMMUFD_PT, a second VFIO_DEVICE_ATTACH_IOMMUFD_PT ioctl +- * passing in another hw_pagetable (hwpt) id is allowed. This action, also known +- * as a hw_pagetable replacement, will replace the device's currently attached +- * hw_pagetable with a new hw_pagetable corresponding to the given pt_id. ++ * If a vfio device or a pasid of this device is currently attached to a valid ++ * hw_pagetable (hwpt), without doing a VFIO_DEVICE_DETACH_IOMMUFD_PT, a second ++ * VFIO_DEVICE_ATTACH_IOMMUFD_PT ioctl passing in another hwpt id is allowed. ++ * This action, also known as a hw_pagetable replacement, will replace the ++ * currently attached hwpt of the device or the pasid of this device with a new ++ * hwpt corresponding to the given pt_id. + * + * Return: 0 on success, -errno on failure. + */ + struct vfio_device_attach_iommufd_pt { + __u32 argsz; + __u32 flags; ++#define VFIO_DEVICE_ATTACH_PASID (1 << 0) + __u32 pt_id; ++ __u32 pasid; + }; + + #define VFIO_DEVICE_ATTACH_IOMMUFD_PT _IO(VFIO_TYPE, VFIO_BASE + 19) +@@ -962,17 +968,21 @@ struct vfio_device_attach_iommufd_pt { + * VFIO_DEVICE_DETACH_IOMMUFD_PT - _IOW(VFIO_TYPE, VFIO_BASE + 20, + * struct vfio_device_detach_iommufd_pt) + * @argsz: User filled size of this data. +- * @flags: Must be 0. ++ * @flags: Flags for detach. ++ * @pasid: The pasid to be detached, only meaningful when ++ * VFIO_DEVICE_DETACH_PASID is set in @flags + * +- * Remove the association of the device and its current associated address +- * space. After it, the device should be in a blocking DMA state. This is only +- * allowed on cdev fds. ++ * Remove the association of the device or a pasid of the device and its current ++ * associated address space. After it, the device or the pasid should be in a ++ * blocking DMA state. This is only allowed on cdev fds. + * + * Return: 0 on success, -errno on failure. + */ + struct vfio_device_detach_iommufd_pt { + __u32 argsz; + __u32 flags; ++#define VFIO_DEVICE_DETACH_PASID (1 << 0) ++ __u32 pasid; + }; + + #define VFIO_DEVICE_DETACH_IOMMUFD_PT _IO(VFIO_TYPE, VFIO_BASE + 20) +-- +2.47.3 + diff --git a/kvm-linux-headers-update-from-6.15-kvm-next.patch b/kvm-linux-headers-update-from-6.15-kvm-next.patch new file mode 100644 index 0000000..f4bae30 --- /dev/null +++ b/kvm-linux-headers-update-from-6.15-kvm-next.patch @@ -0,0 +1,118 @@ +From cc48dcf216e8e4e655b350154469436c20107ff6 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:45 +0200 +Subject: [PATCH 013/100] linux-headers: update from 6.15 + kvm/next + +This brings in the userspace TDX API. + +Reviewed-by: Xiaoyao Li +Signed-off-by: Paolo Bonzini +(cherry picked from commit 428c0acd953a626dab55e2c07401ce99c2271119) +Signed-off-by: Paolo Bonzini +--- + linux-headers/asm-x86/kvm.h | 71 +++++++++++++++++++++++++++++++++++++ + linux-headers/linux/kvm.h | 1 + + 2 files changed, 72 insertions(+) + +diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h +index dc591fb17e..7fb57ccb2a 100644 +--- a/linux-headers/asm-x86/kvm.h ++++ b/linux-headers/asm-x86/kvm.h +@@ -439,6 +439,7 @@ struct kvm_sync_regs { + #define KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS (1 << 6) + #define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7) + #define KVM_X86_QUIRK_STUFF_FEATURE_MSRS (1 << 8) ++#define KVM_X86_QUIRK_IGNORE_GUEST_PAT (1 << 9) + + #define KVM_STATE_NESTED_FORMAT_VMX 0 + #define KVM_STATE_NESTED_FORMAT_SVM 1 +@@ -928,4 +929,74 @@ struct kvm_hyperv_eventfd { + #define KVM_X86_SNP_VM 4 + #define KVM_X86_TDX_VM 5 + ++/* Trust Domain eXtension sub-ioctl() commands. */ ++enum kvm_tdx_cmd_id { ++ KVM_TDX_CAPABILITIES = 0, ++ KVM_TDX_INIT_VM, ++ KVM_TDX_INIT_VCPU, ++ KVM_TDX_INIT_MEM_REGION, ++ KVM_TDX_FINALIZE_VM, ++ KVM_TDX_GET_CPUID, ++ ++ KVM_TDX_CMD_NR_MAX, ++}; ++ ++struct kvm_tdx_cmd { ++ /* enum kvm_tdx_cmd_id */ ++ __u32 id; ++ /* flags for sub-commend. If sub-command doesn't use this, set zero. */ ++ __u32 flags; ++ /* ++ * data for each sub-command. An immediate or a pointer to the actual ++ * data in process virtual address. If sub-command doesn't use it, ++ * set zero. ++ */ ++ __u64 data; ++ /* ++ * Auxiliary error code. The sub-command may return TDX SEAMCALL ++ * status code in addition to -Exxx. ++ */ ++ __u64 hw_error; ++}; ++ ++struct kvm_tdx_capabilities { ++ __u64 supported_attrs; ++ __u64 supported_xfam; ++ __u64 reserved[254]; ++ ++ /* Configurable CPUID bits for userspace */ ++ struct kvm_cpuid2 cpuid; ++}; ++ ++struct kvm_tdx_init_vm { ++ __u64 attributes; ++ __u64 xfam; ++ __u64 mrconfigid[6]; /* sha384 digest */ ++ __u64 mrowner[6]; /* sha384 digest */ ++ __u64 mrownerconfig[6]; /* sha384 digest */ ++ ++ /* The total space for TD_PARAMS before the CPUIDs is 256 bytes */ ++ __u64 reserved[12]; ++ ++ /* ++ * Call KVM_TDX_INIT_VM before vcpu creation, thus before ++ * KVM_SET_CPUID2. ++ * This configuration supersedes KVM_SET_CPUID2s for VCPUs because the ++ * TDX module directly virtualizes those CPUIDs without VMM. The user ++ * space VMM, e.g. qemu, should make KVM_SET_CPUID2 consistent with ++ * those values. If it doesn't, KVM may have wrong idea of vCPUIDs of ++ * the guest, and KVM may wrongly emulate CPUIDs or MSRs that the TDX ++ * module doesn't virtualize. ++ */ ++ struct kvm_cpuid2 cpuid; ++}; ++ ++#define KVM_TDX_MEASURE_MEMORY_REGION _BITULL(0) ++ ++struct kvm_tdx_init_mem_region { ++ __u64 source_addr; ++ __u64 gpa; ++ __u64 nr_pages; ++}; ++ + #endif /* _ASM_X86_KVM_H */ +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index e5f3e8b5a0..99cc82a275 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -369,6 +369,7 @@ struct kvm_run { + #define KVM_SYSTEM_EVENT_WAKEUP 4 + #define KVM_SYSTEM_EVENT_SUSPEND 5 + #define KVM_SYSTEM_EVENT_SEV_TERM 6 ++#define KVM_SYSTEM_EVENT_TDX_FATAL 7 + __u32 type; + __u32 ndata; + union { +-- +2.47.3 + diff --git a/kvm-memory-Change-memory_region_set_ram_discard_manager-.patch b/kvm-memory-Change-memory_region_set_ram_discard_manager-.patch new file mode 100644 index 0000000..ad798fb --- /dev/null +++ b/kvm-memory-Change-memory_region_set_ram_discard_manager-.patch @@ -0,0 +1,152 @@ +From 8f8f4bc301f2940a7224b67f8d7879e094a52f61 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:11:27 +0200 +Subject: [PATCH 097/100] memory: Change + memory_region_set_ram_discard_manager() to return the result + +Modify memory_region_set_ram_discard_manager() to return -EBUSY if a +RamDiscardManager is already set in the MemoryRegion. The caller must +handle this failure, such as having virtio-mem undo its actions and fail +the realize() process. Opportunistically move the call earlier to avoid +complex error handling. + +This change is beneficial when introducing a new RamDiscardManager +instance besides virtio-mem. After +ram_block_coordinated_discard_require(true) unlocks all +RamDiscardManager instances, only one instance is allowed to be set for +one MemoryRegion at present. + +Suggested-by: David Hildenbrand +Reviewed-by: David Hildenbrand +Reviewed-by: Pankaj Gupta +Tested-by: Alexey Kardashevskiy +Reviewed-by: Alexey Kardashevskiy +Reviewed-by: Xiaoyao Li +Signed-off-by: Chenyi Qiang +Link: https://lore.kernel.org/r/20250612082747.51539-3-chenyi.qiang@intel.com +Signed-off-by: Peter Xu +(cherry picked from commit ff1211154c45c9f7f82116ae9a8c72a848e4a8b5) +Signed-off-by: Paolo Bonzini +--- + hw/virtio/virtio-mem.c | 30 +++++++++++++++++------------- + include/system/memory.h | 6 +++--- + system/memory.c | 10 +++++++--- + 3 files changed, 27 insertions(+), 19 deletions(-) + +diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c +index 8f0f2b1794..28406a33f8 100644 +--- a/hw/virtio/virtio-mem.c ++++ b/hw/virtio/virtio-mem.c +@@ -1047,6 +1047,17 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp) + return; + } + ++ /* ++ * Set ourselves as RamDiscardManager before the plug handler maps the ++ * memory region and exposes it via an address space. ++ */ ++ if (memory_region_set_ram_discard_manager(&vmem->memdev->mr, ++ RAM_DISCARD_MANAGER(vmem))) { ++ error_setg(errp, "Failed to set RamDiscardManager"); ++ ram_block_coordinated_discard_require(false); ++ return; ++ } ++ + /* + * We don't know at this point whether shared RAM is migrated using + * QEMU or migrated using the file content. "x-ignore-shared" will be +@@ -1061,6 +1072,7 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp) + ret = ram_block_discard_range(rb, 0, qemu_ram_get_used_length(rb)); + if (ret) { + error_setg_errno(errp, -ret, "Unexpected error discarding RAM"); ++ memory_region_set_ram_discard_manager(&vmem->memdev->mr, NULL); + ram_block_coordinated_discard_require(false); + return; + } +@@ -1122,13 +1134,6 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp) + vmem->system_reset = VIRTIO_MEM_SYSTEM_RESET(obj); + vmem->system_reset->vmem = vmem; + qemu_register_resettable(obj); +- +- /* +- * Set ourselves as RamDiscardManager before the plug handler maps the +- * memory region and exposes it via an address space. +- */ +- memory_region_set_ram_discard_manager(&vmem->memdev->mr, +- RAM_DISCARD_MANAGER(vmem)); + } + + static void virtio_mem_device_unrealize(DeviceState *dev) +@@ -1136,12 +1141,6 @@ static void virtio_mem_device_unrealize(DeviceState *dev) + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOMEM *vmem = VIRTIO_MEM(dev); + +- /* +- * The unplug handler unmapped the memory region, it cannot be +- * found via an address space anymore. Unset ourselves. +- */ +- memory_region_set_ram_discard_manager(&vmem->memdev->mr, NULL); +- + qemu_unregister_resettable(OBJECT(vmem->system_reset)); + object_unref(OBJECT(vmem->system_reset)); + +@@ -1154,6 +1153,11 @@ static void virtio_mem_device_unrealize(DeviceState *dev) + virtio_del_queue(vdev, 0); + virtio_cleanup(vdev); + g_free(vmem->bitmap); ++ /* ++ * The unplug handler unmapped the memory region, it cannot be ++ * found via an address space anymore. Unset ourselves. ++ */ ++ memory_region_set_ram_discard_manager(&vmem->memdev->mr, NULL); + ram_block_coordinated_discard_require(false); + } + +diff --git a/include/system/memory.h b/include/system/memory.h +index 7d77625e2c..28a55834b7 100644 +--- a/include/system/memory.h ++++ b/include/system/memory.h +@@ -2498,13 +2498,13 @@ static inline bool memory_region_has_ram_discard_manager(MemoryRegion *mr) + * + * This function must not be called for a mapped #MemoryRegion, a #MemoryRegion + * that does not cover RAM, or a #MemoryRegion that already has a +- * #RamDiscardManager assigned. ++ * #RamDiscardManager assigned. Return 0 if the rdm is set successfully. + * + * @mr: the #MemoryRegion + * @rdm: #RamDiscardManager to set + */ +-void memory_region_set_ram_discard_manager(MemoryRegion *mr, +- RamDiscardManager *rdm); ++int memory_region_set_ram_discard_manager(MemoryRegion *mr, ++ RamDiscardManager *rdm); + + /** + * memory_region_find: translate an address/size relative to a +diff --git a/system/memory.c b/system/memory.c +index faddcbfd8a..452d29b87e 100644 +--- a/system/memory.c ++++ b/system/memory.c +@@ -2115,12 +2115,16 @@ RamDiscardManager *memory_region_get_ram_discard_manager(MemoryRegion *mr) + return mr->rdm; + } + +-void memory_region_set_ram_discard_manager(MemoryRegion *mr, +- RamDiscardManager *rdm) ++int memory_region_set_ram_discard_manager(MemoryRegion *mr, ++ RamDiscardManager *rdm) + { + g_assert(memory_region_is_ram(mr)); +- g_assert(!rdm || !mr->rdm); ++ if (mr->rdm && rdm) { ++ return -EBUSY; ++ } ++ + mr->rdm = rdm; ++ return 0; + } + + uint64_t ram_discard_manager_get_min_granularity(const RamDiscardManager *rdm, +-- +2.47.3 + diff --git a/kvm-memory-Export-a-helper-to-get-intersection-of-a-Memo.patch b/kvm-memory-Export-a-helper-to-get-intersection-of-a-Memo.patch new file mode 100644 index 0000000..855110b --- /dev/null +++ b/kvm-memory-Export-a-helper-to-get-intersection-of-a-Memo.patch @@ -0,0 +1,149 @@ +From 694f3fbf0a6fa329df54901c46fbcf47915d9543 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:11:27 +0200 +Subject: [PATCH 096/100] memory: Export a helper to get intersection of a + MemoryRegionSection with a given range + +Rename the helper to memory_region_section_intersect_range() to make it +more generic. Meanwhile, define the @end as Int128 and replace the +related operations with Int128_* format since the helper is exported as +a wider API. + +Suggested-by: Alexey Kardashevskiy +Reviewed-by: Alexey Kardashevskiy +Reviewed-by: Pankaj Gupta +Reviewed-by: David Hildenbrand +Reviewed-by: Zhao Liu +Reviewed-by: Xiaoyao Li +Signed-off-by: Chenyi Qiang +Link: https://lore.kernel.org/r/20250612082747.51539-2-chenyi.qiang@intel.com +Signed-off-by: Peter Xu +(cherry picked from commit f47a672a72acd6e2712031f0bc4d4f3ae4b6302c) +Signed-off-by: Paolo Bonzini +--- + hw/virtio/virtio-mem.c | 32 +++++--------------------------- + include/system/memory.h | 30 ++++++++++++++++++++++++++++++ + 2 files changed, 35 insertions(+), 27 deletions(-) + +diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c +index cefb43aca2..8f0f2b1794 100644 +--- a/hw/virtio/virtio-mem.c ++++ b/hw/virtio/virtio-mem.c +@@ -244,28 +244,6 @@ static int virtio_mem_for_each_plugged_range(VirtIOMEM *vmem, void *arg, + return ret; + } + +-/* +- * Adjust the memory section to cover the intersection with the given range. +- * +- * Returns false if the intersection is empty, otherwise returns true. +- */ +-static bool virtio_mem_intersect_memory_section(MemoryRegionSection *s, +- uint64_t offset, uint64_t size) +-{ +- uint64_t start = MAX(s->offset_within_region, offset); +- uint64_t end = MIN(s->offset_within_region + int128_get64(s->size), +- offset + size); +- +- if (end <= start) { +- return false; +- } +- +- s->offset_within_address_space += start - s->offset_within_region; +- s->offset_within_region = start; +- s->size = int128_make64(end - start); +- return true; +-} +- + typedef int (*virtio_mem_section_cb)(MemoryRegionSection *s, void *arg); + + static int virtio_mem_for_each_plugged_section(const VirtIOMEM *vmem, +@@ -287,7 +265,7 @@ static int virtio_mem_for_each_plugged_section(const VirtIOMEM *vmem, + first_bit + 1) - 1; + size = (last_bit - first_bit + 1) * vmem->block_size; + +- if (!virtio_mem_intersect_memory_section(&tmp, offset, size)) { ++ if (!memory_region_section_intersect_range(&tmp, offset, size)) { + break; + } + ret = cb(&tmp, arg); +@@ -319,7 +297,7 @@ static int virtio_mem_for_each_unplugged_section(const VirtIOMEM *vmem, + first_bit + 1) - 1; + size = (last_bit - first_bit + 1) * vmem->block_size; + +- if (!virtio_mem_intersect_memory_section(&tmp, offset, size)) { ++ if (!memory_region_section_intersect_range(&tmp, offset, size)) { + break; + } + ret = cb(&tmp, arg); +@@ -355,7 +333,7 @@ static void virtio_mem_notify_unplug(VirtIOMEM *vmem, uint64_t offset, + QLIST_FOREACH(rdl, &vmem->rdl_list, next) { + MemoryRegionSection tmp = *rdl->section; + +- if (!virtio_mem_intersect_memory_section(&tmp, offset, size)) { ++ if (!memory_region_section_intersect_range(&tmp, offset, size)) { + continue; + } + rdl->notify_discard(rdl, &tmp); +@@ -371,7 +349,7 @@ static int virtio_mem_notify_plug(VirtIOMEM *vmem, uint64_t offset, + QLIST_FOREACH(rdl, &vmem->rdl_list, next) { + MemoryRegionSection tmp = *rdl->section; + +- if (!virtio_mem_intersect_memory_section(&tmp, offset, size)) { ++ if (!memory_region_section_intersect_range(&tmp, offset, size)) { + continue; + } + ret = rdl->notify_populate(rdl, &tmp); +@@ -388,7 +366,7 @@ static int virtio_mem_notify_plug(VirtIOMEM *vmem, uint64_t offset, + if (rdl2 == rdl) { + break; + } +- if (!virtio_mem_intersect_memory_section(&tmp, offset, size)) { ++ if (!memory_region_section_intersect_range(&tmp, offset, size)) { + continue; + } + rdl2->notify_discard(rdl2, &tmp); +diff --git a/include/system/memory.h b/include/system/memory.h +index 8c0590cd7b..7d77625e2c 100644 +--- a/include/system/memory.h ++++ b/include/system/memory.h +@@ -1210,6 +1210,36 @@ MemoryRegionSection *memory_region_section_new_copy(MemoryRegionSection *s); + */ + void memory_region_section_free_copy(MemoryRegionSection *s); + ++/** ++ * memory_region_section_intersect_range: Adjust the memory section to cover ++ * the intersection with the given range. ++ * ++ * @s: the #MemoryRegionSection to be adjusted ++ * @offset: the offset of the given range in the memory region ++ * @size: the size of the given range ++ * ++ * Returns false if the intersection is empty, otherwise returns true. ++ */ ++static inline bool memory_region_section_intersect_range(MemoryRegionSection *s, ++ uint64_t offset, ++ uint64_t size) ++{ ++ uint64_t start = MAX(s->offset_within_region, offset); ++ Int128 end = int128_min(int128_add(int128_make64(s->offset_within_region), ++ s->size), ++ int128_add(int128_make64(offset), ++ int128_make64(size))); ++ ++ if (int128_le(end, int128_make64(start))) { ++ return false; ++ } ++ ++ s->offset_within_address_space += start - s->offset_within_region; ++ s->offset_within_region = start; ++ s->size = int128_sub(end, int128_make64(start)); ++ return true; ++} ++ + /** + * memory_region_init: Initialize a memory region + * +-- +2.47.3 + diff --git a/kvm-memory-Unify-the-definiton-of-ReplayRamPopulate-and-.patch b/kvm-memory-Unify-the-definiton-of-ReplayRamPopulate-and-.patch new file mode 100644 index 0000000..ea9b739 --- /dev/null +++ b/kvm-memory-Unify-the-definiton-of-ReplayRamPopulate-and-.patch @@ -0,0 +1,269 @@ +From b2625fcb4b40ee4def2fcbb173113ffd01a05be7 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:11:28 +0200 +Subject: [PATCH 098/100] memory: Unify the definiton of ReplayRamPopulate() + and ReplayRamDiscard() + +Update ReplayRamDiscard() function to return the result and unify the +ReplayRamPopulate() and ReplayRamDiscard() to ReplayRamDiscardState() at +the same time due to their identical definitions. This unification +simplifies related structures, such as VirtIOMEMReplayData, which makes +it cleaner. + +Reviewed-by: David Hildenbrand +Reviewed-by: Pankaj Gupta +Reviewed-by: Xiaoyao Li +Signed-off-by: Chenyi Qiang +Link: https://lore.kernel.org/r/20250612082747.51539-4-chenyi.qiang@intel.com +Signed-off-by: Peter Xu +(cherry picked from commit 2205b8466733f8c6e3306c964f31c5a7cac69dfa) +Signed-off-by: Paolo Bonzini +--- + hw/virtio/virtio-mem.c | 21 ++++++------ + include/system/memory.h | 74 +++++++++++++++++++++++++++++++---------- + migration/ram.c | 5 +-- + system/memory.c | 12 +++---- + 4 files changed, 76 insertions(+), 36 deletions(-) + +diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c +index 28406a33f8..b4638cf645 100644 +--- a/hw/virtio/virtio-mem.c ++++ b/hw/virtio/virtio-mem.c +@@ -1733,7 +1733,7 @@ static bool virtio_mem_rdm_is_populated(const RamDiscardManager *rdm, + } + + struct VirtIOMEMReplayData { +- void *fn; ++ ReplayRamDiscardState fn; + void *opaque; + }; + +@@ -1741,12 +1741,12 @@ static int virtio_mem_rdm_replay_populated_cb(MemoryRegionSection *s, void *arg) + { + struct VirtIOMEMReplayData *data = arg; + +- return ((ReplayRamPopulate)data->fn)(s, data->opaque); ++ return data->fn(s, data->opaque); + } + + static int virtio_mem_rdm_replay_populated(const RamDiscardManager *rdm, + MemoryRegionSection *s, +- ReplayRamPopulate replay_fn, ++ ReplayRamDiscardState replay_fn, + void *opaque) + { + const VirtIOMEM *vmem = VIRTIO_MEM(rdm); +@@ -1765,14 +1765,13 @@ static int virtio_mem_rdm_replay_discarded_cb(MemoryRegionSection *s, + { + struct VirtIOMEMReplayData *data = arg; + +- ((ReplayRamDiscard)data->fn)(s, data->opaque); +- return 0; ++ return data->fn(s, data->opaque); + } + +-static void virtio_mem_rdm_replay_discarded(const RamDiscardManager *rdm, +- MemoryRegionSection *s, +- ReplayRamDiscard replay_fn, +- void *opaque) ++static int virtio_mem_rdm_replay_discarded(const RamDiscardManager *rdm, ++ MemoryRegionSection *s, ++ ReplayRamDiscardState replay_fn, ++ void *opaque) + { + const VirtIOMEM *vmem = VIRTIO_MEM(rdm); + struct VirtIOMEMReplayData data = { +@@ -1781,8 +1780,8 @@ static void virtio_mem_rdm_replay_discarded(const RamDiscardManager *rdm, + }; + + g_assert(s->mr == &vmem->memdev->mr); +- virtio_mem_for_each_unplugged_section(vmem, s, &data, +- virtio_mem_rdm_replay_discarded_cb); ++ return virtio_mem_for_each_unplugged_section(vmem, s, &data, ++ virtio_mem_rdm_replay_discarded_cb); + } + + static void virtio_mem_rdm_register_listener(RamDiscardManager *rdm, +diff --git a/include/system/memory.h b/include/system/memory.h +index 28a55834b7..322ce0b834 100644 +--- a/include/system/memory.h ++++ b/include/system/memory.h +@@ -574,8 +574,20 @@ static inline void ram_discard_listener_init(RamDiscardListener *rdl, + rdl->double_discard_supported = double_discard_supported; + } + +-typedef int (*ReplayRamPopulate)(MemoryRegionSection *section, void *opaque); +-typedef void (*ReplayRamDiscard)(MemoryRegionSection *section, void *opaque); ++/** ++ * typedef ReplayRamDiscardState: ++ * ++ * The callback handler for #RamDiscardManagerClass.replay_populated/ ++ * #RamDiscardManagerClass.replay_discarded to invoke on populated/discarded ++ * parts. ++ * ++ * @section: the #MemoryRegionSection of populated/discarded part ++ * @opaque: pointer to forward to the callback ++ * ++ * Returns 0 on success, or a negative error if failed. ++ */ ++typedef int (*ReplayRamDiscardState)(MemoryRegionSection *section, ++ void *opaque); + + /* + * RamDiscardManagerClass: +@@ -649,36 +661,38 @@ struct RamDiscardManagerClass { + /** + * @replay_populated: + * +- * Call the #ReplayRamPopulate callback for all populated parts within the +- * #MemoryRegionSection via the #RamDiscardManager. ++ * Call the #ReplayRamDiscardState callback for all populated parts within ++ * the #MemoryRegionSection via the #RamDiscardManager. + * + * In case any call fails, no further calls are made. + * + * @rdm: the #RamDiscardManager + * @section: the #MemoryRegionSection +- * @replay_fn: the #ReplayRamPopulate callback ++ * @replay_fn: the #ReplayRamDiscardState callback + * @opaque: pointer to forward to the callback + * + * Returns 0 on success, or a negative error if any notification failed. + */ + int (*replay_populated)(const RamDiscardManager *rdm, + MemoryRegionSection *section, +- ReplayRamPopulate replay_fn, void *opaque); ++ ReplayRamDiscardState replay_fn, void *opaque); + + /** + * @replay_discarded: + * +- * Call the #ReplayRamDiscard callback for all discarded parts within the +- * #MemoryRegionSection via the #RamDiscardManager. ++ * Call the #ReplayRamDiscardState callback for all discarded parts within ++ * the #MemoryRegionSection via the #RamDiscardManager. + * + * @rdm: the #RamDiscardManager + * @section: the #MemoryRegionSection +- * @replay_fn: the #ReplayRamDiscard callback ++ * @replay_fn: the #ReplayRamDiscardState callback + * @opaque: pointer to forward to the callback ++ * ++ * Returns 0 on success, or a negative error if any notification failed. + */ +- void (*replay_discarded)(const RamDiscardManager *rdm, +- MemoryRegionSection *section, +- ReplayRamDiscard replay_fn, void *opaque); ++ int (*replay_discarded)(const RamDiscardManager *rdm, ++ MemoryRegionSection *section, ++ ReplayRamDiscardState replay_fn, void *opaque); + + /** + * @register_listener: +@@ -719,15 +733,41 @@ uint64_t ram_discard_manager_get_min_granularity(const RamDiscardManager *rdm, + bool ram_discard_manager_is_populated(const RamDiscardManager *rdm, + const MemoryRegionSection *section); + ++/** ++ * ram_discard_manager_replay_populated: ++ * ++ * A wrapper to call the #RamDiscardManagerClass.replay_populated callback ++ * of the #RamDiscardManager. ++ * ++ * @rdm: the #RamDiscardManager ++ * @section: the #MemoryRegionSection ++ * @replay_fn: the #ReplayRamDiscardState callback ++ * @opaque: pointer to forward to the callback ++ * ++ * Returns 0 on success, or a negative error if any notification failed. ++ */ + int ram_discard_manager_replay_populated(const RamDiscardManager *rdm, + MemoryRegionSection *section, +- ReplayRamPopulate replay_fn, ++ ReplayRamDiscardState replay_fn, + void *opaque); + +-void ram_discard_manager_replay_discarded(const RamDiscardManager *rdm, +- MemoryRegionSection *section, +- ReplayRamDiscard replay_fn, +- void *opaque); ++/** ++ * ram_discard_manager_replay_discarded: ++ * ++ * A wrapper to call the #RamDiscardManagerClass.replay_discarded callback ++ * of the #RamDiscardManager. ++ * ++ * @rdm: the #RamDiscardManager ++ * @section: the #MemoryRegionSection ++ * @replay_fn: the #ReplayRamDiscardState callback ++ * @opaque: pointer to forward to the callback ++ * ++ * Returns 0 on success, or a negative error if any notification failed. ++ */ ++int ram_discard_manager_replay_discarded(const RamDiscardManager *rdm, ++ MemoryRegionSection *section, ++ ReplayRamDiscardState replay_fn, ++ void *opaque); + + void ram_discard_manager_register_listener(RamDiscardManager *rdm, + RamDiscardListener *rdl, +diff --git a/migration/ram.c b/migration/ram.c +index e0468210bd..a75bebc4eb 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -848,8 +848,8 @@ static inline bool migration_bitmap_clear_dirty(RAMState *rs, + return ret; + } + +-static void dirty_bitmap_clear_section(MemoryRegionSection *section, +- void *opaque) ++static int dirty_bitmap_clear_section(MemoryRegionSection *section, ++ void *opaque) + { + const hwaddr offset = section->offset_within_region; + const hwaddr size = int128_get64(section->size); +@@ -868,6 +868,7 @@ static void dirty_bitmap_clear_section(MemoryRegionSection *section, + } + *cleared_bits += bitmap_count_one_with_offset(rb->bmap, start, npages); + bitmap_clear(rb->bmap, start, npages); ++ return 0; + } + + /* +diff --git a/system/memory.c b/system/memory.c +index 452d29b87e..b0a83ed9fc 100644 +--- a/system/memory.c ++++ b/system/memory.c +@@ -2147,7 +2147,7 @@ bool ram_discard_manager_is_populated(const RamDiscardManager *rdm, + + int ram_discard_manager_replay_populated(const RamDiscardManager *rdm, + MemoryRegionSection *section, +- ReplayRamPopulate replay_fn, ++ ReplayRamDiscardState replay_fn, + void *opaque) + { + RamDiscardManagerClass *rdmc = RAM_DISCARD_MANAGER_GET_CLASS(rdm); +@@ -2156,15 +2156,15 @@ int ram_discard_manager_replay_populated(const RamDiscardManager *rdm, + return rdmc->replay_populated(rdm, section, replay_fn, opaque); + } + +-void ram_discard_manager_replay_discarded(const RamDiscardManager *rdm, +- MemoryRegionSection *section, +- ReplayRamDiscard replay_fn, +- void *opaque) ++int ram_discard_manager_replay_discarded(const RamDiscardManager *rdm, ++ MemoryRegionSection *section, ++ ReplayRamDiscardState replay_fn, ++ void *opaque) + { + RamDiscardManagerClass *rdmc = RAM_DISCARD_MANAGER_GET_CLASS(rdm); + + g_assert(rdmc->replay_discarded); +- rdmc->replay_discarded(rdm, section, replay_fn, opaque); ++ return rdmc->replay_discarded(rdm, section, replay_fn, opaque); + } + + void ram_discard_manager_register_listener(RamDiscardManager *rdm, +-- +2.47.3 + diff --git a/kvm-meson-configure-add-valgrind-option-en-dis-able-valg.patch b/kvm-meson-configure-add-valgrind-option-en-dis-able-valg.patch new file mode 100644 index 0000000..c2fc552 --- /dev/null +++ b/kvm-meson-configure-add-valgrind-option-en-dis-able-valg.patch @@ -0,0 +1,107 @@ +From 8227a9534bb09d202441b3e554da53815be66a28 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Fri, 25 Apr 2025 13:17:12 +0100 +Subject: [PATCH 2/4] meson/configure: add 'valgrind' option & --{en, + dis}able-valgrind flag +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Daniel P. BerrangĂ© +RH-MergeRequest: 360: distro: add an explicit valgrind-devel build dep +RH-Jira: RHEL-88457 +RH-Acked-by: Thomas Huth +RH-Acked-by: Eric Blake +RH-Commit: [1/2] 55ab738650e95ff0e951897001d9246a725ee699 (berrange/centos-src-qemu) + +Currently valgrind debugging support for coroutine stacks is enabled +unconditionally when valgrind/valgrind.h is found. There is no way +to disable valgrind support if valgrind.h is present in the build env. + +This is bad for distros, as an dependency far down the chain may cause +valgrind.h to become installed, inadvertently enabling QEMU's valgrind +debugging support. It also means if a distro wants valgrind support +there is no way to mandate this. + +The solution is to add a 'valgrind' build feature to meson and thus +configure script. + +Signed-off-by: Daniel P. BerrangĂ© +Reviewed-by: Thomas Huth +Message-ID: <20250425121713.1913424-1-berrange@redhat.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 6b1c744ec0d66d6d568f9a156282153fc11a21cf) +--- + meson.build | 13 ++++++++++++- + meson_options.txt | 2 ++ + scripts/meson-buildoptions.sh | 3 +++ + 3 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/meson.build b/meson.build +index 0607c1313b..dadd47d362 100644 +--- a/meson.build ++++ b/meson.build +@@ -2617,7 +2617,17 @@ config_host_data.set('CONFIG_FSTRIM', qga_fstrim) + # has_header + config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h')) + config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h')) +-config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h')) ++valgrind = false ++if get_option('valgrind').allowed() ++ if cc.has_header('valgrind/valgrind.h') ++ valgrind = true ++ else ++ if get_option('valgrind').enabled() ++ error('valgrind requested but valgrind.h not found') ++ endif ++ endif ++endif ++config_host_data.set('CONFIG_VALGRIND_H', valgrind) + config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h')) + config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h')) + config_host_data.set('HAVE_OPENAT2_H', cc.has_header('linux/openat2.h')) +@@ -4856,6 +4866,7 @@ endif + if host_os == 'darwin' + summary_info += {'ParavirtualizedGraphics support': pvg} + endif ++summary_info += {'valgrind': valgrind} + summary(summary_info, bool_yn: true, section: 'Dependencies') + + if host_arch == 'unknown' +diff --git a/meson_options.txt b/meson_options.txt +index ad6996178c..6592d9fb07 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -117,6 +117,8 @@ option('dbus_display', type: 'feature', value: 'auto', + description: '-display dbus support') + option('tpm', type : 'feature', value : 'auto', + description: 'TPM support') ++option('valgrind', type : 'feature', value: 'auto', ++ description: 'valgrind debug support for coroutine stacks') + + # Do not enable it by default even for Mingw32, because it doesn't + # work on Wine. +diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh +index e9edc8a919..541e1e7a2f 100644 +--- a/scripts/meson-buildoptions.sh ++++ b/scripts/meson-buildoptions.sh +@@ -199,6 +199,7 @@ meson_options_help() { + printf "%s\n" ' u2f U2F emulation support' + printf "%s\n" ' uadk UADK Library support' + printf "%s\n" ' usb-redir libusbredir support' ++ printf "%s\n" ' valgrind valgrind debug support for coroutine stacks' + printf "%s\n" ' vde vde network backend support' + printf "%s\n" ' vdi vdi image format support' + printf "%s\n" ' vduse-blk-export' +@@ -528,6 +529,8 @@ _meson_option_parse() { + --disable-ubsan) printf "%s" -Dubsan=false ;; + --enable-usb-redir) printf "%s" -Dusb_redir=enabled ;; + --disable-usb-redir) printf "%s" -Dusb_redir=disabled ;; ++ --enable-valgrind) printf "%s" -Dvalgrind=enabled ;; ++ --disable-valgrind) printf "%s" -Dvalgrind=disabled ;; + --enable-vde) printf "%s" -Dvde=enabled ;; + --disable-vde) printf "%s" -Dvde=disabled ;; + --enable-vdi) printf "%s" -Dvdi=enabled ;; +-- +2.39.3 + diff --git a/kvm-migration-Add-helper-to-get-target-runstate.patch b/kvm-migration-Add-helper-to-get-target-runstate.patch deleted file mode 100644 index fb34d70..0000000 --- a/kvm-migration-Add-helper-to-get-target-runstate.patch +++ /dev/null @@ -1,84 +0,0 @@ -From b6ed71f7b16e09a29ab479f437805d83ee0c85e0 Mon Sep 17 00:00:00 2001 -From: Peter Xu -Date: Fri, 6 Dec 2024 18:08:33 -0500 -Subject: [PATCH 01/22] migration: Add helper to get target runstate - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [1/22] a64178a0575a1b921e8a868a8007d0a50eb7ae29 (kmwolf/centos-qemu-kvm) - -In 99% cases, after QEMU migrates to dest host, it tries to detect the -target VM runstate using global_state_get_runstate(). - -There's one outlier so far which is Xen that won't send global state. -That's the major reason why global_state_received() check was always there -together with global_state_get_runstate(). - -However it's utterly confusing why global_state_received() has anything to -do with "let's start VM or not". - -Provide a helper to explain it, then we have an unified entry for getting -the target dest QEMU runstate after migration. - -Suggested-by: Fabiano Rosas -Signed-off-by: Peter Xu -Message-Id: <20241206230838.1111496-2-peterx@redhat.com> -Signed-off-by: Fabiano Rosas -(cherry picked from commit 7815f69867da92335055d4b5248430b0f122ce4e) -Signed-off-by: Kevin Wolf ---- - migration/migration.c | 21 +++++++++++++++++---- - 1 file changed, 17 insertions(+), 4 deletions(-) - -diff --git a/migration/migration.c b/migration/migration.c -index 3dea06d577..c7a9e2e026 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -135,6 +135,21 @@ static bool migration_needs_multiple_sockets(void) - return migrate_multifd() || migrate_postcopy_preempt(); - } - -+static RunState migration_get_target_runstate(void) -+{ -+ /* -+ * When the global state is not migrated, it means we don't know the -+ * runstate of the src QEMU. We don't have much choice but assuming -+ * the VM is running. NOTE: this is pretty rare case, so far only Xen -+ * uses it. -+ */ -+ if (!global_state_received()) { -+ return RUN_STATE_RUNNING; -+ } -+ -+ return global_state_get_runstate(); -+} -+ - static bool transport_supports_multi_channels(MigrationAddress *addr) - { - if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) { -@@ -727,8 +742,7 @@ static void process_incoming_migration_bh(void *opaque) - * unless we really are starting the VM. - */ - if (!migrate_late_block_activate() || -- (autostart && (!global_state_received() || -- runstate_is_live(global_state_get_runstate())))) { -+ (autostart && runstate_is_live(migration_get_target_runstate()))) { - /* Make sure all file formats throw away their mutable metadata. - * If we get an error here, just don't restart the VM yet. */ - bdrv_activate_all(&local_err); -@@ -751,8 +765,7 @@ static void process_incoming_migration_bh(void *opaque) - - dirty_bitmap_mig_before_vm_start(); - -- if (!global_state_received() || -- runstate_is_live(global_state_get_runstate())) { -+ if (runstate_is_live(migration_get_target_runstate())) { - if (autostart) { - vm_start(); - } else { --- -2.39.3 - diff --git a/kvm-migration-Add-qtest-for-migration-over-RDMA.patch b/kvm-migration-Add-qtest-for-migration-over-RDMA.patch new file mode 100644 index 0000000..c6b3a73 --- /dev/null +++ b/kvm-migration-Add-qtest-for-migration-over-RDMA.patch @@ -0,0 +1,222 @@ +From a408d755e0c764f80c8dc50942c9d74e4458cf98 Mon Sep 17 00:00:00 2001 +From: Li Zhijian +Date: Tue, 11 Mar 2025 10:42:21 +0800 +Subject: [PATCH 08/33] migration: Add qtest for migration over RDMA +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Prasad Pandit +RH-MergeRequest: 390: migration: allow to enable multifd+postcopy features together, but use multifd during precopy only +RH-Jira: RHEL-59697 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Miroslav Rezanina +RH-Commit: [8/11] bf9644e800b982d81d3b68f6d3951c207c66fc76 (pjp/cs-qemu-kvm) + +This qtest requires there is a RDMA(RoCE) link in the host. +In order to make the test work smoothly, introduce a +scripts/rdma-migration-helper.sh to detect existing RoCE link before +running the test. + +Test will be skipped if there is no available RoCE link. + # Start of rdma tests + # Running /x86_64/migration/precopy/rdma/plain + ok 1 /x86_64/migration/precopy/rdma/plain # SKIP No rdma link available + # To enable the test: + # Run 'scripts/rdma-migration-helper.sh setup' with root to setup a new rdma/rxe link and rerun the test + # Optional: run 'scripts/rdma-migration-helper.sh clean' to revert the 'setup' + + # End of rdma tests + +Jira: https://issues.redhat.com/browse/RHEL-59697 +Cc: Philippe Mathieu-DaudĂ© +Cc: Stefan Hajnoczi +Reviewed-by: Peter Xu +Signed-off-by: Li Zhijian +Message-ID: <20250311024221.363421-1-lizhijian@fujitsu.com> +[add 'head -1' to script, reformat test message] +Signed-off-by: Fabiano Rosas +(cherry picked from commit 7d9849c3c41463ab9ba40348a8606927dc0fb85d) +Signed-off-by: Prasad Pandit +--- + MAINTAINERS | 1 + + scripts/rdma-migration-helper.sh | 70 +++++++++++++++++++++++++++ + tests/qtest/migration/precopy-tests.c | 66 +++++++++++++++++++++++++ + 3 files changed, 137 insertions(+) + create mode 100755 scripts/rdma-migration-helper.sh + +diff --git a/MAINTAINERS b/MAINTAINERS +index d54b5578f8..465aedbcfb 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -3516,6 +3516,7 @@ R: Li Zhijian + R: Peter Xu + S: Odd Fixes + F: migration/rdma* ++F: scripts/rdma-migration-helper.sh + + Migration dirty limit and dirty page rate + M: Hyman Huang +diff --git a/scripts/rdma-migration-helper.sh b/scripts/rdma-migration-helper.sh +new file mode 100755 +index 0000000000..a39f2fb0e5 +--- /dev/null ++++ b/scripts/rdma-migration-helper.sh +@@ -0,0 +1,70 @@ ++#!/bin/bash ++ ++# Copied from blktests ++get_ipv4_addr() ++{ ++ ip -4 -o addr show dev "$1" | ++ sed -n 's/.*[[:blank:]]inet[[:blank:]]*\([^[:blank:]/]*\).*/\1/p' | ++ head -1 | tr -d '\n' ++} ++ ++# existing rdma interfaces ++rdma_interfaces() ++{ ++ rdma link show | sed -nE 's/^link .* netdev ([^ ]+).*$/\1 /p' ++} ++ ++# existing valid ipv4 interfaces ++ipv4_interfaces() ++{ ++ ip -o addr show | awk '/inet / {print $2}' | grep -v -w lo ++} ++ ++rdma_rxe_detect() ++{ ++ for r in $(rdma_interfaces) ++ do ++ ipv4_interfaces | grep -qw $r && get_ipv4_addr $r && return ++ done ++ ++ return 1 ++} ++ ++rdma_rxe_setup() ++{ ++ for i in $(ipv4_interfaces) ++ do ++ rdma_interfaces | grep -qw $i && continue ++ rdma link add "${i}_rxe" type rxe netdev "$i" && { ++ echo "Setup new rdma/rxe ${i}_rxe for $i with $(get_ipv4_addr $i)" ++ return ++ } ++ done ++ ++ echo "Failed to setup any new rdma/rxe link" >&2 ++ return 1 ++} ++ ++rdma_rxe_clean() ++{ ++ modprobe -r rdma_rxe ++} ++ ++operation=${1:-detect} ++ ++command -v rdma >/dev/null || { ++ echo "Command 'rdma' is not available, please install it first." >&2 ++ exit 1 ++} ++ ++if [ "$operation" == "setup" ] || [ "$operation" == "clean" ]; then ++ [ "$UID" == 0 ] || { ++ echo "Root privilege is required to setup/clean a rdma/rxe link" >&2 ++ exit 1 ++ } ++ rdma_rxe_"$operation" ++elif [ "$operation" == "detect" ]; then ++ rdma_rxe_detect ++else ++ echo "Usage: $0 [setup | detect | clean]" ++fi +diff --git a/tests/qtest/migration/precopy-tests.c b/tests/qtest/migration/precopy-tests.c +index f8404793b8..87b0a7e8ef 100644 +--- a/tests/qtest/migration/precopy-tests.c ++++ b/tests/qtest/migration/precopy-tests.c +@@ -99,6 +99,68 @@ static void test_precopy_unix_dirty_ring(void) + test_precopy_common(&args); + } + ++#ifdef CONFIG_RDMA ++ ++#define RDMA_MIGRATION_HELPER "scripts/rdma-migration-helper.sh" ++static int new_rdma_link(char *buffer) ++{ ++ char cmd[256]; ++ bool verbose = g_getenv("QTEST_LOG"); ++ ++ snprintf(cmd, sizeof(cmd), "%s detect %s", RDMA_MIGRATION_HELPER, ++ verbose ? "" : "2>/dev/null"); ++ ++ FILE *pipe = popen(cmd, "r"); ++ if (pipe == NULL) { ++ perror("Failed to run script"); ++ return -1; ++ } ++ ++ int idx = 0; ++ while (fgets(buffer + idx, 128 - idx, pipe) != NULL) { ++ idx += strlen(buffer); ++ } ++ ++ int status = pclose(pipe); ++ if (status == -1) { ++ perror("Error reported by pclose()"); ++ return -1; ++ } else if (WIFEXITED(status)) { ++ return WEXITSTATUS(status); ++ } ++ ++ return -1; ++} ++ ++static void test_precopy_rdma_plain(void) ++{ ++ char buffer[128] = {}; ++ ++ if (new_rdma_link(buffer)) { ++ g_test_skip("No rdma link available\n" ++ "# To enable the test:\n" ++ "# Run \'" RDMA_MIGRATION_HELPER " setup\' with root to " ++ "setup a new rdma/rxe link and rerun the test\n" ++ "# Optional: run 'scripts/rdma-migration-helper.sh clean' " ++ "to revert the 'setup'"); ++ return; ++ } ++ ++ /* ++ * TODO: query a free port instead of hard code. ++ * 29200=('R'+'D'+'M'+'A')*100 ++ **/ ++ g_autofree char *uri = g_strdup_printf("rdma:%s:29200", buffer); ++ ++ MigrateCommon args = { ++ .listen_uri = uri, ++ .connect_uri = uri, ++ }; ++ ++ test_precopy_common(&args); ++} ++#endif ++ + static void test_precopy_tcp_plain(void) + { + MigrateCommon args = { +@@ -1127,6 +1189,10 @@ static void migration_test_add_precopy_smoke(MigrationTestEnv *env) + test_multifd_tcp_uri_none); + migration_test_add("/migration/multifd/tcp/plain/cancel", + test_multifd_tcp_cancel); ++#ifdef CONFIG_RDMA ++ migration_test_add("/migration/precopy/rdma/plain", ++ test_precopy_rdma_plain); ++#endif + } + + void migration_test_add_precopy(MigrationTestEnv *env) +-- +2.39.3 + diff --git a/kvm-migration-Add-save_postcopy_prepare-savevm-handler.patch b/kvm-migration-Add-save_postcopy_prepare-savevm-handler.patch new file mode 100644 index 0000000..861a15a --- /dev/null +++ b/kvm-migration-Add-save_postcopy_prepare-savevm-handler.patch @@ -0,0 +1,140 @@ +From 883ddd4af17376fc62bdee9f4b30dfaa45d0c968 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Fri, 11 Apr 2025 17:15:30 +0530 +Subject: [PATCH 03/33] migration: Add save_postcopy_prepare() savevm handler + +RH-Author: Prasad Pandit +RH-MergeRequest: 390: migration: allow to enable multifd+postcopy features together, but use multifd during precopy only +RH-Jira: RHEL-59697 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Miroslav Rezanina +RH-Commit: [3/11] 2f2f108041d921985e2ddce5fd8e805fc539e74f (pjp/cs-qemu-kvm) + +Add a savevm handler for a module to opt-in sending extra sections right +before postcopy starts, and before VM is stopped. + +RAM will start to use this new savevm handler in the next patch to do flush +and sync for multifd pages. + +Note that we choose to do it before VM stopped because the current only +potential user is not sensitive to VM status, so doing it before VM is +stopped is preferred to enlarge any postcopy downtime. + +It is still a bit unfortunate that we need to introduce such a new savevm +handler just for the only use case, however it's so far the cleanest. + +Jira: https://issues.redhat.com/browse/RHEL-59697 +Signed-off-by: Peter Xu +Signed-off-by: Prasad Pandit +Reviewed-by: Fabiano Rosas +Message-ID: <20250411114534.3370816-4-ppandit@redhat.com> +Signed-off-by: Fabiano Rosas +(cherry picked from commit 1d481116015428c02f7e3635f9bc0b88b0978fdc) +Signed-off-by: Prasad Pandit +--- + include/migration/register.h | 15 +++++++++++++++ + migration/migration.c | 4 ++++ + migration/savevm.c | 33 +++++++++++++++++++++++++++++++++ + migration/savevm.h | 1 + + 4 files changed, 53 insertions(+) + +diff --git a/include/migration/register.h b/include/migration/register.h +index c041ce32f2..b79dc81b8d 100644 +--- a/include/migration/register.h ++++ b/include/migration/register.h +@@ -189,6 +189,21 @@ typedef struct SaveVMHandlers { + + /* This runs outside the BQL! */ + ++ /** ++ * @save_postcopy_prepare ++ * ++ * This hook will be invoked on the source side right before switching ++ * to postcopy (before VM stopped). ++ * ++ * @f: QEMUFile where to send the data ++ * @opaque: Data pointer passed to register_savevm_live() ++ * @errp: Error** used to report error message ++ * ++ * Returns: true if succeeded, false if error occured. When false is ++ * returned, @errp must be set. ++ */ ++ bool (*save_postcopy_prepare)(QEMUFile *f, void *opaque, Error **errp); ++ + /** + * @state_pending_estimate + * +diff --git a/migration/migration.c b/migration/migration.c +index 64f4f40ae3..4bb29b7193 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -2717,6 +2717,10 @@ static int postcopy_start(MigrationState *ms, Error **errp) + } + } + ++ if (!qemu_savevm_state_postcopy_prepare(ms->to_dst_file, errp)) { ++ return -1; ++ } ++ + trace_postcopy_start(); + bql_lock(); + trace_postcopy_start_set_run(); +diff --git a/migration/savevm.c b/migration/savevm.c +index ce158c3512..23ef4c7dc9 100644 +--- a/migration/savevm.c ++++ b/migration/savevm.c +@@ -1523,6 +1523,39 @@ void qemu_savevm_state_complete_postcopy(QEMUFile *f) + qemu_fflush(f); + } + ++bool qemu_savevm_state_postcopy_prepare(QEMUFile *f, Error **errp) ++{ ++ SaveStateEntry *se; ++ bool ret; ++ ++ QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { ++ if (!se->ops || !se->ops->save_postcopy_prepare) { ++ continue; ++ } ++ ++ if (se->ops->is_active) { ++ if (!se->ops->is_active(se->opaque)) { ++ continue; ++ } ++ } ++ ++ trace_savevm_section_start(se->idstr, se->section_id); ++ ++ save_section_header(f, se, QEMU_VM_SECTION_PART); ++ ret = se->ops->save_postcopy_prepare(f, se->opaque, errp); ++ save_section_footer(f, se); ++ ++ trace_savevm_section_end(se->idstr, se->section_id, ret); ++ ++ if (!ret) { ++ assert(*errp); ++ return false; ++ } ++ } ++ ++ return true; ++} ++ + int qemu_savevm_state_complete_precopy_iterable(QEMUFile *f, bool in_postcopy) + { + int64_t start_ts_each, end_ts_each; +diff --git a/migration/savevm.h b/migration/savevm.h +index 138c39a7f9..2d5e9c7166 100644 +--- a/migration/savevm.h ++++ b/migration/savevm.h +@@ -45,6 +45,7 @@ void qemu_savevm_state_pending_exact(uint64_t *must_precopy, + void qemu_savevm_state_pending_estimate(uint64_t *must_precopy, + uint64_t *can_postcopy); + int qemu_savevm_state_complete_precopy_iterable(QEMUFile *f, bool in_postcopy); ++bool qemu_savevm_state_postcopy_prepare(QEMUFile *f, Error **errp); + void qemu_savevm_send_ping(QEMUFile *f, uint32_t value); + void qemu_savevm_send_open_return_path(QEMUFile *f); + int qemu_savevm_send_packaged(QEMUFile *f, const uint8_t *buf, size_t len); +-- +2.39.3 + diff --git a/kvm-migration-Allow-pipes-to-keep-working-for-fd-migrati.patch b/kvm-migration-Allow-pipes-to-keep-working-for-fd-migrati.patch deleted file mode 100644 index 145d080..0000000 --- a/kvm-migration-Allow-pipes-to-keep-working-for-fd-migrati.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 3f4762ae8fd1fb148b97cd713209d3b55e8ea489 Mon Sep 17 00:00:00 2001 -From: Peter Xu -Date: Wed, 20 Nov 2024 11:01:32 -0500 -Subject: [PATCH] migration: Allow pipes to keep working for fd migrations -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Peter Xu -RH-MergeRequest: 302: migration: Allow pipes to keep working for fd migrations -RH-Jira: RHEL-69047 -RH-Acked-by: Juraj Marcin -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/1] f5c0af772cbd3ced12a7b260f86f98e74d8345d1 (peterx/qemu-kvm) - -Libvirt may still use pipes for old file migrations in fd: URI form, -especially when loading old images dumped from Libvirt's compression -algorithms. - -In that case, Libvirt needs to compress / uncompress the images on its own -over the migration binary stream, and pipes are passed over to QEMU for -outgoing / incoming migrations in "fd:" URIs. - -For future such use case, it should be suggested to use mapped-ram when -saving such VM image. However there can still be old images that was -compressed in such way, so libvirt needs to be able to load those images, -uncompress them and use the same pipe mechanism to pass that over to QEMU. - -It means, even if new file migrations can be gradually moved over to -mapped-ram (after Libvirt start supporting it), Libvirt still needs the -uncompressor for the old images to be able to load like before. - -Meanwhile since Libvirt currently exposes the compression capability to -guest images, it may needs its own lifecycle management to move that over -to mapped-ram, maybe can be done after mapped-ram saved the image, however -Dan and PeterK raised concern on temporary double disk space consumption. -I suppose for now the easiest is to enable pipes for both sides of "fd:" -migrations, until all things figured out from Libvirt side on how to move -on. - -And for "channels" QMP interface support on "migrate" / "migrate-incoming" -commands, we'll also need to move away from pipe. But let's leave that for -later too. - -So far, still allow pipes to happen like before on both save/load sides, -just like we would allow sockets to pass. - -Cc: qemu-stable -Cc: Fabiano Rosas -Cc: Peter Krempa -Cc: Daniel P. BerrangĂ© -Fixes: c55deb860c ("migration: Deprecate fd: for file migration") -Reviewed-by: Fabiano Rosas -Link: https://lore.kernel.org/r/20241120160132.3659735-1-peterx@redhat.com -Signed-off-by: Peter Xu -(cherry picked from commit 87ae45e602e2943d58509e470e3a1d4ba084ab2f) -Signed-off-by: Peter Xu ---- - migration/fd.c | 27 +++++++++++++++++++++++++-- - 1 file changed, 25 insertions(+), 2 deletions(-) - -diff --git a/migration/fd.c b/migration/fd.c -index aab5189eac..9bf9be6acb 100644 ---- a/migration/fd.c -+++ b/migration/fd.c -@@ -25,6 +25,29 @@ - #include "io/channel-util.h" - #include "trace.h" - -+static bool fd_is_pipe(int fd) -+{ -+ struct stat statbuf; -+ -+ if (fstat(fd, &statbuf) == -1) { -+ return false; -+ } -+ -+ return S_ISFIFO(statbuf.st_mode); -+} -+ -+static bool migration_fd_valid(int fd) -+{ -+ if (fd_is_socket(fd)) { -+ return true; -+ } -+ -+ if (fd_is_pipe(fd)) { -+ return true; -+ } -+ -+ return false; -+} - - void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp) - { -@@ -34,7 +57,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error ** - return; - } - -- if (!fd_is_socket(fd)) { -+ if (!migration_fd_valid(fd)) { - warn_report("fd: migration to a file is deprecated." - " Use file: instead."); - } -@@ -68,7 +91,7 @@ void fd_start_incoming_migration(const char *fdname, Error **errp) - return; - } - -- if (!fd_is_socket(fd)) { -+ if (!migration_fd_valid(fd)) { - warn_report("fd: migration to a file is deprecated." - " Use file: instead."); - } --- -2.39.3 - diff --git a/kvm-migration-Ensure-vmstate_save-sets-errp.patch b/kvm-migration-Ensure-vmstate_save-sets-errp.patch deleted file mode 100644 index 47a3c70..0000000 --- a/kvm-migration-Ensure-vmstate_save-sets-errp.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 6be2f51c147df1ab1dd7c68c6b554512dfc05e6f Mon Sep 17 00:00:00 2001 -From: Hanna Czenczek -Date: Tue, 15 Oct 2024 19:04:37 +0200 -Subject: [PATCH 1/9] migration: Ensure vmstate_save() sets errp - -RH-Author: Hanna Czenczek -RH-MergeRequest: 288: migration: Ensure vmstate_save() sets errp -RH-Jira: RHEL-63051 -RH-Acked-by: Stefano Garzarella -RH-Acked-by: German Maglione -RH-Commit: [1/1] 4d5a65c294ae83a29db885e42fb3f2ca913c36f0 (hreitz/qemu-kvm-c-9-s) - -migration/savevm.c contains some calls to vmstate_save() that are -followed by migrate_set_error() if the integer return value indicates an -error. migrate_set_error() requires that the `Error *` object passed to -it is set. Therefore, vmstate_save() is assumed to always set *errp on -error. - -Right now, that assumption is not met: vmstate_save_state_v() (called -internally by vmstate_save()) will not set *errp if -vmstate_subsection_save() or vmsd->post_save() fail. Fix that by adding -an *errp parameter to vmstate_subsection_save(), and by generating a -generic error in case post_save() fails (as is already done for -pre_save()). - -Without this patch, qemu will crash after vmstate_subsection_save() or -post_save() have failed inside of a vmstate_save() call (unless -migrate_set_error() then happen to discard the new error because -s->error is already set). This happens e.g. when receiving the state -from a virtio-fs back-end (virtiofsd) fails. - -Signed-off-by: Hanna Czenczek -Link: https://lore.kernel.org/r/20241015170437.310358-1-hreitz@redhat.com -Signed-off-by: Peter Xu -(cherry picked from commit 37dfcba1a04989830c706f9cbc00450e5d3a7447) -Signed-off-by: Hanna Czenczek ---- - migration/vmstate.c | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - -diff --git a/migration/vmstate.c b/migration/vmstate.c -index ff5d589a6d..fa002b24e8 100644 ---- a/migration/vmstate.c -+++ b/migration/vmstate.c -@@ -22,7 +22,8 @@ - #include "trace.h" - - static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, -- void *opaque, JSONWriter *vmdesc); -+ void *opaque, JSONWriter *vmdesc, -+ Error **errp); - static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, - void *opaque); - -@@ -441,12 +442,13 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd, - json_writer_end_array(vmdesc); - } - -- ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc); -+ ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc, errp); - - if (vmsd->post_save) { - int ps_ret = vmsd->post_save(opaque); -- if (!ret) { -+ if (!ret && ps_ret) { - ret = ps_ret; -+ error_setg(errp, "post-save failed: %s", vmsd->name); - } - } - return ret; -@@ -518,7 +520,8 @@ static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, - } - - static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, -- void *opaque, JSONWriter *vmdesc) -+ void *opaque, JSONWriter *vmdesc, -+ Error **errp) - { - const VMStateDescription * const *sub = vmsd->subsections; - bool vmdesc_has_subsections = false; -@@ -546,7 +549,7 @@ static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, - qemu_put_byte(f, len); - qemu_put_buffer(f, (uint8_t *)vmsdsub->name, len); - qemu_put_be32(f, vmsdsub->version_id); -- ret = vmstate_save_state(f, vmsdsub, opaque, vmdesc); -+ ret = vmstate_save_state_with_err(f, vmsdsub, opaque, vmdesc, errp); - if (ret) { - return ret; - } --- -2.39.3 - diff --git a/kvm-migration-block-Apply-late-block-active-behavior-to-.patch b/kvm-migration-block-Apply-late-block-active-behavior-to-.patch deleted file mode 100644 index 93dc4d5..0000000 --- a/kvm-migration-block-Apply-late-block-active-behavior-to-.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 48773d81978e4c355445cb767c6c8b5346555092 Mon Sep 17 00:00:00 2001 -From: Peter Xu -Date: Fri, 6 Dec 2024 18:08:36 -0500 -Subject: [PATCH 04/22] migration/block: Apply late-block-active behavior to - postcopy - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [4/22] 917b74fe13976f066f7c31dbd0eee85f424bbab5 (kmwolf/centos-qemu-kvm) - -Postcopy never cared about late-block-active. However there's no mention -in the capability that it doesn't apply to postcopy. - -Considering that we _assumed_ late activation is always good, do that too -for postcopy unconditionally, just like precopy. After this patch, we -should have unified the behavior across all. - -Signed-off-by: Peter Xu -Reviewed-by: Fabiano Rosas -Message-Id: <20241206230838.1111496-5-peterx@redhat.com> -Signed-off-by: Fabiano Rosas -(cherry picked from commit 61f2b489987c51159c53101a072c6aa901b50506) -Signed-off-by: Kevin Wolf ---- - migration/savevm.c | 25 ++++++++++++------------- - 1 file changed, 12 insertions(+), 13 deletions(-) - -diff --git a/migration/savevm.c b/migration/savevm.c -index 6bb404b9c8..a0c4befdc1 100644 ---- a/migration/savevm.c -+++ b/migration/savevm.c -@@ -2156,22 +2156,21 @@ static void loadvm_postcopy_handle_run_bh(void *opaque) - - trace_vmstate_downtime_checkpoint("dst-postcopy-bh-announced"); - -- /* Make sure all file formats throw away their mutable metadata. -- * If we get an error here, just don't restart the VM yet. */ -- bdrv_activate_all(&local_err); -- if (local_err) { -- error_report_err(local_err); -- local_err = NULL; -- autostart = false; -- } -- -- trace_vmstate_downtime_checkpoint("dst-postcopy-bh-cache-invalidated"); -- - dirty_bitmap_mig_before_vm_start(); - - if (autostart) { -- /* Hold onto your hats, starting the CPU */ -- vm_start(); -+ /* -+ * Make sure all file formats throw away their mutable metadata. -+ * If we get an error here, just don't restart the VM yet. -+ */ -+ bdrv_activate_all(&local_err); -+ trace_vmstate_downtime_checkpoint("dst-postcopy-bh-cache-invalidated"); -+ if (local_err) { -+ error_report_err(local_err); -+ local_err = NULL; -+ } else { -+ vm_start(); -+ } - } else { - /* leave it paused and let management decide when to start the CPU */ - runstate_set(RUN_STATE_PAUSED); --- -2.39.3 - diff --git a/kvm-migration-block-Fix-possible-race-with-block_inactiv.patch b/kvm-migration-block-Fix-possible-race-with-block_inactiv.patch deleted file mode 100644 index b8f6591..0000000 --- a/kvm-migration-block-Fix-possible-race-with-block_inactiv.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 3c6e09fe92972513d38c15c03db29a6843e44d3d Mon Sep 17 00:00:00 2001 -From: Peter Xu -Date: Fri, 6 Dec 2024 18:08:37 -0500 -Subject: [PATCH 05/22] migration/block: Fix possible race with block_inactive - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [5/22] a88a20817cb28674367cc57dfe16e6c60c7122b1 (kmwolf/centos-qemu-kvm) - -Src QEMU sets block_inactive=true very early before the invalidation takes -place. It means if something wrong happened during setting the flag but -before reaching qemu_savevm_state_complete_precopy_non_iterable() where it -did the invalidation work, it'll make block_inactive flag inconsistent. - -For example, think about when qemu_savevm_state_complete_precopy_iterable() -can fail: it will have block_inactive set to true even if all block drives -are active. - -Fix that by only update the flag after the invalidation is done. - -No Fixes for any commit, because it's not an issue if bdrv_activate_all() -is re-entrant upon all-active disks - false positive block_inactive can -bring nothing more than "trying to active the blocks but they're already -active". However let's still do it right to avoid the inconsistent flag -v.s. reality. - -Signed-off-by: Peter Xu -Reviewed-by: Fabiano Rosas -Message-Id: <20241206230838.1111496-6-peterx@redhat.com> -Signed-off-by: Fabiano Rosas -(cherry picked from commit 8c97c5a476d146b35b2873ef73df601216a494d9) -Signed-off-by: Kevin Wolf ---- - migration/migration.c | 9 +++------ - migration/savevm.c | 2 ++ - 2 files changed, 5 insertions(+), 6 deletions(-) - -diff --git a/migration/migration.c b/migration/migration.c -index 8a262e01ff..784b7e9b90 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -2779,14 +2779,11 @@ static int migration_completion_precopy(MigrationState *s, - goto out_unlock; - } - -- /* -- * Inactivate disks except in COLO, and track that we have done so in order -- * to remember to reactivate them if migration fails or is cancelled. -- */ -- s->block_inactive = !migrate_colo(); - migration_rate_set(RATE_LIMIT_DISABLED); -+ -+ /* Inactivate disks except in COLO */ - ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false, -- s->block_inactive); -+ !migrate_colo()); - out_unlock: - bql_unlock(); - return ret; -diff --git a/migration/savevm.c b/migration/savevm.c -index a0c4befdc1..b88dadd904 100644 ---- a/migration/savevm.c -+++ b/migration/savevm.c -@@ -1577,6 +1577,8 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f, - qemu_file_set_error(f, ret); - return ret; - } -+ /* Remember that we did this */ -+ s->block_inactive = true; - } - if (!in_postcopy) { - /* Postcopy stream will still be going */ --- -2.39.3 - diff --git a/kvm-migration-block-Make-late-block-active-the-default.patch b/kvm-migration-block-Make-late-block-active-the-default.patch deleted file mode 100644 index 6381fff..0000000 --- a/kvm-migration-block-Make-late-block-active-the-default.patch +++ /dev/null @@ -1,94 +0,0 @@ -From e97150d6dad119d3dd234c25f9b0373a2c323299 Mon Sep 17 00:00:00 2001 -From: Peter Xu -Date: Fri, 6 Dec 2024 18:08:35 -0500 -Subject: [PATCH 03/22] migration/block: Make late-block-active the default - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [3/22] 9e197765811f282cd133013bd949be9bc49ca249 (kmwolf/centos-qemu-kvm) - -Migration capability 'late-block-active' controls when the block drives -will be activated. If enabled, block drives will only be activated until -VM starts, either src runstate was "live" (RUNNING, or SUSPENDED), or it'll -be postponed until qmp_cont(). - -Let's do this unconditionally. There's no harm to delay activation of -block drives. Meanwhile there's no ABI breakage if dest does it, because -src QEMU has nothing to do with it, so it's no concern on ABI breakage. - -IIUC we could avoid introducing this cap when introducing it before, but -now it's still not too late to just always do it. Cap now prone to -removal, but it'll be for later patches. - -Signed-off-by: Peter Xu -Reviewed-by: Fabiano Rosas -Message-Id: <20241206230838.1111496-4-peterx@redhat.com> -Signed-off-by: Fabiano Rosas -(cherry picked from commit fca9aef1c8d8fc4482cc541638dbfac76dc125d6) -Signed-off-by: Kevin Wolf ---- - migration/migration.c | 38 +++++++++++++++++++------------------- - 1 file changed, 19 insertions(+), 19 deletions(-) - -diff --git a/migration/migration.c b/migration/migration.c -index c7a9e2e026..8a262e01ff 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -735,24 +735,6 @@ static void process_incoming_migration_bh(void *opaque) - - trace_vmstate_downtime_checkpoint("dst-precopy-bh-enter"); - -- /* If capability late_block_activate is set: -- * Only fire up the block code now if we're going to restart the -- * VM, else 'cont' will do it. -- * This causes file locking to happen; so we don't want it to happen -- * unless we really are starting the VM. -- */ -- if (!migrate_late_block_activate() || -- (autostart && runstate_is_live(migration_get_target_runstate()))) { -- /* Make sure all file formats throw away their mutable metadata. -- * If we get an error here, just don't restart the VM yet. */ -- bdrv_activate_all(&local_err); -- if (local_err) { -- error_report_err(local_err); -- local_err = NULL; -- autostart = false; -- } -- } -- - /* - * This must happen after all error conditions are dealt with and - * we're sure the VM is going to be running on this host. -@@ -767,7 +749,25 @@ static void process_incoming_migration_bh(void *opaque) - - if (runstate_is_live(migration_get_target_runstate())) { - if (autostart) { -- vm_start(); -+ /* -+ * Block activation is always delayed until VM starts, either -+ * here (which means we need to start the dest VM right now..), -+ * or until qmp_cont() later. -+ * -+ * We used to have cap 'late-block-activate' but now we do this -+ * unconditionally, as it has no harm but only benefit. E.g., -+ * it's not part of migration ABI on the time of disk activation. -+ * -+ * Make sure all file formats throw away their mutable -+ * metadata. If error, don't restart the VM yet. -+ */ -+ bdrv_activate_all(&local_err); -+ if (local_err) { -+ error_report_err(local_err); -+ local_err = NULL; -+ } else { -+ vm_start(); -+ } - } else { - runstate_set(RUN_STATE_PAUSED); - } --- -2.39.3 - diff --git a/kvm-migration-block-Rewrite-disk-activation.patch b/kvm-migration-block-Rewrite-disk-activation.patch deleted file mode 100644 index d449df0..0000000 --- a/kvm-migration-block-Rewrite-disk-activation.patch +++ /dev/null @@ -1,565 +0,0 @@ -From d97a28baf4a05c67bf644ac543a3f48a0f2875c0 Mon Sep 17 00:00:00 2001 -From: Peter Xu -Date: Fri, 6 Dec 2024 18:08:38 -0500 -Subject: [PATCH 06/22] migration/block: Rewrite disk activation - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [6/22] c029cea2613097e1f26c563e6c220a00caa18501 (kmwolf/centos-qemu-kvm) - -This patch proposes a flag to maintain disk activation status globally. It -mostly rewrites disk activation mgmt for QEMU, including COLO and QMP -command xen_save_devices_state. - -Backgrounds -=========== - -We have two problems on disk activations, one resolved, one not. - -Problem 1: disk activation recover (for switchover interruptions) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When migration is either cancelled or failed during switchover, especially -when after the disks are inactivated, QEMU needs to remember re-activate -the disks again before vm starts. - -It used to be done separately in two paths: one in qmp_migrate_cancel(), -the other one in the failure path of migration_completion(). - -It used to be fixed in different commits, all over the places in QEMU. So -these are the relevant changes I saw, I'm not sure if it's complete list: - - - In 2016, commit fe904ea824 ("migration: regain control of images when - migration fails to complete") - - - In 2017, commit 1d2acc3162 ("migration: re-active images while migration - been canceled after inactive them") - - - In 2023, commit 6dab4c93ec ("migration: Attempt disk reactivation in - more failure scenarios") - -Now since we have a slightly better picture maybe we can unify the -reactivation in a single path. - -One side benefit of doing so is, we can move the disk operation outside QMP -command "migrate_cancel". It's possible that in the future we may want to -make "migrate_cancel" be OOB-compatible, while that requires the command -doesn't need BQL in the first place. This will already do that and make -migrate_cancel command lightweight. - -Problem 2: disk invalidation on top of invalidated disks -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This is an unresolved bug for current QEMU. Link in "Resolves:" at the -end. It turns out besides the src switchover phase (problem 1 above), QEMU -also needs to remember block activation on destination. - -Consider two continuous migration in a row, where the VM was always paused. -In that scenario, the disks are not activated even until migration -completed in the 1st round. When the 2nd round starts, if QEMU doesn't -know the status of the disks, it needs to try inactivate the disk again. - -Here the issue is the block layer API bdrv_inactivate_all() will crash a -QEMU if invoked on already inactive disks for the 2nd migration. For -detail, see the bug link at the end. - -Implementation -============== - -This patch proposes to maintain disk activation with a global flag, so we -know: - - - If we used to inactivate disks for migration, but migration got - cancelled, or failed, QEMU will know it should reactivate the disks. - - - On incoming side, if the disks are never activated but then another - migration is triggered, QEMU should be able to tell that inactivate is - not needed for the 2nd migration. - -We used to have disk_inactive, but it only solves the 1st issue, not the -2nd. Also, it's done in completely separate paths so it's extremely hard -to follow either how the flag changes, or the duration that the flag is -valid, and when we will reactivate the disks. - -Convert the existing disk_inactive flag into that global flag (also invert -its naming), and maintain the disk activation status for the whole -lifecycle of qemu. That includes the incoming QEMU. - -Put both of the error cases of source migration (failure, cancelled) -together into migration_iteration_finish(), which will be invoked for -either of the scenario. So from that part QEMU should behave the same as -before. However with such global maintenance on disk activation status, we -not only cleanup quite a few temporary paths that we try to maintain the -disk activation status (e.g. in postcopy code), meanwhile it fixes the -crash for problem 2 in one shot. - -For freshly started QEMU, the flag is initialized to TRUE showing that the -QEMU owns the disks by default. - -For incoming migrated QEMU, the flag will be initialized to FALSE once and -for all showing that the dest QEMU doesn't own the disks until switchover. -That is guaranteed by the "once" variable. - -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2395 -Signed-off-by: Peter Xu -Reviewed-by: Fabiano Rosas -Message-Id: <20241206230838.1111496-7-peterx@redhat.com> -Signed-off-by: Fabiano Rosas -(cherry picked from commit 8597af76153a87068b675d8099063c3ad8695773) -Signed-off-by: Kevin Wolf ---- - include/migration/misc.h | 4 ++ - migration/block-active.c | 94 ++++++++++++++++++++++++++++++++++++++++ - migration/colo.c | 2 +- - migration/meson.build | 1 + - migration/migration.c | 80 ++++++++-------------------------- - migration/migration.h | 5 +-- - migration/savevm.c | 33 ++++++-------- - migration/trace-events | 3 ++ - monitor/qmp-cmds.c | 8 +--- - 9 files changed, 139 insertions(+), 91 deletions(-) - create mode 100644 migration/block-active.c - -diff --git a/include/migration/misc.h b/include/migration/misc.h -index bfadc5613b..35ca8e1194 100644 ---- a/include/migration/misc.h -+++ b/include/migration/misc.h -@@ -111,4 +111,8 @@ bool migration_in_bg_snapshot(void); - /* migration/block-dirty-bitmap.c */ - void dirty_bitmap_mig_init(void); - -+/* Wrapper for block active/inactive operations */ -+bool migration_block_activate(Error **errp); -+bool migration_block_inactivate(void); -+ - #endif -diff --git a/migration/block-active.c b/migration/block-active.c -new file mode 100644 -index 0000000000..d477cf8182 ---- /dev/null -+++ b/migration/block-active.c -@@ -0,0 +1,94 @@ -+/* -+ * Block activation tracking for migration purpose -+ * -+ * SPDX-License-Identifier: GPL-2.0-or-later -+ * -+ * Copyright (C) 2024 Red Hat, Inc. -+ */ -+#include "qemu/osdep.h" -+#include "block/block.h" -+#include "qapi/error.h" -+#include "migration/migration.h" -+#include "qemu/error-report.h" -+#include "trace.h" -+ -+/* -+ * Migration-only cache to remember the block layer activation status. -+ * Protected by BQL. -+ * -+ * We need this because.. -+ * -+ * - Migration can fail after block devices are invalidated (during -+ * switchover phase). When that happens, we need to be able to recover -+ * the block drive status by re-activating them. -+ * -+ * - Currently bdrv_inactivate_all() is not safe to be invoked on top of -+ * invalidated drives (even if bdrv_activate_all() is actually safe to be -+ * called any time!). It means remembering this could help migration to -+ * make sure it won't invalidate twice in a row, crashing QEMU. It can -+ * happen when we migrate a PAUSED VM from host1 to host2, then migrate -+ * again to host3 without starting it. TODO: a cleaner solution is to -+ * allow safe invoke of bdrv_inactivate_all() at anytime, like -+ * bdrv_activate_all(). -+ * -+ * For freshly started QEMU, the flag is initialized to TRUE reflecting the -+ * scenario where QEMU owns block device ownerships. -+ * -+ * For incoming QEMU taking a migration stream, the flag is initialized to -+ * FALSE reflecting that the incoming side doesn't own the block devices, -+ * not until switchover happens. -+ */ -+static bool migration_block_active; -+ -+/* Setup the disk activation status */ -+void migration_block_active_setup(bool active) -+{ -+ migration_block_active = active; -+} -+ -+bool migration_block_activate(Error **errp) -+{ -+ ERRP_GUARD(); -+ -+ assert(bql_locked()); -+ -+ if (migration_block_active) { -+ trace_migration_block_activation("active-skipped"); -+ return true; -+ } -+ -+ trace_migration_block_activation("active"); -+ -+ bdrv_activate_all(errp); -+ if (*errp) { -+ error_report_err(error_copy(*errp)); -+ return false; -+ } -+ -+ migration_block_active = true; -+ return true; -+} -+ -+bool migration_block_inactivate(void) -+{ -+ int ret; -+ -+ assert(bql_locked()); -+ -+ if (!migration_block_active) { -+ trace_migration_block_activation("inactive-skipped"); -+ return true; -+ } -+ -+ trace_migration_block_activation("inactive"); -+ -+ ret = bdrv_inactivate_all(); -+ if (ret) { -+ error_report("%s: bdrv_inactivate_all() failed: %d", -+ __func__, ret); -+ return false; -+ } -+ -+ migration_block_active = false; -+ return true; -+} -diff --git a/migration/colo.c b/migration/colo.c -index 6449490221..ab903f34cb 100644 ---- a/migration/colo.c -+++ b/migration/colo.c -@@ -836,7 +836,7 @@ static void *colo_process_incoming_thread(void *opaque) - - /* Make sure all file formats throw away their mutable metadata */ - bql_lock(); -- bdrv_activate_all(&local_err); -+ migration_block_activate(&local_err); - bql_unlock(); - if (local_err) { - error_report_err(local_err); -diff --git a/migration/meson.build b/migration/meson.build -index 5ce2acb41e..6b79861d3c 100644 ---- a/migration/meson.build -+++ b/migration/meson.build -@@ -11,6 +11,7 @@ migration_files = files( - - system_ss.add(files( - 'block-dirty-bitmap.c', -+ 'block-active.c', - 'channel.c', - 'channel-block.c', - 'dirtyrate.c', -diff --git a/migration/migration.c b/migration/migration.c -index 784b7e9b90..38631d1206 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -730,7 +730,6 @@ static void qemu_start_incoming_migration(const char *uri, bool has_channels, - - static void process_incoming_migration_bh(void *opaque) - { -- Error *local_err = NULL; - MigrationIncomingState *mis = opaque; - - trace_vmstate_downtime_checkpoint("dst-precopy-bh-enter"); -@@ -761,11 +760,7 @@ static void process_incoming_migration_bh(void *opaque) - * Make sure all file formats throw away their mutable - * metadata. If error, don't restart the VM yet. - */ -- bdrv_activate_all(&local_err); -- if (local_err) { -- error_report_err(local_err); -- local_err = NULL; -- } else { -+ if (migration_block_activate(NULL)) { - vm_start(); - } - } else { -@@ -1562,16 +1557,6 @@ static void migrate_fd_cancel(MigrationState *s) - } - } - } -- if (s->state == MIGRATION_STATUS_CANCELLING && s->block_inactive) { -- Error *local_err = NULL; -- -- bdrv_activate_all(&local_err); -- if (local_err) { -- error_report_err(local_err); -- } else { -- s->block_inactive = false; -- } -- } - } - - void migration_add_notifier_mode(NotifierWithReturn *notify, -@@ -1890,6 +1875,12 @@ void qmp_migrate_incoming(const char *uri, bool has_channels, - return; - } - -+ /* -+ * Newly setup incoming QEMU. Mark the block active state to reflect -+ * that the src currently owns the disks. -+ */ -+ migration_block_active_setup(false); -+ - once = false; - } - -@@ -2542,7 +2533,6 @@ static int postcopy_start(MigrationState *ms, Error **errp) - QIOChannelBuffer *bioc; - QEMUFile *fb; - uint64_t bandwidth = migrate_max_postcopy_bandwidth(); -- bool restart_block = false; - int cur_state = MIGRATION_STATUS_ACTIVE; - - if (migrate_postcopy_preempt()) { -@@ -2578,13 +2568,10 @@ static int postcopy_start(MigrationState *ms, Error **errp) - goto fail; - } - -- ret = bdrv_inactivate_all(); -- if (ret < 0) { -- error_setg_errno(errp, -ret, "%s: Failed in bdrv_inactivate_all()", -- __func__); -+ if (!migration_block_inactivate()) { -+ error_setg(errp, "%s: Failed in bdrv_inactivate_all()", __func__); - goto fail; - } -- restart_block = true; - - /* - * Cause any non-postcopiable, but iterative devices to -@@ -2654,8 +2641,6 @@ static int postcopy_start(MigrationState *ms, Error **errp) - goto fail_closefb; - } - -- restart_block = false; -- - /* Now send that blob */ - if (qemu_savevm_send_packaged(ms->to_dst_file, bioc->data, bioc->usage)) { - error_setg(errp, "%s: Failed to send packaged data", __func__); -@@ -2700,17 +2685,7 @@ fail_closefb: - fail: - migrate_set_state(&ms->state, MIGRATION_STATUS_POSTCOPY_ACTIVE, - MIGRATION_STATUS_FAILED); -- if (restart_block) { -- /* A failure happened early enough that we know the destination hasn't -- * accessed block devices, so we're safe to recover. -- */ -- Error *local_err = NULL; -- -- bdrv_activate_all(&local_err); -- if (local_err) { -- error_report_err(local_err); -- } -- } -+ migration_block_activate(NULL); - migration_call_notifiers(ms, MIG_EVENT_PRECOPY_FAILED, NULL); - bql_unlock(); - return -1; -@@ -2808,31 +2783,6 @@ static void migration_completion_postcopy(MigrationState *s) - trace_migration_completion_postcopy_end_after_complete(); - } - --static void migration_completion_failed(MigrationState *s, -- int current_active_state) --{ -- if (s->block_inactive && (s->state == MIGRATION_STATUS_ACTIVE || -- s->state == MIGRATION_STATUS_DEVICE)) { -- /* -- * If not doing postcopy, vm_start() will be called: let's -- * regain control on images. -- */ -- Error *local_err = NULL; -- -- bql_lock(); -- bdrv_activate_all(&local_err); -- if (local_err) { -- error_report_err(local_err); -- } else { -- s->block_inactive = false; -- } -- bql_unlock(); -- } -- -- migrate_set_state(&s->state, current_active_state, -- MIGRATION_STATUS_FAILED); --} -- - /** - * migration_completion: Used by migration_thread when there's not much left. - * The caller 'breaks' the loop when this returns. -@@ -2886,7 +2836,8 @@ fail: - error_free(local_err); - } - -- migration_completion_failed(s, current_active_state); -+ migrate_set_state(&s->state, current_active_state, -+ MIGRATION_STATUS_FAILED); - } - - /** -@@ -3309,6 +3260,11 @@ static void migration_iteration_finish(MigrationState *s) - case MIGRATION_STATUS_FAILED: - case MIGRATION_STATUS_CANCELLED: - case MIGRATION_STATUS_CANCELLING: -+ /* -+ * Re-activate the block drives if they're inactivated. Note, COLO -+ * shouldn't use block_active at all, so it should be no-op there. -+ */ -+ migration_block_activate(NULL); - if (runstate_is_live(s->vm_old_state)) { - if (!runstate_check(RUN_STATE_SHUTDOWN)) { - vm_start(); -@@ -3869,6 +3825,8 @@ static void migration_instance_init(Object *obj) - ms->state = MIGRATION_STATUS_NONE; - ms->mbps = -1; - ms->pages_per_second = -1; -+ /* Freshly started QEMU owns all the block devices */ -+ migration_block_active_setup(true); - qemu_sem_init(&ms->pause_sem, 0); - qemu_mutex_init(&ms->error_mutex); - -diff --git a/migration/migration.h b/migration/migration.h -index 38aa1402d5..5b17c1344d 100644 ---- a/migration/migration.h -+++ b/migration/migration.h -@@ -356,9 +356,6 @@ struct MigrationState { - /* Flag set once the migration thread is running (and needs joining) */ - bool migration_thread_running; - -- /* Flag set once the migration thread called bdrv_inactivate_all */ -- bool block_inactive; -- - /* Migration is waiting for guest to unplug device */ - QemuSemaphore wait_unplug_sem; - -@@ -537,4 +534,6 @@ int migration_rp_wait(MigrationState *s); - */ - void migration_rp_kick(MigrationState *s); - -+/* migration/block-active.c */ -+void migration_block_active_setup(bool active); - #endif -diff --git a/migration/savevm.c b/migration/savevm.c -index b88dadd904..7f8d177462 100644 ---- a/migration/savevm.c -+++ b/migration/savevm.c -@@ -1566,19 +1566,18 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f, - } - - if (inactivate_disks) { -- /* Inactivate before sending QEMU_VM_EOF so that the -- * bdrv_activate_all() on the other end won't fail. */ -- ret = bdrv_inactivate_all(); -- if (ret) { -- error_setg(&local_err, "%s: bdrv_inactivate_all() failed (%d)", -- __func__, ret); -+ /* -+ * Inactivate before sending QEMU_VM_EOF so that the -+ * bdrv_activate_all() on the other end won't fail. -+ */ -+ if (!migration_block_inactivate()) { -+ error_setg(&local_err, "%s: bdrv_inactivate_all() failed", -+ __func__); - migrate_set_error(ms, local_err); - error_report_err(local_err); -- qemu_file_set_error(f, ret); -+ qemu_file_set_error(f, -EFAULT); - return ret; - } -- /* Remember that we did this */ -- s->block_inactive = true; - } - if (!in_postcopy) { - /* Postcopy stream will still be going */ -@@ -2142,7 +2141,6 @@ static int loadvm_postcopy_handle_listen(MigrationIncomingState *mis) - - static void loadvm_postcopy_handle_run_bh(void *opaque) - { -- Error *local_err = NULL; - MigrationIncomingState *mis = opaque; - - trace_vmstate_downtime_checkpoint("dst-postcopy-bh-enter"); -@@ -2165,12 +2163,11 @@ static void loadvm_postcopy_handle_run_bh(void *opaque) - * Make sure all file formats throw away their mutable metadata. - * If we get an error here, just don't restart the VM yet. - */ -- bdrv_activate_all(&local_err); -+ bool success = migration_block_activate(NULL); -+ - trace_vmstate_downtime_checkpoint("dst-postcopy-bh-cache-invalidated"); -- if (local_err) { -- error_report_err(local_err); -- local_err = NULL; -- } else { -+ -+ if (success) { - vm_start(); - } - } else { -@@ -3214,11 +3211,7 @@ void qmp_xen_save_devices_state(const char *filename, bool has_live, bool live, - * side of the migration take control of the images. - */ - if (live && !saved_vm_running) { -- ret = bdrv_inactivate_all(); -- if (ret) { -- error_setg(errp, "%s: bdrv_inactivate_all() failed (%d)", -- __func__, ret); -- } -+ migration_block_inactivate(); - } - } - -diff --git a/migration/trace-events b/migration/trace-events -index 0b7c3324fb..62141dc2ff 100644 ---- a/migration/trace-events -+++ b/migration/trace-events -@@ -377,3 +377,6 @@ migration_block_progression(unsigned percent) "Completed %u%%" - # page_cache.c - migration_pagecache_init(int64_t max_num_items) "Setting cache buckets to %" PRId64 - migration_pagecache_insert(void) "Error allocating page" -+ -+# block-active.c -+migration_block_activation(const char *name) "%s" -diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c -index 76f21e8af3..6f76d9beaf 100644 ---- a/monitor/qmp-cmds.c -+++ b/monitor/qmp-cmds.c -@@ -31,6 +31,7 @@ - #include "qapi/type-helpers.h" - #include "hw/mem/memory-device.h" - #include "hw/intc/intc.h" -+#include "migration/misc.h" - - NameInfo *qmp_query_name(Error **errp) - { -@@ -103,13 +104,8 @@ void qmp_cont(Error **errp) - * Continuing after completed migration. Images have been - * inactivated to allow the destination to take control. Need to - * get control back now. -- * -- * If there are no inactive block nodes (e.g. because the VM was -- * just paused rather than completing a migration), -- * bdrv_inactivate_all() simply doesn't do anything. - */ -- bdrv_activate_all(&local_err); -- if (local_err) { -+ if (!migration_block_activate(&local_err)) { - error_propagate(errp, local_err); - return; - } --- -2.39.3 - diff --git a/kvm-migration-block-active-Remove-global-active-flag.patch b/kvm-migration-block-active-Remove-global-active-flag.patch deleted file mode 100644 index 936aaa1..0000000 --- a/kvm-migration-block-active-Remove-global-active-flag.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 927a37838380b5405596795f0f8968ac8b94bda2 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Tue, 4 Feb 2025 22:13:55 +0100 -Subject: [PATCH 10/22] migration/block-active: Remove global active flag - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [10/22] caa43249916319b11a18994510e68176fae61d50 (kmwolf/centos-qemu-kvm) - -Block devices have an individual active state, a single global flag -can't cover this correctly. This becomes more important as we allow -users to manually manage which nodes are active or inactive. - -Now that it's allowed to call bdrv_inactivate_all() even when some -nodes are already inactive, we can remove the flag and just -unconditionally call bdrv_inactivate_all() and, more importantly, -bdrv_activate_all() before we make use of the nodes. - -Signed-off-by: Kevin Wolf -Acked-by: Fabiano Rosas -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Message-ID: <20250204211407.381505-5-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit c2a189976e211c9ff782538d5a5ed5e5cffeccd6) -Signed-off-by: Kevin Wolf ---- - migration/block-active.c | 46 ---------------------------------------- - migration/migration.c | 8 ------- - migration/migration.h | 2 -- - 3 files changed, 56 deletions(-) - -diff --git a/migration/block-active.c b/migration/block-active.c -index d477cf8182..40e986aade 100644 ---- a/migration/block-active.c -+++ b/migration/block-active.c -@@ -12,51 +12,12 @@ - #include "qemu/error-report.h" - #include "trace.h" - --/* -- * Migration-only cache to remember the block layer activation status. -- * Protected by BQL. -- * -- * We need this because.. -- * -- * - Migration can fail after block devices are invalidated (during -- * switchover phase). When that happens, we need to be able to recover -- * the block drive status by re-activating them. -- * -- * - Currently bdrv_inactivate_all() is not safe to be invoked on top of -- * invalidated drives (even if bdrv_activate_all() is actually safe to be -- * called any time!). It means remembering this could help migration to -- * make sure it won't invalidate twice in a row, crashing QEMU. It can -- * happen when we migrate a PAUSED VM from host1 to host2, then migrate -- * again to host3 without starting it. TODO: a cleaner solution is to -- * allow safe invoke of bdrv_inactivate_all() at anytime, like -- * bdrv_activate_all(). -- * -- * For freshly started QEMU, the flag is initialized to TRUE reflecting the -- * scenario where QEMU owns block device ownerships. -- * -- * For incoming QEMU taking a migration stream, the flag is initialized to -- * FALSE reflecting that the incoming side doesn't own the block devices, -- * not until switchover happens. -- */ --static bool migration_block_active; -- --/* Setup the disk activation status */ --void migration_block_active_setup(bool active) --{ -- migration_block_active = active; --} -- - bool migration_block_activate(Error **errp) - { - ERRP_GUARD(); - - assert(bql_locked()); - -- if (migration_block_active) { -- trace_migration_block_activation("active-skipped"); -- return true; -- } -- - trace_migration_block_activation("active"); - - bdrv_activate_all(errp); -@@ -65,7 +26,6 @@ bool migration_block_activate(Error **errp) - return false; - } - -- migration_block_active = true; - return true; - } - -@@ -75,11 +35,6 @@ bool migration_block_inactivate(void) - - assert(bql_locked()); - -- if (!migration_block_active) { -- trace_migration_block_activation("inactive-skipped"); -- return true; -- } -- - trace_migration_block_activation("inactive"); - - ret = bdrv_inactivate_all(); -@@ -89,6 +44,5 @@ bool migration_block_inactivate(void) - return false; - } - -- migration_block_active = false; - return true; - } -diff --git a/migration/migration.c b/migration/migration.c -index 38631d1206..999d4cac54 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -1875,12 +1875,6 @@ void qmp_migrate_incoming(const char *uri, bool has_channels, - return; - } - -- /* -- * Newly setup incoming QEMU. Mark the block active state to reflect -- * that the src currently owns the disks. -- */ -- migration_block_active_setup(false); -- - once = false; - } - -@@ -3825,8 +3819,6 @@ static void migration_instance_init(Object *obj) - ms->state = MIGRATION_STATUS_NONE; - ms->mbps = -1; - ms->pages_per_second = -1; -- /* Freshly started QEMU owns all the block devices */ -- migration_block_active_setup(true); - qemu_sem_init(&ms->pause_sem, 0); - qemu_mutex_init(&ms->error_mutex); - -diff --git a/migration/migration.h b/migration/migration.h -index 5b17c1344d..c38d2a37e4 100644 ---- a/migration/migration.h -+++ b/migration/migration.h -@@ -534,6 +534,4 @@ int migration_rp_wait(MigrationState *s); - */ - void migration_rp_kick(MigrationState *s); - --/* migration/block-active.c */ --void migration_block_active_setup(bool active); - #endif --- -2.39.3 - diff --git a/kvm-migration-enable-multifd-and-postcopy-together.patch b/kvm-migration-enable-multifd-and-postcopy-together.patch new file mode 100644 index 0000000..5b8a373 --- /dev/null +++ b/kvm-migration-enable-multifd-and-postcopy-together.patch @@ -0,0 +1,111 @@ +From 12f7ba5e8b344e578dc99f5ce6e371d4c51108bb Mon Sep 17 00:00:00 2001 +From: Prasad Pandit +Date: Mon, 12 May 2025 18:21:23 +0530 +Subject: [PATCH 07/33] migration: enable multifd and postcopy together + +RH-Author: Prasad Pandit +RH-MergeRequest: 390: migration: allow to enable multifd+postcopy features together, but use multifd during precopy only +RH-Jira: RHEL-59697 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Miroslav Rezanina +RH-Commit: [7/11] 3e5d91a4aed5f18f1c29ae1ab9296ae41b6cf3ca (pjp/cs-qemu-kvm) + +Enable Multifd and Postcopy migration together. +The migration_ioc_process_incoming() routine checks +magic value sent on each channel and helps to properly +setup multifd and postcopy channels. + +The Precopy and Multifd threads work during the initial +guest RAM transfer. When migration moves to the Postcopy +phase, the multifd threads cease to send data on multifd +channels and Postcopy threads on the destination +request/pull data from the source side. + +Jira: https://issues.redhat.com/browse/RHEL-59697 +Reviewed-by: Fabiano Rosas +Signed-off-by: Prasad Pandit +Link: https://lore.kernel.org/r/20250512125124.147064-3-ppandit@redhat.com +Signed-off-by: Peter Xu +(cherry picked from commit e27418861288285d20352448fef4491a68223d39) +Signed-off-by: Prasad Pandit +--- + migration/multifd-nocomp.c | 3 ++- + migration/multifd.c | 7 +++++++ + migration/options.c | 5 ----- + migration/ram.c | 5 ++--- + 4 files changed, 11 insertions(+), 9 deletions(-) + +diff --git a/migration/multifd-nocomp.c b/migration/multifd-nocomp.c +index ffe75256c9..02f8bf8ce8 100644 +--- a/migration/multifd-nocomp.c ++++ b/migration/multifd-nocomp.c +@@ -17,6 +17,7 @@ + #include "migration-stats.h" + #include "multifd.h" + #include "options.h" ++#include "migration.h" + #include "qapi/error.h" + #include "qemu/cutils.h" + #include "qemu/error-report.h" +@@ -399,7 +400,7 @@ int multifd_ram_flush_and_sync(QEMUFile *f) + MultiFDSyncReq req; + int ret; + +- if (!migrate_multifd()) { ++ if (!migrate_multifd() || migration_in_postcopy()) { + return 0; + } + +diff --git a/migration/multifd.c b/migration/multifd.c +index 6139cabe44..074d16d07d 100644 +--- a/migration/multifd.c ++++ b/migration/multifd.c +@@ -1379,6 +1379,13 @@ static void *multifd_recv_thread(void *opaque) + } + + if (has_data) { ++ /* ++ * multifd thread should not be active and receive data ++ * when migration is in the Postcopy phase. Two threads ++ * writing the same memory area could easily corrupt ++ * the guest state. ++ */ ++ assert(!migration_in_postcopy()); + if (is_device_state) { + assert(use_packets); + ret = multifd_device_state_recv(p, &local_err); +diff --git a/migration/options.c b/migration/options.c +index b0ac2ea408..48aa6076de 100644 +--- a/migration/options.c ++++ b/migration/options.c +@@ -491,11 +491,6 @@ bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp) + error_setg(errp, "Postcopy is not compatible with ignore-shared"); + return false; + } +- +- if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) { +- error_setg(errp, "Postcopy is not yet compatible with multifd"); +- return false; +- } + } + + if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) { +diff --git a/migration/ram.c b/migration/ram.c +index 856769a77c..6f390b28d9 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -2013,9 +2013,8 @@ static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss) + } + } + +- if (migrate_multifd()) { +- RAMBlock *block = pss->block; +- return ram_save_multifd_page(block, offset); ++ if (migrate_multifd() && !migration_in_postcopy()) { ++ return ram_save_multifd_page(pss->block, offset); + } + + return ram_save_page(rs, pss); +-- +2.39.3 + diff --git a/kvm-migration-multifd-move-macros-to-multifd-header.patch b/kvm-migration-multifd-move-macros-to-multifd-header.patch new file mode 100644 index 0000000..053eeba --- /dev/null +++ b/kvm-migration-multifd-move-macros-to-multifd-header.patch @@ -0,0 +1,63 @@ +From 8eb8ea8cf070ac88d8caa50c4a0cfc9e00398616 Mon Sep 17 00:00:00 2001 +From: Prasad Pandit +Date: Fri, 11 Apr 2025 17:15:28 +0530 +Subject: [PATCH 01/33] migration/multifd: move macros to multifd header + +RH-Author: Prasad Pandit +RH-MergeRequest: 390: migration: allow to enable multifd+postcopy features together, but use multifd during precopy only +RH-Jira: RHEL-59697 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/11] 438135a73f4247ac3d35f2798b7ca75b0b55cbd8 (pjp/cs-qemu-kvm) + +Move MULTIFD_ macros to the header file so that +they are accessible from other source files. + +Jira: https://issues.redhat.com/browse/RHEL-59697 +Reviewed-by: Fabiano Rosas +Signed-off-by: Prasad Pandit +Reviewed-by: Peter Xu +Message-ID: <20250411114534.3370816-2-ppandit@redhat.com> +Signed-off-by: Fabiano Rosas +(cherry picked from commit 56e3c89f44ecebc946fbe4ffed325d1a79b26e38) +Signed-off-by: Prasad Pandit +--- + migration/multifd.c | 5 ----- + migration/multifd.h | 5 +++++ + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/migration/multifd.c b/migration/multifd.c +index dfb5189f0e..6139cabe44 100644 +--- a/migration/multifd.c ++++ b/migration/multifd.c +@@ -36,11 +36,6 @@ + #include "io/channel-socket.h" + #include "yank_functions.h" + +-/* Multiple fd's */ +- +-#define MULTIFD_MAGIC 0x11223344U +-#define MULTIFD_VERSION 1 +- + typedef struct { + uint32_t magic; + uint32_t version; +diff --git a/migration/multifd.h b/migration/multifd.h +index 2d337e7b3b..9b6d81e7ed 100644 +--- a/migration/multifd.h ++++ b/migration/multifd.h +@@ -49,6 +49,11 @@ bool multifd_queue_page(RAMBlock *block, ram_addr_t offset); + bool multifd_recv(void); + MultiFDRecvData *multifd_get_recv_data(void); + ++/* Multiple fd's */ ++ ++#define MULTIFD_MAGIC 0x11223344U ++#define MULTIFD_VERSION 1 ++ + /* Multifd Compression flags */ + #define MULTIFD_FLAG_SYNC (1 << 0) + +-- +2.39.3 + diff --git a/kvm-migration-postcopy-Spatial-locality-page-hint-for-pr.patch b/kvm-migration-postcopy-Spatial-locality-page-hint-for-pr.patch new file mode 100644 index 0000000..c6d9ec0 --- /dev/null +++ b/kvm-migration-postcopy-Spatial-locality-page-hint-for-pr.patch @@ -0,0 +1,234 @@ +From 2e49bdf20390600286cd2596859feb400a932c44 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Thu, 24 Apr 2025 18:07:05 -0400 +Subject: [PATCH 1/4] migration/postcopy: Spatial locality page hint for + preempt mode + +RH-Author: Peter Xu +RH-MergeRequest: 357: migration/postcopy: Spatial locality page hint for preempt mode +RH-Jira: RHEL-85635 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/1] 05f3befe60e1d3f2f8beaaf0e0e577e49a126dfe (peterx/qemu-kvm) + +The preempt mode postcopy has been introduced for a while. From latency +POV, it should always win the vanilla postcopy. + +However there's one thing missing when preempt mode is enabled right now, +which is the spatial locality hint when there're page requests from the +destination side. + +In vanilla postcopy, as long as a page request was unqueued, it will update +the PSS of the precopy background stream, so that after a page request the +background thread will move the pages after whatever was requested. It's +pretty much a natural behavior when there's only one channel anyway, and +one scanner to send the pages. + +Preempt mode didn't follow that, because preempt mode has its own channel +and its own PSS (which doesn't linearly scan the guest memory, but +dedicated to resolve page requested from destination). So the page request +process and the background migration process are completely separate. + +This patch adds the hint explicitly for preempt mode. With that, whenever +the preempt mode receives a page request on the source, it will service the +remote page fault in the return path, then it'll provide a hint to the +background thread so that we'll start sending the pages right after the +requested ones in the background, assuming the follow up pages have a +higher chance to be accessed later. + +NOTE: since the background migration thread and return path thread run +completely concurrently, it doesn't always mean the hint will be applied +every single time. For example, it's possible that the return path thread +receives multiple page requests in a row without the background thread +getting the chance to consume one. In such case, the preempt thread only +provide the hint if the previous hint has been consumed. After all, +there's no point queuing hints when we only have one linear scanner. + +This could measureably improve the simple sequential memory access pattern +during postcopy (when preempt is on). For random accesses, I can measure a +slight increase of remote page fault latency from ~500us -> ~600us, that +could be a trade-off to have such hint mechanism, and after all that's +still greatly improved comparing to vanilla postcopy on random (~10ms). + +The patch is verified by our QE team in a video streaming test case, to +reduce the pause of the video from ~1min to a few seconds when switching +over to postcopy with preempt mode. + +Reported-by: Xiaohui Li +Tested-by: Xiaohui Li +Reviewed-by: Juraj Marcin +Link: https://lore.kernel.org/r/20250424220705.195544-1-peterx@redhat.com +Signed-off-by: Peter Xu +(cherry picked from commit 20d82622812d888478d04a2d0d8575d70eb5d749) +Signed-off-by: Peter Xu +--- + migration/ram.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 96 insertions(+), 1 deletion(-) + +diff --git a/migration/ram.c b/migration/ram.c +index 424df6d9f1..21d2f87ff1 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -91,6 +91,36 @@ + + XBZRLECacheStats xbzrle_counters; + ++/* ++ * This structure locates a specific location of a guest page. In QEMU, ++ * it's described in a tuple of (ramblock, offset). ++ */ ++struct PageLocation { ++ RAMBlock *block; ++ unsigned long offset; ++}; ++typedef struct PageLocation PageLocation; ++ ++/** ++ * PageLocationHint: describes a hint to a page location ++ * ++ * @valid set if the hint is vaild and to be consumed ++ * @location: the hint content ++ * ++ * In postcopy preempt mode, the urgent channel may provide hints to the ++ * background channel, so that QEMU source can try to migrate whatever is ++ * right after the requested urgent pages. ++ * ++ * This is based on the assumption that the VM (already running on the ++ * destination side) tends to access the memory with spatial locality. ++ * This is also the default behavior of vanilla postcopy (preempt off). ++ */ ++struct PageLocationHint { ++ bool valid; ++ PageLocation location; ++}; ++typedef struct PageLocationHint PageLocationHint; ++ + /* used by the search for pages to send */ + struct PageSearchStatus { + /* The migration channel used for a specific host page */ +@@ -395,6 +425,13 @@ struct RAMState { + * RAM migration. + */ + unsigned int postcopy_bmap_sync_requested; ++ /* ++ * Page hint during postcopy when preempt mode is on. Return path ++ * thread sets it, while background migration thread consumes it. ++ * ++ * Protected by @bitmap_mutex. ++ */ ++ PageLocationHint page_hint; + }; + typedef struct RAMState RAMState; + +@@ -2039,6 +2076,21 @@ static void pss_host_page_finish(PageSearchStatus *pss) + pss->host_page_start = pss->host_page_end = 0; + } + ++static void ram_page_hint_update(RAMState *rs, PageSearchStatus *pss) ++{ ++ PageLocationHint *hint = &rs->page_hint; ++ ++ /* If there's a pending hint not consumed, don't bother */ ++ if (hint->valid) { ++ return; ++ } ++ ++ /* Provide a hint to the background stream otherwise */ ++ hint->location.block = pss->block; ++ hint->location.offset = pss->page; ++ hint->valid = true; ++} ++ + /* + * Send an urgent host page specified by `pss'. Need to be called with + * bitmap_mutex held. +@@ -2084,6 +2136,7 @@ out: + /* For urgent requests, flush immediately if sent */ + if (sent) { + qemu_fflush(pss->pss_channel); ++ ram_page_hint_update(rs, pss); + } + return ret; + } +@@ -2171,6 +2224,30 @@ static int ram_save_host_page(RAMState *rs, PageSearchStatus *pss) + return (res < 0 ? res : pages); + } + ++static bool ram_page_hint_valid(RAMState *rs) ++{ ++ /* There's only page hint during postcopy preempt mode */ ++ if (!postcopy_preempt_active()) { ++ return false; ++ } ++ ++ return rs->page_hint.valid; ++} ++ ++static void ram_page_hint_collect(RAMState *rs, RAMBlock **block, ++ unsigned long *page) ++{ ++ PageLocationHint *hint = &rs->page_hint; ++ ++ assert(hint->valid); ++ ++ *block = hint->location.block; ++ *page = hint->location.offset; ++ ++ /* Mark the hint consumed */ ++ hint->valid = false; ++} ++ + /** + * ram_find_and_save_block: finds a dirty page and sends it to f + * +@@ -2187,6 +2264,8 @@ static int ram_save_host_page(RAMState *rs, PageSearchStatus *pss) + static int ram_find_and_save_block(RAMState *rs) + { + PageSearchStatus *pss = &rs->pss[RAM_CHANNEL_PRECOPY]; ++ unsigned long next_page; ++ RAMBlock *next_block; + int pages = 0; + + /* No dirty page as there is zero RAM */ +@@ -2206,7 +2285,14 @@ static int ram_find_and_save_block(RAMState *rs) + rs->last_page = 0; + } + +- pss_init(pss, rs->last_seen_block, rs->last_page); ++ if (ram_page_hint_valid(rs)) { ++ ram_page_hint_collect(rs, &next_block, &next_page); ++ } else { ++ next_block = rs->last_seen_block; ++ next_page = rs->last_page; ++ } ++ ++ pss_init(pss, next_block, next_page); + + while (true){ + if (!get_queued_page(rs, pss)) { +@@ -2339,6 +2425,13 @@ static void ram_save_cleanup(void *opaque) + ram_state_cleanup(rsp); + } + ++static void ram_page_hint_reset(PageLocationHint *hint) ++{ ++ hint->location.block = NULL; ++ hint->location.offset = 0; ++ hint->valid = false; ++} ++ + static void ram_state_reset(RAMState *rs) + { + int i; +@@ -2351,6 +2444,8 @@ static void ram_state_reset(RAMState *rs) + rs->last_page = 0; + rs->last_version = ram_list.version; + rs->xbzrle_started = false; ++ ++ ram_page_hint_reset(&rs->page_hint); + } + + #define MAX_WAIT 50 /* ms, half buffered_file limit */ +-- +2.39.3 + diff --git a/kvm-migration-ram-Implement-save_postcopy_prepare.patch b/kvm-migration-ram-Implement-save_postcopy_prepare.patch new file mode 100644 index 0000000..6991716 --- /dev/null +++ b/kvm-migration-ram-Implement-save_postcopy_prepare.patch @@ -0,0 +1,85 @@ +From d5b76b77dc891f0bec211a6d00b099a2979223ee Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Fri, 11 Apr 2025 17:15:31 +0530 +Subject: [PATCH 04/33] migration/ram: Implement save_postcopy_prepare() + +RH-Author: Prasad Pandit +RH-MergeRequest: 390: migration: allow to enable multifd+postcopy features together, but use multifd during precopy only +RH-Jira: RHEL-59697 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Miroslav Rezanina +RH-Commit: [4/11] 4df55b4e65458ffccf48df5de3afad0b38cded51 (pjp/cs-qemu-kvm) + +Implement save_postcopy_prepare(), preparing for the enablement +of both multifd and postcopy. + +Jira: https://issues.redhat.com/browse/RHEL-59697 +Signed-off-by: Peter Xu +Signed-off-by: Prasad Pandit +Reviewed-by: Fabiano Rosas +Message-ID: <20250411114534.3370816-5-ppandit@redhat.com> +Signed-off-by: Fabiano Rosas +(cherry picked from commit ad8d82ffbb8b8034f58a570911e6e9c6328c9384) +Signed-off-by: Prasad Pandit +--- + migration/ram.c | 37 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +diff --git a/migration/ram.c b/migration/ram.c +index 21d2f87ff1..856769a77c 100644 +--- a/migration/ram.c ++++ b/migration/ram.c +@@ -4515,6 +4515,42 @@ static int ram_resume_prepare(MigrationState *s, void *opaque) + return 0; + } + ++static bool ram_save_postcopy_prepare(QEMUFile *f, void *opaque, Error **errp) ++{ ++ int ret; ++ ++ if (migrate_multifd()) { ++ /* ++ * When multifd is enabled, source QEMU needs to make sure all the ++ * pages queued before postcopy starts have been flushed. ++ * ++ * The load of these pages must happen before switching to postcopy. ++ * It's because loading of guest pages (so far) in multifd recv ++ * threads is still non-atomic, so the load cannot happen with vCPUs ++ * running on the destination side. ++ * ++ * This flush and sync will guarantee that those pages are loaded ++ * _before_ postcopy starts on the destination. The rationale is, ++ * this happens before VM stops (and before source QEMU sends all ++ * the rest of the postcopy messages). So when the destination QEMU ++ * receives the postcopy messages, it must have received the sync ++ * message on the main channel (either RAM_SAVE_FLAG_MULTIFD_FLUSH, ++ * or RAM_SAVE_FLAG_EOS), and such message would guarantee that ++ * all previous guest pages queued in the multifd channels are ++ * completely loaded. ++ */ ++ ret = multifd_ram_flush_and_sync(f); ++ if (ret < 0) { ++ error_setg(errp, "%s: multifd flush and sync failed", __func__); ++ return false; ++ } ++ } ++ ++ qemu_put_be64(f, RAM_SAVE_FLAG_EOS); ++ ++ return true; ++} ++ + void postcopy_preempt_shutdown_file(MigrationState *s) + { + qemu_put_be64(s->postcopy_qemufile_src, RAM_SAVE_FLAG_EOS); +@@ -4534,6 +4570,7 @@ static SaveVMHandlers savevm_ram_handlers = { + .load_setup = ram_load_setup, + .load_cleanup = ram_load_cleanup, + .resume_prepare = ram_resume_prepare, ++ .save_postcopy_prepare = ram_save_postcopy_prepare, + }; + + static void ram_mig_ram_block_resized(RAMBlockNotifier *n, void *host, +-- +2.39.3 + diff --git a/kvm-migration-refactor-channel-discovery-mechanism.patch b/kvm-migration-refactor-channel-discovery-mechanism.patch new file mode 100644 index 0000000..d77363b --- /dev/null +++ b/kvm-migration-refactor-channel-discovery-mechanism.patch @@ -0,0 +1,239 @@ +From 21ec86cdc48de9ddf3f5bba994edd9f9427ffd4c Mon Sep 17 00:00:00 2001 +From: Prasad Pandit +Date: Fri, 11 Apr 2025 17:15:29 +0530 +Subject: [PATCH 02/33] migration: refactor channel discovery mechanism + +RH-Author: Prasad Pandit +RH-MergeRequest: 390: migration: allow to enable multifd+postcopy features together, but use multifd during precopy only +RH-Jira: RHEL-59697 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Miroslav Rezanina +RH-Commit: [2/11] 7f40da01d8c9a827627c73641f3b90a27bbfb8a0 (pjp/cs-qemu-kvm) + +The various logical migration channels don't have a +standardized way of advertising themselves and their +connections may be seen out of order by the migration +destination. When a new connection arrives, the incoming +migration currently make use of heuristics to determine +which channel it belongs to. + +The next few patches will need to change how the multifd +and postcopy capabilities interact and that affects the +channel discovery heuristic. + +Refactor the channel discovery heuristic to make it less +opaque and simplify the subsequent patches. + +Jira: https://issues.redhat.com/browse/RHEL-59697 +Signed-off-by: Prasad Pandit +Reviewed-by: Fabiano Rosas +Message-ID: <20250411114534.3370816-3-ppandit@redhat.com> +Signed-off-by: Fabiano Rosas +(cherry picked from commit 00f3fcef1981eb23f98b956d9cda2df528bfef40) +Signed-off-by: Prasad Pandit +--- + migration/migration.c | 130 +++++++++++++++++++++++------------------- + 1 file changed, 70 insertions(+), 60 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index d46e776e24..64f4f40ae3 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -95,6 +95,9 @@ enum mig_rp_message_type { + MIG_RP_MSG_MAX + }; + ++/* Migration channel types */ ++enum { CH_MAIN, CH_MULTIFD, CH_POSTCOPY }; ++ + /* When we add fault tolerance, we could have several + migrations at once. For now we don't need to add + dynamic creation of migration */ +@@ -931,9 +934,8 @@ static void migration_incoming_setup(QEMUFile *f) + { + MigrationIncomingState *mis = migration_incoming_get_current(); + +- if (!mis->from_src_file) { +- mis->from_src_file = f; +- } ++ assert(!mis->from_src_file); ++ mis->from_src_file = f; + qemu_file_set_blocking(f, false); + } + +@@ -985,28 +987,19 @@ void migration_fd_process_incoming(QEMUFile *f) + migration_incoming_process(); + } + +-/* +- * Returns true when we want to start a new incoming migration process, +- * false otherwise. +- */ +-static bool migration_should_start_incoming(bool main_channel) ++static bool migration_has_main_and_multifd_channels(void) + { +- /* Multifd doesn't start unless all channels are established */ +- if (migrate_multifd()) { +- return migration_has_all_channels(); ++ MigrationIncomingState *mis = migration_incoming_get_current(); ++ if (!mis->from_src_file) { ++ /* main channel not established */ ++ return false; + } + +- /* Preempt channel only starts when the main channel is created */ +- if (migrate_postcopy_preempt()) { +- return main_channel; ++ if (migrate_multifd() && !multifd_recv_all_channels_created()) { ++ return false; + } + +- /* +- * For all the rest types of migration, we should only reach here when +- * it's the main channel that's being created, and we should always +- * proceed with this channel. +- */ +- assert(main_channel); ++ /* main and all multifd channels are established */ + return true; + } + +@@ -1015,59 +1008,81 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp) + MigrationIncomingState *mis = migration_incoming_get_current(); + Error *local_err = NULL; + QEMUFile *f; +- bool default_channel = true; ++ uint8_t channel; + uint32_t channel_magic = 0; + int ret = 0; + +- if (migrate_multifd() && !migrate_mapped_ram() && +- !migrate_postcopy_ram() && +- qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) { +- /* +- * With multiple channels, it is possible that we receive channels +- * out of order on destination side, causing incorrect mapping of +- * source channels on destination side. Check channel MAGIC to +- * decide type of channel. Please note this is best effort, postcopy +- * preempt channel does not send any magic number so avoid it for +- * postcopy live migration. Also tls live migration already does +- * tls handshake while initializing main channel so with tls this +- * issue is not possible. +- */ +- ret = migration_channel_read_peek(ioc, (void *)&channel_magic, +- sizeof(channel_magic), errp); ++ if (!migration_has_main_and_multifd_channels()) { ++ if (qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) { ++ /* ++ * With multiple channels, it is possible that we receive channels ++ * out of order on destination side, causing incorrect mapping of ++ * source channels on destination side. Check channel MAGIC to ++ * decide type of channel. Please note this is best effort, ++ * postcopy preempt channel does not send any magic number so ++ * avoid it for postcopy live migration. Also tls live migration ++ * already does tls handshake while initializing main channel so ++ * with tls this issue is not possible. ++ */ ++ ret = migration_channel_read_peek(ioc, (void *)&channel_magic, ++ sizeof(channel_magic), errp); ++ if (ret != 0) { ++ return; ++ } + +- if (ret != 0) { ++ channel_magic = be32_to_cpu(channel_magic); ++ if (channel_magic == QEMU_VM_FILE_MAGIC) { ++ channel = CH_MAIN; ++ } else if (channel_magic == MULTIFD_MAGIC) { ++ assert(migrate_multifd()); ++ channel = CH_MULTIFD; ++ } else if (!mis->from_src_file && ++ mis->state == MIGRATION_STATUS_POSTCOPY_PAUSED) { ++ /* reconnect main channel for postcopy recovery */ ++ channel = CH_MAIN; ++ } else { ++ error_setg(errp, "unknown channel magic: %u", channel_magic); ++ return; ++ } ++ } else if (mis->from_src_file && migrate_multifd()) { ++ /* ++ * Non-peekable channels like tls/file are processed as ++ * multifd channels when multifd is enabled. ++ */ ++ channel = CH_MULTIFD; ++ } else if (!mis->from_src_file) { ++ channel = CH_MAIN; ++ } else { ++ error_setg(errp, "non-peekable channel used without multifd"); + return; + } +- +- default_channel = (channel_magic == cpu_to_be32(QEMU_VM_FILE_MAGIC)); + } else { +- default_channel = !mis->from_src_file; ++ assert(migrate_postcopy_preempt()); ++ channel = CH_POSTCOPY; + } + + if (multifd_recv_setup(errp) != 0) { + return; + } + +- if (default_channel) { ++ if (channel == CH_MAIN) { + f = qemu_file_new_input(ioc); + migration_incoming_setup(f); +- } else { ++ } else if (channel == CH_MULTIFD) { + /* Multiple connections */ +- assert(migration_needs_multiple_sockets()); +- if (migrate_multifd()) { +- multifd_recv_new_channel(ioc, &local_err); +- } else { +- assert(migrate_postcopy_preempt()); +- f = qemu_file_new_input(ioc); +- postcopy_preempt_new_channel(mis, f); +- } ++ multifd_recv_new_channel(ioc, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } ++ } else if (channel == CH_POSTCOPY) { ++ assert(!mis->postcopy_qemufile_dst); ++ f = qemu_file_new_input(ioc); ++ postcopy_preempt_new_channel(mis, f); ++ return; + } + +- if (migration_should_start_incoming(default_channel)) { ++ if (migration_has_main_and_multifd_channels()) { + /* If it's a recovery, we're done */ + if (postcopy_try_recover()) { + return; +@@ -1084,18 +1099,13 @@ void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp) + */ + bool migration_has_all_channels(void) + { +- MigrationIncomingState *mis = migration_incoming_get_current(); +- +- if (!mis->from_src_file) { ++ if (!migration_has_main_and_multifd_channels()) { + return false; + } + +- if (migrate_multifd()) { +- return multifd_recv_all_channels_created(); +- } +- +- if (migrate_postcopy_preempt()) { +- return mis->postcopy_qemufile_dst != NULL; ++ MigrationIncomingState *mis = migration_incoming_get_current(); ++ if (migrate_postcopy_preempt() && !mis->postcopy_qemufile_dst) { ++ return false; + } + + return true; +-- +2.39.3 + diff --git a/kvm-migration-write-zero-pages-when-postcopy-enabled.patch b/kvm-migration-write-zero-pages-when-postcopy-enabled.patch new file mode 100644 index 0000000..953132e --- /dev/null +++ b/kvm-migration-write-zero-pages-when-postcopy-enabled.patch @@ -0,0 +1,69 @@ +From d25e369e01fcb30d4d12802907372d3320c095ff Mon Sep 17 00:00:00 2001 +From: Prasad Pandit +Date: Mon, 12 May 2025 18:21:22 +0530 +Subject: [PATCH 06/33] migration: write zero pages when postcopy enabled + +RH-Author: Prasad Pandit +RH-MergeRequest: 390: migration: allow to enable multifd+postcopy features together, but use multifd during precopy only +RH-Jira: RHEL-59697 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Miroslav Rezanina +RH-Commit: [6/11] 28ab95cd8a382d400d28511b0bb2e1ea1fd21c0a (pjp/cs-qemu-kvm) + +During multifd migration, zero pages are written if +they are migrated more than once. + +This may result in a migration thread hang issue when +multifd and postcopy are enabled together. + +When postcopy is enabled, always write zero pages as and +when they are migrated. + +Jira: https://issues.redhat.com/browse/RHEL-59697 +Signed-off-by: Prasad Pandit +Reviewed-by: Fabiano Rosas +Link: https://lore.kernel.org/r/20250512125124.147064-2-ppandit@redhat.com +Signed-off-by: Peter Xu +(cherry picked from commit 249543d0c02d7645b8bcda552dad138769e96831) +Signed-off-by: Prasad Pandit +--- + migration/multifd-zero-page.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/migration/multifd-zero-page.c b/migration/multifd-zero-page.c +index f1e988a959..3e0a04f2b5 100644 +--- a/migration/multifd-zero-page.c ++++ b/migration/multifd-zero-page.c +@@ -85,9 +85,27 @@ void multifd_recv_zero_page_process(MultiFDRecvParams *p) + { + for (int i = 0; i < p->zero_num; i++) { + void *page = p->host + p->zero[i]; +- if (ramblock_recv_bitmap_test_byte_offset(p->block, p->zero[i])) { ++ bool received = ++ ramblock_recv_bitmap_test_byte_offset(p->block, p->zero[i]); ++ ++ /* ++ * During multifd migration zero page is written to the memory ++ * only if it is migrated more than once. ++ * ++ * It becomes a problem when both multifd & postcopy options are ++ * enabled. If the zero page which was skipped during multifd phase, ++ * is accessed during the postcopy phase of the migration, a page ++ * fault occurs. But this page fault is not served because the ++ * 'receivedmap' says the zero page is already received. Thus the ++ * thread accessing that page may hang. ++ * ++ * When postcopy is enabled, always write the zero page as and when ++ * it is migrated. ++ */ ++ if (migrate_postcopy_ram() || received) { + memset(page, 0, multifd_ram_page_size()); +- } else { ++ } ++ if (!received) { + ramblock_recv_bitmap_set_offset(p->block, p->zero[i]); + } + } +-- +2.39.3 + diff --git a/kvm-mirror-Allow-QMP-override-to-declare-target-already-.patch b/kvm-mirror-Allow-QMP-override-to-declare-target-already-.patch new file mode 100644 index 0000000..19b79e7 --- /dev/null +++ b/kvm-mirror-Allow-QMP-override-to-declare-target-already-.patch @@ -0,0 +1,295 @@ +From bc4571743fc3bbb829101fbf294615e3b8fb3577 Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Fri, 9 May 2025 15:40:25 -0500 +Subject: [PATCH 08/14] mirror: Allow QMP override to declare target already + zero + +RH-Author: Eric Blake +RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors +RH-Jira: RHEL-88435 RHEL-88437 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +RH-Commit: [8/14] 4ad06d67db8c43df4e6e0b8f929b1d8c19e4b338 (ebblake/centos-qemu-kvm) + +QEMU has an optimization for a just-created drive-mirror destination +that is not possible for blockdev-mirror (which can't create the +destination) - any time we know the destination starts life as all +zeroes, we can skip a pre-zeroing pass on the destination. Recent +patches have added an improved heuristic for detecting if a file +contains all zeroes, and we plan to use that heuristic in upcoming +patches. But since a heuristic cannot quickly detect all scenarios, +and there may be cases where the caller is aware of information that +QEMU cannot learn quickly, it makes sense to have a way to tell QEMU +to assume facts about the destination that can make the mirror +operation faster. Given our existing example of "qemu-img convert +--target-is-zero", it is time to expose this override in QMP for +blockdev-mirror as well. + +This patch results in some slight redundancy between the older +s->zero_target (set any time mode==FULL and the destination image was +not just created - ie. clear if drive-mirror is asking to skip the +pre-zero pass) and the newly-introduced s->target_is_zero (in addition +to the QMP override, it is set when drive-mirror creates the +destination image); this will be cleaned up in the next patch. + +There is also a subtlety that we must consider. When drive-mirror is +passing target_is_zero on behalf of a just-created image, we know the +image is sparse (skipping the pre-zeroing keeps it that way), so it +doesn't matter whether the destination also has "discard":"unmap" and +"detect-zeroes":"unmap". But now that we are letting the user set the +knob for target-is-zero, if the user passes a pre-existing file that +is fully allocated, it is fine to leave the file fully allocated under +"detect-zeroes":"on", but if the file is open with +"detect-zeroes":"unmap", we should really be trying harder to punch +holes in the destination for every region of zeroes copied from the +source. The easiest way to do this is to still run the pre-zeroing +pass (turning the entire destination file sparse before populating +just the allocated portions of the source), even though that currently +results in double I/O to the portions of the file that are allocated. +A later patch will add further optimizations to reduce redundant +zeroing I/O during the mirror operation. + +Since "target-is-zero":true is designed for optimizations, it is okay +to silently ignore the parameter rather than erroring if the user ever +sets the parameter in a scenario where the mirror job can't exploit it +(for example, when doing "sync":"top" instead of "sync":"full", we +can't pre-zero, so setting the parameter won't make a speed +difference). + +Signed-off-by: Eric Blake +Acked-by: Markus Armbruster +Message-ID: <20250509204341.3553601-23-eblake@redhat.com> +Reviewed-by: Sunny Zhu +Reviewed-by: Stefan Hajnoczi +(cherry picked from commit d17a34bfb94bda3a89d7320ae67255ded1d8c939) +Jira: https://issues.redhat.com/browse/RHEL-88435 +Jira: https://issues.redhat.com/browse/RHEL-88437 +Signed-off-by: Eric Blake +--- + block/mirror.c | 27 ++++++++++++++++++++++---- + blockdev.c | 18 ++++++++++------- + include/block/block_int-global-state.h | 3 ++- + qapi/block-core.json | 8 +++++++- + tests/unit/test-block-iothread.c | 2 +- + 5 files changed, 44 insertions(+), 14 deletions(-) + +diff --git a/block/mirror.c b/block/mirror.c +index 2599b75d09..4dcb50c81a 100644 +--- a/block/mirror.c ++++ b/block/mirror.c +@@ -55,6 +55,8 @@ typedef struct MirrorBlockJob { + BlockMirrorBackingMode backing_mode; + /* Whether the target image requires explicit zero-initialization */ + bool zero_target; ++ /* Whether the target should be assumed to be already zero initialized */ ++ bool target_is_zero; + /* + * To be accesssed with atomics. Written only under the BQL (required by the + * current implementation of mirror_change()). +@@ -844,12 +846,26 @@ static int coroutine_fn GRAPH_UNLOCKED mirror_dirty_init(MirrorBlockJob *s) + BlockDriverState *target_bs = blk_bs(s->target); + int ret = -EIO; + int64_t count; ++ bool punch_holes = ++ target_bs->detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP && ++ bdrv_can_write_zeroes_with_unmap(target_bs); + + bdrv_graph_co_rdlock(); + bs = s->mirror_top_bs->backing->bs; + bdrv_graph_co_rdunlock(); + +- if (s->zero_target) { ++ if (s->zero_target && (!s->target_is_zero || punch_holes)) { ++ /* ++ * Here, we are in FULL mode; our goal is to avoid writing ++ * zeroes if the destination already reads as zero, except ++ * when we are trying to punch holes. This is possible if ++ * zeroing happened externally (s->target_is_zero) or if we ++ * have a fast way to pre-zero the image (the dirty bitmap ++ * will be populated later by the non-zero portions, the same ++ * as for TOP mode). If pre-zeroing is not fast, or we need ++ * to punch holes, then our only recourse is to write the ++ * entire image. ++ */ + if (!bdrv_can_write_zeroes_with_unmap(target_bs)) { + bdrv_set_dirty_bitmap(s->dirty_bitmap, 0, s->bdev_length); + return 0; +@@ -1714,7 +1730,7 @@ static BlockJob *mirror_start_job( + uint32_t granularity, int64_t buf_size, + MirrorSyncMode sync_mode, + BlockMirrorBackingMode backing_mode, +- bool zero_target, ++ bool zero_target, bool target_is_zero, + BlockdevOnError on_source_error, + BlockdevOnError on_target_error, + bool unmap, +@@ -1883,6 +1899,7 @@ static BlockJob *mirror_start_job( + s->sync_mode = sync_mode; + s->backing_mode = backing_mode; + s->zero_target = zero_target; ++ s->target_is_zero = target_is_zero; + qatomic_set(&s->copy_mode, copy_mode); + s->base = base; + s->base_overlay = bdrv_find_overlay(bs, base); +@@ -2011,7 +2028,7 @@ void mirror_start(const char *job_id, BlockDriverState *bs, + int creation_flags, int64_t speed, + uint32_t granularity, int64_t buf_size, + MirrorSyncMode mode, BlockMirrorBackingMode backing_mode, +- bool zero_target, ++ bool zero_target, bool target_is_zero, + BlockdevOnError on_source_error, + BlockdevOnError on_target_error, + bool unmap, const char *filter_node_name, +@@ -2034,7 +2051,8 @@ void mirror_start(const char *job_id, BlockDriverState *bs, + + mirror_start_job(job_id, bs, creation_flags, target, replaces, + speed, granularity, buf_size, mode, backing_mode, +- zero_target, on_source_error, on_target_error, unmap, ++ zero_target, ++ target_is_zero, on_source_error, on_target_error, unmap, + NULL, NULL, &mirror_job_driver, base, false, + filter_node_name, true, copy_mode, false, errp); + } +@@ -2062,6 +2080,7 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs, + job = mirror_start_job( + job_id, bs, creation_flags, base, NULL, speed, 0, 0, + MIRROR_SYNC_MODE_TOP, MIRROR_LEAVE_BACKING_CHAIN, false, ++ false, + on_error, on_error, true, cb, opaque, + &commit_active_job_driver, base, auto_complete, + filter_node_name, false, MIRROR_COPY_MODE_BACKGROUND, +diff --git a/blockdev.c b/blockdev.c +index 1d1f27cfff..2e2fed539e 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -2798,7 +2798,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, + const char *replaces, + enum MirrorSyncMode sync, + BlockMirrorBackingMode backing_mode, +- bool zero_target, ++ bool zero_target, bool target_is_zero, + bool has_speed, int64_t speed, + bool has_granularity, uint32_t granularity, + bool has_buf_size, int64_t buf_size, +@@ -2909,11 +2909,10 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, + /* pass the node name to replace to mirror start since it's loose coupling + * and will allow to check whether the node still exist at mirror completion + */ +- mirror_start(job_id, bs, target, +- replaces, job_flags, ++ mirror_start(job_id, bs, target, replaces, job_flags, + speed, granularity, buf_size, sync, backing_mode, zero_target, +- on_source_error, on_target_error, unmap, filter_node_name, +- copy_mode, errp); ++ target_is_zero, on_source_error, on_target_error, unmap, ++ filter_node_name, copy_mode, errp); + } + + void qmp_drive_mirror(DriveMirror *arg, Error **errp) +@@ -2928,6 +2927,7 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) + int64_t size; + const char *format = arg->format; + bool zero_target; ++ bool target_is_zero; + int ret; + + bs = qmp_get_root_bs(arg->device, errp); +@@ -3044,6 +3044,8 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) + zero_target = (arg->sync == MIRROR_SYNC_MODE_FULL && + (arg->mode == NEW_IMAGE_MODE_EXISTING || + !bdrv_has_zero_init(target_bs))); ++ target_is_zero = (arg->mode != NEW_IMAGE_MODE_EXISTING && ++ bdrv_has_zero_init(target_bs)); + bdrv_graph_rdunlock_main_loop(); + + +@@ -3055,7 +3057,7 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) + + blockdev_mirror_common(arg->job_id, bs, target_bs, + arg->replaces, arg->sync, +- backing_mode, zero_target, ++ backing_mode, zero_target, target_is_zero, + arg->has_speed, arg->speed, + arg->has_granularity, arg->granularity, + arg->has_buf_size, arg->buf_size, +@@ -3085,6 +3087,7 @@ void qmp_blockdev_mirror(const char *job_id, + bool has_copy_mode, MirrorCopyMode copy_mode, + bool has_auto_finalize, bool auto_finalize, + bool has_auto_dismiss, bool auto_dismiss, ++ bool has_target_is_zero, bool target_is_zero, + Error **errp) + { + BlockDriverState *bs; +@@ -3115,7 +3118,8 @@ void qmp_blockdev_mirror(const char *job_id, + + blockdev_mirror_common(job_id, bs, target_bs, + replaces, sync, backing_mode, +- zero_target, has_speed, speed, ++ zero_target, has_target_is_zero && target_is_zero, ++ has_speed, speed, + has_granularity, granularity, + has_buf_size, buf_size, + has_on_source_error, on_source_error, +diff --git a/include/block/block_int-global-state.h b/include/block/block_int-global-state.h +index eb2d92a226..8cf0003ce7 100644 +--- a/include/block/block_int-global-state.h ++++ b/include/block/block_int-global-state.h +@@ -140,6 +140,7 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs, + * @mode: Whether to collapse all images in the chain to the target. + * @backing_mode: How to establish the target's backing chain after completion. + * @zero_target: Whether the target should be explicitly zero-initialized ++ * @target_is_zero: Whether the target already is zero-initialized. + * @on_source_error: The action to take upon error reading from the source. + * @on_target_error: The action to take upon error writing to the target. + * @unmap: Whether to unmap target where source sectors only contain zeroes. +@@ -159,7 +160,7 @@ void mirror_start(const char *job_id, BlockDriverState *bs, + int creation_flags, int64_t speed, + uint32_t granularity, int64_t buf_size, + MirrorSyncMode mode, BlockMirrorBackingMode backing_mode, +- bool zero_target, ++ bool zero_target, bool target_is_zero, + BlockdevOnError on_source_error, + BlockdevOnError on_target_error, + bool unmap, const char *filter_node_name, +diff --git a/qapi/block-core.json b/qapi/block-core.json +index b1937780e1..7f70ec6d3c 100644 +--- a/qapi/block-core.json ++++ b/qapi/block-core.json +@@ -2538,6 +2538,11 @@ + # disappear from the query list without user intervention. + # Defaults to true. (Since 3.1) + # ++# @target-is-zero: Assume the destination reads as all zeroes before ++# the mirror started. Setting this to true can speed up the ++# mirror. Setting this to true when the destination is not ++# actually all zero can corrupt the destination. (Since 10.1) ++# + # Since: 2.6 + # + # .. qmp-example:: +@@ -2557,7 +2562,8 @@ + '*on-target-error': 'BlockdevOnError', + '*filter-node-name': 'str', + '*copy-mode': 'MirrorCopyMode', +- '*auto-finalize': 'bool', '*auto-dismiss': 'bool' }, ++ '*auto-finalize': 'bool', '*auto-dismiss': 'bool', ++ '*target-is-zero': 'bool'}, + 'allow-preconfig': true } + + ## +diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c +index e26b3be593..54aed8252c 100644 +--- a/tests/unit/test-block-iothread.c ++++ b/tests/unit/test-block-iothread.c +@@ -755,7 +755,7 @@ static void test_propagate_mirror(void) + + /* Start a mirror job */ + mirror_start("job0", src, target, NULL, JOB_DEFAULT, 0, 0, 0, +- MIRROR_SYNC_MODE_NONE, MIRROR_OPEN_BACKING_CHAIN, false, ++ MIRROR_SYNC_MODE_NONE, MIRROR_OPEN_BACKING_CHAIN, false, false, + BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT, + false, "filter_node", MIRROR_COPY_MODE_BACKGROUND, + &error_abort); +-- +2.39.3 + diff --git a/kvm-mirror-Drop-redundant-zero_target-parameter.patch b/kvm-mirror-Drop-redundant-zero_target-parameter.patch new file mode 100644 index 0000000..bd35c8c --- /dev/null +++ b/kvm-mirror-Drop-redundant-zero_target-parameter.patch @@ -0,0 +1,241 @@ +From db1a158312c2b94af1c1a50e0f13ace6ae58f0b6 Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Fri, 9 May 2025 15:40:26 -0500 +Subject: [PATCH 09/14] mirror: Drop redundant zero_target parameter + +RH-Author: Eric Blake +RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors +RH-Jira: RHEL-88435 RHEL-88437 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +RH-Commit: [9/14] b4cbd267c81b4758f59e0d51b947fd450caf6ef5 (ebblake/centos-qemu-kvm) + +The two callers to a mirror job (drive-mirror and blockdev-mirror) set +zero_target precisely when sync mode == FULL, with the one exception +that drive-mirror skips zeroing the target if it was newly created and +reads as zero. But given the previous patch, that exception is +equally captured by target_is_zero. + +Meanwhile, there is another slight wrinkle, fortunately caught by +iotest 185: if the caller uses "sync":"top" but the source has no +backing file, the code in blockdev.c was changing sync to be FULL, but +only after it had set zero_target=false. In mirror.c, prior to recent +patches, this didn't matter: the only places that inspected sync were +setting is_none_mode (both TOP and FULL had set that to false), and +mirror_start() setting base = mode == MIRROR_SYNC_MODE_TOP ? +bdrv_backing_chain_next(bs) : NULL. But now that we are passing sync +around, the slammed sync mode would result in a new pre-zeroing pass +even when the user had passed "sync":"top" in an effort to skip +pre-zeroing. Fortunately, the assignment of base when bs has no +backing chain still works out to NULL if we don't slam things. So +with the forced change of sync ripped out of blockdev.c, the sync mode +is passed through the full callstack unmolested, and we can now +reliably reconstruct the same settings as what used to be passed in by +zero_target=false, without the redundant parameter. + +Signed-off-by: Eric Blake +Message-ID: <20250509204341.3553601-24-eblake@redhat.com> +Reviewed-by: Sunny Zhu +Reviewed-by: Stefan Hajnoczi +[eblake: Fix regression in iotest 185] +Signed-off-by: Eric Blake +(cherry picked from commit 253b43a29077de9266351e120c600a73b82e9c49) +Jira: https://issues.redhat.com/browse/RHEL-88435 +Jira: https://issues.redhat.com/browse/RHEL-88437 +Signed-off-by: Eric Blake +--- + block/mirror.c | 13 +++++-------- + blockdev.c | 19 ++++--------------- + include/block/block_int-global-state.h | 3 +-- + tests/unit/test-block-iothread.c | 2 +- + 4 files changed, 11 insertions(+), 26 deletions(-) + +diff --git a/block/mirror.c b/block/mirror.c +index 4dcb50c81a..d04db85883 100644 +--- a/block/mirror.c ++++ b/block/mirror.c +@@ -53,8 +53,6 @@ typedef struct MirrorBlockJob { + Error *replace_blocker; + MirrorSyncMode sync_mode; + BlockMirrorBackingMode backing_mode; +- /* Whether the target image requires explicit zero-initialization */ +- bool zero_target; + /* Whether the target should be assumed to be already zero initialized */ + bool target_is_zero; + /* +@@ -854,7 +852,9 @@ static int coroutine_fn GRAPH_UNLOCKED mirror_dirty_init(MirrorBlockJob *s) + bs = s->mirror_top_bs->backing->bs; + bdrv_graph_co_rdunlock(); + +- if (s->zero_target && (!s->target_is_zero || punch_holes)) { ++ if (s->sync_mode == MIRROR_SYNC_MODE_TOP) { ++ /* In TOP mode, there is no benefit to a pre-zeroing pass. */ ++ } else if (!s->target_is_zero || punch_holes) { + /* + * Here, we are in FULL mode; our goal is to avoid writing + * zeroes if the destination already reads as zero, except +@@ -1730,7 +1730,7 @@ static BlockJob *mirror_start_job( + uint32_t granularity, int64_t buf_size, + MirrorSyncMode sync_mode, + BlockMirrorBackingMode backing_mode, +- bool zero_target, bool target_is_zero, ++ bool target_is_zero, + BlockdevOnError on_source_error, + BlockdevOnError on_target_error, + bool unmap, +@@ -1898,7 +1898,6 @@ static BlockJob *mirror_start_job( + s->on_target_error = on_target_error; + s->sync_mode = sync_mode; + s->backing_mode = backing_mode; +- s->zero_target = zero_target; + s->target_is_zero = target_is_zero; + qatomic_set(&s->copy_mode, copy_mode); + s->base = base; +@@ -2028,7 +2027,7 @@ void mirror_start(const char *job_id, BlockDriverState *bs, + int creation_flags, int64_t speed, + uint32_t granularity, int64_t buf_size, + MirrorSyncMode mode, BlockMirrorBackingMode backing_mode, +- bool zero_target, bool target_is_zero, ++ bool target_is_zero, + BlockdevOnError on_source_error, + BlockdevOnError on_target_error, + bool unmap, const char *filter_node_name, +@@ -2051,7 +2050,6 @@ void mirror_start(const char *job_id, BlockDriverState *bs, + + mirror_start_job(job_id, bs, creation_flags, target, replaces, + speed, granularity, buf_size, mode, backing_mode, +- zero_target, + target_is_zero, on_source_error, on_target_error, unmap, + NULL, NULL, &mirror_job_driver, base, false, + filter_node_name, true, copy_mode, false, errp); +@@ -2080,7 +2078,6 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs, + job = mirror_start_job( + job_id, bs, creation_flags, base, NULL, speed, 0, 0, + MIRROR_SYNC_MODE_TOP, MIRROR_LEAVE_BACKING_CHAIN, false, +- false, + on_error, on_error, true, cb, opaque, + &commit_active_job_driver, base, auto_complete, + filter_node_name, false, MIRROR_COPY_MODE_BACKGROUND, +diff --git a/blockdev.c b/blockdev.c +index 2e2fed539e..0fa8813efe 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -2798,7 +2798,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, + const char *replaces, + enum MirrorSyncMode sync, + BlockMirrorBackingMode backing_mode, +- bool zero_target, bool target_is_zero, ++ bool target_is_zero, + bool has_speed, int64_t speed, + bool has_granularity, uint32_t granularity, + bool has_buf_size, int64_t buf_size, +@@ -2865,10 +2865,6 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, + return; + } + +- if (!bdrv_backing_chain_next(bs) && sync == MIRROR_SYNC_MODE_TOP) { +- sync = MIRROR_SYNC_MODE_FULL; +- } +- + if (!replaces) { + /* We want to mirror from @bs, but keep implicit filters on top */ + unfiltered_bs = bdrv_skip_implicit_filters(bs); +@@ -2910,7 +2906,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, + * and will allow to check whether the node still exist at mirror completion + */ + mirror_start(job_id, bs, target, replaces, job_flags, +- speed, granularity, buf_size, sync, backing_mode, zero_target, ++ speed, granularity, buf_size, sync, backing_mode, + target_is_zero, on_source_error, on_target_error, unmap, + filter_node_name, copy_mode, errp); + } +@@ -2926,7 +2922,6 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) + int flags; + int64_t size; + const char *format = arg->format; +- bool zero_target; + bool target_is_zero; + int ret; + +@@ -3041,9 +3036,6 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) + } + + bdrv_graph_rdlock_main_loop(); +- zero_target = (arg->sync == MIRROR_SYNC_MODE_FULL && +- (arg->mode == NEW_IMAGE_MODE_EXISTING || +- !bdrv_has_zero_init(target_bs))); + target_is_zero = (arg->mode != NEW_IMAGE_MODE_EXISTING && + bdrv_has_zero_init(target_bs)); + bdrv_graph_rdunlock_main_loop(); +@@ -3057,7 +3049,7 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) + + blockdev_mirror_common(arg->job_id, bs, target_bs, + arg->replaces, arg->sync, +- backing_mode, zero_target, target_is_zero, ++ backing_mode, target_is_zero, + arg->has_speed, arg->speed, + arg->has_granularity, arg->granularity, + arg->has_buf_size, arg->buf_size, +@@ -3094,7 +3086,6 @@ void qmp_blockdev_mirror(const char *job_id, + BlockDriverState *target_bs; + AioContext *aio_context; + BlockMirrorBackingMode backing_mode = MIRROR_LEAVE_BACKING_CHAIN; +- bool zero_target; + int ret; + + bs = qmp_get_root_bs(device, errp); +@@ -3107,8 +3098,6 @@ void qmp_blockdev_mirror(const char *job_id, + return; + } + +- zero_target = (sync == MIRROR_SYNC_MODE_FULL); +- + aio_context = bdrv_get_aio_context(bs); + + ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp); +@@ -3118,7 +3107,7 @@ void qmp_blockdev_mirror(const char *job_id, + + blockdev_mirror_common(job_id, bs, target_bs, + replaces, sync, backing_mode, +- zero_target, has_target_is_zero && target_is_zero, ++ has_target_is_zero && target_is_zero, + has_speed, speed, + has_granularity, granularity, + has_buf_size, buf_size, +diff --git a/include/block/block_int-global-state.h b/include/block/block_int-global-state.h +index 8cf0003ce7..d21bd7fd2f 100644 +--- a/include/block/block_int-global-state.h ++++ b/include/block/block_int-global-state.h +@@ -139,7 +139,6 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs, + * @buf_size: The amount of data that can be in flight at one time. + * @mode: Whether to collapse all images in the chain to the target. + * @backing_mode: How to establish the target's backing chain after completion. +- * @zero_target: Whether the target should be explicitly zero-initialized + * @target_is_zero: Whether the target already is zero-initialized. + * @on_source_error: The action to take upon error reading from the source. + * @on_target_error: The action to take upon error writing to the target. +@@ -160,7 +159,7 @@ void mirror_start(const char *job_id, BlockDriverState *bs, + int creation_flags, int64_t speed, + uint32_t granularity, int64_t buf_size, + MirrorSyncMode mode, BlockMirrorBackingMode backing_mode, +- bool zero_target, bool target_is_zero, ++ bool target_is_zero, + BlockdevOnError on_source_error, + BlockdevOnError on_target_error, + bool unmap, const char *filter_node_name, +diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c +index 54aed8252c..e26b3be593 100644 +--- a/tests/unit/test-block-iothread.c ++++ b/tests/unit/test-block-iothread.c +@@ -755,7 +755,7 @@ static void test_propagate_mirror(void) + + /* Start a mirror job */ + mirror_start("job0", src, target, NULL, JOB_DEFAULT, 0, 0, 0, +- MIRROR_SYNC_MODE_NONE, MIRROR_OPEN_BACKING_CHAIN, false, false, ++ MIRROR_SYNC_MODE_NONE, MIRROR_OPEN_BACKING_CHAIN, false, + BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT, + false, "filter_node", MIRROR_COPY_MODE_BACKGROUND, + &error_abort); +-- +2.39.3 + diff --git a/kvm-mirror-Minor-refactoring.patch b/kvm-mirror-Minor-refactoring.patch new file mode 100644 index 0000000..d658673 --- /dev/null +++ b/kvm-mirror-Minor-refactoring.patch @@ -0,0 +1,90 @@ +From e95294aecc606deacf716861d716f9178b132ed8 Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Fri, 9 May 2025 15:40:23 -0500 +Subject: [PATCH 06/14] mirror: Minor refactoring + +RH-Author: Eric Blake +RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors +RH-Jira: RHEL-88435 RHEL-88437 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +RH-Commit: [6/14] 22a87aca8033f3f5d10fd224dc0786633a4d040f (ebblake/centos-qemu-kvm) + +Commit 5791ba52 (v9.2) pre-initialized ret in mirror_dirty_init to +silence a false positive compiler warning, even though in all code +paths where ret is used, it was guaranteed to be reassigned +beforehand. But since the function returns -errno, and -1 is not +always the right errno, it's better to initialize to -EIO. + +An upcoming patch wants to track two bitmaps in +do_sync_target_write(); this will be easier if the current variables +related to the dirty bitmap are renamed. + +Signed-off-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-ID: <20250509204341.3553601-21-eblake@redhat.com> +(cherry picked from commit 870f8963cf1a84f8ec929b05a6d68906974a76c5) +Jira: https://issues.redhat.com/browse/RHEL-88435 +Jira: https://issues.redhat.com/browse/RHEL-88437 +Signed-off-by: Eric Blake +--- + block/mirror.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/block/mirror.c b/block/mirror.c +index a53582f17b..34c6c5252e 100644 +--- a/block/mirror.c ++++ b/block/mirror.c +@@ -841,7 +841,7 @@ static int coroutine_fn GRAPH_UNLOCKED mirror_dirty_init(MirrorBlockJob *s) + int64_t offset; + BlockDriverState *bs; + BlockDriverState *target_bs = blk_bs(s->target); +- int ret = -1; ++ int ret = -EIO; + int64_t count; + + bdrv_graph_co_rdlock(); +@@ -1341,7 +1341,7 @@ do_sync_target_write(MirrorBlockJob *job, MirrorMethod method, + { + int ret; + size_t qiov_offset = 0; +- int64_t bitmap_offset, bitmap_end; ++ int64_t dirty_bitmap_offset, dirty_bitmap_end; + + if (!QEMU_IS_ALIGNED(offset, job->granularity) && + bdrv_dirty_bitmap_get(job->dirty_bitmap, offset)) +@@ -1388,11 +1388,11 @@ do_sync_target_write(MirrorBlockJob *job, MirrorMethod method, + * Tails are either clean or shrunk, so for bitmap resetting + * we safely align the range down. + */ +- bitmap_offset = QEMU_ALIGN_UP(offset, job->granularity); +- bitmap_end = QEMU_ALIGN_DOWN(offset + bytes, job->granularity); +- if (bitmap_offset < bitmap_end) { +- bdrv_reset_dirty_bitmap(job->dirty_bitmap, bitmap_offset, +- bitmap_end - bitmap_offset); ++ dirty_bitmap_offset = QEMU_ALIGN_UP(offset, job->granularity); ++ dirty_bitmap_end = QEMU_ALIGN_DOWN(offset + bytes, job->granularity); ++ if (dirty_bitmap_offset < dirty_bitmap_end) { ++ bdrv_reset_dirty_bitmap(job->dirty_bitmap, dirty_bitmap_offset, ++ dirty_bitmap_end - dirty_bitmap_offset); + } + + job_progress_increase_remaining(&job->common.job, bytes); +@@ -1430,10 +1430,10 @@ do_sync_target_write(MirrorBlockJob *job, MirrorMethod method, + * at function start, and they must be still dirty, as we've locked + * the region for in-flight op. + */ +- bitmap_offset = QEMU_ALIGN_DOWN(offset, job->granularity); +- bitmap_end = QEMU_ALIGN_UP(offset + bytes, job->granularity); +- bdrv_set_dirty_bitmap(job->dirty_bitmap, bitmap_offset, +- bitmap_end - bitmap_offset); ++ dirty_bitmap_offset = QEMU_ALIGN_DOWN(offset, job->granularity); ++ dirty_bitmap_end = QEMU_ALIGN_UP(offset + bytes, job->granularity); ++ bdrv_set_dirty_bitmap(job->dirty_bitmap, dirty_bitmap_offset, ++ dirty_bitmap_end - dirty_bitmap_offset); + qatomic_set(&job->actively_synced, false); + + action = mirror_error_action(job, false, -ret); +-- +2.39.3 + diff --git a/kvm-mirror-Pass-full-sync-mode-rather-than-bool-to-inter.patch b/kvm-mirror-Pass-full-sync-mode-rather-than-bool-to-inter.patch new file mode 100644 index 0000000..3029150 --- /dev/null +++ b/kvm-mirror-Pass-full-sync-mode-rather-than-bool-to-inter.patch @@ -0,0 +1,139 @@ +From db0b92495a4e774caafaaa148e778b575112bad2 Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Fri, 9 May 2025 15:40:24 -0500 +Subject: [PATCH 07/14] mirror: Pass full sync mode rather than bool to + internals + +RH-Author: Eric Blake +RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors +RH-Jira: RHEL-88435 RHEL-88437 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +RH-Commit: [7/14] e8872e3edad069ee6c76f6104c1bc277c025b5ac (ebblake/centos-qemu-kvm) + +Out of the five possible values for MirrorSyncMode, INCREMENTAL and +BITMAP are already rejected up front in mirror_start, leaving NONE, +TOP, and FULL as the remaining values that the code was collapsing +into a single bool is_none_mode. Furthermore, mirror_dirty_init() is +only reachable for modes TOP and FULL, as further guided by +s->zero_target. However, upcoming patches want to further optimize +the pre-zeroing pass of a sync=full mirror in mirror_dirty_init(), +while avoiding that pass on a sync=top action. Instead of throwing +away context by collapsing these two values into +s->is_none_mode=false, it is better to pass s->sync_mode throughout +the entire operation. For active commit, the desired semantics match +sync mode TOP. + +Signed-off-by: Eric Blake +Message-ID: <20250509204341.3553601-22-eblake@redhat.com> +Reviewed-by: Sunny Zhu +Reviewed-by: Stefan Hajnoczi +(cherry picked from commit 9474d97bd7421b4fe7c806ab0949697514d11e88) +Jira: https://issues.redhat.com/browse/RHEL-88435 +Jira: https://issues.redhat.com/browse/RHEL-88437 +Signed-off-by: Eric Blake +--- + block/mirror.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/block/mirror.c b/block/mirror.c +index 34c6c5252e..2599b75d09 100644 +--- a/block/mirror.c ++++ b/block/mirror.c +@@ -51,7 +51,7 @@ typedef struct MirrorBlockJob { + BlockDriverState *to_replace; + /* Used to block operations on the drive-mirror-replace target */ + Error *replace_blocker; +- bool is_none_mode; ++ MirrorSyncMode sync_mode; + BlockMirrorBackingMode backing_mode; + /* Whether the target image requires explicit zero-initialization */ + bool zero_target; +@@ -723,9 +723,10 @@ static int mirror_exit_common(Job *job) + &error_abort); + + if (!abort && s->backing_mode == MIRROR_SOURCE_BACKING_CHAIN) { +- BlockDriverState *backing = s->is_none_mode ? src : s->base; ++ BlockDriverState *backing; + BlockDriverState *unfiltered_target = bdrv_skip_filters(target_bs); + ++ backing = s->sync_mode == MIRROR_SYNC_MODE_NONE ? src : s->base; + if (bdrv_cow_bs(unfiltered_target) != backing) { + bdrv_set_backing_hd(unfiltered_target, backing, &local_err); + if (local_err) { +@@ -1020,7 +1021,7 @@ static int coroutine_fn mirror_run(Job *job, Error **errp) + mirror_free_init(s); + + s->last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); +- if (!s->is_none_mode) { ++ if (s->sync_mode != MIRROR_SYNC_MODE_NONE) { + ret = mirror_dirty_init(s); + if (ret < 0 || job_is_cancelled(&s->common.job)) { + goto immediate_exit; +@@ -1711,6 +1712,7 @@ static BlockJob *mirror_start_job( + int creation_flags, BlockDriverState *target, + const char *replaces, int64_t speed, + uint32_t granularity, int64_t buf_size, ++ MirrorSyncMode sync_mode, + BlockMirrorBackingMode backing_mode, + bool zero_target, + BlockdevOnError on_source_error, +@@ -1719,7 +1721,7 @@ static BlockJob *mirror_start_job( + BlockCompletionFunc *cb, + void *opaque, + const BlockJobDriver *driver, +- bool is_none_mode, BlockDriverState *base, ++ BlockDriverState *base, + bool auto_complete, const char *filter_node_name, + bool is_mirror, MirrorCopyMode copy_mode, + bool base_ro, +@@ -1878,7 +1880,7 @@ static BlockJob *mirror_start_job( + s->replaces = g_strdup(replaces); + s->on_source_error = on_source_error; + s->on_target_error = on_target_error; +- s->is_none_mode = is_none_mode; ++ s->sync_mode = sync_mode; + s->backing_mode = backing_mode; + s->zero_target = zero_target; + qatomic_set(&s->copy_mode, copy_mode); +@@ -2015,7 +2017,6 @@ void mirror_start(const char *job_id, BlockDriverState *bs, + bool unmap, const char *filter_node_name, + MirrorCopyMode copy_mode, Error **errp) + { +- bool is_none_mode; + BlockDriverState *base; + + GLOBAL_STATE_CODE(); +@@ -2028,14 +2029,13 @@ void mirror_start(const char *job_id, BlockDriverState *bs, + } + + bdrv_graph_rdlock_main_loop(); +- is_none_mode = mode == MIRROR_SYNC_MODE_NONE; + base = mode == MIRROR_SYNC_MODE_TOP ? bdrv_backing_chain_next(bs) : NULL; + bdrv_graph_rdunlock_main_loop(); + + mirror_start_job(job_id, bs, creation_flags, target, replaces, +- speed, granularity, buf_size, backing_mode, zero_target, +- on_source_error, on_target_error, unmap, NULL, NULL, +- &mirror_job_driver, is_none_mode, base, false, ++ speed, granularity, buf_size, mode, backing_mode, ++ zero_target, on_source_error, on_target_error, unmap, ++ NULL, NULL, &mirror_job_driver, base, false, + filter_node_name, true, copy_mode, false, errp); + } + +@@ -2061,9 +2061,9 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs, + + job = mirror_start_job( + job_id, bs, creation_flags, base, NULL, speed, 0, 0, +- MIRROR_LEAVE_BACKING_CHAIN, false, ++ MIRROR_SYNC_MODE_TOP, MIRROR_LEAVE_BACKING_CHAIN, false, + on_error, on_error, true, cb, opaque, +- &commit_active_job_driver, false, base, auto_complete, ++ &commit_active_job_driver, base, auto_complete, + filter_node_name, false, MIRROR_COPY_MODE_BACKGROUND, + base_read_only, errp); + if (!job) { +-- +2.39.3 + diff --git a/kvm-mirror-Reduce-I-O-when-destination-is-detect-zeroes-.patch b/kvm-mirror-Reduce-I-O-when-destination-is-detect-zeroes-.patch new file mode 100644 index 0000000..27a0ccc --- /dev/null +++ b/kvm-mirror-Reduce-I-O-when-destination-is-detect-zeroes-.patch @@ -0,0 +1,58 @@ +From 9fedd14da6f1dc7aa3f0711d86f722397d080993 Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Tue, 13 May 2025 17:00:45 -0500 +Subject: [PATCH 14/14] mirror: Reduce I/O when destination is + detect-zeroes:unmap + +RH-Author: Eric Blake +RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors +RH-Jira: RHEL-88435 RHEL-88437 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +RH-Commit: [14/14] d4ba9d88a8da00f82c2ba7ebf050152fbe1e2465 (ebblake/centos-qemu-kvm) + +If we are going to punch holes in the mirror destination even for the +portions where the source image is unallocated, it is nicer to treat +the entire image as dirty and punch as we go, rather than pre-zeroing +the entire image just to re-do I/O to the allocated portions of the +image. + +Signed-off-by: Eric Blake +Message-ID: <20250513220142.535200-2-eblake@redhat.com> +Reviewed-by: Stefan Hajnoczi +(cherry picked from commit 9abfc81246c9cc1845080eec5920779961187c07) +Jira: https://issues.redhat.com/browse/RHEL-88435 +Jira: https://issues.redhat.com/browse/RHEL-88437 +Signed-off-by: Eric Blake +--- + block/mirror.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/block/mirror.c b/block/mirror.c +index 724318f037..c2c5099c95 100644 +--- a/block/mirror.c ++++ b/block/mirror.c +@@ -920,11 +920,16 @@ static int coroutine_fn GRAPH_UNLOCKED mirror_dirty_init(MirrorBlockJob *s) + * zeroing happened externally (ret > 0) or if we have a fast + * way to pre-zero the image (the dirty bitmap will be + * populated later by the non-zero portions, the same as for +- * TOP mode). If pre-zeroing is not fast, then our only +- * recourse is to mark the entire image dirty. The act of +- * pre-zeroing will populate the zero bitmap. ++ * TOP mode). If pre-zeroing is not fast, or we need to visit ++ * the entire image in order to punch holes even in the ++ * non-allocated regions of the source, then just mark the ++ * entire image dirty and leave the zero bitmap clear at this ++ * point in time. Otherwise, it can be faster to pre-zero the ++ * image now, even if we re-write the allocated portions of ++ * the disk later, and the pre-zero pass will populate the ++ * zero bitmap. + */ +- if (!bdrv_can_write_zeroes_with_unmap(target_bs)) { ++ if (!bdrv_can_write_zeroes_with_unmap(target_bs) || punch_holes) { + bdrv_set_dirty_bitmap(s->dirty_bitmap, 0, s->bdev_length); + return 0; + } +-- +2.39.3 + diff --git a/kvm-mirror-Skip-pre-zeroing-destination-if-it-is-already.patch b/kvm-mirror-Skip-pre-zeroing-destination-if-it-is-already.patch new file mode 100644 index 0000000..cb2b25f --- /dev/null +++ b/kvm-mirror-Skip-pre-zeroing-destination-if-it-is-already.patch @@ -0,0 +1,180 @@ +From 92a033b6c8394c8efb5b881cbbe463eeff5711cd Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Fri, 9 May 2025 15:40:27 -0500 +Subject: [PATCH 10/14] mirror: Skip pre-zeroing destination if it is already + zero + +RH-Author: Eric Blake +RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors +RH-Jira: RHEL-88435 RHEL-88437 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +RH-Commit: [10/14] 5d86d9c763a1bb49fab591a45e211d3be819ccfe (ebblake/centos-qemu-kvm) + +When doing a sync=full mirroring, we can skip pre-zeroing the +destination if it already reads as zeroes and we are not also trying +to punch holes due to detect-zeroes. With this patch, there are fewer +scenarios that have to pass in an explicit target-is-zero, while still +resulting in a sparse destination remaining sparse. + +A later patch will then further improve things to skip writing to the +destination for parts of the image where the source is zero; but even +with just this patch, it is possible to see a difference for any +source that does not report itself as fully allocated, coupled with a +destination BDS that can quickly report that it already reads as zero. +(For a source that reports as fully allocated, such as a file, the +rest of mirror_dirty_init() still sets the entire dirty bitmap to +true, so even though we avoided the pre-zeroing, we are not yet +avoiding all redundant I/O). + +Iotest 194 detects the difference made by this patch: for a file +source (where block status reports the entire image as allocated, and +therefore we end up writing zeroes everywhere in the destination +anyways), the job length remains the same. But for a qcow2 source and +a destination that reads as all zeroes, the dirty bitmap changes to +just tracking the allocated portions of the source, which results in +faster completion and smaller job statistics. For the test to pass +with both ./check -file and -qcow2, a new python filter is needed to +mask out the now-varying job amounts (this matches the shell filters +_filter_block_job_{offset,len} in common.filter). A later test will +also be added which further validates expected sparseness, so it does +not matter that 194 is no longer explicitly looking at how many bytes +were copied. + +Signed-off-by: Eric Blake +Message-ID: <20250509204341.3553601-25-eblake@redhat.com> +Reviewed-by: Sunny Zhu +Reviewed-by: Stefan Hajnoczi +(cherry picked from commit 181a63667adf16c35b57e446def3e41c70f1fea6) +Jira: https://issues.redhat.com/browse/RHEL-88435 +Jira: https://issues.redhat.com/browse/RHEL-88437 +Signed-off-by: Eric Blake +--- + block/mirror.c | 24 ++++++++++++++++-------- + tests/qemu-iotests/194 | 6 ++++-- + tests/qemu-iotests/194.out | 4 ++-- + tests/qemu-iotests/iotests.py | 12 +++++++++++- + 4 files changed, 33 insertions(+), 13 deletions(-) + +diff --git a/block/mirror.c b/block/mirror.c +index d04db85883..bca99ec206 100644 +--- a/block/mirror.c ++++ b/block/mirror.c +@@ -848,23 +848,31 @@ static int coroutine_fn GRAPH_UNLOCKED mirror_dirty_init(MirrorBlockJob *s) + target_bs->detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP && + bdrv_can_write_zeroes_with_unmap(target_bs); + ++ /* Determine if the image is already zero, regardless of sync mode. */ + bdrv_graph_co_rdlock(); + bs = s->mirror_top_bs->backing->bs; ++ if (s->target_is_zero) { ++ ret = 1; ++ } else { ++ ret = bdrv_co_is_all_zeroes(target_bs); ++ } + bdrv_graph_co_rdunlock(); + +- if (s->sync_mode == MIRROR_SYNC_MODE_TOP) { ++ /* Determine if a pre-zeroing pass is necessary. */ ++ if (ret < 0) { ++ return ret; ++ } else if (s->sync_mode == MIRROR_SYNC_MODE_TOP) { + /* In TOP mode, there is no benefit to a pre-zeroing pass. */ +- } else if (!s->target_is_zero || punch_holes) { ++ } else if (ret == 0 || punch_holes) { + /* + * Here, we are in FULL mode; our goal is to avoid writing + * zeroes if the destination already reads as zero, except + * when we are trying to punch holes. This is possible if +- * zeroing happened externally (s->target_is_zero) or if we +- * have a fast way to pre-zero the image (the dirty bitmap +- * will be populated later by the non-zero portions, the same +- * as for TOP mode). If pre-zeroing is not fast, or we need +- * to punch holes, then our only recourse is to write the +- * entire image. ++ * zeroing happened externally (ret > 0) or if we have a fast ++ * way to pre-zero the image (the dirty bitmap will be ++ * populated later by the non-zero portions, the same as for ++ * TOP mode). If pre-zeroing is not fast, or we need to punch ++ * holes, then our only recourse is to write the entire image. + */ + if (!bdrv_can_write_zeroes_with_unmap(target_bs)) { + bdrv_set_dirty_bitmap(s->dirty_bitmap, 0, s->bdev_length); +diff --git a/tests/qemu-iotests/194 b/tests/qemu-iotests/194 +index d0b9c084f5..e114c0b269 100755 +--- a/tests/qemu-iotests/194 ++++ b/tests/qemu-iotests/194 +@@ -62,7 +62,8 @@ with iotests.FilePath('source.img') as source_img_path, \ + + iotests.log('Waiting for `drive-mirror` to complete...') + iotests.log(source_vm.event_wait('BLOCK_JOB_READY'), +- filters=[iotests.filter_qmp_event]) ++ filters=[iotests.filter_qmp_event, ++ iotests.filter_block_job]) + + iotests.log('Starting migration...') + capabilities = [{'capability': 'events', 'state': True}, +@@ -88,7 +89,8 @@ with iotests.FilePath('source.img') as source_img_path, \ + + while True: + event2 = source_vm.event_wait('BLOCK_JOB_COMPLETED') +- iotests.log(event2, filters=[iotests.filter_qmp_event]) ++ iotests.log(event2, filters=[iotests.filter_qmp_event, ++ iotests.filter_block_job]) + if event2['event'] == 'BLOCK_JOB_COMPLETED': + iotests.log('Stopping the NBD server on destination...') + iotests.log(dest_vm.qmp('nbd-server-stop')) +diff --git a/tests/qemu-iotests/194.out b/tests/qemu-iotests/194.out +index 6940e809cd..d02655a514 100644 +--- a/tests/qemu-iotests/194.out ++++ b/tests/qemu-iotests/194.out +@@ -7,7 +7,7 @@ Launching NBD server on destination... + Starting `drive-mirror` on source... + {"return": {}} + Waiting for `drive-mirror` to complete... +-{"data": {"device": "mirror-job0", "len": 1073741824, "offset": 1073741824, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} ++{"data": {"device": "mirror-job0", "len": "LEN", "offset": "OFFSET", "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} + Starting migration... + {"return": {}} + {"execute": "migrate-start-postcopy", "arguments": {}} +@@ -18,7 +18,7 @@ Starting migration... + {"data": {"status": "completed"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} + Gracefully ending the `drive-mirror` job on source... + {"return": {}} +-{"data": {"device": "mirror-job0", "len": 1073741824, "offset": 1073741824, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} ++{"data": {"device": "mirror-job0", "len": "LEN", "offset": "OFFSET", "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} + Stopping the NBD server on destination... + {"return": {}} + Wait for migration completion on target... +diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py +index 7292c8b342..05274772ce 100644 +--- a/tests/qemu-iotests/iotests.py ++++ b/tests/qemu-iotests/iotests.py +@@ -601,13 +601,23 @@ def filter_chown(msg): + return chown_re.sub("chown UID:GID", msg) + + def filter_qmp_event(event): +- '''Filter a QMP event dict''' ++ '''Filter the timestamp of a QMP event dict''' + event = dict(event) + if 'timestamp' in event: + event['timestamp']['seconds'] = 'SECS' + event['timestamp']['microseconds'] = 'USECS' + return event + ++def filter_block_job(event): ++ '''Filter the offset and length of a QMP block job event dict''' ++ event = dict(event) ++ if 'data' in event: ++ if 'offset' in event['data']: ++ event['data']['offset'] = 'OFFSET' ++ if 'len' in event['data']: ++ event['data']['len'] = 'LEN' ++ return event ++ + def filter_qmp(qmsg, filter_fn): + '''Given a string filter, filter a QMP object's values. + filter_fn takes a (key, value) pair.''' +-- +2.39.3 + diff --git a/kvm-mirror-Skip-writing-zeroes-when-target-is-already-ze.patch b/kvm-mirror-Skip-writing-zeroes-when-target-is-already-ze.patch new file mode 100644 index 0000000..af29809 --- /dev/null +++ b/kvm-mirror-Skip-writing-zeroes-when-target-is-already-ze.patch @@ -0,0 +1,355 @@ +From cc72e6ec30fb113b82fcdb61f79a0fae18e31e79 Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Fri, 9 May 2025 15:40:28 -0500 +Subject: [PATCH 11/14] mirror: Skip writing zeroes when target is already zero + +RH-Author: Eric Blake +RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors +RH-Jira: RHEL-88435 RHEL-88437 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +RH-Commit: [11/14] 82df7fcf94606e6b6570469d3c05666da5039408 (ebblake/centos-qemu-kvm) + +When mirroring, the goal is to ensure that the destination reads the +same as the source; this goal is met whether the destination is sparse +or fully-allocated (except when explicitly punching holes, then merely +reading zero is not enough to know if it is sparse, so we still want +to punch the hole). Avoiding a redundant write to zero (whether in +the background because the zero cluster was marked in the dirty +bitmap, or in the foreground because the guest is writing zeroes) when +the destination already reads as zero makes mirroring faster, and +avoids allocating the destination merely because the source reports as +allocated. + +The effect is especially pronounced when the source is a raw file. +That's because when the source is a qcow2 file, the dirty bitmap only +visits the portions of the source that are allocated, which tend to be +non-zero. But when the source is a raw file, +bdrv_co_is_allocated_above() reports the entire file as allocated so +mirror_dirty_init sets the entire dirty bitmap, and it is only later +during mirror_iteration that we change to consulting the more precise +bdrv_co_block_status_above() to learn where the source reads as zero. + +Remember that since a mirror operation can write a cluster more than +once (every time the guest changes the source, the destination is also +changed to keep up), and the guest can change whether a given cluster +reads as zero, is discarded, or has non-zero data over the course of +the mirror operation, we can't take the shortcut of relying on +s->target_is_zero (which is static for the life of the job) in +mirror_co_zero() to see if the destination is already zero, because +that information may be stale. Any solution we use must be dynamic in +the face of the guest writing or discarding a cluster while the mirror +has been ongoing. + +We could just teach mirror_co_zero() to do a block_status() probe of +the destination, and skip the zeroes if the destination already reads +as zero, but we know from past experience that extra block_status() +calls are not always cheap (tmpfs, anyone?), especially when they are +random access rather than linear. Use of block_status() of the source +by the background task in a linear fashion is not our bottleneck (it's +a background task, after all); but since mirroring can be done while +the source is actively being changed, we don't want a slow +block_status() of the destination to occur on the hot path of the +guest trying to do random-access writes to the source. + +So this patch takes a slightly different approach: any time we have to +track dirty clusters, we can also track which clusters are known to +read as zero. For sync=TOP or when we are punching holes from +"detect-zeroes":"unmap", the zero bitmap starts out empty, but +prevents a second write zero to a cluster that was already zero by an +earlier pass; for sync=FULL when we are not punching holes, the zero +bitmap starts out full if the destination reads as zero during +initialization. Either way, I/O to the destination can now avoid +redundant write zero to a cluster that already reads as zero, all +without having to do a block_status() per write on the destination. + +With this patch, if I create a raw sparse destination file, connect it +with QMP 'blockdev-add' while leaving it at the default "discard": +"ignore", then run QMP 'blockdev-mirror' with "sync": "full", the +destination remains sparse rather than fully allocated. Meanwhile, a +destination image that is already fully allocated remains so unless it +was opened with "detect-zeroes": "unmap". And any time writing zeroes +is skipped, the job counters are not incremented. + +Signed-off-by: Eric Blake +Message-ID: <20250509204341.3553601-26-eblake@redhat.com> +Reviewed-by: Stefan Hajnoczi +(cherry picked from commit 7e277545b90874171128804e256a538fb0e8dd7e) +Jira: https://issues.redhat.com/browse/RHEL-88435 +Jira: https://issues.redhat.com/browse/RHEL-88437 +Signed-off-by: Eric Blake +--- + block/mirror.c | 107 ++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 93 insertions(+), 14 deletions(-) + +diff --git a/block/mirror.c b/block/mirror.c +index bca99ec206..724318f037 100644 +--- a/block/mirror.c ++++ b/block/mirror.c +@@ -73,6 +73,7 @@ typedef struct MirrorBlockJob { + size_t buf_size; + int64_t bdev_length; + unsigned long *cow_bitmap; ++ unsigned long *zero_bitmap; + BdrvDirtyBitmap *dirty_bitmap; + BdrvDirtyBitmapIter *dbi; + uint8_t *buf; +@@ -108,9 +109,12 @@ struct MirrorOp { + int64_t offset; + uint64_t bytes; + +- /* The pointee is set by mirror_co_read(), mirror_co_zero(), and +- * mirror_co_discard() before yielding for the first time */ ++ /* ++ * These pointers are set by mirror_co_read(), mirror_co_zero(), and ++ * mirror_co_discard() before yielding for the first time ++ */ + int64_t *bytes_handled; ++ bool *io_skipped; + + bool is_pseudo_op; + bool is_active_write; +@@ -408,15 +412,34 @@ static void coroutine_fn mirror_co_read(void *opaque) + static void coroutine_fn mirror_co_zero(void *opaque) + { + MirrorOp *op = opaque; +- int ret; ++ bool write_needed = true; ++ int ret = 0; + + op->s->in_flight++; + op->s->bytes_in_flight += op->bytes; + *op->bytes_handled = op->bytes; + op->is_in_flight = true; + +- ret = blk_co_pwrite_zeroes(op->s->target, op->offset, op->bytes, +- op->s->unmap ? BDRV_REQ_MAY_UNMAP : 0); ++ if (op->s->zero_bitmap) { ++ unsigned long end = DIV_ROUND_UP(op->offset + op->bytes, ++ op->s->granularity); ++ assert(QEMU_IS_ALIGNED(op->offset, op->s->granularity)); ++ assert(QEMU_IS_ALIGNED(op->bytes, op->s->granularity) || ++ op->offset + op->bytes == op->s->bdev_length); ++ if (find_next_zero_bit(op->s->zero_bitmap, end, ++ op->offset / op->s->granularity) == end) { ++ write_needed = false; ++ *op->io_skipped = true; ++ } ++ } ++ if (write_needed) { ++ ret = blk_co_pwrite_zeroes(op->s->target, op->offset, op->bytes, ++ op->s->unmap ? BDRV_REQ_MAY_UNMAP : 0); ++ } ++ if (ret >= 0 && op->s->zero_bitmap) { ++ bitmap_set(op->s->zero_bitmap, op->offset / op->s->granularity, ++ DIV_ROUND_UP(op->bytes, op->s->granularity)); ++ } + mirror_write_complete(op, ret); + } + +@@ -435,29 +458,43 @@ static void coroutine_fn mirror_co_discard(void *opaque) + } + + static unsigned mirror_perform(MirrorBlockJob *s, int64_t offset, +- unsigned bytes, MirrorMethod mirror_method) ++ unsigned bytes, MirrorMethod mirror_method, ++ bool *io_skipped) + { + MirrorOp *op; + Coroutine *co; + int64_t bytes_handled = -1; + ++ assert(QEMU_IS_ALIGNED(offset, s->granularity)); ++ assert(QEMU_IS_ALIGNED(bytes, s->granularity) || ++ offset + bytes == s->bdev_length); + op = g_new(MirrorOp, 1); + *op = (MirrorOp){ + .s = s, + .offset = offset, + .bytes = bytes, + .bytes_handled = &bytes_handled, ++ .io_skipped = io_skipped, + }; + qemu_co_queue_init(&op->waiting_requests); + + switch (mirror_method) { + case MIRROR_METHOD_COPY: ++ if (s->zero_bitmap) { ++ bitmap_clear(s->zero_bitmap, offset / s->granularity, ++ DIV_ROUND_UP(bytes, s->granularity)); ++ } + co = qemu_coroutine_create(mirror_co_read, op); + break; + case MIRROR_METHOD_ZERO: ++ /* s->zero_bitmap handled in mirror_co_zero */ + co = qemu_coroutine_create(mirror_co_zero, op); + break; + case MIRROR_METHOD_DISCARD: ++ if (s->zero_bitmap) { ++ bitmap_clear(s->zero_bitmap, offset / s->granularity, ++ DIV_ROUND_UP(bytes, s->granularity)); ++ } + co = qemu_coroutine_create(mirror_co_discard, op); + break; + default: +@@ -568,6 +605,7 @@ static void coroutine_fn GRAPH_UNLOCKED mirror_iteration(MirrorBlockJob *s) + int ret = -1; + int64_t io_bytes; + int64_t io_bytes_acct; ++ bool io_skipped = false; + MirrorMethod mirror_method = MIRROR_METHOD_COPY; + + assert(!(offset % s->granularity)); +@@ -611,8 +649,10 @@ static void coroutine_fn GRAPH_UNLOCKED mirror_iteration(MirrorBlockJob *s) + } + + io_bytes = mirror_clip_bytes(s, offset, io_bytes); +- io_bytes = mirror_perform(s, offset, io_bytes, mirror_method); +- if (mirror_method != MIRROR_METHOD_COPY && write_zeroes_ok) { ++ io_bytes = mirror_perform(s, offset, io_bytes, mirror_method, ++ &io_skipped); ++ if (io_skipped || ++ (mirror_method != MIRROR_METHOD_COPY && write_zeroes_ok)) { + io_bytes_acct = 0; + } else { + io_bytes_acct = io_bytes; +@@ -847,8 +887,10 @@ static int coroutine_fn GRAPH_UNLOCKED mirror_dirty_init(MirrorBlockJob *s) + bool punch_holes = + target_bs->detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP && + bdrv_can_write_zeroes_with_unmap(target_bs); ++ int64_t bitmap_length = DIV_ROUND_UP(s->bdev_length, s->granularity); + + /* Determine if the image is already zero, regardless of sync mode. */ ++ s->zero_bitmap = bitmap_new(bitmap_length); + bdrv_graph_co_rdlock(); + bs = s->mirror_top_bs->backing->bs; + if (s->target_is_zero) { +@@ -862,7 +904,14 @@ static int coroutine_fn GRAPH_UNLOCKED mirror_dirty_init(MirrorBlockJob *s) + if (ret < 0) { + return ret; + } else if (s->sync_mode == MIRROR_SYNC_MODE_TOP) { +- /* In TOP mode, there is no benefit to a pre-zeroing pass. */ ++ /* ++ * In TOP mode, there is no benefit to a pre-zeroing pass, but ++ * the zero bitmap can be set if the destination already reads ++ * as zero and we are not punching holes. ++ */ ++ if (ret > 0 && !punch_holes) { ++ bitmap_set(s->zero_bitmap, 0, bitmap_length); ++ } + } else if (ret == 0 || punch_holes) { + /* + * Here, we are in FULL mode; our goal is to avoid writing +@@ -871,8 +920,9 @@ static int coroutine_fn GRAPH_UNLOCKED mirror_dirty_init(MirrorBlockJob *s) + * zeroing happened externally (ret > 0) or if we have a fast + * way to pre-zero the image (the dirty bitmap will be + * populated later by the non-zero portions, the same as for +- * TOP mode). If pre-zeroing is not fast, or we need to punch +- * holes, then our only recourse is to write the entire image. ++ * TOP mode). If pre-zeroing is not fast, then our only ++ * recourse is to mark the entire image dirty. The act of ++ * pre-zeroing will populate the zero bitmap. + */ + if (!bdrv_can_write_zeroes_with_unmap(target_bs)) { + bdrv_set_dirty_bitmap(s->dirty_bitmap, 0, s->bdev_length); +@@ -883,6 +933,7 @@ static int coroutine_fn GRAPH_UNLOCKED mirror_dirty_init(MirrorBlockJob *s) + for (offset = 0; offset < s->bdev_length; ) { + int bytes = MIN(s->bdev_length - offset, + QEMU_ALIGN_DOWN(INT_MAX, s->granularity)); ++ bool ignored; + + mirror_throttle(s); + +@@ -898,12 +949,15 @@ static int coroutine_fn GRAPH_UNLOCKED mirror_dirty_init(MirrorBlockJob *s) + continue; + } + +- mirror_perform(s, offset, bytes, MIRROR_METHOD_ZERO); ++ mirror_perform(s, offset, bytes, MIRROR_METHOD_ZERO, &ignored); + offset += bytes; + } + + mirror_wait_for_all_io(s); + s->initial_zeroing_ongoing = false; ++ } else { ++ /* In FULL mode, and image already reads as zero. */ ++ bitmap_set(s->zero_bitmap, 0, bitmap_length); + } + + /* First part, loop on the sectors and initialize the dirty bitmap. */ +@@ -1188,6 +1242,7 @@ immediate_exit: + assert(s->in_flight == 0); + qemu_vfree(s->buf); + g_free(s->cow_bitmap); ++ g_free(s->zero_bitmap); + g_free(s->in_flight_bitmap); + bdrv_dirty_iter_free(s->dbi); + +@@ -1367,6 +1422,7 @@ do_sync_target_write(MirrorBlockJob *job, MirrorMethod method, + int ret; + size_t qiov_offset = 0; + int64_t dirty_bitmap_offset, dirty_bitmap_end; ++ int64_t zero_bitmap_offset, zero_bitmap_end; + + if (!QEMU_IS_ALIGNED(offset, job->granularity) && + bdrv_dirty_bitmap_get(job->dirty_bitmap, offset)) +@@ -1410,8 +1466,9 @@ do_sync_target_write(MirrorBlockJob *job, MirrorMethod method, + } + + /* +- * Tails are either clean or shrunk, so for bitmap resetting +- * we safely align the range down. ++ * Tails are either clean or shrunk, so for dirty bitmap resetting ++ * we safely align the range narrower. But for zero bitmap, round ++ * range wider for checking or clearing, and narrower for setting. + */ + dirty_bitmap_offset = QEMU_ALIGN_UP(offset, job->granularity); + dirty_bitmap_end = QEMU_ALIGN_DOWN(offset + bytes, job->granularity); +@@ -1419,22 +1476,44 @@ do_sync_target_write(MirrorBlockJob *job, MirrorMethod method, + bdrv_reset_dirty_bitmap(job->dirty_bitmap, dirty_bitmap_offset, + dirty_bitmap_end - dirty_bitmap_offset); + } ++ zero_bitmap_offset = offset / job->granularity; ++ zero_bitmap_end = DIV_ROUND_UP(offset + bytes, job->granularity); + + job_progress_increase_remaining(&job->common.job, bytes); + job->active_write_bytes_in_flight += bytes; + + switch (method) { + case MIRROR_METHOD_COPY: ++ if (job->zero_bitmap) { ++ bitmap_clear(job->zero_bitmap, zero_bitmap_offset, ++ zero_bitmap_end - zero_bitmap_offset); ++ } + ret = blk_co_pwritev_part(job->target, offset, bytes, + qiov, qiov_offset, flags); + break; + + case MIRROR_METHOD_ZERO: ++ if (job->zero_bitmap) { ++ if (find_next_zero_bit(job->zero_bitmap, zero_bitmap_end, ++ zero_bitmap_offset) == zero_bitmap_end) { ++ ret = 0; ++ break; ++ } ++ } + assert(!qiov); + ret = blk_co_pwrite_zeroes(job->target, offset, bytes, flags); ++ if (job->zero_bitmap && ret >= 0) { ++ bitmap_set(job->zero_bitmap, dirty_bitmap_offset / job->granularity, ++ (dirty_bitmap_end - dirty_bitmap_offset) / ++ job->granularity); ++ } + break; + + case MIRROR_METHOD_DISCARD: ++ if (job->zero_bitmap) { ++ bitmap_clear(job->zero_bitmap, zero_bitmap_offset, ++ zero_bitmap_end - zero_bitmap_offset); ++ } + assert(!qiov); + ret = blk_co_pdiscard(job->target, offset, bytes); + break; +-- +2.39.3 + diff --git a/kvm-nbd-server-Silence-server-warnings-on-port-probes.patch b/kvm-nbd-server-Silence-server-warnings-on-port-probes.patch deleted file mode 100644 index a09d883..0000000 --- a/kvm-nbd-server-Silence-server-warnings-on-port-probes.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 4364ac20ae74ae2fa4cc2dfa4e982411d9902b59 Mon Sep 17 00:00:00 2001 -From: Eric Blake -Date: Fri, 15 Nov 2024 13:55:53 -0600 -Subject: [PATCH] nbd-server: Silence server warnings on port probes - -RH-Author: Eric Blake -RH-MergeRequest: 334: nbd-server: Silence server warnings on port probes -RH-Jira: RHEL-76908 -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/1] a66ea3900e0a8515871b6342dfbc0d2c108b4911 (ebblake/centos-qemu-kvm) - -While testing the use of qemu-nbd in a Pod of a Kubernetes cluster, I -got LOTS of log messages of the forms: - -qemu-nbd: option negotiation failed: Failed to read flags: Unexpected end-of-file before all data were read -qemu-nbd: option negotiation failed: Failed to read flags: Unable to read from socket: Connection reset by peer - -While it is nice to warn about clients that aren't following protocol -(in case it helps diagnosing bugs in those clients), a mere port probe -(where the client never write()s any bytes, and where we might even -hit EPIPE in trying to send our greeting to the client) is NOT -abnormal, but merely serves to pollute the log. And Kubernetes -_really_ likes to do port probes to determine whether a given Pod is -up and running. - -Easy ways to demonstrate the above port probes: -$ qemu-nbd -r -f raw path/to/file & -$ nc localhost 10809 -Message-ID: <20241115195638.1132007-2-eblake@redhat.com> -Reviewed-by: Vladimir Sementsov-Ogievskiy -(cherry picked from commit efd3dda312129b91986f85976afbda58d40f757f) -Signed-off-by: Eric Blake ---- - nbd/server.c | 26 +++++++++++++++++--------- - 1 file changed, 17 insertions(+), 9 deletions(-) - -diff --git a/nbd/server.c b/nbd/server.c -index c30e687fc8..f64e47270c 100644 ---- a/nbd/server.c -+++ b/nbd/server.c -@@ -1150,8 +1150,8 @@ nbd_negotiate_meta_queries(NBDClient *client, Error **errp) - * Return: - * -errno on error, errp is set - * 0 on successful negotiation, errp is not set -- * 1 if client sent NBD_OPT_ABORT, i.e. on valid disconnect, -- * errp is not set -+ * 1 if client sent NBD_OPT_ABORT (i.e. on valid disconnect) or never -+ * wrote anything (i.e. port probe); errp is not set - */ - static coroutine_fn int - nbd_negotiate_options(NBDClient *client, Error **errp) -@@ -1175,8 +1175,13 @@ nbd_negotiate_options(NBDClient *client, Error **errp) - ... Rest of request - */ - -- if (nbd_read32(client->ioc, &flags, "flags", errp) < 0) { -- return -EIO; -+ /* -+ * Intentionally ignore errors on this first read - we do not want -+ * to be noisy about a mere port probe, but only for clients that -+ * start talking the protocol and then quit abruptly. -+ */ -+ if (nbd_read32(client->ioc, &flags, "flags", NULL) < 0) { -+ return 1; - } - client->mode = NBD_MODE_EXPORT_NAME; - trace_nbd_negotiate_options_flags(flags); -@@ -1383,8 +1388,8 @@ nbd_negotiate_options(NBDClient *client, Error **errp) - * Return: - * -errno on error, errp is set - * 0 on successful negotiation, errp is not set -- * 1 if client sent NBD_OPT_ABORT, i.e. on valid disconnect, -- * errp is not set -+ * 1 if client sent NBD_OPT_ABORT (i.e. on valid disconnect) or never -+ * wrote anything (i.e. port probe); errp is not set - */ - static coroutine_fn int nbd_negotiate(NBDClient *client, Error **errp) - { -@@ -1415,9 +1420,12 @@ static coroutine_fn int nbd_negotiate(NBDClient *client, Error **errp) - stq_be_p(buf + 8, NBD_OPTS_MAGIC); - stw_be_p(buf + 16, NBD_FLAG_FIXED_NEWSTYLE | NBD_FLAG_NO_ZEROES); - -- if (nbd_write(client->ioc, buf, 18, errp) < 0) { -- error_prepend(errp, "write failed: "); -- return -EINVAL; -+ /* -+ * Be silent about failure to write our greeting: there is nothing -+ * wrong with a client testing if our port is alive. -+ */ -+ if (nbd_write(client->ioc, buf, 18, NULL) < 0) { -+ return 1; - } - ret = nbd_negotiate_options(client, errp); - if (ret != 0) { --- -2.39.3 - diff --git a/kvm-nbd-server-Support-inactive-nodes.patch b/kvm-nbd-server-Support-inactive-nodes.patch deleted file mode 100644 index 03c4fb3..0000000 --- a/kvm-nbd-server-Support-inactive-nodes.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 8c6301c578000fff63c5ee0406020ecc4d3ca170 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Tue, 4 Feb 2025 22:14:04 +0100 -Subject: [PATCH 19/22] nbd/server: Support inactive nodes - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [19/22] 140f88e93d88437c8c9c63299f714230ebfd9228 (kmwolf/centos-qemu-kvm) - -In order to support running an NBD export on inactive nodes, we must -make sure to return errors for any operations that aren't allowed on -inactive nodes. Reads are the only operation we know we need for -inactive images, so to err on the side of caution, return errors for -everything else, even if some operations could possibly be okay. - -Signed-off-by: Kevin Wolf -Acked-by: Fabiano Rosas -Message-ID: <20250204211407.381505-14-kwolf@redhat.com> -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Eric Blake -Signed-off-by: Kevin Wolf -(cherry picked from commit 2e73a17c68f4d80023dc616e596e8c1f3ea8dd75) -Signed-off-by: Kevin Wolf ---- - nbd/server.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/nbd/server.c b/nbd/server.c -index f64e47270c..2076fb2666 100644 ---- a/nbd/server.c -+++ b/nbd/server.c -@@ -2026,6 +2026,7 @@ static void nbd_export_delete(BlockExport *blk_exp) - const BlockExportDriver blk_exp_nbd = { - .type = BLOCK_EXPORT_TYPE_NBD, - .instance_size = sizeof(NBDExport), -+ .supports_inactive = true, - .create = nbd_export_create, - .delete = nbd_export_delete, - .request_shutdown = nbd_export_request_shutdown, -@@ -2920,6 +2921,22 @@ static coroutine_fn int nbd_handle_request(NBDClient *client, - NBDExport *exp = client->exp; - char *msg; - size_t i; -+ bool inactive; -+ -+ WITH_GRAPH_RDLOCK_GUARD() { -+ inactive = bdrv_is_inactive(blk_bs(exp->common.blk)); -+ if (inactive) { -+ switch (request->type) { -+ case NBD_CMD_READ: -+ /* These commands are allowed on inactive nodes */ -+ break; -+ default: -+ /* Return an error for the rest */ -+ return nbd_send_generic_reply(client, request, -EPERM, -+ "export is inactive", errp); -+ } -+ } -+ } - - switch (request->type) { - case NBD_CMD_CACHE: --- -2.39.3 - diff --git a/kvm-net-Fix-announce_self.patch b/kvm-net-Fix-announce_self.patch deleted file mode 100644 index b288d44..0000000 --- a/kvm-net-Fix-announce_self.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 6b03a9c09340ee9d9f4dfda204832858057892ae Mon Sep 17 00:00:00 2001 -From: Laurent Vivier -Date: Fri, 17 Jan 2025 12:17:08 +0100 -Subject: [PATCH 1/3] net: Fix announce_self -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Laurent Vivier -RH-MergeRequest: 335: net: Fix announce_self -RH-Jira: RHEL-73894 -RH-Acked-by: Eugenio PĂ©rez -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/1] f50da0292fdbfbdf20782b5a75cac2c362b8e472 (lvivier/qemu-kvm-centos) - -JIRA: https://issues.redhat.com/browse/RHEL-73894 - -b9ad513e1876 ("net: Remove receive_raw()") adds an iovec entry -in qemu_deliver_packet_iov() to add the virtio-net header -in the data when QEMU_NET_PACKET_FLAG_RAW is set but forgets -to increase the number of iovec entries in the array, so -receive_iov() will only send the first entry (the virtio-net -entry, full of 0) and no data. The packet will be discarded. - -The only user of QEMU_NET_PACKET_FLAG_RAW is announce_self. - -We can see the problem with tcpdump: - -- QEMU parameters: - - .. -monitor stdio \ - -netdev bridge,id=netdev0,br=virbr0 \ - -device virtio-net,mac=9a:2b:2c:2d:2e:2f,netdev=netdev0 \ - -- HMP command: - - (qemu) announce_self - -- TCP dump: - - $ sudo tcpdump -nxi virbr0 - - without the fix: - - - - with the fix: - - ARP, Reverse Request who-is 9a:2b:2c:2d:2e:2f tell 9a:2b:2c:2d:2e:2f, length 46 - 0x0000: 0001 0800 0604 0003 9a2b 2c2d 2e2f 0000 - 0x0010: 0000 9a2b 2c2d 2e2f 0000 0000 0000 0000 - 0x0020: 0000 0000 0000 0000 0000 0000 0000 - -Reported-by: Xiaohui Li -Bug: https://issues.redhat.com/browse/RHEL-73891 -Fixes: b9ad513e1876 ("net: Remove receive_raw()") -Cc: akihiko.odaki@daynix.com -Signed-off-by: Laurent Vivier -Reviewed-by: Akihiko Odaki -Reviewed-by: Michael Tokarev -Signed-off-by: Michael Tokarev -(cherry picked from commit 84dfdcbff33fff185528501be408c25c44499f32) -Signed-off-by: Laurent Vivier ---- - net/net.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/net/net.c b/net/net.c -index fc1125111c..94f51b6e5f 100644 ---- a/net/net.c -+++ b/net/net.c -@@ -828,6 +828,7 @@ static ssize_t qemu_deliver_packet_iov(NetClientState *sender, - iov_copy[0].iov_len = nc->vnet_hdr_len; - memcpy(&iov_copy[1], iov, iovcnt * sizeof(*iov)); - iov = iov_copy; -+ iovcnt++; - } - - if (nc->info->receive_iov) { --- -2.39.3 - diff --git a/kvm-net-socket-skip-automatic-zero-init-of-large-array.patch b/kvm-net-socket-skip-automatic-zero-init-of-large-array.patch index 69a55f4..6bc5323 100644 --- a/kvm-net-socket-skip-automatic-zero-init-of-large-array.patch +++ b/kvm-net-socket-skip-automatic-zero-init-of-large-array.patch @@ -1,16 +1,16 @@ -From 7b7f18b36ef46073aee2b9a60404df6a7e58e949 Mon Sep 17 00:00:00 2001 +From 7f3f625c3046f8a44ac158bef1e627f18856a2ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:37:08 +0100 -Subject: [PATCH 30/31] net/socket: skip automatic zero-init of large array +Subject: [PATCH 38/43] net/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 -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 -RH-Commit: [29/30] d9cf9e82838eb14f338030cc9951f66d82673081 +RH-Commit: [30/31] b45f973634d85a5cb99d51ef79b0c04c695a43d6 (stefanha/centos-stream-qemu-kvm) The 'net_socket_send' method has a 68k byte array used for copying data between guest and host. Skip the automatic zero-init of this diff --git a/kvm-net-stream-skip-automatic-zero-init-of-large-array.patch b/kvm-net-stream-skip-automatic-zero-init-of-large-array.patch index 5557a52..62e5d38 100644 --- a/kvm-net-stream-skip-automatic-zero-init-of-large-array.patch +++ b/kvm-net-stream-skip-automatic-zero-init-of-large-array.patch @@ -1,16 +1,16 @@ -From af36b7abd6dbdfae9a85f775e09114634a5a1212 Mon Sep 17 00:00:00 2001 +From 074465b3a94a8d18c4202d13d9506f9dee8030e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:37:09 +0100 -Subject: [PATCH 31/31] net/stream: skip automatic zero-init of large array +Subject: [PATCH 39/43] net/stream: 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 -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 -RH-Commit: [30/30] 09cbcf10340b74656b6f97f4bf0ddd2042a65515 +RH-Commit: [31/31] 5200215cfd9e263d24342ee4a2b5aafe3d1e1eb7 (stefanha/centos-stream-qemu-kvm) The 'net_stream_send' method has a 68k byte array used for copying data between guest and host. Skip the automatic zero-init of this @@ -32,7 +32,7 @@ Signed-off-by: Stefan Hajnoczi 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/stream.c b/net/stream.c -index 97e6ec6679..12384ffee5 100644 +index 4de5613844..6152d2a05e 100644 --- a/net/stream.c +++ b/net/stream.c @@ -148,7 +148,7 @@ static gboolean net_stream_send(QIOChannel *ioc, diff --git a/kvm-net-vhost-user-add-QAPI-events-to-report-connection-.patch b/kvm-net-vhost-user-add-QAPI-events-to-report-connection-.patch deleted file mode 100644 index ca2777b..0000000 --- a/kvm-net-vhost-user-add-QAPI-events-to-report-connection-.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 6b80d6f0432f3a05f71d046ad2bc68d9b2aa5ea0 Mon Sep 17 00:00:00 2001 -From: Laurent Vivier -Date: Mon, 17 Feb 2025 10:25:50 +0100 -Subject: [PATCH] net: vhost-user: add QAPI events to report connection state -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Laurent Vivier -RH-MergeRequest: 431: net: vhost-user: add QAPI events to report connection state -RH-Jira: RHEL-80522 -RH-Acked-by: Eugenio PĂ©rez -RH-Acked-by: Jason Wang -RH-Acked-by: Cindy Lu -RH-Commit: [1/1] 8dd1ffd02c0ea5718c190e4e26faa72b79f4f19f - -JIRA: https://issues.redhat.com/browse/RHEL-80522 - -The netdev reports NETDEV_VHOST_USER_CONNECTED event when -the chardev is connected, and NETDEV_VHOST_USER_DISCONNECTED -when it is disconnected. - -The NETDEV_VHOST_USER_CONNECTED event includes the chardev id. - -This allows a system manager like libvirt to detect when the server -fails. - -For instance with passt: - -{ 'execute': 'qmp_capabilities' } -{ "return": { } } - -[killing passt here] - -{ "timestamp": { "seconds": 1739538634, "microseconds": 920450 }, - "event": "NETDEV_VHOST_USER_DISCONNECTED", - "data": { "netdev-id": "netdev0" } } - -[automatic reconnection with reconnect-ms] - -{ "timestamp": { "seconds": 1739538638, "microseconds": 354181 }, - "event": "NETDEV_VHOST_USER_CONNECTED", - "data": { "netdev-id": "netdev0", "chardev-id": "chr0" } } - -Tested-by: Stefano Brivio -Signed-off-by: Laurent Vivier -Message-Id: <20250217092550.1172055-1-lvivier@redhat.com> -Acked-by: Markus Armbruster -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry picked from commit 02fd9f8aeeb184276b283ae2f404bc3acf1e7b7a) -Signed-off-by: Laurent Vivier ---- - net/vhost-user.c | 3 +++ - qapi/net.json | 40 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 43 insertions(+) - -diff --git a/net/vhost-user.c b/net/vhost-user.c -index 12555518e8..0b235e50c6 100644 ---- a/net/vhost-user.c -+++ b/net/vhost-user.c -@@ -16,6 +16,7 @@ - #include "chardev/char-fe.h" - #include "qapi/error.h" - #include "qapi/qapi-commands-net.h" -+#include "qapi/qapi-events-net.h" - #include "qemu/config-file.h" - #include "qemu/error-report.h" - #include "qemu/option.h" -@@ -271,6 +272,7 @@ static void chr_closed_bh(void *opaque) - if (err) { - error_report_err(err); - } -+ qapi_event_send_netdev_vhost_user_disconnected(name); - } - - static void net_vhost_user_event(void *opaque, QEMUChrEvent event) -@@ -300,6 +302,7 @@ static void net_vhost_user_event(void *opaque, QEMUChrEvent event) - net_vhost_user_watch, s); - qmp_set_link(name, true, &err); - s->started = true; -+ qapi_event_send_netdev_vhost_user_connected(name, chr->label); - break; - case CHR_EVENT_CLOSED: - /* a close event may happen during a read/write, but vhost -diff --git a/qapi/net.json b/qapi/net.json -index 87fc0d0b28..7bd1eaa1ba 100644 ---- a/qapi/net.json -+++ b/qapi/net.json -@@ -1020,3 +1020,43 @@ - ## - { 'event': 'NETDEV_STREAM_DISCONNECTED', - 'data': { 'netdev-id': 'str' } } -+ -+## -+# @NETDEV_VHOST_USER_CONNECTED: -+# -+# Emitted when the vhost-user chardev is connected -+# -+# @netdev-id: QEMU netdev id that is connected -+# -+# @chardev-id: The character device id used by the QEMU netdev -+# -+# Since: 10.0 -+# -+# .. qmp-example:: -+# -+# <- { "timestamp": {"seconds": 1739538638, "microseconds": 354181 }, -+# "event": "NETDEV_VHOST_USER_CONNECTED", -+# "data": { "netdev-id": "netdev0", "chardev-id": "chr0" } } -+# -+## -+{ 'event': 'NETDEV_VHOST_USER_CONNECTED', -+ 'data': { 'netdev-id': 'str', 'chardev-id': 'str' } } -+ -+## -+# @NETDEV_VHOST_USER_DISCONNECTED: -+# -+# Emitted when the vhost-user chardev is disconnected -+# -+# @netdev-id: QEMU netdev id that is disconnected -+# -+# Since: 10.0 -+# -+# .. qmp-example:: -+# -+# <- { "timestamp": { "seconds": 1739538634, "microseconds": 920450 }, -+# "event": "NETDEV_VHOST_USER_DISCONNECTED", -+# "data": { "netdev-id": "netdev0" } } -+# -+## -+{ 'event': 'NETDEV_VHOST_USER_DISCONNECTED', -+ 'data': { 'netdev-id': 'str' } } --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-Abort-IPL-on-invalid-loadparm.patch b/kvm-pc-bios-s390-ccw-Abort-IPL-on-invalid-loadparm.patch deleted file mode 100644 index ea0410d..0000000 --- a/kvm-pc-bios-s390-ccw-Abort-IPL-on-invalid-loadparm.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 3add991f9da7abac1ddc293a17f90a8b3ab5bb67 Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Fri, 17 Jan 2025 16:22:35 -0500 -Subject: [PATCH 2/6] pc-bios/s390-ccw: Abort IPL on invalid loadparm -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 331: Fix boot problems when falling back from network to another boot device on s390x [RHEL10] -RH-Jira: RHEL-72717 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/4] fdde5c57ff03fa0d2e69d711bbf485dcefc8f55b (thuth/qemu-kvm-cs) - -Because the loadparm specifies an exact kernel the user wants to boot, if the -loadparm is invalid it must represent a misconfiguration of the guest. Thus we -should abort the IPL immediately, without attempting to use other devices, to -avoid booting into an unintended guest image. - -Signed-off-by: Jared Rossi -Message-ID: <20250117212235.1324063-2-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 64fa0de46ee3cc972af5d3ce8c5dc0db8198cd2b) ---- - pc-bios/s390-ccw/bootmap.c | 15 +++++++++------ - 1 file changed, 9 insertions(+), 6 deletions(-) - -diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c -index 56f2f75640..0f8baa0198 100644 ---- a/pc-bios/s390-ccw/bootmap.c -+++ b/pc-bios/s390-ccw/bootmap.c -@@ -336,8 +336,7 @@ static int run_eckd_boot_script(block_number_t bmt_block_nr, - - debug_print_int("loadparm", loadparm); - if (loadparm >= MAX_BOOT_ENTRIES) { -- puts("loadparm value greater than max number of boot entries allowed"); -- return -EINVAL; -+ panic("loadparm value greater than max number of boot entries allowed"); - } - - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); -@@ -348,8 +347,8 @@ static int run_eckd_boot_script(block_number_t bmt_block_nr, - - block_nr = gen_eckd_block_num(&bmt->entry[loadparm].xeckd, ldipl); - if (block_nr == NULL_BLOCK_NR) { -- puts("Cannot find Boot Map Table Entry"); -- return -EIO; -+ printf("The requested boot entry (%d) is invalid\n", loadparm); -+ panic("Invalid loadparm"); - } - - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); -@@ -792,8 +791,12 @@ static int ipl_scsi(void) - - debug_print_int("loadparm", loadparm); - if (loadparm >= MAX_BOOT_ENTRIES) { -- puts("loadparm value greater than max number of boot entries allowed"); -- return -EINVAL; -+ panic("loadparm value greater than max number of boot entries allowed"); -+ } -+ -+ if (!valid_entries[loadparm]) { -+ printf("The requested boot entry (%d) is invalid\n", loadparm); -+ panic("Invalid loadparm"); - } - - return zipl_run(&prog_table->entry[loadparm].scsi); --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch b/kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch deleted file mode 100644 index 357bfe7..0000000 --- a/kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 57746476c81359507743671addee330e303c1e02 Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Tue, 1 Oct 2024 17:36:16 +0200 -Subject: [PATCH 22/38] pc-bios/s390-ccw: Clarify alignment is in bytes -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [21/23] 17e89c1a3ca01b9de4683aebdbd06c5350422d27 (thuth/qemu-kvm-cs9) - -The assembler directive .align [1] has architecture-dependent behavior, -which may be ambiguous for the reader. Some architectures perform the -alignment in bytes, others in power of two. s390 does in bytes. - -Use the directive .balign [2] instead, to clarify that the alignment -request is in bytes. No functional change. - -[1] https://sourceware.org/binutils/docs/as/Align.html -[2] https://sourceware.org/binutils/docs/as/Balign.html - -Signed-off-by: Jens Remus -Reviewed-by: Marc Hartmayer -Message-ID: <20241001153618.17791-2-mhartmay@linux.ibm.com> -Reviewed-by: Thomas Huth -Signed-off-by: Thomas Huth -(cherry picked from commit c58df213af7ec8924d219025a593b8f3ac475f16) ---- - pc-bios/s390-ccw/start.S | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S -index 061b06591c..576fc12c06 100644 ---- a/pc-bios/s390-ccw/start.S -+++ b/pc-bios/s390-ccw/start.S -@@ -112,7 +112,7 @@ io_new_code: - lctlg %c6,%c6,0(%r15) - br %r14 - -- .align 8 -+ .balign 8 - bss_start_literal: - .quad __bss_start - disabled_wait_psw: -@@ -125,7 +125,7 @@ io_new_mask: - .quad 0x0000000180000000 - - .bss -- .align 8 -+ .balign 8 - stack: - .space STACK_SIZE - .size stack,STACK_SIZE --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch b/kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch deleted file mode 100644 index a113e2f..0000000 --- a/kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 62433cc6df65f10e99dab8b2ec9918b69c3c73ae Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Tue, 1 Oct 2024 17:36:17 +0200 -Subject: [PATCH 23/38] pc-bios/s390-ccw: Don't generate TEXTRELs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [22/23] 57de00e48321faf13f673c6d52fd9d59d9be5c83 (thuth/qemu-kvm-cs9) - -Commit 7cd50cbe4ca3 ("pc-bios/s390-ccw: Don't use __bss_start with the -"larl" instruction") introduced the address constant bss_start_literal -for __bss_start in the .text section, which introduced a relocation in -code (i.e. TEXTREL). The dedicated constant is required, as __bss_start -may not necessarily be aligned on a 2-byte boundary (see subject commit -for details). - -Move the constant to the .data section to get rid of the relocation in -the .text section. Add the linker option -z text to prevent TEXTRELs to -get introduced in the future. - -Note that the R_390_RELATIVE relocations are taken care of by function -glue() in include/hw/elf_ops.h.inc introduced by commit 5dce07e1cb67 -("elf-loader: Provide the possibility to relocate s390 ELF files"). - -Reported-by: Marc Hartmayer -Signed-off-by: Jens Remus -Reviewed-by: Marc Hartmayer -Message-ID: <20241001153618.17791-3-mhartmay@linux.ibm.com> -Reviewed-by: Thomas Huth -Signed-off-by: Thomas Huth -(cherry picked from commit 3259b4424a85d9cdfd1a33ed6030a6c51c1b9b8b) ---- - pc-bios/s390-ccw/Makefile | 2 +- - pc-bios/s390-ccw/start.S | 7 +++++-- - 2 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile -index db9e8f0892..38254e22df 100644 ---- a/pc-bios/s390-ccw/Makefile -+++ b/pc-bios/s390-ccw/Makefile -@@ -46,7 +46,7 @@ EXTRA_CFLAGS += -fwrapv -fno-strict-aliasing -fno-asynchronous-unwind-tables - EXTRA_CFLAGS += -msoft-float - EXTRA_CFLAGS += -std=gnu99 - EXTRA_CFLAGS += $(LIBC_INC) $(LIBNET_INC) --LDFLAGS += -Wl,-pie -nostdlib -z noexecstack -+LDFLAGS += -Wl,-pie -nostdlib -z noexecstack -z text - - cc-test = $(CC) -Werror $1 -c -o /dev/null -xc /dev/null >/dev/null 2>/dev/null - cc-option = if $(call cc-test, $1); then \ -diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S -index 576fc12c06..b70213e412 100644 ---- a/pc-bios/s390-ccw/start.S -+++ b/pc-bios/s390-ccw/start.S -@@ -113,8 +113,6 @@ io_new_code: - br %r14 - - .balign 8 --bss_start_literal: -- .quad __bss_start - disabled_wait_psw: - .quad 0x0002000180000000,0x0000000000000000 - enabled_wait_psw: -@@ -124,6 +122,11 @@ external_new_mask: - io_new_mask: - .quad 0x0000000180000000 - -+.data -+ .balign 8 -+bss_start_literal: -+ .quad __bss_start -+ - .bss - .balign 8 - stack: --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch b/kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch deleted file mode 100644 index d4d3246..0000000 --- a/kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch +++ /dev/null @@ -1,426 +0,0 @@ -From cfc51bd73616b36a98f7f65f0df3b637d3711811 Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:46 -0400 -Subject: [PATCH 14/38] pc-bios/s390-ccw: Enable failed IPL to return after - error -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [13/23] a78913dc1a9de94de76d484475b967997c457d57 (thuth/qemu-kvm-cs9) - -Remove panic-on-error from IPL functions such that a return code is propagated -back to the main IPL calling function (rather than terminating immediately), -which facilitates possible error recovery in the future. - -A select few panics remain, which indicate fatal non-devices errors that must -result in termination. - -Signed-off-by: Jared Rossi -Reviewed-by: Thomas Huth -Message-ID: <20241020012953.1380075-13-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 0181e23713114fd4c33326c3372aaf48dcfb412a) ---- - pc-bios/s390-ccw/bootmap.c | 53 ++++++++++++++++++-------- - pc-bios/s390-ccw/cio.c | 3 +- - pc-bios/s390-ccw/jump2ipl.c | 5 ++- - pc-bios/s390-ccw/main.c | 32 +++++++++------- - pc-bios/s390-ccw/s390-ccw.h | 2 +- - pc-bios/s390-ccw/virtio-blkdev.c | 2 +- - pc-bios/s390-ccw/virtio.c | 65 +++++++++++++++++++++----------- - pc-bios/s390-ccw/virtio.h | 2 +- - 8 files changed, 108 insertions(+), 56 deletions(-) - -diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c -index 95ef9104d0..56f2f75640 100644 ---- a/pc-bios/s390-ccw/bootmap.c -+++ b/pc-bios/s390-ccw/bootmap.c -@@ -62,15 +62,34 @@ static void *s2_prev_blk = _s2; - static void *s2_cur_blk = _s2 + MAX_SECTOR_SIZE; - static void *s2_next_blk = _s2 + MAX_SECTOR_SIZE * 2; - --static inline void verify_boot_info(BootInfo *bip) -+static inline int verify_boot_info(BootInfo *bip) - { -- IPL_assert(magic_match(bip->magic, ZIPL_MAGIC), "No zIPL sig in BootInfo"); -- IPL_assert(bip->version == BOOT_INFO_VERSION, "Wrong zIPL version"); -- IPL_assert(bip->bp_type == BOOT_INFO_BP_TYPE_IPL, "DASD is not for IPL"); -- IPL_assert(bip->dev_type == BOOT_INFO_DEV_TYPE_ECKD, "DASD is not ECKD"); -- IPL_assert(bip->flags == BOOT_INFO_FLAGS_ARCH, "Not for this arch"); -- IPL_assert(block_size_ok(bip->bp.ipl.bm_ptr.eckd.bptr.size), -- "Bad block size in zIPL section of the 1st record."); -+ if (!magic_match(bip->magic, ZIPL_MAGIC)) { -+ puts("No zIPL sig in BootInfo"); -+ return -EINVAL; -+ } -+ if (bip->version != BOOT_INFO_VERSION) { -+ puts("Wrong zIPL version"); -+ return -EINVAL; -+ } -+ if (bip->bp_type != BOOT_INFO_BP_TYPE_IPL) { -+ puts("DASD is not for IPL"); -+ return -ENODEV; -+ } -+ if (bip->dev_type != BOOT_INFO_DEV_TYPE_ECKD) { -+ puts("DASD is not ECKD"); -+ return -ENODEV; -+ } -+ if (bip->flags != BOOT_INFO_FLAGS_ARCH) { -+ puts("Not for this arch"); -+ return -EINVAL; -+ } -+ if (!block_size_ok(bip->bp.ipl.bm_ptr.eckd.bptr.size)) { -+ puts("Bad block size in zIPL section of 1st record"); -+ return -EINVAL; -+ } -+ -+ return 0; - } - - static void eckd_format_chs(ExtEckdBlockPtr *ptr, bool ldipl, -@@ -367,8 +386,8 @@ static int run_eckd_boot_script(block_number_t bmt_block_nr, - puts("Unknown script entry type"); - return -EINVAL; - } -- write_reset_psw(bms->entry[i].address.load_address); /* no return */ -- jump_to_IPL_code(0); /* no return */ -+ write_reset_psw(bms->entry[i].address.load_address); -+ jump_to_IPL_code(0); - return -1; - } - -@@ -1067,16 +1086,19 @@ void zipl_load(void) - - if (vdev->is_cdrom) { - ipl_iso_el_torito(); -- panic("\n! Cannot IPL this ISO image !\n"); -+ puts("Failed to IPL this ISO image!"); -+ return; - } - - if (virtio_get_device_type() == VIRTIO_ID_NET) { - netmain(); -- panic("\n! Cannot IPL from this network !\n"); -+ puts("Failed to IPL from this network!"); -+ return; - } - - if (ipl_scsi()) { -- panic("\n! Cannot IPL this SCSI device !\n"); -+ puts("Failed to IPL from this SCSI device!"); -+ return; - } - - switch (virtio_get_device_type()) { -@@ -1087,8 +1109,9 @@ void zipl_load(void) - zipl_load_vscsi(); - break; - default: -- panic("\n! Unknown IPL device type !\n"); -+ puts("Unknown IPL device type!"); -+ return; - } - -- puts("zIPL load failed."); -+ puts("zIPL load failed!"); - } -diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c -index 7b09a38c96..5d543da73f 100644 ---- a/pc-bios/s390-ccw/cio.c -+++ b/pc-bios/s390-ccw/cio.c -@@ -59,7 +59,8 @@ uint16_t cu_type(SubChannelId schid) - }; - - if (do_cio(schid, CU_TYPE_UNKNOWN, ptr2u32(&sense_id_ccw), CCW_FMT1)) { -- panic("Failed to run SenseID CCw\n"); -+ puts("Failed to run SenseID CCW"); -+ return CU_TYPE_UNKNOWN; - } - - return sense_data.cu_type; -diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c -index 80b7f6a1f3..8db1764ff3 100644 ---- a/pc-bios/s390-ccw/jump2ipl.c -+++ b/pc-bios/s390-ccw/jump2ipl.c -@@ -33,7 +33,7 @@ static void jump_to_IPL_addr(void) - /* should not return */ - } - --void jump_to_IPL_code(uint64_t address) -+int jump_to_IPL_code(uint64_t address) - { - /* store the subsystem information _after_ the bootmap was loaded */ - write_subsystem_identification(); -@@ -68,7 +68,8 @@ void jump_to_IPL_code(uint64_t address) - asm volatile("lghi %%r1,1\n\t" - "diag %%r1,%%r1,0x308\n\t" - : : : "1", "memory"); -- panic("\n! IPL returns !\n"); -+ puts("IPL code jump failed"); -+ return -1; - } - - void jump_to_low_kernel(void) -diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c -index fc44da3161..34ef27d7a6 100644 ---- a/pc-bios/s390-ccw/main.c -+++ b/pc-bios/s390-ccw/main.c -@@ -77,6 +77,9 @@ static int is_dev_possibly_bootable(int dev_no, int sch_no) - - enable_subchannel(blk_schid); - cutype = cu_type(blk_schid); -+ if (cutype == CU_TYPE_UNKNOWN) { -+ return -EIO; -+ } - - /* - * Note: we always have to run virtio_is_supported() here to make -@@ -194,10 +197,10 @@ static void boot_setup(void) - have_iplb = store_iplb(&iplb); - } - --static void find_boot_device(void) -+static bool find_boot_device(void) - { - VDev *vdev = virtio_get_device(); -- bool found; -+ bool found = false; - - switch (iplb.pbt) { - case S390_IPL_TYPE_CCW: -@@ -215,10 +218,10 @@ static void find_boot_device(void) - found = find_subch(iplb.scsi.devno); - break; - default: -- panic("List-directed IPL not supported yet!\n"); -+ puts("Unsupported IPLB"); - } - -- IPL_assert(found, "Boot device not found\n"); -+ return found; - } - - static int virtio_setup(void) -@@ -244,11 +247,13 @@ static int virtio_setup(void) - ret = virtio_scsi_setup_device(blk_schid); - break; - default: -- panic("\n! No IPL device available !\n"); -+ puts("\n! No IPL device available !\n"); -+ return -1; - } - -- if (!ret) { -- IPL_assert(virtio_ipl_disk_is_valid(), "No valid IPL device detected"); -+ if (!ret && !virtio_ipl_disk_is_valid()) { -+ puts("No valid IPL device detected"); -+ return -ENODEV; - } - - return ret; -@@ -259,16 +264,16 @@ static void ipl_boot_device(void) - switch (cutype) { - case CU_TYPE_DASD_3990: - case CU_TYPE_DASD_2107: -- dasd_ipl(blk_schid, cutype); /* no return */ -+ dasd_ipl(blk_schid, cutype); - break; - case CU_TYPE_VIRTIO: -- if (virtio_setup() == 0) { -- zipl_load(); /* Only returns in case of errors */ -+ if (virtio_setup()) { -+ return; /* Only returns in case of errors */ - } -+ zipl_load(); - break; - default: - printf("Attempting to boot from unexpected device type 0x%X\n", cutype); -- panic("\nBoot failed.\n"); - } - } - -@@ -301,12 +306,11 @@ void main(void) - sclp_setup(); - css_setup(); - boot_setup(); -- if (have_iplb) { -- find_boot_device(); -+ if (have_iplb && find_boot_device()) { - ipl_boot_device(); - } else { - probe_boot_device(); - } - -- panic("Failed to load OS from hard disk\n"); -+ panic("Failed to IPL. Halting..."); - } -diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h -index 344ad15655..6cdce3e5e5 100644 ---- a/pc-bios/s390-ccw/s390-ccw.h -+++ b/pc-bios/s390-ccw/s390-ccw.h -@@ -78,7 +78,7 @@ void zipl_load(void); - - /* jump2ipl.c */ - void write_reset_psw(uint64_t psw); --void jump_to_IPL_code(uint64_t address); -+int jump_to_IPL_code(uint64_t address); - void jump_to_low_kernel(void); - - /* menu.c */ -diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c -index 1c585f034b..7b2d1e20f4 100644 ---- a/pc-bios/s390-ccw/virtio-blkdev.c -+++ b/pc-bios/s390-ccw/virtio-blkdev.c -@@ -59,7 +59,7 @@ int virtio_read_many(unsigned long sector, void *load_addr, int sec_num) - case VIRTIO_ID_SCSI: - return virtio_scsi_read_many(vdev, sector, load_addr, sec_num); - } -- panic("\n! No readable IPL device !\n"); -+ - return -1; - } - -diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c -index 8c6b0a8a92..8b5a370bb3 100644 ---- a/pc-bios/s390-ccw/virtio.c -+++ b/pc-bios/s390-ccw/virtio.c -@@ -217,16 +217,19 @@ int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd) - return 0; - } - --void virtio_setup_ccw(VDev *vdev) -+int virtio_setup_ccw(VDev *vdev) - { -- int i, rc, cfg_size = 0; -+ int i, cfg_size = 0; - uint8_t status; - struct VirtioFeatureDesc { - uint32_t features; - uint8_t index; - } __attribute__((packed)) feats; - -- IPL_assert(virtio_is_supported(vdev->schid), "PE"); -+ if (!virtio_is_supported(vdev->schid)) { -+ puts("Virtio unsupported for this device ID"); -+ return -ENODEV; -+ } - /* device ID has been established now */ - - vdev->config.blk.blk_size = 0; /* mark "illegal" - setup started... */ -@@ -235,8 +238,10 @@ void virtio_setup_ccw(VDev *vdev) - run_ccw(vdev, CCW_CMD_VDEV_RESET, NULL, 0, false); - - status = VIRTIO_CONFIG_S_ACKNOWLEDGE; -- rc = run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false); -- IPL_assert(rc == 0, "Could not write ACKNOWLEDGE status to host"); -+ if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) { -+ puts("Could not write ACKNOWLEDGE status to host"); -+ return -EIO; -+ } - - switch (vdev->senseid.cu_model) { - case VIRTIO_ID_NET: -@@ -255,27 +260,37 @@ void virtio_setup_ccw(VDev *vdev) - cfg_size = sizeof(vdev->config.scsi); - break; - default: -- panic("Unsupported virtio device\n"); -+ puts("Unsupported virtio device"); -+ return -ENODEV; - } - - status |= VIRTIO_CONFIG_S_DRIVER; -- rc = run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false); -- IPL_assert(rc == 0, "Could not write DRIVER status to host"); -+ if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) { -+ puts("Could not write DRIVER status to host"); -+ return -EIO; -+ } - - /* Feature negotiation */ - for (i = 0; i < ARRAY_SIZE(vdev->guest_features); i++) { - feats.features = 0; - feats.index = i; -- rc = run_ccw(vdev, CCW_CMD_READ_FEAT, &feats, sizeof(feats), false); -- IPL_assert(rc == 0, "Could not get features bits"); -+ if (run_ccw(vdev, CCW_CMD_READ_FEAT, &feats, sizeof(feats), false)) { -+ puts("Could not get features bits"); -+ return -EIO; -+ } -+ - vdev->guest_features[i] &= bswap32(feats.features); - feats.features = bswap32(vdev->guest_features[i]); -- rc = run_ccw(vdev, CCW_CMD_WRITE_FEAT, &feats, sizeof(feats), false); -- IPL_assert(rc == 0, "Could not set features bits"); -+ if (run_ccw(vdev, CCW_CMD_WRITE_FEAT, &feats, sizeof(feats), false)) { -+ puts("Could not set features bits"); -+ return -EIO; -+ } - } - -- rc = run_ccw(vdev, CCW_CMD_READ_CONF, &vdev->config, cfg_size, false); -- IPL_assert(rc == 0, "Could not get virtio device configuration"); -+ if (run_ccw(vdev, CCW_CMD_READ_CONF, &vdev->config, cfg_size, false)) { -+ puts("Could not get virtio device configuration"); -+ return -EIO; -+ } - - for (i = 0; i < vdev->nr_vqs; i++) { - VqInfo info = { -@@ -289,19 +304,27 @@ void virtio_setup_ccw(VDev *vdev) - .num = 0, - }; - -- rc = run_ccw(vdev, CCW_CMD_READ_VQ_CONF, &config, sizeof(config), false); -- IPL_assert(rc == 0, "Could not get virtio device VQ configuration"); -+ if (run_ccw(vdev, CCW_CMD_READ_VQ_CONF, &config, sizeof(config), -+ false)) { -+ puts("Could not get virtio device VQ config"); -+ return -EIO; -+ } - info.num = config.num; - vring_init(&vdev->vrings[i], &info); - vdev->vrings[i].schid = vdev->schid; -- IPL_assert( -- run_ccw(vdev, CCW_CMD_SET_VQ, &info, sizeof(info), false) == 0, -- "Cannot set VQ info"); -+ if (run_ccw(vdev, CCW_CMD_SET_VQ, &info, sizeof(info), false)) { -+ puts("Cannot set VQ info"); -+ return -EIO; -+ } - } - - status |= VIRTIO_CONFIG_S_DRIVER_OK; -- rc = run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false); -- IPL_assert(rc == 0, "Could not write DRIVER_OK status to host"); -+ if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) { -+ puts("Could not write DRIVER_OK status to host"); -+ return -EIO; -+ } -+ -+ return 0; - } - - bool virtio_is_supported(SubChannelId schid) -diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h -index 6f9a558ff5..9faf3986b1 100644 ---- a/pc-bios/s390-ccw/virtio.h -+++ b/pc-bios/s390-ccw/virtio.h -@@ -274,7 +274,7 @@ void vring_send_buf(VRing *vr, void *p, int len, int flags); - int vr_poll(VRing *vr); - int vring_wait_reply(void); - int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd); --void virtio_setup_ccw(VDev *vdev); -+int virtio_setup_ccw(VDev *vdev); - - int virtio_net_init(void *mac_addr); - --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-Fix-boot-problem-with-virtio-net-de.patch b/kvm-pc-bios-s390-ccw-Fix-boot-problem-with-virtio-net-de.patch deleted file mode 100644 index d29be6d..0000000 --- a/kvm-pc-bios-s390-ccw-Fix-boot-problem-with-virtio-net-de.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 548a415cff7d590d86033902fb29d5e15f57d17f Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Thu, 16 Jan 2025 12:58:25 +0100 -Subject: [PATCH 4/6] pc-bios/s390-ccw: Fix boot problem with virtio-net - devices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 331: Fix boot problems when falling back from network to another boot device on s390x [RHEL10] -RH-Jira: RHEL-72717 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [3/4] f7ef8c63507c7f1ee8d05083f9540bee1697071c (thuth/qemu-kvm-cs) - -When we are trying to boot from virtio-net devices, the -s390-ccw bios currently leaves the virtio-net device enabled -after using it. That means that the receiving virt queues will -continue to happily write incoming network packets into memory. -This can corrupt data of the following boot process. For example, -if you set up a second guest on a virtual network and create a -lot of broadcast traffic there, e.g. with: - - ping -i 0.02 -s 1400 -b 192.168.1.255 - -and then you try to boot a guest with two boot devices, a network -device first (which should not be bootable) and e.g. a bootable SCSI -CD second, then this guest will fail to load the kernel from the CD -image: - - $ qemu-system-s390x -m 2G -nographic -device virtio-scsi-ccw \ - -netdev tap,id=net0 -device virtio-net-ccw,netdev=net0,bootindex=1 \ - -drive if=none,file=test.iso,format=raw,id=cd1 \ - -device scsi-cd,drive=cd1,bootindex=2 - LOADPARM=[ ] - - Network boot device detected - Network boot starting... - Using MAC address: 52:54:00:12:34:56 - Requesting information via DHCP: done - Using IPv4 address: 192.168.1.76 - Using TFTP server: 192.168.1.1 - Trying pxelinux.cfg files... - TFTP error: ICMP ERROR "port unreachable" - Receiving data: 0 KBytes - Repeating TFTP read request... - TFTP error: ICMP ERROR "port unreachable" - Failed to load OS from network. - Failed to IPL from this network! - LOADPARM=[ ] - - Using virtio-scsi. - - ! virtio-scsi:setup:inquiry: response VS RESP=ff ! - ERROR: No suitable device for IPL. Halting... - -We really have to shut up the virtio-net devices after we're not -using it anymore. The easiest way to do this is to simply reset -the device, so let's do that now. - -Reviewed-by: Jared Rossi -Reviewed-by: Eric Farman -Tested-by: Jared Rossi -Message-ID: <20250116115826.192047-3-thuth@redhat.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 68c95ed1db070f7545e487e742715f01a545aab0) ---- - pc-bios/s390-ccw/netmain.c | 33 +++++++++++++++++++++++---------- - pc-bios/s390-ccw/virtio-net.c | 5 +++++ - pc-bios/s390-ccw/virtio.h | 1 + - 3 files changed, 29 insertions(+), 10 deletions(-) - -diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c -index e46e470db4..335ea9b63e 100644 ---- a/pc-bios/s390-ccw/netmain.c -+++ b/pc-bios/s390-ccw/netmain.c -@@ -153,19 +153,10 @@ static int tftp_load(filename_ip_t *fnip, void *buffer, int len) - return rc; - } - --static int net_init(filename_ip_t *fn_ip) -+static int net_init_ip(filename_ip_t *fn_ip) - { - int rc; - -- memset(fn_ip, 0, sizeof(filename_ip_t)); -- -- rc = virtio_net_init(mac); -- if (rc < 0) { -- puts("Could not initialize network device"); -- return -101; -- } -- fn_ip->fd = rc; -- - printf(" Using MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - -@@ -221,11 +212,33 @@ static int net_init(filename_ip_t *fn_ip) - return rc; - } - -+static int net_init(filename_ip_t *fn_ip) -+{ -+ int rc; -+ -+ memset(fn_ip, 0, sizeof(filename_ip_t)); -+ -+ rc = virtio_net_init(mac); -+ if (rc < 0) { -+ puts("Could not initialize network device"); -+ return -101; -+ } -+ fn_ip->fd = rc; -+ -+ rc = net_init_ip(fn_ip); -+ if (rc < 0) { -+ virtio_net_deinit(); -+ } -+ -+ return rc; -+} -+ - static void net_release(filename_ip_t *fn_ip) - { - if (fn_ip->ip_version == 4) { - dhcp_send_release(fn_ip->fd); - } -+ virtio_net_deinit(); - } - - /** -diff --git a/pc-bios/s390-ccw/virtio-net.c b/pc-bios/s390-ccw/virtio-net.c -index 578c89d0c5..301445bf97 100644 ---- a/pc-bios/s390-ccw/virtio-net.c -+++ b/pc-bios/s390-ccw/virtio-net.c -@@ -140,3 +140,8 @@ int recv(int fd, void *buf, int maxlen, int flags) - - return len; - } -+ -+void virtio_net_deinit(void) -+{ -+ virtio_reset(virtio_get_device()); -+} -diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h -index f13fa6f5fe..5c5e808a50 100644 ---- a/pc-bios/s390-ccw/virtio.h -+++ b/pc-bios/s390-ccw/virtio.h -@@ -278,5 +278,6 @@ int virtio_reset(VDev *vdev); - int virtio_setup_ccw(VDev *vdev); - - int virtio_net_init(void *mac_addr); -+void virtio_net_deinit(void); - - #endif /* VIRTIO_H */ --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch b/kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch deleted file mode 100644 index b37a033..0000000 --- a/kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 06818b9971babd2895158f9fb913d6262eea4cb7 Mon Sep 17 00:00:00 2001 -From: Marc Hartmayer -Date: Tue, 1 Oct 2024 17:36:18 +0200 -Subject: [PATCH 24/38] pc-bios/s390-ccw: Introduce `EXTRA_LDFLAGS` -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [23/23] 148b9e68cb80b5535c6bb732e5b5ce324ba3848e (thuth/qemu-kvm-cs9) - -Some packaging tools want to override `LDFLAGS` when building QEMU, this will -result in a build error as most likely no `-nostdlib` flag is passed. Introduce -`EXTRA_LDFLAGS` so that the packager can override `LDFLAGS` without breaking the -build. - -Signed-off-by: Marc Hartmayer -Message-ID: <20241001153618.17791-4-mhartmay@linux.ibm.com> -Reviewed-by: Thomas Huth -[thuth: Drop the hunk to netbook.mak which is not necessary anymore] -Signed-off-by: Thomas Huth -(cherry picked from commit 694d79ffce996c0993cebccc07c2ab6fc281e7d0) ---- - pc-bios/s390-ccw/Makefile | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile -index 38254e22df..dc69dd484f 100644 ---- a/pc-bios/s390-ccw/Makefile -+++ b/pc-bios/s390-ccw/Makefile -@@ -4,6 +4,7 @@ all: build-all - - include config-host.mak - CFLAGS = -O2 -g -I $(SRC_PATH)/../../include/hw/s390x/ipl -+LDFLAGS ?= - MAKEFLAGS += -rR - - GIT_SUBMODULES = roms/SLOF -@@ -46,7 +47,7 @@ EXTRA_CFLAGS += -fwrapv -fno-strict-aliasing -fno-asynchronous-unwind-tables - EXTRA_CFLAGS += -msoft-float - EXTRA_CFLAGS += -std=gnu99 - EXTRA_CFLAGS += $(LIBC_INC) $(LIBNET_INC) --LDFLAGS += -Wl,-pie -nostdlib -z noexecstack -z text -+EXTRA_LDFLAGS += -Wl,-pie -nostdlib -z noexecstack -z text - - cc-test = $(CC) -Werror $1 -c -o /dev/null -xc /dev/null >/dev/null 2>/dev/null - cc-option = if $(call cc-test, $1); then \ -@@ -111,7 +112,7 @@ libnet.a: $(LIBNETOBJS) - build-all: s390-ccw.img - - s390-ccw.elf: $(OBJECTS) libnet.a libc.a -- $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^,Linking) -+ $(call quiet-command,$(CC) $(EXTRA_LDFLAGS) $(LDFLAGS) -o $@ $^,Linking) - - s390-ccw.img: s390-ccw.elf - $(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,Stripping $< into) --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch b/kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch deleted file mode 100644 index 835a818..0000000 --- a/kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch +++ /dev/null @@ -1,263 +0,0 @@ -From 7686f2129e50540b6e9865fad8b4ab9c0343c432 Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:37 -0400 -Subject: [PATCH 04/38] pc-bios/s390-ccw: Link the netboot code into the main - s390-ccw.img binary -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [3/23] 5c7283de7f4e2388e157ea408a44176fdaf5127a (thuth/qemu-kvm-cs9) - -We originally built a separate binary for the netboot code since it -was considered as experimental and we could not be sure that the -necessary SLOF module had been checked out. Time passed, the code -proved its usefulness, and the build system nowadays makes sure that -the SLOF module is checked out if you have a s390x compiler available -for building the s390-ccw bios. So there is no real compelling reason -anymore to keep the netboot code in a separate binary. Linking the -code together with the main s390-ccw.img will make future enhancements -much easier, like supporting more than one boot device. - -Co-authored by: Thomas Huth -Signed-off-by: Jared Rossi -Message-ID: <20241020012953.1380075-4-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 8e5739ce4b0b04d7121cb2b29521acde2a8f3a24) ---- - pc-bios/s390-ccw/Makefile | 13 +++++++------ - pc-bios/s390-ccw/bootmap.c | 2 +- - pc-bios/s390-ccw/cio.h | 2 ++ - pc-bios/s390-ccw/iplb.h | 4 ++-- - pc-bios/s390-ccw/main.c | 10 +++++++--- - pc-bios/s390-ccw/netboot.mak | 14 -------------- - pc-bios/s390-ccw/netmain.c | 15 ++------------- - pc-bios/s390-ccw/s390-ccw.h | 3 +++ - pc-bios/s390-ccw/virtio.h | 1 - - 9 files changed, 24 insertions(+), 40 deletions(-) - -diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile -index 3f4232636e..cf6859823a 100644 ---- a/pc-bios/s390-ccw/Makefile -+++ b/pc-bios/s390-ccw/Makefile -@@ -32,19 +32,20 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d - - .PHONY : all clean build-all distclean - --OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \ -- virtio.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o -+OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o netmain.o \ -+ virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o - - SLOF_DIR := $(SRC_PATH)/../../roms/SLOF - - LIBC_INC := -nostdinc -I$(SLOF_DIR)/lib/libc/include -+LIBNET_INC := -I$(SLOF_DIR)/lib/libnet - - EXTRA_CFLAGS += -Wall - EXTRA_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -fno-common -fPIE - EXTRA_CFLAGS += -fwrapv -fno-strict-aliasing -fno-asynchronous-unwind-tables - EXTRA_CFLAGS += -msoft-float - EXTRA_CFLAGS += -std=gnu99 --EXTRA_CFLAGS += $(LIBC_INC) -+EXTRA_CFLAGS += $(LIBC_INC) $(LIBNET_INC) - LDFLAGS += -Wl,-pie -nostdlib -z noexecstack - - cc-test = $(CC) -Werror $1 -c -o /dev/null -xc /dev/null >/dev/null 2>/dev/null -@@ -62,9 +63,9 @@ config-cc.mak: Makefile - - include $(SRC_PATH)/netboot.mak - --build-all: s390-ccw.img s390-netboot.img -+build-all: s390-ccw.img - --s390-ccw.elf: $(OBJECTS) libc.a -+s390-ccw.elf: $(OBJECTS) libnet.a libc.a - $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^,Linking) - - s390-ccw.img: s390-ccw.elf -@@ -72,7 +73,7 @@ s390-ccw.img: s390-ccw.elf - - $(OBJECTS): Makefile - --ALL_OBJS = $(sort $(OBJECTS) $(NETOBJS) $(LIBCOBJS) $(LIBNETOBJS)) -+ALL_OBJS = $(sort $(OBJECTS) $(LIBCOBJS) $(LIBNETOBJS)) - -include $(ALL_OBJS:%.o=%.d) - - clean: -diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c -index 3cc79706be..414c3f1b47 100644 ---- a/pc-bios/s390-ccw/bootmap.c -+++ b/pc-bios/s390-ccw/bootmap.c -@@ -929,7 +929,7 @@ void zipl_load(void) - } - - if (virtio_get_device_type() == VIRTIO_ID_NET) { -- jump_to_IPL_code(vdev->netboot_start_addr); -+ netmain(); - } - - ipl_scsi(); -diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h -index 8b18153deb..6a5e86ba01 100644 ---- a/pc-bios/s390-ccw/cio.h -+++ b/pc-bios/s390-ccw/cio.h -@@ -361,6 +361,8 @@ typedef struct CcwSearchIdData { - uint8_t record; - } __attribute__((packed)) CcwSearchIdData; - -+extern SubChannelId net_schid; -+ - int enable_mss_facility(void); - void enable_subchannel(SubChannelId schid); - uint16_t cu_type(SubChannelId schid); -diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h -index cb6ac8a880..3758698468 100644 ---- a/pc-bios/s390-ccw/iplb.h -+++ b/pc-bios/s390-ccw/iplb.h -@@ -87,9 +87,9 @@ extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); - struct QemuIplParameters { - uint8_t qipl_flags; - uint8_t reserved1[3]; -- uint64_t netboot_start_addr; -+ uint64_t reserved2; - uint32_t boot_menu_timeout; -- uint8_t reserved2[12]; -+ uint8_t reserved3[12]; - } __attribute__ ((packed)); - typedef struct QemuIplParameters QemuIplParameters; - -diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c -index 203df20965..fc44da3161 100644 ---- a/pc-bios/s390-ccw/main.c -+++ b/pc-bios/s390-ccw/main.c -@@ -38,8 +38,13 @@ LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */ - */ - void write_subsystem_identification(void) - { -- lowcore->subchannel_id = blk_schid.sch_id; -- lowcore->subchannel_nr = blk_schid.sch_no; -+ if (cutype == CU_TYPE_VIRTIO && virtio_get_device_type() == VIRTIO_ID_NET) { -+ lowcore->subchannel_id = net_schid.sch_id; -+ lowcore->subchannel_nr = net_schid.sch_no; -+ } else { -+ lowcore->subchannel_id = blk_schid.sch_id; -+ lowcore->subchannel_nr = blk_schid.sch_no; -+ } - lowcore->io_int_parm = 0; - } - -@@ -231,7 +236,6 @@ static int virtio_setup(void) - switch (vdev->senseid.cu_model) { - case VIRTIO_ID_NET: - puts("Network boot device detected"); -- vdev->netboot_start_addr = qipl.netboot_start_addr; - return 0; - case VIRTIO_ID_BLOCK: - ret = virtio_blk_setup_device(blk_schid); -diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak -index d2b3d8ee74..0a24257ff4 100644 ---- a/pc-bios/s390-ccw/netboot.mak -+++ b/pc-bios/s390-ccw/netboot.mak -@@ -1,18 +1,4 @@ - --NETOBJS := start.o sclp.o cio.o virtio.o virtio-net.o jump2ipl.o netmain.o -- --LIBNET_INC := -I$(SLOF_DIR)/lib/libnet -- --NETLDFLAGS := $(LDFLAGS) -Wl,-Ttext=0x7800000 -- --$(NETOBJS): EXTRA_CFLAGS += $(LIBC_INC) $(LIBNET_INC) -- --s390-netboot.elf: $(NETOBJS) libnet.a libc.a -- $(call quiet-command,$(CC) $(NETLDFLAGS) -o $@ $^,Linking) -- --s390-netboot.img: s390-netboot.elf -- $(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,Stripping $< into) -- - # libc files: - - LIBC_CFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \ -diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c -index 509119be15..bc6ad8695f 100644 ---- a/pc-bios/s390-ccw/netmain.c -+++ b/pc-bios/s390-ccw/netmain.c -@@ -41,7 +41,6 @@ - #define DEFAULT_TFTP_RETRIES 20 - - extern char _start[]; --void write_iplb_location(void) {} - - #define KERNEL_ADDR ((void *)0L) - #define KERNEL_MAX_SIZE ((long)_start) -@@ -50,10 +49,9 @@ void write_iplb_location(void) {} - /* STSI 3.2.2 offset of first vmdb + offset of uuid inside vmdb */ - #define STSI322_VMDB_UUID_OFFSET ((8 + 12) * 4) - --IplParameterBlock iplb __attribute__((aligned(PAGE_SIZE))); - static char cfgbuf[2048]; - --static SubChannelId net_schid = { .one = 1 }; -+SubChannelId net_schid = { .one = 1 }; - static uint8_t mac[6]; - static uint64_t dest_timer; - -@@ -438,15 +436,6 @@ static int net_try_direct_tftp_load(filename_ip_t *fn_ip) - return rc; - } - --void write_subsystem_identification(void) --{ -- SubChannelId *schid = (SubChannelId *) 184; -- uint32_t *zeroes = (uint32_t *) 188; -- -- *schid = net_schid; -- *zeroes = 0; --} -- - static bool find_net_dev(Schib *schib, int dev_no) - { - int i, r; -@@ -509,7 +498,7 @@ static void virtio_setup(void) - IPL_assert(found, "No virtio net device found"); - } - --void main(void) -+void netmain(void) - { - filename_ip_t fn_ip; - int rc, fnlen; -diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h -index 6f6d95d170..6abb34e563 100644 ---- a/pc-bios/s390-ccw/s390-ccw.h -+++ b/pc-bios/s390-ccw/s390-ccw.h -@@ -55,6 +55,9 @@ void write_iplb_location(void); - unsigned int get_loadparm_index(void); - void main(void); - -+/* netmain.c */ -+void netmain(void); -+ - /* sclp.c */ - void sclp_print(const char *string); - void sclp_set_write_mask(uint32_t receive_mask, uint32_t send_mask); -diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h -index 85bd9d1695..6f9a558ff5 100644 ---- a/pc-bios/s390-ccw/virtio.h -+++ b/pc-bios/s390-ccw/virtio.h -@@ -253,7 +253,6 @@ struct VDev { - uint8_t scsi_dev_heads; - bool scsi_device_selected; - ScsiDevice selected_scsi_device; -- uint64_t netboot_start_addr; - uint32_t max_transfer; - uint32_t guest_features[2]; - }; --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch b/kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch deleted file mode 100644 index c587fec..0000000 --- a/kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 56030483f01524ee7021218e07c8d0ce1b588c62 Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Fri, 21 Jun 2024 09:40:11 +0200 -Subject: [PATCH 07/38] pc-bios/s390-ccw: Merge netboot.mak into the main - Makefile -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [6/23] 9ce64794a5c328673cdee6fa058088c3426efad8 (thuth/qemu-kvm-cs9) - -Now that the netboot code has been merged into the main s390-ccw.img, -it also does not make sense to keep the build rules in a separate -file. Thus let's merge netboot.mak into the main Makefile. - -Message-Id: <20240621082422.136217-7-thuth@redhat.com> -Signed-off-by: Thomas Huth -(cherry picked from commit f1fdadda36f73c9a4a96f92deb3062528cd12acc) ---- - pc-bios/s390-ccw/Makefile | 47 +++++++++++++++++++++++++++++++++++- - pc-bios/s390-ccw/netboot.mak | 45 ---------------------------------- - 2 files changed, 46 insertions(+), 46 deletions(-) - delete mode 100644 pc-bios/s390-ccw/netboot.mak - -diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile -index cf6859823a..27cbb354af 100644 ---- a/pc-bios/s390-ccw/Makefile -+++ b/pc-bios/s390-ccw/Makefile -@@ -61,7 +61,52 @@ config-cc.mak: Makefile - $(call cc-option,-march=z900,-march=z10)) 3> config-cc.mak - -include config-cc.mak - --include $(SRC_PATH)/netboot.mak -+# libc files: -+ -+LIBC_CFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \ -+ -MMD -MP -MT $@ -MF $(@:%.o=%.d) -+ -+CTYPE_OBJS = isdigit.o isxdigit.o toupper.o -+%.o : $(SLOF_DIR)/lib/libc/ctype/%.c -+ $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) -+ -+STRING_OBJS = strcat.o strchr.o strrchr.o strcpy.o strlen.o strncpy.o \ -+ strcmp.o strncmp.o strcasecmp.o strncasecmp.o strstr.o \ -+ memset.o memcpy.o memmove.o memcmp.o -+%.o : $(SLOF_DIR)/lib/libc/string/%.c -+ $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) -+ -+STDLIB_OBJS = atoi.o atol.o strtoul.o strtol.o rand.o malloc.o free.o -+%.o : $(SLOF_DIR)/lib/libc/stdlib/%.c -+ $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) -+ -+STDIO_OBJS = sprintf.o snprintf.o vfprintf.o vsnprintf.o vsprintf.o fprintf.o \ -+ printf.o putc.o puts.o putchar.o stdchnls.o fileno.o -+%.o : $(SLOF_DIR)/lib/libc/stdio/%.c -+ $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) -+ -+sbrk.o: $(SLOF_DIR)/slof/sbrk.c -+ $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) -+ -+LIBCOBJS := $(STRING_OBJS) $(CTYPE_OBJS) $(STDLIB_OBJS) $(STDIO_OBJS) sbrk.o -+ -+libc.a: $(LIBCOBJS) -+ $(call quiet-command,$(AR) -rc $@ $^,Creating static library) -+ -+# libnet files: -+ -+LIBNETOBJS := args.o dhcp.o dns.o icmpv6.o ipv6.o tcp.o udp.o bootp.o \ -+ dhcpv6.o ethernet.o ipv4.o ndp.o tftp.o pxelinux.o -+LIBNETCFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \ -+ -DDHCPARCH=0x1F -MMD -MP -MT $@ -MF $(@:%.o=%.d) -+ -+%.o : $(SLOF_DIR)/lib/libnet/%.c -+ $(call quiet-command,$(CC) $(LIBNETCFLAGS) -c -o $@ $<,Compiling) -+ -+libnet.a: $(LIBNETOBJS) -+ $(call quiet-command,$(AR) -rc $@ $^,Creating static library) -+ -+# Main targets: - - build-all: s390-ccw.img - -diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak -deleted file mode 100644 -index 0a24257ff4..0000000000 ---- a/pc-bios/s390-ccw/netboot.mak -+++ /dev/null -@@ -1,45 +0,0 @@ -- --# libc files: -- --LIBC_CFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \ -- -MMD -MP -MT $@ -MF $(@:%.o=%.d) -- --CTYPE_OBJS = isdigit.o isxdigit.o toupper.o --%.o : $(SLOF_DIR)/lib/libc/ctype/%.c -- $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) -- --STRING_OBJS = strcat.o strchr.o strrchr.o strcpy.o strlen.o strncpy.o \ -- strcmp.o strncmp.o strcasecmp.o strncasecmp.o strstr.o \ -- memset.o memcpy.o memmove.o memcmp.o --%.o : $(SLOF_DIR)/lib/libc/string/%.c -- $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) -- --STDLIB_OBJS = atoi.o atol.o strtoul.o strtol.o rand.o malloc.o free.o --%.o : $(SLOF_DIR)/lib/libc/stdlib/%.c -- $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) -- --STDIO_OBJS = sprintf.o snprintf.o vfprintf.o vsnprintf.o vsprintf.o fprintf.o \ -- printf.o putc.o puts.o putchar.o stdchnls.o fileno.o --%.o : $(SLOF_DIR)/lib/libc/stdio/%.c -- $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) -- --sbrk.o: $(SLOF_DIR)/slof/sbrk.c -- $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) -- --LIBCOBJS := $(STRING_OBJS) $(CTYPE_OBJS) $(STDLIB_OBJS) $(STDIO_OBJS) sbrk.o -- --libc.a: $(LIBCOBJS) -- $(call quiet-command,$(AR) -rc $@ $^,Creating static library) -- --# libnet files: -- --LIBNETOBJS := args.o dhcp.o dns.o icmpv6.o ipv6.o tcp.o udp.o bootp.o \ -- dhcpv6.o ethernet.o ipv4.o ndp.o tftp.o pxelinux.o --LIBNETCFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \ -- -DDHCPARCH=0x1F -MMD -MP -MT $@ -MF $(@:%.o=%.d) -- --%.o : $(SLOF_DIR)/lib/libnet/%.c -- $(call quiet-command,$(CC) $(LIBNETCFLAGS) -c -o $@ $<,Compiling) -- --libnet.a: $(LIBNETOBJS) -- $(call quiet-command,$(AR) -rc $@ $^,Creating static library) --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-Re-initialize-receive-queue-index-b.patch b/kvm-pc-bios-s390-ccw-Re-initialize-receive-queue-index-b.patch deleted file mode 100644 index bd90563..0000000 --- a/kvm-pc-bios-s390-ccw-Re-initialize-receive-queue-index-b.patch +++ /dev/null @@ -1,41 +0,0 @@ -From b2add99e201168c36eed56a3982ab02f63e5717a Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Mon, 11 Nov 2024 14:11:20 +0100 -Subject: [PATCH 9/9] pc-bios/s390-ccw: Re-initialize receive queue index - before each boot attempt - -RH-Author: Thomas Huth -RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature -RH-Jira: RHEL-68444 -RH-Acked-by: Miroslav Rezanina -RH-Commit: [8/8] 8d40508aaf993f2e1b94d471f0e50d0f375e22d2 (thuth/qemu-kvm-cs9) - -Now that we can boot from multiple boot devices, we have to make sure -to reinitialize static variables like rx_last_idx to avoid that they -contain garbage data during the second boot attempt (which can lead to -crashes when the code tries to access the wrong ring data). - -Message-ID: <20241111131120.317796-1-thuth@redhat.com> -Reviewed-by: Jared Rossi -Signed-off-by: Thomas Huth -(cherry picked from commit 6ba1f714c00f8839a8df9f643e0058f00da3fd25) ---- - pc-bios/s390-ccw/virtio-net.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/pc-bios/s390-ccw/virtio-net.c b/pc-bios/s390-ccw/virtio-net.c -index f9854a22c3..578c89d0c5 100644 ---- a/pc-bios/s390-ccw/virtio-net.c -+++ b/pc-bios/s390-ccw/virtio-net.c -@@ -51,6 +51,8 @@ int virtio_net_init(void *mac_addr) - void *buf; - int i; - -+ rx_last_idx = 0; -+ - vdev->guest_features[0] = VIRTIO_NET_F_MAC_BIT; - virtio_setup_ccw(vdev); - --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch b/kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch deleted file mode 100644 index 774fb08..0000000 --- a/kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch +++ /dev/null @@ -1,177 +0,0 @@ -From 8279e0d5e38b31b9fcd36ff38f0175163ac4ba28 Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:44 -0400 -Subject: [PATCH 12/38] pc-bios/s390-ccw: Remove panics from DASD IPL path -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [11/23] 10de76e1707b351835081f37ddf8ef1c2c00fe61 (thuth/qemu-kvm-cs9) - -Remove panic-on-error from DASD IPL specific functions so that error recovery -may be possible in the future. - -Functions that would previously panic now provide a return code. - -Signed-off-by: Jared Rossi -Reviewed-by: Thomas Huth -Message-ID: <20241020012953.1380075-11-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 1d5c7f078e938e6844f404429dd70bc52b39dac6) ---- - pc-bios/s390-ccw/dasd-ipl.c | 66 ++++++++++++++++++++----------------- - pc-bios/s390-ccw/dasd-ipl.h | 2 +- - 2 files changed, 37 insertions(+), 31 deletions(-) - -diff --git a/pc-bios/s390-ccw/dasd-ipl.c b/pc-bios/s390-ccw/dasd-ipl.c -index ae751adec1..babece95ea 100644 ---- a/pc-bios/s390-ccw/dasd-ipl.c -+++ b/pc-bios/s390-ccw/dasd-ipl.c -@@ -111,38 +111,29 @@ static void make_readipl(void) - ccwIplRead->count = 0x18; /* Read 0x18 bytes of data */ - } - --static void run_readipl(SubChannelId schid, uint16_t cutype) -+static int run_readipl(SubChannelId schid, uint16_t cutype) - { -- if (do_cio(schid, cutype, 0x00, CCW_FMT0)) { -- panic("dasd-ipl: Failed to run Read IPL channel program\n"); -- } -+ return do_cio(schid, cutype, 0x00, CCW_FMT0); - } - - /* - * The architecture states that IPL1 data should consist of a psw followed by - * format-0 READ and TIC CCWs. Let's sanity check. - */ --static void check_ipl1(void) -+static bool check_ipl1(void) - { - Ccw0 *ccwread = (Ccw0 *)0x08; - Ccw0 *ccwtic = (Ccw0 *)0x10; - -- if (ccwread->cmd_code != CCW_CMD_DASD_READ || -- ccwtic->cmd_code != CCW_CMD_TIC) { -- panic("dasd-ipl: IPL1 data invalid. Is this disk really bootable?\n"); -- } -+ return (ccwread->cmd_code == CCW_CMD_DASD_READ && -+ ccwtic->cmd_code == CCW_CMD_TIC); - } - --static void check_ipl2(uint32_t ipl2_addr) -+static bool check_ipl2(uint32_t ipl2_addr) - { - Ccw0 *ccw = u32toptr(ipl2_addr); - -- if (ipl2_addr == 0x00) { -- panic("IPL2 address invalid. Is this disk really bootable?\n"); -- } -- if (ccw->cmd_code == 0x00) { -- panic("IPL2 ccw data invalid. Is this disk really bootable?\n"); -- } -+ return (ipl2_addr != 0x00 && ccw->cmd_code != 0x00); - } - - static uint32_t read_ipl2_addr(void) -@@ -188,52 +179,67 @@ static void ipl1_fixup(void) - ccwSearchTic->cda = ptr2u32(ccwSearchID); - } - --static void run_ipl1(SubChannelId schid, uint16_t cutype) -+static int run_ipl1(SubChannelId schid, uint16_t cutype) - { - uint32_t startAddr = 0x08; - -- if (do_cio(schid, cutype, startAddr, CCW_FMT0)) { -- panic("dasd-ipl: Failed to run IPL1 channel program\n"); -- } -+ return do_cio(schid, cutype, startAddr, CCW_FMT0); - } - --static void run_ipl2(SubChannelId schid, uint16_t cutype, uint32_t addr) -+static int run_ipl2(SubChannelId schid, uint16_t cutype, uint32_t addr) - { -- if (run_dynamic_ccw_program(schid, cutype, addr)) { -- panic("dasd-ipl: Failed to run IPL2 channel program\n"); -- } -+ return run_dynamic_ccw_program(schid, cutype, addr); - } - - /* - * Limitations in vfio-ccw support complicate the IPL process. Details can - * be found in docs/devel/s390-dasd-ipl.rst - */ --void dasd_ipl(SubChannelId schid, uint16_t cutype) -+int dasd_ipl(SubChannelId schid, uint16_t cutype) - { - PSWLegacy *pswl = (PSWLegacy *) 0x00; - uint32_t ipl2_addr; - - /* Construct Read IPL CCW and run it to read IPL1 from boot disk */ - make_readipl(); -- run_readipl(schid, cutype); -+ if (run_readipl(schid, cutype)) { -+ puts("Failed to run Read IPL channel program"); -+ return -EIO; -+ } -+ - ipl2_addr = read_ipl2_addr(); -- check_ipl1(); -+ -+ if (!check_ipl1()) { -+ puts("IPL1 invalid for DASD-IPL"); -+ return -EINVAL; -+ } - - /* - * Fixup IPL1 channel program to account for vfio-ccw limitations, then run - * it to read IPL2 channel program from boot disk. - */ - ipl1_fixup(); -- run_ipl1(schid, cutype); -- check_ipl2(ipl2_addr); -+ if (run_ipl1(schid, cutype)) { -+ puts("Failed to run IPL1 channel program"); -+ return -EIO; -+ } -+ -+ if (!check_ipl2(ipl2_addr)) { -+ puts("IPL2 invalid for DASD-IPL"); -+ return -EINVAL; -+ } - - /* - * Run IPL2 channel program to read operating system code from boot disk - */ -- run_ipl2(schid, cutype, ipl2_addr); -+ if (run_ipl2(schid, cutype, ipl2_addr)) { -+ puts("Failed to run IPL2 channel program"); -+ return -EIO; -+ } - - /* Transfer control to the guest operating system */ - pswl->mask |= PSW_MASK_EAMODE; /* Force z-mode */ - pswl->addr |= PSW_MASK_BAMODE; /* ... */ - jump_to_low_kernel(); -+ return -1; - } -diff --git a/pc-bios/s390-ccw/dasd-ipl.h b/pc-bios/s390-ccw/dasd-ipl.h -index c394828906..eb1898c84a 100644 ---- a/pc-bios/s390-ccw/dasd-ipl.h -+++ b/pc-bios/s390-ccw/dasd-ipl.h -@@ -11,6 +11,6 @@ - #ifndef DASD_IPL_H - #define DASD_IPL_H - --void dasd_ipl(SubChannelId schid, uint16_t cutype); -+int dasd_ipl(SubChannelId schid, uint16_t cutype); - - #endif /* DASD_IPL_H */ --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch b/kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch deleted file mode 100644 index 4d55909..0000000 --- a/kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch +++ /dev/null @@ -1,475 +0,0 @@ -From 0a8e0f11dd82d5988b1090e8e4b8326be0dcb30c Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:42 -0400 -Subject: [PATCH 10/38] pc-bios/s390-ccw: Remove panics from ECKD IPL path -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [9/23] 628c2800ed02da8920e7e7c21d9f57e38a9a933d (thuth/qemu-kvm-cs9) - -Remove panic-on-error from ECKD block device IPL specific functions so that -error recovery may be possible in the future. - -Functions that would previously panic now provide a return code. - -Signed-off-by: Jared Rossi -Reviewed-by: Thomas Huth -Message-ID: <20241020012953.1380075-9-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 806315279d5c629e1cc3a945bcfba3fe5482d84b) ---- - pc-bios/s390-ccw/bootmap.c | 187 +++++++++++++++++++++++++------------ - pc-bios/s390-ccw/bootmap.h | 1 + - 2 files changed, 130 insertions(+), 58 deletions(-) - -diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c -index af73254acb..b9596e28c7 100644 ---- a/pc-bios/s390-ccw/bootmap.c -+++ b/pc-bios/s390-ccw/bootmap.c -@@ -145,14 +145,17 @@ static block_number_t load_eckd_segments(block_number_t blk, bool ldipl, - bool more_data; - - memset(_bprs, FREE_SPACE_FILLER, sizeof(_bprs)); -- read_block(blk, bprs, "BPRS read failed"); -+ if (virtio_read(blk, bprs)) { -+ puts("BPRS read failed"); -+ return ERROR_BLOCK_NR; -+ } - - do { - more_data = false; - for (j = 0;; j++) { - block_nr = gen_eckd_block_num(&bprs[j].xeckd, ldipl); - if (is_null_block_number(block_nr)) { /* end of chunk */ -- break; -+ return NULL_BLOCK_NR; - } - - /* we need the updated blockno for the next indirect entry -@@ -163,15 +166,20 @@ static block_number_t load_eckd_segments(block_number_t blk, bool ldipl, - } - - /* List directed pointer does not store block size */ -- IPL_assert(ldipl || block_size_ok(bprs[j].xeckd.bptr.size), -- "bad chunk block size"); -+ if (!ldipl && !block_size_ok(bprs[j].xeckd.bptr.size)) { -+ puts("Bad chunk block size"); -+ return ERROR_BLOCK_NR; -+ } - - if (!eckd_valid_address(&bprs[j].xeckd, ldipl)) { - /* - * If an invalid address is found during LD-IPL then break and -- * retry as CCW -+ * retry as CCW-IPL, otherwise abort on error - */ -- IPL_assert(ldipl, "bad chunk ECKD addr"); -+ if (!ldipl) { -+ puts("Bad chunk ECKD address"); -+ return ERROR_BLOCK_NR; -+ } - break; - } - -@@ -189,7 +197,10 @@ static block_number_t load_eckd_segments(block_number_t blk, bool ldipl, - * I.e. the next ptr must point to the unused memory area - */ - memset(_bprs, FREE_SPACE_FILLER, sizeof(_bprs)); -- read_block(block_nr, bprs, "BPRS continuation read failed"); -+ if (virtio_read(block_nr, bprs)) { -+ puts("BPRS continuation read failed"); -+ return ERROR_BLOCK_NR; -+ } - more_data = true; - break; - } -@@ -198,7 +209,10 @@ static block_number_t load_eckd_segments(block_number_t blk, bool ldipl, - * to memory (address). - */ - rc = virtio_read_many(block_nr, (void *)(*address), count + 1); -- IPL_assert(rc == 0, "code chunk read failed"); -+ if (rc != 0) { -+ puts("Code chunk read failed"); -+ return ERROR_BLOCK_NR; -+ } - - *address += (count + 1) * virtio_get_block_size(); - } -@@ -232,7 +246,10 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr) - - /* Get Stage1b data */ - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); -- read_block(s1b_block_nr, s1b, "Cannot read stage1b boot loader"); -+ if (virtio_read(s1b_block_nr, s1b)) { -+ puts("Cannot read stage1b boot loader"); -+ return -EIO; -+ } - - memset(_s2, FREE_SPACE_FILLER, sizeof(_s2)); - -@@ -244,7 +261,10 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr) - break; - } - -- read_block(cur_block_nr, s2_cur_blk, "Cannot read stage2 boot loader"); -+ if (virtio_read(cur_block_nr, s2_cur_blk)) { -+ puts("Cannot read stage2 boot loader"); -+ return -EIO; -+ } - - if (find_zipl_boot_menu_banner(&banner_offset)) { - /* -@@ -252,8 +272,10 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr) - * possibility of menu data spanning multiple blocks. - */ - if (prev_block_nr) { -- read_block(prev_block_nr, s2_prev_blk, -- "Cannot read stage2 boot loader"); -+ if (virtio_read(prev_block_nr, s2_prev_blk)) { -+ puts("Cannot read stage2 boot loader"); -+ return -EIO; -+ } - } - - if (i + 1 < STAGE2_BLK_CNT_MAX) { -@@ -261,8 +283,10 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr) - } - - if (next_block_nr && !is_null_block_number(next_block_nr)) { -- read_block(next_block_nr, s2_next_blk, -- "Cannot read stage2 boot loader"); -+ if (virtio_read(next_block_nr, s2_next_blk)) { -+ puts("Cannot read stage2 boot loader"); -+ return -EIO; -+ } - } - - return menu_get_zipl_boot_index(s2_cur_blk + banner_offset); -@@ -275,7 +299,7 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr) - return 0; - } - --static void run_eckd_boot_script(block_number_t bmt_block_nr, -+static int run_eckd_boot_script(block_number_t bmt_block_nr, - block_number_t s1b_block_nr) - { - int i; -@@ -292,17 +316,28 @@ static void run_eckd_boot_script(block_number_t bmt_block_nr, - } - - debug_print_int("loadparm", loadparm); -- IPL_assert(loadparm < MAX_BOOT_ENTRIES, "loadparm value greater than" -- " maximum number of boot entries allowed"); -+ if (loadparm >= MAX_BOOT_ENTRIES) { -+ puts("loadparm value greater than max number of boot entries allowed"); -+ return -EINVAL; -+ } - - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); -- read_block(bmt_block_nr, sec, "Cannot read Boot Map Table"); -+ if (virtio_read(bmt_block_nr, sec)) { -+ puts("Cannot read Boot Map Table"); -+ return -EIO; -+ } - - block_nr = gen_eckd_block_num(&bmt->entry[loadparm].xeckd, ldipl); -- IPL_assert(block_nr != -1, "Cannot find Boot Map Table Entry"); -+ if (block_nr == NULL_BLOCK_NR) { -+ puts("Cannot find Boot Map Table Entry"); -+ return -EIO; -+ } - - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); -- read_block(block_nr, sec, "Cannot read Boot Map Script"); -+ if (virtio_read(block_nr, sec)) { -+ puts("Cannot read Boot Map Script"); -+ return -EIO; -+ } - - for (i = 0; bms->entry[i].type == BOOT_SCRIPT_LOAD || - bms->entry[i].type == BOOT_SCRIPT_SIGNATURE; i++) { -@@ -317,21 +352,27 @@ static void run_eckd_boot_script(block_number_t bmt_block_nr, - - do { - block_nr = load_eckd_segments(block_nr, ldipl, &address); -- } while (block_nr != -1); -+ if (block_nr == ERROR_BLOCK_NR) { -+ return ldipl ? 0 : -EIO; -+ } -+ } while (block_nr != NULL_BLOCK_NR); - } - - if (ldipl && bms->entry[i].type != BOOT_SCRIPT_EXEC) { - /* Abort LD-IPL and retry as CCW-IPL */ -- return; -+ return 0; - } - -- IPL_assert(bms->entry[i].type == BOOT_SCRIPT_EXEC, -- "Unknown script entry type"); -+ if (bms->entry[i].type != BOOT_SCRIPT_EXEC) { -+ puts("Unknown script entry type"); -+ return -EINVAL; -+ } - write_reset_psw(bms->entry[i].address.load_address); /* no return */ - jump_to_IPL_code(0); /* no return */ -+ return -1; - } - --static void ipl_eckd_cdl(void) -+static int ipl_eckd_cdl(void) - { - XEckdMbr *mbr; - EckdCdlIpl2 *ipl2 = (void *)sec; -@@ -342,20 +383,23 @@ static void ipl_eckd_cdl(void) - puts("CDL"); - - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); -- read_block(1, ipl2, "Cannot read IPL2 record at block 1"); -+ if (virtio_read(1, ipl2)) { -+ puts("Cannot read IPL2 record at block 1"); -+ return -EIO; -+ } - - mbr = &ipl2->mbr; - if (!magic_match(mbr, ZIPL_MAGIC)) { - puts("No zIPL section in IPL2 record."); -- return; -+ return 0; - } - if (!block_size_ok(mbr->blockptr.xeckd.bptr.size)) { - puts("Bad block size in zIPL section of IPL2 record."); -- return; -+ return 0; - } - if (mbr->dev_type != DEV_TYPE_ECKD) { - puts("Non-ECKD device type in zIPL section of IPL2 record."); -- return; -+ return 0; - } - - /* save pointer to Boot Map Table */ -@@ -365,19 +409,21 @@ static void ipl_eckd_cdl(void) - s1b_block_nr = eckd_block_num(&ipl2->stage1.seek[0].chs); - - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); -- read_block(2, vlbl, "Cannot read Volume Label at block 2"); -+ if (virtio_read(2, vlbl)) { -+ puts("Cannot read Volume Label at block 2"); -+ return -EIO; -+ } - if (!magic_match(vlbl->key, VOL1_MAGIC)) { - puts("Invalid magic of volume label block."); -- return; -+ return 0; - } - if (!magic_match(vlbl->f.key, VOL1_MAGIC)) { - puts("Invalid magic of volser block."); -- return; -+ return 0; - } - print_volser(vlbl->f.volser); - -- run_eckd_boot_script(bmt_block_nr, s1b_block_nr); -- /* no return */ -+ return run_eckd_boot_script(bmt_block_nr, s1b_block_nr); - } - - static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode) -@@ -403,7 +449,7 @@ static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode) - print_volser(vlbl->volser); - } - --static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) -+static int ipl_eckd_ldl(ECKD_IPL_mode_t mode) - { - block_number_t bmt_block_nr, s1b_block_nr; - EckdLdlIpl1 *ipl1 = (void *)sec; -@@ -415,10 +461,13 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) - /* DO NOT read BootMap pointer (only one, xECKD) at block #2 */ - - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); -- read_block(0, sec, "Cannot read block 0 to grab boot info."); -+ if (virtio_read(0, sec)) { -+ puts("Cannot read block 0 to grab boot info."); -+ return -EIO; -+ } - if (mode == ECKD_LDL_UNLABELED) { - if (!magic_match(ipl1->bip.magic, ZIPL_MAGIC)) { -- return; /* not applicable layout */ -+ return 0; /* not applicable layout */ - } - puts("unlabeled LDL."); - } -@@ -430,8 +479,7 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) - /* save pointer to Stage1b Data */ - s1b_block_nr = eckd_block_num(&ipl1->stage1.seek[0].chs); - -- run_eckd_boot_script(bmt_block_nr, s1b_block_nr); -- /* no return */ -+ return run_eckd_boot_script(bmt_block_nr, s1b_block_nr); - } - - static block_number_t eckd_find_bmt(ExtEckdBlockPtr *ptr) -@@ -441,7 +489,10 @@ static block_number_t eckd_find_bmt(ExtEckdBlockPtr *ptr) - BootRecord *br; - - blockno = gen_eckd_block_num(ptr, 0); -- read_block(blockno, tmp_sec, "Cannot read boot record"); -+ if (virtio_read(blockno, tmp_sec)) { -+ puts("Cannot read boot record"); -+ return ERROR_BLOCK_NR; -+ } - br = (BootRecord *)tmp_sec; - if (!magic_match(br->magic, ZIPL_MAGIC)) { - /* If the boot record is invalid, return and try CCW-IPL instead */ -@@ -470,7 +521,7 @@ static void print_eckd_msg(void) - printf("%s", msg); - } - --static void ipl_eckd(void) -+static int ipl_eckd(void) - { - IplVolumeLabel *vlbl = (void *)sec; - LDL_VTOC *vtoc = (void *)sec; -@@ -480,7 +531,10 @@ static void ipl_eckd(void) - - /* Block 2 can contain either the CDL VOL1 label or the LDL VTOC */ - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); -- read_block(2, vlbl, "Cannot read block 2"); -+ if (virtio_read(2, vlbl)) { -+ puts("Cannot read block 2"); -+ return -EIO; -+ } - - /* - * First check for a list-directed-format pointer which would -@@ -488,36 +542,53 @@ static void ipl_eckd(void) - */ - if (eckd_valid_address((ExtEckdBlockPtr *)&vlbl->f.br, 0)) { - ldipl_bmt = eckd_find_bmt((ExtEckdBlockPtr *)&vlbl->f.br); -- if (ldipl_bmt) { -+ switch (ldipl_bmt) { -+ case ERROR_BLOCK_NR: -+ return -EIO; -+ case NULL_BLOCK_NR: -+ break; /* Invalid BMT but the device may still boot with CCW-IPL */ -+ default: - puts("List-Directed"); -- /* LD-IPL does not use the S1B bock, just make it NULL */ -- run_eckd_boot_script(ldipl_bmt, NULL_BLOCK_NR); -- /* Only return in error, retry as CCW-IPL */ -+ /* -+ * LD-IPL does not use the S1B bock, just make it NULL_BLOCK_NR. -+ * In some failure cases retry IPL before aborting. -+ */ -+ if (run_eckd_boot_script(ldipl_bmt, NULL_BLOCK_NR)) { -+ return -EIO; -+ } -+ /* Non-fatal error, retry as CCW-IPL */ - printf("Retrying IPL "); - print_eckd_msg(); - } - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); -- read_block(2, vtoc, "Cannot read block 2"); -+ if (virtio_read(2, vtoc)) { -+ puts("Cannot read block 2"); -+ return -EIO; -+ } - } - - /* Not list-directed */ - if (magic_match(vtoc->magic, VOL1_MAGIC)) { -- ipl_eckd_cdl(); /* may return in error */ -+ if (ipl_eckd_cdl()) { -+ return -1; -+ } - } - - if (magic_match(vtoc->magic, CMS1_MAGIC)) { -- ipl_eckd_ldl(ECKD_CMS); /* no return */ -+ return ipl_eckd_ldl(ECKD_CMS); - } - if (magic_match(vtoc->magic, LNX1_MAGIC)) { -- ipl_eckd_ldl(ECKD_LDL); /* no return */ -+ return ipl_eckd_ldl(ECKD_LDL); - } - -- ipl_eckd_ldl(ECKD_LDL_UNLABELED); /* it still may return */ -+ if (ipl_eckd_ldl(ECKD_LDL_UNLABELED)) { -+ return -1; -+ } - /* - * Ok, it is not a LDL by any means. - * It still might be a CDL with zero record keys for IPL1 and IPL2 - */ -- ipl_eckd_cdl(); -+ return ipl_eckd_cdl(); - } - - /*********************************************************************** -@@ -910,7 +981,7 @@ static bool has_iso_signature(void) - * Bus specific IPL sequences - */ - --static void zipl_load_vblk(void) -+static int zipl_load_vblk(void) - { - int blksize = virtio_get_block_size(); - -@@ -919,7 +990,7 @@ static void zipl_load_vblk(void) - virtio_assume_iso9660(); - } - if (ipl_iso_el_torito()) { -- return; -+ return 0; - } - } - -@@ -927,21 +998,21 @@ static void zipl_load_vblk(void) - puts("Using guessed DASD geometry."); - virtio_assume_eckd(); - } -- ipl_eckd(); -+ return ipl_eckd(); - } - --static void zipl_load_vscsi(void) -+static int zipl_load_vscsi(void) - { - if (virtio_get_block_size() == VIRTIO_ISO_BLOCK_SIZE) { - /* Is it an ISO image in non-CD drive? */ - if (ipl_iso_el_torito()) { -- return; -+ return 0; - } - } - - puts("Using guessed DASD geometry."); - virtio_assume_eckd(); -- ipl_eckd(); -+ return ipl_eckd(); - } - - /*********************************************************************** -diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h -index 3cb573b86b..95943441d3 100644 ---- a/pc-bios/s390-ccw/bootmap.h -+++ b/pc-bios/s390-ccw/bootmap.h -@@ -16,6 +16,7 @@ - - typedef uint64_t block_number_t; - #define NULL_BLOCK_NR 0xffffffffffffffffULL -+#define ERROR_BLOCK_NR 0xfffffffffffffffeULL - - #define FREE_SPACE_FILLER '\xAA' - --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch b/kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch deleted file mode 100644 index 7004386..0000000 --- a/kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch +++ /dev/null @@ -1,269 +0,0 @@ -From 6238d2aa6b1a1f421ac04b0d35281dd5e4c65b5c Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:41 -0400 -Subject: [PATCH 09/38] pc-bios/s390-ccw: Remove panics from ISO IPL path -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [8/23] de54d00bb7f300a38e7babdf8c9b587c0ed81883 (thuth/qemu-kvm-cs9) - -Remove panic-on-error from IPL ISO El Torito specific functions so that error -recovery may be possible in the future. - -Functions that would previously panic now provide a return code. - -Signed-off-by: Jared Rossi -Reviewed-by: Thomas Huth -Message-ID: <20241020012953.1380075-8-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit bef2b8dd1a36fc79cabcda48e667f2cba476924c) ---- - pc-bios/s390-ccw/bootmap.c | 87 ++++++++++++++++++++++++------------- - pc-bios/s390-ccw/bootmap.h | 15 +++---- - pc-bios/s390-ccw/s390-ccw.h | 1 + - 3 files changed, 65 insertions(+), 38 deletions(-) - -diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c -index 414c3f1b47..af73254acb 100644 ---- a/pc-bios/s390-ccw/bootmap.c -+++ b/pc-bios/s390-ccw/bootmap.c -@@ -678,8 +678,10 @@ static bool is_iso_bc_entry_compatible(IsoBcSection *s) - if (s->unused || !s->sector_count) { - return false; - } -- read_iso_sector(bswap32(s->load_rba), magic_sec, -- "Failed to read image sector 0"); -+ if (virtio_read(bswap32(s->load_rba), magic_sec)) { -+ puts("Failed to read image sector 0"); -+ return false; -+ } - - /* Checking bytes 8 - 32 for S390 Linux magic */ - return !memcmp(magic_sec + 8, linux_s390_magic, 24); -@@ -692,28 +694,35 @@ static uint32_t sec_offset[ISO9660_MAX_DIR_DEPTH]; - /* Remained directory space in bytes */ - static uint32_t dir_rem[ISO9660_MAX_DIR_DEPTH]; - --static inline uint32_t iso_get_file_size(uint32_t load_rba) -+static inline long iso_get_file_size(uint32_t load_rba) - { - IsoVolDesc *vd = (IsoVolDesc *)sec; - IsoDirHdr *cur_record = &vd->vd.primary.rootdir; - uint8_t *temp = sec + ISO_SECTOR_SIZE; - int level = 0; - -- read_iso_sector(ISO_PRIMARY_VD_SECTOR, sec, -- "Failed to read ISO primary descriptor"); -+ if (virtio_read(ISO_PRIMARY_VD_SECTOR, sec)) { -+ puts("Failed to read ISO primary descriptor"); -+ return -EIO; -+ } -+ - sec_loc[0] = iso_733_to_u32(cur_record->ext_loc); - dir_rem[0] = 0; - sec_offset[0] = 0; - - while (level >= 0) { -- IPL_assert(sec_offset[level] <= ISO_SECTOR_SIZE, -- "Directory tree structure violation"); -+ if (sec_offset[level] > ISO_SECTOR_SIZE) { -+ puts("Directory tree structure violation"); -+ return -EIO; -+ } - - cur_record = (IsoDirHdr *)(temp + sec_offset[level]); - - if (sec_offset[level] == 0) { -- read_iso_sector(sec_loc[level], temp, -- "Failed to read ISO directory"); -+ if (virtio_read(sec_loc[level], temp)) { -+ puts("Failed to read ISO directory"); -+ return -EIO; -+ } - if (dir_rem[level] == 0) { - /* Skip self and parent records */ - dir_rem[level] = iso_733_to_u32(cur_record->data_len) - -@@ -758,8 +767,10 @@ static inline uint32_t iso_get_file_size(uint32_t load_rba) - if (dir_rem[level] == 0) { - /* Nothing remaining */ - level--; -- read_iso_sector(sec_loc[level], temp, -- "Failed to read ISO directory"); -+ if (virtio_read(sec_loc[level], temp)) { -+ puts("Failed to read ISO directory"); -+ return -EIO; -+ } - } - } - -@@ -774,19 +785,24 @@ static void load_iso_bc_entry(IsoBcSection *load) - * is padded and ISO_SECTOR_SIZE bytes aligned - */ - uint32_t blks_to_load = bswap16(s.sector_count) >> ET_SECTOR_SHIFT; -- uint32_t real_size = iso_get_file_size(bswap32(s.load_rba)); -+ long real_size = iso_get_file_size(bswap32(s.load_rba)); - -- if (real_size) { -+ if (real_size > 0) { - /* Round up blocks to load */ - blks_to_load = (real_size + ISO_SECTOR_SIZE - 1) / ISO_SECTOR_SIZE; - puts("ISO boot image size verified"); - } else { - puts("ISO boot image size could not be verified"); -+ if (real_size < 0) { -+ return; -+ } - } - -- read_iso_boot_image(bswap32(s.load_rba), -+ if (read_iso_boot_image(bswap32(s.load_rba), - (void *)((uint64_t)bswap16(s.load_segment)), -- blks_to_load); -+ blks_to_load)) { -+ return; -+ } - - jump_to_low_kernel(); - } -@@ -809,17 +825,18 @@ static uint32_t find_iso_bc(void) - return bswap32(et->bc_offset); - } - } -- read_iso_sector(block_num++, sec, -- "Failed to read ISO volume descriptor"); -+ if (virtio_read(block_num++, sec)) { -+ puts("Failed to read ISO volume descriptor"); -+ return 0; -+ } - } - - return 0; - } - --static IsoBcSection *find_iso_bc_entry(void) -+static IsoBcSection *find_iso_bc_entry(uint32_t offset) - { - IsoBcEntry *e = (IsoBcEntry *)sec; -- uint32_t offset = find_iso_bc(); - int i; - unsigned int loadparm = get_loadparm_index(); - -@@ -827,11 +844,13 @@ static IsoBcSection *find_iso_bc_entry(void) - return NULL; - } - -- read_iso_sector(offset, sec, "Failed to read El Torito boot catalog"); -+ if (virtio_read(offset, sec)) { -+ puts("Failed to read El Torito boot catalog"); -+ return NULL; -+ } - - if (!is_iso_bc_valid(e)) { - /* The validation entry is mandatory */ -- panic("No valid boot catalog found!\n"); - return NULL; - } - -@@ -851,19 +870,25 @@ static IsoBcSection *find_iso_bc_entry(void) - } - } - -- panic("No suitable boot entry found on ISO-9660 media!\n"); -- - return NULL; - } - --static void ipl_iso_el_torito(void) -+static int ipl_iso_el_torito(void) - { -- IsoBcSection *s = find_iso_bc_entry(); -+ uint32_t offset = find_iso_bc(); -+ if (!offset) { -+ return 0; -+ } -+ -+ IsoBcSection *s = find_iso_bc_entry(offset); - - if (s) { -- load_iso_bc_entry(s); -- /* no return */ -+ load_iso_bc_entry(s); /* only return in error */ -+ return -1; - } -+ -+ puts("No suitable boot entry found on ISO-9660 media!"); -+ return -EIO; - } - - /** -@@ -893,7 +918,9 @@ static void zipl_load_vblk(void) - if (blksize != VIRTIO_ISO_BLOCK_SIZE) { - virtio_assume_iso9660(); - } -- ipl_iso_el_torito(); -+ if (ipl_iso_el_torito()) { -+ return; -+ } - } - - if (blksize != VIRTIO_DASD_DEFAULT_BLOCK_SIZE) { -@@ -907,7 +934,9 @@ static void zipl_load_vscsi(void) - { - if (virtio_get_block_size() == VIRTIO_ISO_BLOCK_SIZE) { - /* Is it an ISO image in non-CD drive? */ -- ipl_iso_el_torito(); -+ if (ipl_iso_el_torito()) { -+ return; -+ } - } - - puts("Using guessed DASD geometry."); -diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h -index 4a7d8a91f1..3cb573b86b 100644 ---- a/pc-bios/s390-ccw/bootmap.h -+++ b/pc-bios/s390-ccw/bootmap.h -@@ -385,17 +385,14 @@ static inline uint32_t iso_733_to_u32(uint64_t x) - - #define ISO_PRIMARY_VD_SECTOR 16 - --static inline void read_iso_sector(uint32_t block_offset, void *buf, -- const char *errmsg) --{ -- IPL_assert(virtio_read_many(block_offset, buf, 1) == 0, errmsg); --} -- --static inline void read_iso_boot_image(uint32_t block_offset, void *load_addr, -+static inline int read_iso_boot_image(uint32_t block_offset, void *load_addr, - uint32_t blks_to_load) - { -- IPL_assert(virtio_read_many(block_offset, load_addr, blks_to_load) == 0, -- "Failed to read boot image!"); -+ if (virtio_read_many(block_offset, load_addr, blks_to_load)) { -+ puts("Failed to read boot image!"); -+ return -1; -+ } -+ return 0; - } - - #define ISO9660_MAX_DIR_DEPTH 8 -diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h -index 6abb34e563..3e844abd71 100644 ---- a/pc-bios/s390-ccw/s390-ccw.h -+++ b/pc-bios/s390-ccw/s390-ccw.h -@@ -30,6 +30,7 @@ typedef unsigned long long u64; - #define EIO 1 - #define EBUSY 2 - #define ENODEV 3 -+#define EINVAL 4 - - #ifndef MIN - #define MIN(a, b) (((a) < (b)) ? (a) : (b)) --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch b/kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch deleted file mode 100644 index d66f32c..0000000 --- a/kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch +++ /dev/null @@ -1,130 +0,0 @@ -From d5e0f77bd63bc767856e1922b24556ef1b123b55 Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:45 -0400 -Subject: [PATCH 13/38] pc-bios/s390-ccw: Remove panics from Netboot IPL path -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [12/23] 26920462eca8a2e6d443c811efa69023fbe4f31f (thuth/qemu-kvm-cs9) - -Remove panic-on-error from Netboot specific functions so that error recovery -may be possible in the future. - -Functions that would previously panic now provide a return code. - -Signed-off-by: Jared Rossi -Reviewed-by: Thomas Huth -Message-ID: <20241020012953.1380075-12-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit f1a2a6e41ef76e02ddc5ede3dd042ef96b4fb8d2) ---- - pc-bios/s390-ccw/bootmap.c | 1 + - pc-bios/s390-ccw/netmain.c | 17 +++++++++++------ - pc-bios/s390-ccw/s390-ccw.h | 2 +- - pc-bios/s390-ccw/virtio-net.c | 7 +++++-- - 4 files changed, 18 insertions(+), 9 deletions(-) - -diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c -index 652807a16a..95ef9104d0 100644 ---- a/pc-bios/s390-ccw/bootmap.c -+++ b/pc-bios/s390-ccw/bootmap.c -@@ -1072,6 +1072,7 @@ void zipl_load(void) - - if (virtio_get_device_type() == VIRTIO_ID_NET) { - netmain(); -+ panic("\n! Cannot IPL from this network !\n"); - } - - if (ipl_scsi()) { -diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c -index bc6ad8695f..d1a6c9a91c 100644 ---- a/pc-bios/s390-ccw/netmain.c -+++ b/pc-bios/s390-ccw/netmain.c -@@ -464,7 +464,7 @@ static bool find_net_dev(Schib *schib, int dev_no) - return false; - } - --static void virtio_setup(void) -+static bool virtio_setup(void) - { - Schib schib; - int ssid; -@@ -495,10 +495,10 @@ static void virtio_setup(void) - } - } - -- IPL_assert(found, "No virtio net device found"); -+ return found; - } - --void netmain(void) -+int netmain(void) - { - filename_ip_t fn_ip; - int rc, fnlen; -@@ -506,11 +506,15 @@ void netmain(void) - sclp_setup(); - puts("Network boot starting..."); - -- virtio_setup(); -+ if (!virtio_setup()) { -+ puts("No virtio net device found."); -+ return -1; -+ } - - rc = net_init(&fn_ip); - if (rc) { -- panic("Network initialization failed. Halting."); -+ puts("Network initialization failed."); -+ return -1; - } - - fnlen = strlen(fn_ip.filename); -@@ -528,5 +532,6 @@ void netmain(void) - jump_to_low_kernel(); - } - -- panic("Failed to load OS from network."); -+ puts("Failed to load OS from network."); -+ return -1; - } -diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h -index 3e844abd71..344ad15655 100644 ---- a/pc-bios/s390-ccw/s390-ccw.h -+++ b/pc-bios/s390-ccw/s390-ccw.h -@@ -57,7 +57,7 @@ unsigned int get_loadparm_index(void); - void main(void); - - /* netmain.c */ --void netmain(void); -+int netmain(void); - - /* sclp.c */ - void sclp_print(const char *string); -diff --git a/pc-bios/s390-ccw/virtio-net.c b/pc-bios/s390-ccw/virtio-net.c -index 2fcb0a58c5..f9854a22c3 100644 ---- a/pc-bios/s390-ccw/virtio-net.c -+++ b/pc-bios/s390-ccw/virtio-net.c -@@ -54,8 +54,11 @@ int virtio_net_init(void *mac_addr) - vdev->guest_features[0] = VIRTIO_NET_F_MAC_BIT; - virtio_setup_ccw(vdev); - -- IPL_assert(vdev->guest_features[0] & VIRTIO_NET_F_MAC_BIT, -- "virtio-net device does not support the MAC address feature"); -+ if (!(vdev->guest_features[0] & VIRTIO_NET_F_MAC_BIT)) { -+ puts("virtio-net device does not support the MAC address feature"); -+ return -1; -+ } -+ - memcpy(mac_addr, vdev->config.net.mac, ETH_ALEN); - - for (i = 0; i < 64; i++) { --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch b/kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch deleted file mode 100644 index e02a98d..0000000 --- a/kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch +++ /dev/null @@ -1,554 +0,0 @@ -From 6212bfb4f7a45b06b38bf5d11774de1d3df982aa Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:43 -0400 -Subject: [PATCH 11/38] pc-bios/s390-ccw: Remove panics from SCSI IPL path -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [10/23] 3d67ba81c0296f59f5ec2fab3361512e83b6d78d (thuth/qemu-kvm-cs9) - -Remove panic-on-error from virtio-scsi IPL specific functions so that error -recovery may be possible in the future. - -Functions that would previously panic now provide a return code. - -Signed-off-by: Jared Rossi -Reviewed-by: Thomas Huth -Message-ID: <20241020012953.1380075-10-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit facd91ac1af75b657fc80189fe9cb026bb1abdbc) ---- - pc-bios/s390-ccw/bootmap.c | 88 ++++++++++++++----- - pc-bios/s390-ccw/virtio-blkdev.c | 4 +- - pc-bios/s390-ccw/virtio-scsi.c | 143 +++++++++++++++++++++---------- - 3 files changed, 164 insertions(+), 71 deletions(-) - -diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c -index b9596e28c7..652807a16a 100644 ---- a/pc-bios/s390-ccw/bootmap.c -+++ b/pc-bios/s390-ccw/bootmap.c -@@ -595,7 +595,7 @@ static int ipl_eckd(void) - * IPL a SCSI disk - */ - --static void zipl_load_segment(ComponentEntry *entry) -+static int zipl_load_segment(ComponentEntry *entry) - { - const int max_entries = (MAX_SECTOR_SIZE / sizeof(ScsiBlockPtr)); - ScsiBlockPtr *bprs = (void *)sec; -@@ -615,7 +615,10 @@ static void zipl_load_segment(ComponentEntry *entry) - do { - memset(bprs, FREE_SPACE_FILLER, bprs_size); - fill_hex_val(blk_no, &blockno, sizeof(blockno)); -- read_block(blockno, bprs, err_msg); -+ if (virtio_read(blockno, bprs)) { -+ puts(err_msg); -+ return -EIO; -+ } - - for (i = 0;; i++) { - uint64_t *cur_desc = (void *)&bprs[i]; -@@ -643,23 +646,37 @@ static void zipl_load_segment(ComponentEntry *entry) - } - address = virtio_load_direct(cur_desc[0], cur_desc[1], 0, - (void *)address); -- IPL_assert(address != -1, "zIPL load segment failed"); -+ if (!address) { -+ puts("zIPL load segment failed"); -+ return -EIO; -+ } - } - } while (blockno); -+ -+ return 0; - } - - /* Run a zipl program */ --static void zipl_run(ScsiBlockPtr *pte) -+static int zipl_run(ScsiBlockPtr *pte) - { - ComponentHeader *header; - ComponentEntry *entry; - uint8_t tmp_sec[MAX_SECTOR_SIZE]; - -- read_block(pte->blockno, tmp_sec, "Cannot read header"); -+ if (virtio_read(pte->blockno, tmp_sec)) { -+ puts("Cannot read header"); -+ return -EIO; -+ } - header = (ComponentHeader *)tmp_sec; - -- IPL_assert(magic_match(tmp_sec, ZIPL_MAGIC), "No zIPL magic in header"); -- IPL_assert(header->type == ZIPL_COMP_HEADER_IPL, "Bad header type"); -+ if (!magic_match(tmp_sec, ZIPL_MAGIC)) { -+ puts("No zIPL magic in header"); -+ return -EINVAL; -+ } -+ if (header->type != ZIPL_COMP_HEADER_IPL) { -+ puts("Bad header type"); -+ return -EINVAL; -+ } - - dputs("start loading images\n"); - -@@ -674,22 +691,30 @@ static void zipl_run(ScsiBlockPtr *pte) - continue; - } - -- zipl_load_segment(entry); -+ if (zipl_load_segment(entry)) { -+ return -1; -+ } - - entry++; - -- IPL_assert((uint8_t *)(&entry[1]) <= (tmp_sec + MAX_SECTOR_SIZE), -- "Wrong entry value"); -+ if ((uint8_t *)(&entry[1]) > (tmp_sec + MAX_SECTOR_SIZE)) { -+ puts("Wrong entry value"); -+ return -EINVAL; -+ } - } - -- IPL_assert(entry->component_type == ZIPL_COMP_ENTRY_EXEC, "No EXEC entry"); -+ if (entry->component_type != ZIPL_COMP_ENTRY_EXEC) { -+ puts("No EXEC entry"); -+ return -EINVAL; -+ } - - /* should not return */ - write_reset_psw(entry->compdat.load_psw); - jump_to_IPL_code(0); -+ return -1; - } - --static void ipl_scsi(void) -+static int ipl_scsi(void) - { - ScsiMbr *mbr = (void *)sec; - int program_table_entries = 0; -@@ -700,10 +725,13 @@ static void ipl_scsi(void) - - /* Grab the MBR */ - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); -- read_block(0, mbr, "Cannot read block 0"); -+ if (virtio_read(0, mbr)) { -+ puts("Cannot read block 0"); -+ return -EIO; -+ } - - if (!magic_match(mbr->magic, ZIPL_MAGIC)) { -- return; -+ return 0; - } - - puts("Using SCSI scheme."); -@@ -711,11 +739,20 @@ static void ipl_scsi(void) - IPL_check(mbr->version_id == 1, - "Unknown MBR layout version, assuming version 1"); - debug_print_int("program table", mbr->pt.blockno); -- IPL_assert(mbr->pt.blockno, "No Program Table"); -+ if (!mbr->pt.blockno) { -+ puts("No Program Table"); -+ return -EINVAL; -+ } - - /* Parse the program table */ -- read_block(mbr->pt.blockno, sec, "Error reading Program Table"); -- IPL_assert(magic_match(sec, ZIPL_MAGIC), "No zIPL magic in PT"); -+ if (virtio_read(mbr->pt.blockno, sec)) { -+ puts("Error reading Program Table"); -+ return -EIO; -+ } -+ if (!magic_match(sec, ZIPL_MAGIC)) { -+ puts("No zIPL magic in Program Table"); -+ return -EINVAL; -+ } - - for (i = 0; i < MAX_BOOT_ENTRIES; i++) { - if (prog_table->entry[i].scsi.blockno) { -@@ -725,17 +762,22 @@ static void ipl_scsi(void) - } - - debug_print_int("program table entries", program_table_entries); -- IPL_assert(program_table_entries != 0, "Empty Program Table"); -+ if (program_table_entries == 0) { -+ puts("Empty Program Table"); -+ return -EINVAL; -+ } - - if (menu_is_enabled_enum()) { - loadparm = menu_get_enum_boot_index(valid_entries); - } - - debug_print_int("loadparm", loadparm); -- IPL_assert(loadparm < MAX_BOOT_ENTRIES, "loadparm value greater than" -- " maximum number of boot entries allowed"); -+ if (loadparm >= MAX_BOOT_ENTRIES) { -+ puts("loadparm value greater than max number of boot entries allowed"); -+ return -EINVAL; -+ } - -- zipl_run(&prog_table->entry[loadparm].scsi); /* no return */ -+ return zipl_run(&prog_table->entry[loadparm].scsi); - } - - /*********************************************************************** -@@ -1032,7 +1074,9 @@ void zipl_load(void) - netmain(); - } - -- ipl_scsi(); -+ if (ipl_scsi()) { -+ panic("\n! Cannot IPL this SCSI device !\n"); -+ } - - switch (virtio_get_device_type()) { - case VIRTIO_ID_BLOCK: -diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c -index 2666326801..1c585f034b 100644 ---- a/pc-bios/s390-ccw/virtio-blkdev.c -+++ b/pc-bios/s390-ccw/virtio-blkdev.c -@@ -73,13 +73,13 @@ unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list - unsigned long addr = (unsigned long)load_addr; - - if (sec_len != virtio_get_block_size()) { -- return -1; -+ return 0; - } - - printf("."); - status = virtio_read_many(sec, (void *)addr, sec_num); - if (status) { -- panic("I/O Error"); -+ return 0; - } - addr += sec_num * virtio_get_block_size(); - -diff --git a/pc-bios/s390-ccw/virtio-scsi.c b/pc-bios/s390-ccw/virtio-scsi.c -index 6b4a1caf8a..71db75ce7b 100644 ---- a/pc-bios/s390-ccw/virtio-scsi.c -+++ b/pc-bios/s390-ccw/virtio-scsi.c -@@ -26,7 +26,7 @@ static uint8_t scsi_inquiry_std_response[256]; - static ScsiInquiryEvpdPages scsi_inquiry_evpd_pages_response; - static ScsiInquiryEvpdBl scsi_inquiry_evpd_bl_response; - --static inline void vs_assert(bool term, const char **msgs) -+static inline bool vs_assert(bool term, const char **msgs) - { - if (!term) { - int i = 0; -@@ -35,11 +35,13 @@ static inline void vs_assert(bool term, const char **msgs) - while (msgs[i]) { - printf("%s", msgs[i++]); - } -- panic(" !\n"); -+ puts(" !"); - } -+ -+ return term; - } - --static void virtio_scsi_verify_response(VirtioScsiCmdResp *resp, -+static bool virtio_scsi_verify_response(VirtioScsiCmdResp *resp, - const char *title) - { - const char *mr[] = { -@@ -56,8 +58,8 @@ static void virtio_scsi_verify_response(VirtioScsiCmdResp *resp, - 0 - }; - -- vs_assert(resp->response == VIRTIO_SCSI_S_OK, mr); -- vs_assert(resp->status == CDB_STATUS_GOOD, ms); -+ return vs_assert(resp->response == VIRTIO_SCSI_S_OK, mr) && -+ vs_assert(resp->status == CDB_STATUS_GOOD, ms); - } - - static void prepare_request(VDev *vdev, const void *cdb, int cdb_size, -@@ -78,24 +80,31 @@ static void prepare_request(VDev *vdev, const void *cdb, int cdb_size, - } - } - --static inline void vs_io_assert(bool term, const char *msg) -+static inline bool vs_io_assert(bool term, const char *msg) - { -- if (!term) { -- virtio_scsi_verify_response(&resp, msg); -+ if (!term && !virtio_scsi_verify_response(&resp, msg)) { -+ return false; - } -+ -+ return true; - } - --static void vs_run(const char *title, VirtioCmd *cmd, VDev *vdev, -+static int vs_run(const char *title, VirtioCmd *cmd, VDev *vdev, - const void *cdb, int cdb_size, - void *data, uint32_t data_size) - { - prepare_request(vdev, cdb, cdb_size, data, data_size); -- vs_io_assert(virtio_run(vdev, VR_REQUEST, cmd) == 0, title); -+ if (!vs_io_assert(virtio_run(vdev, VR_REQUEST, cmd) == 0, title)) { -+ puts(title); -+ return -EIO; -+ } -+ -+ return 0; - } - - /* SCSI protocol implementation routines */ - --static bool scsi_inquiry(VDev *vdev, uint8_t evpd, uint8_t page, -+static int scsi_inquiry(VDev *vdev, uint8_t evpd, uint8_t page, - void *data, uint32_t data_size) - { - ScsiCdbInquiry cdb = { -@@ -110,12 +119,13 @@ static bool scsi_inquiry(VDev *vdev, uint8_t evpd, uint8_t page, - { data, data_size, VRING_DESC_F_WRITE }, - }; - -- vs_run("inquiry", inquiry, vdev, &cdb, sizeof(cdb), data, data_size); -+ int ret = vs_run("inquiry", inquiry, -+ vdev, &cdb, sizeof(cdb), data, data_size); - -- return virtio_scsi_response_ok(&resp); -+ return ret ? ret : virtio_scsi_response_ok(&resp); - } - --static bool scsi_test_unit_ready(VDev *vdev) -+static int scsi_test_unit_ready(VDev *vdev) - { - ScsiCdbTestUnitReady cdb = { - .command = 0x00, -@@ -131,7 +141,7 @@ static bool scsi_test_unit_ready(VDev *vdev) - return virtio_scsi_response_ok(&resp); - } - --static bool scsi_report_luns(VDev *vdev, void *data, uint32_t data_size) -+static int scsi_report_luns(VDev *vdev, void *data, uint32_t data_size) - { - ScsiCdbReportLuns cdb = { - .command = 0xa0, -@@ -144,13 +154,13 @@ static bool scsi_report_luns(VDev *vdev, void *data, uint32_t data_size) - { data, data_size, VRING_DESC_F_WRITE }, - }; - -- vs_run("report luns", report_luns, -+ int ret = vs_run("report luns", report_luns, - vdev, &cdb, sizeof(cdb), data, data_size); - -- return virtio_scsi_response_ok(&resp); -+ return ret ? ret : virtio_scsi_response_ok(&resp); - } - --static bool scsi_read_10(VDev *vdev, -+static int scsi_read_10(VDev *vdev, - unsigned long sector, int sectors, void *data, - unsigned int data_size) - { -@@ -168,12 +178,13 @@ static bool scsi_read_10(VDev *vdev, - debug_print_int("read_10 sector", sector); - debug_print_int("read_10 sectors", sectors); - -- vs_run("read(10)", read_10, vdev, &cdb, sizeof(cdb), data, data_size); -+ int ret = vs_run("read(10)", read_10, -+ vdev, &cdb, sizeof(cdb), data, data_size); - -- return virtio_scsi_response_ok(&resp); -+ return ret ? ret : virtio_scsi_response_ok(&resp); - } - --static bool scsi_read_capacity(VDev *vdev, -+static int scsi_read_capacity(VDev *vdev, - void *data, uint32_t data_size) - { - ScsiCdbReadCapacity16 cdb = { -@@ -187,10 +198,10 @@ static bool scsi_read_capacity(VDev *vdev, - { data, data_size, VRING_DESC_F_WRITE }, - }; - -- vs_run("read capacity", read_capacity_16, -+ int ret = vs_run("read capacity", read_capacity_16, - vdev, &cdb, sizeof(cdb), data, data_size); - -- return virtio_scsi_response_ok(&resp); -+ return ret ? ret : virtio_scsi_response_ok(&resp); - } - - /* virtio-scsi routines */ -@@ -207,7 +218,7 @@ static int virtio_scsi_locate_device(VDev *vdev) - static uint8_t data[16 + 8 * 63]; - ScsiLunReport *r = (void *) data; - ScsiDevice *sdev = vdev->scsi_device; -- int i, luns; -+ int i, ret, luns; - - /* QEMU has hardcoded channel #0 in many places. - * If this hardcoded value is ever changed, we'll need to add code for -@@ -233,13 +244,21 @@ static int virtio_scsi_locate_device(VDev *vdev) - sdev->channel = channel; - sdev->target = target; - sdev->lun = 0; /* LUN has to be 0 for REPORT LUNS */ -- if (!scsi_report_luns(vdev, data, sizeof(data))) { -+ ret = scsi_report_luns(vdev, data, sizeof(data)); -+ if (ret < 0) { -+ return ret; -+ } -+ -+ else if (ret == 0) { - if (resp.response == VIRTIO_SCSI_S_BAD_TARGET) { - continue; - } - printf("target 0x%X\n", target); -- virtio_scsi_verify_response(&resp, "SCSI cannot report LUNs"); -+ if (!virtio_scsi_verify_response(&resp, "SCSI cannot report LUNs")) { -+ return -EIO; -+ } - } -+ - if (r->lun_list_len == 0) { - printf("no LUNs for target 0x%X\n", target); - continue; -@@ -283,7 +302,9 @@ int virtio_scsi_read_many(VDev *vdev, - data_size = sector_count * virtio_get_block_size() * f; - if (!scsi_read_10(vdev, sector * f, sector_count * f, load_addr, - data_size)) { -- virtio_scsi_verify_response(&resp, "virtio-scsi:read_many"); -+ if (!virtio_scsi_verify_response(&resp, "virtio-scsi:read_many")) { -+ return -1; -+ } - } - load_addr += data_size; - sector += sector_count; -@@ -352,11 +373,16 @@ static int virtio_scsi_setup(VDev *vdev) - uint8_t code = resp.sense[0] & SCSI_SENSE_CODE_MASK; - uint8_t sense_key = resp.sense[2] & SCSI_SENSE_KEY_MASK; - -- IPL_assert(resp.sense_len != 0, "virtio-scsi:setup: no SENSE data"); -+ if (resp.sense_len == 0) { -+ puts("virtio-scsi: setup: no SENSE data"); -+ return -EINVAL; -+ } - -- IPL_assert(retry_test_unit_ready && code == 0x70 && -- sense_key == SCSI_SENSE_KEY_UNIT_ATTENTION, -- "virtio-scsi:setup: cannot retry"); -+ if (!retry_test_unit_ready || code != 0x70 || -+ sense_key != SCSI_SENSE_KEY_UNIT_ATTENTION) { -+ puts("virtio-scsi:setup: cannot retry"); -+ return -EIO; -+ } - - /* retry on CHECK_CONDITION/UNIT_ATTENTION as it - * may not designate a real error, but it may be -@@ -367,16 +393,22 @@ static int virtio_scsi_setup(VDev *vdev) - continue; - } - -- virtio_scsi_verify_response(&resp, "virtio-scsi:setup"); -+ if (!virtio_scsi_verify_response(&resp, "virtio-scsi:setup")) { -+ return -1; -+ } - } - - /* read and cache SCSI INQUIRY response */ -- if (!scsi_inquiry(vdev, -+ ret = scsi_inquiry(vdev, - SCSI_INQUIRY_STANDARD, - SCSI_INQUIRY_STANDARD_NONE, - scsi_inquiry_std_response, -- sizeof(scsi_inquiry_std_response))) { -- virtio_scsi_verify_response(&resp, "virtio-scsi:setup:inquiry"); -+ sizeof(scsi_inquiry_std_response)); -+ if (ret < 1) { -+ if (ret != 0 || !virtio_scsi_verify_response(&resp, -+ "virtio-scsi:setup:inquiry")) { -+ return -1; -+ } - } - - if (virtio_scsi_inquiry_response_is_cdrom(scsi_inquiry_std_response)) { -@@ -385,12 +417,16 @@ static int virtio_scsi_setup(VDev *vdev) - vdev->scsi_block_size = VIRTIO_ISO_BLOCK_SIZE; - } - -- if (!scsi_inquiry(vdev, -+ ret = scsi_inquiry(vdev, - SCSI_INQUIRY_EVPD, - SCSI_INQUIRY_EVPD_SUPPORTED_PAGES, - evpd, -- sizeof(*evpd))) { -- virtio_scsi_verify_response(&resp, "virtio-scsi:setup:supported_pages"); -+ sizeof(*evpd)); -+ if (ret < 1) { -+ if (ret != 0 || !virtio_scsi_verify_response(&resp, -+ "virtio-scsi:setup:supported_pages")) { -+ return -1; -+ } - } - - debug_print_int("EVPD length", evpd->page_length); -@@ -402,12 +438,16 @@ static int virtio_scsi_setup(VDev *vdev) - continue; - } - -- if (!scsi_inquiry(vdev, -+ ret = scsi_inquiry(vdev, - SCSI_INQUIRY_EVPD, - SCSI_INQUIRY_EVPD_BLOCK_LIMITS, - evpd_bl, -- sizeof(*evpd_bl))) { -- virtio_scsi_verify_response(&resp, "virtio-scsi:setup:blocklimits"); -+ sizeof(*evpd_bl)); -+ if (ret < 1) { -+ if (ret != 0 || !virtio_scsi_verify_response(&resp, -+ "virtio-scsi:setup:blocklimits")) { -+ return -1; -+ } - } - - debug_print_int("max transfer", evpd_bl->max_transfer); -@@ -423,8 +463,12 @@ static int virtio_scsi_setup(VDev *vdev) - vdev->max_transfer = MIN_NON_ZERO(VIRTIO_SCSI_MAX_SECTORS, - vdev->max_transfer); - -- if (!scsi_read_capacity(vdev, data, data_size)) { -- virtio_scsi_verify_response(&resp, "virtio-scsi:setup:read_capacity"); -+ ret = scsi_read_capacity(vdev, data, data_size); -+ if (ret < 1) { -+ if (ret != 0 || !virtio_scsi_verify_response(&resp, -+ "virtio-scsi:setup:read_capacity")) { -+ return -1; -+ } - } - scsi_parse_capacity_report(data, &vdev->scsi_last_block, - (uint32_t *) &vdev->scsi_block_size); -@@ -439,10 +483,15 @@ int virtio_scsi_setup_device(SubChannelId schid) - vdev->schid = schid; - virtio_setup_ccw(vdev); - -- IPL_assert(vdev->config.scsi.sense_size == VIRTIO_SCSI_SENSE_SIZE, -- "Config: sense size mismatch"); -- IPL_assert(vdev->config.scsi.cdb_size == VIRTIO_SCSI_CDB_SIZE, -- "Config: CDB size mismatch"); -+ if (vdev->config.scsi.sense_size != VIRTIO_SCSI_SENSE_SIZE) { -+ puts("Config: sense size mismatch"); -+ return -EINVAL; -+ } -+ -+ if (vdev->config.scsi.cdb_size != VIRTIO_SCSI_CDB_SIZE) { -+ puts("Config: CDB size mismatch"); -+ return -EINVAL; -+ } - - puts("Using virtio-scsi."); - --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch b/kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch deleted file mode 100644 index 9d14f0c..0000000 --- a/kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch +++ /dev/null @@ -1,1208 +0,0 @@ -From 736819e0c108bdd8bcb75e28c24ff97c2411d85c Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:36 -0400 -Subject: [PATCH 03/38] pc-bios/s390-ccw: Use the libc from SLOF and remove - sclp prints -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [2/23] cfb15217ddbad8b3ae9606763ff1e1085807d381 (thuth/qemu-kvm-cs9) - -We are already using the libc from SLOF for the s390-netboot.img, and -this libc implementation is way more complete and accurate than the -simple implementation that we currently use for the s390-ccw.img binary. -Since we are now always assuming that the SLOF submodule is available -when building the s390-ccw bios (see commit bf6903f6944f), we can drop -the simple implementation and use the SLOF libc for the s390-ccw.img -binary, too. - -Additionally replace sclp_print calls with puts/printf now that it is -available. - -Co-authored by: Thomas Huth -Signed-off-by: Jared Rossi -Message-ID: <20241020012953.1380075-3-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 9f4278837dc770266c8a026696dd91a525dd2682) ---- - pc-bios/s390-ccw/Makefile | 15 +++-- - pc-bios/s390-ccw/bootmap.c | 47 ++++++------- - pc-bios/s390-ccw/bootmap.h | 4 +- - pc-bios/s390-ccw/cio.c | 78 ++++++++++------------ - pc-bios/s390-ccw/dasd-ipl.c | 5 +- - pc-bios/s390-ccw/jump2ipl.c | 5 +- - pc-bios/s390-ccw/libc.c | 88 ------------------------ - pc-bios/s390-ccw/libc.h | 89 ------------------------- - pc-bios/s390-ccw/main.c | 14 ++-- - pc-bios/s390-ccw/menu.c | 51 +++++++------- - pc-bios/s390-ccw/netboot.mak | 3 - - pc-bios/s390-ccw/netmain.c | 10 +-- - pc-bios/s390-ccw/s390-ccw.h | 30 +++------ - pc-bios/s390-ccw/sclp.c | 7 +- - pc-bios/s390-ccw/virtio-blkdev.c | 6 +- - pc-bios/s390-ccw/virtio-scsi.c | 17 ++--- - pc-bios/s390-ccw/virtio.c | 2 +- - tests/tcg/s390x/Makefile.softmmu-target | 2 +- - tests/tcg/s390x/console.c | 3 + - 19 files changed, 140 insertions(+), 336 deletions(-) - delete mode 100644 pc-bios/s390-ccw/libc.c - delete mode 100644 pc-bios/s390-ccw/libc.h - -diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile -index 6207911b53..3f4232636e 100644 ---- a/pc-bios/s390-ccw/Makefile -+++ b/pc-bios/s390-ccw/Makefile -@@ -33,13 +33,18 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d - .PHONY : all clean build-all distclean - - OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \ -- virtio.o virtio-scsi.o virtio-blkdev.o libc.o cio.o dasd-ipl.o -+ virtio.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o -+ -+SLOF_DIR := $(SRC_PATH)/../../roms/SLOF -+ -+LIBC_INC := -nostdinc -I$(SLOF_DIR)/lib/libc/include - - EXTRA_CFLAGS += -Wall - EXTRA_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -fno-common -fPIE - EXTRA_CFLAGS += -fwrapv -fno-strict-aliasing -fno-asynchronous-unwind-tables - EXTRA_CFLAGS += -msoft-float - EXTRA_CFLAGS += -std=gnu99 -+EXTRA_CFLAGS += $(LIBC_INC) - LDFLAGS += -Wl,-pie -nostdlib -z noexecstack - - cc-test = $(CC) -Werror $1 -c -o /dev/null -xc /dev/null >/dev/null 2>/dev/null -@@ -55,18 +60,18 @@ config-cc.mak: Makefile - $(call cc-option,-march=z900,-march=z10)) 3> config-cc.mak - -include config-cc.mak - -+include $(SRC_PATH)/netboot.mak -+ - build-all: s390-ccw.img s390-netboot.img - --s390-ccw.elf: $(OBJECTS) -- $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $(OBJECTS),Linking) -+s390-ccw.elf: $(OBJECTS) libc.a -+ $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^,Linking) - - s390-ccw.img: s390-ccw.elf - $(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,Stripping $< into) - - $(OBJECTS): Makefile - --include $(SRC_PATH)/netboot.mak -- - ALL_OBJS = $(sort $(OBJECTS) $(NETOBJS) $(LIBCOBJS) $(LIBNETOBJS)) - -include $(ALL_OBJS:%.o=%.d) - -diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c -index a2137449dc..3cc79706be 100644 ---- a/pc-bios/s390-ccw/bootmap.c -+++ b/pc-bios/s390-ccw/bootmap.c -@@ -8,7 +8,8 @@ - * directory. - */ - --#include "libc.h" -+#include -+#include - #include "s390-ccw.h" - #include "s390-arch.h" - #include "bootmap.h" -@@ -21,7 +22,7 @@ - - #ifdef DEBUG_FALLBACK - #define dputs(txt) \ -- do { sclp_print("zipl: " txt); } while (0) -+ do { printf("zipl: " txt); } while (0) - #else - #define dputs(fmt, ...) \ - do { } while (0) -@@ -270,7 +271,7 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr) - prev_block_nr = cur_block_nr; - } - -- sclp_print("No zipl boot menu data found. Booting default entry."); -+ printf("No zipl boot menu data found. Booting default entry."); - return 0; - } - -@@ -338,22 +339,22 @@ static void ipl_eckd_cdl(void) - block_number_t bmt_block_nr, s1b_block_nr; - - /* we have just read the block #0 and recognized it as "IPL1" */ -- sclp_print("CDL\n"); -+ puts("CDL"); - - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); - read_block(1, ipl2, "Cannot read IPL2 record at block 1"); - - mbr = &ipl2->mbr; - if (!magic_match(mbr, ZIPL_MAGIC)) { -- sclp_print("No zIPL section in IPL2 record.\n"); -+ puts("No zIPL section in IPL2 record."); - return; - } - if (!block_size_ok(mbr->blockptr.xeckd.bptr.size)) { -- sclp_print("Bad block size in zIPL section of IPL2 record.\n"); -+ puts("Bad block size in zIPL section of IPL2 record."); - return; - } - if (mbr->dev_type != DEV_TYPE_ECKD) { -- sclp_print("Non-ECKD device type in zIPL section of IPL2 record.\n"); -+ puts("Non-ECKD device type in zIPL section of IPL2 record."); - return; - } - -@@ -366,11 +367,11 @@ static void ipl_eckd_cdl(void) - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); - read_block(2, vlbl, "Cannot read Volume Label at block 2"); - if (!magic_match(vlbl->key, VOL1_MAGIC)) { -- sclp_print("Invalid magic of volume label block.\n"); -+ puts("Invalid magic of volume label block."); - return; - } - if (!magic_match(vlbl->f.key, VOL1_MAGIC)) { -- sclp_print("Invalid magic of volser block.\n"); -+ puts("Invalid magic of volser block."); - return; - } - print_volser(vlbl->f.volser); -@@ -384,8 +385,8 @@ static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode) - LDL_VTOC *vlbl = (void *)sec; /* already read, 3rd block */ - char msg[4] = { '?', '.', '\n', '\0' }; - -- sclp_print((mode == ECKD_CMS) ? "CMS" : "LDL"); -- sclp_print(" version "); -+ printf((mode == ECKD_CMS) ? "CMS" : "LDL"); -+ printf(" version "); - switch (vlbl->LDL_version) { - case LDL1_VERSION: - msg[0] = '1'; -@@ -398,7 +399,7 @@ static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode) - msg[1] = '?'; - break; - } -- sclp_print(msg); -+ printf("%s", msg); - print_volser(vlbl->volser); - } - -@@ -419,7 +420,7 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) - if (!magic_match(ipl1->bip.magic, ZIPL_MAGIC)) { - return; /* not applicable layout */ - } -- sclp_print("unlabeled LDL.\n"); -+ puts("unlabeled LDL."); - } - verify_boot_info(&ipl1->bip); - -@@ -466,7 +467,7 @@ static void print_eckd_msg(void) - *p-- = ' '; - } - } -- sclp_print(msg); -+ printf("%s", msg); - } - - static void ipl_eckd(void) -@@ -488,11 +489,11 @@ static void ipl_eckd(void) - if (eckd_valid_address((ExtEckdBlockPtr *)&vlbl->f.br, 0)) { - ldipl_bmt = eckd_find_bmt((ExtEckdBlockPtr *)&vlbl->f.br); - if (ldipl_bmt) { -- sclp_print("List-Directed\n"); -+ puts("List-Directed"); - /* LD-IPL does not use the S1B bock, just make it NULL */ - run_eckd_boot_script(ldipl_bmt, NULL_BLOCK_NR); - /* Only return in error, retry as CCW-IPL */ -- sclp_print("Retrying IPL "); -+ printf("Retrying IPL "); - print_eckd_msg(); - } - memset(sec, FREE_SPACE_FILLER, sizeof(sec)); -@@ -634,7 +635,7 @@ static void ipl_scsi(void) - return; - } - -- sclp_print("Using SCSI scheme.\n"); -+ puts("Using SCSI scheme."); - debug_print_int("MBR Version", mbr->version_id); - IPL_check(mbr->version_id == 1, - "Unknown MBR layout version, assuming version 1"); -@@ -743,7 +744,7 @@ static inline uint32_t iso_get_file_size(uint32_t load_rba) - if (cur_record->file_flags & 0x2) { - /* Subdirectory */ - if (level == ISO9660_MAX_DIR_DEPTH - 1) { -- sclp_print("ISO-9660 directory depth limit exceeded\n"); -+ puts("ISO-9660 directory depth limit exceeded"); - } else { - level++; - sec_loc[level] = iso_733_to_u32(cur_record->ext_loc); -@@ -778,9 +779,9 @@ static void load_iso_bc_entry(IsoBcSection *load) - if (real_size) { - /* Round up blocks to load */ - blks_to_load = (real_size + ISO_SECTOR_SIZE - 1) / ISO_SECTOR_SIZE; -- sclp_print("ISO boot image size verified\n"); -+ puts("ISO boot image size verified"); - } else { -- sclp_print("ISO boot image size could not be verified\n"); -+ puts("ISO boot image size could not be verified"); - } - - read_iso_boot_image(bswap32(s.load_rba), -@@ -896,7 +897,7 @@ static void zipl_load_vblk(void) - } - - if (blksize != VIRTIO_DASD_DEFAULT_BLOCK_SIZE) { -- sclp_print("Using guessed DASD geometry.\n"); -+ puts("Using guessed DASD geometry."); - virtio_assume_eckd(); - } - ipl_eckd(); -@@ -909,7 +910,7 @@ static void zipl_load_vscsi(void) - ipl_iso_el_torito(); - } - -- sclp_print("Using guessed DASD geometry.\n"); -+ puts("Using guessed DASD geometry."); - virtio_assume_eckd(); - ipl_eckd(); - } -@@ -944,5 +945,5 @@ void zipl_load(void) - panic("\n! Unknown IPL device type !\n"); - } - -- sclp_print("zIPL load failed.\n"); -+ puts("zIPL load failed."); - } -diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h -index d4690a88c2..4a7d8a91f1 100644 ---- a/pc-bios/s390-ccw/bootmap.h -+++ b/pc-bios/s390-ccw/bootmap.h -@@ -336,9 +336,7 @@ static inline void print_volser(const void *volser) - - ebcdic_to_ascii((char *)volser, ascii, 6); - ascii[6] = '\0'; -- sclp_print("VOLSER=["); -- sclp_print(ascii); -- sclp_print("]\n"); -+ printf("VOLSER=[%s]\n", ascii); - } - - static inline bool unused_space(const void *p, size_t size) -diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c -index 83ca27ab41..7b09a38c96 100644 ---- a/pc-bios/s390-ccw/cio.c -+++ b/pc-bios/s390-ccw/cio.c -@@ -11,7 +11,8 @@ - * directory. - */ - --#include "libc.h" -+#include -+#include - #include "s390-ccw.h" - #include "s390-arch.h" - #include "helper.h" -@@ -90,9 +91,9 @@ static void print_eckd_dasd_sense_data(SenseDataEckdDasd *sd) - char msgline[512]; - - if (sd->config_info & 0x8000) { -- sclp_print("Eckd Dasd Sense Data (fmt 24-bytes):\n"); -+ puts("Eckd Dasd Sense Data (fmt 24-bytes):"); - } else { -- sclp_print("Eckd Dasd Sense Data (fmt 32-bytes):\n"); -+ puts("Eckd Dasd Sense Data (fmt 32-bytes):"); - } - - strcat(msgline, " Sense Condition Flags :"); -@@ -158,22 +159,21 @@ static void print_eckd_dasd_sense_data(SenseDataEckdDasd *sd) - if (sd->status[1] & SNS_STAT2_IMPRECISE_END) { - strcat(msgline, " [Imprecise-End]"); - } -- strcat(msgline, "\n"); -- sclp_print(msgline); -- -- print_int(" Residual Count =", sd->res_count); -- print_int(" Phys Drive ID =", sd->phys_drive_id); -- print_int(" low cyl address =", sd->low_cyl_addr); -- print_int(" head addr & hi cyl =", sd->head_high_cyl_addr); -- print_int(" format/message =", sd->fmt_msg); -- print_int(" fmt-dependent[0-7] =", sd->fmt_dependent_info[0]); -- print_int(" fmt-dependent[8-15]=", sd->fmt_dependent_info[1]); -- print_int(" prog action code =", sd->program_action_code); -- print_int(" Configuration info =", sd->config_info); -- print_int(" mcode / hi-cyl =", sd->mcode_hicyl); -- print_int(" cyl & head addr [0]=", sd->cyl_head_addr[0]); -- print_int(" cyl & head addr [1]=", sd->cyl_head_addr[1]); -- print_int(" cyl & head addr [2]=", sd->cyl_head_addr[2]); -+ puts(msgline); -+ -+ printf(" Residual Count = 0x%X\n", sd->res_count); -+ printf(" Phys Drive ID = 0x%X\n", sd->phys_drive_id); -+ printf(" low cyl address = 0x%X\n", sd->low_cyl_addr); -+ printf(" head addr & hi cyl = 0x%X\n", sd->head_high_cyl_addr); -+ printf(" format/message = 0x%X\n", sd->fmt_msg); -+ printf(" fmt-dependent[0-7] = 0x%llX\n", sd->fmt_dependent_info[0]); -+ printf(" fmt-dependent[8-15]= 0x%llX\n", sd->fmt_dependent_info[1]); -+ printf(" prog action code = 0x%X\n", sd->program_action_code); -+ printf(" Configuration info = 0x%X\n", sd->config_info); -+ printf(" mcode / hi-cyl = 0x%X\n", sd->mcode_hicyl); -+ printf(" cyl & head addr [0]= 0x%X\n", sd->cyl_head_addr[0]); -+ printf(" cyl & head addr [1]= 0x%X\n", sd->cyl_head_addr[1]); -+ printf(" cyl & head addr [2]= 0x%X\n", sd->cyl_head_addr[2]); - } - - static void print_irb_err(Irb *irb) -@@ -182,7 +182,7 @@ static void print_irb_err(Irb *irb) - uint64_t prev_ccw = *(uint64_t *)u32toptr(irb->scsw.cpa - 8); - char msgline[256]; - -- sclp_print("Interrupt Response Block Data:\n"); -+ puts("Interrupt Response Block Data:"); - - strcat(msgline, " Function Ctrl :"); - if (irb->scsw.ctrl & SCSW_FCTL_START_FUNC) { -@@ -194,8 +194,7 @@ static void print_irb_err(Irb *irb) - if (irb->scsw.ctrl & SCSW_FCTL_CLEAR_FUNC) { - strcat(msgline, " [Clear]"); - } -- strcat(msgline, "\n"); -- sclp_print(msgline); -+ puts(msgline); - - msgline[0] = '\0'; - strcat(msgline, " Activity Ctrl :"); -@@ -220,8 +219,7 @@ static void print_irb_err(Irb *irb) - if (irb->scsw.ctrl & SCSW_ACTL_SUSPENDED) { - strcat(msgline, " [Suspended]"); - } -- strcat(msgline, "\n"); -- sclp_print(msgline); -+ puts(msgline); - - msgline[0] = '\0'; - strcat(msgline, " Status Ctrl :"); -@@ -240,9 +238,7 @@ static void print_irb_err(Irb *irb) - if (irb->scsw.ctrl & SCSW_SCTL_STATUS_PEND) { - strcat(msgline, " [Status-Pending]"); - } -- -- strcat(msgline, "\n"); -- sclp_print(msgline); -+ puts(msgline); - - msgline[0] = '\0'; - strcat(msgline, " Device Status :"); -@@ -270,8 +266,7 @@ static void print_irb_err(Irb *irb) - if (irb->scsw.dstat & SCSW_DSTAT_UEXCP) { - strcat(msgline, " [Unit-Exception]"); - } -- strcat(msgline, "\n"); -- sclp_print(msgline); -+ puts(msgline); - - msgline[0] = '\0'; - strcat(msgline, " Channel Status :"); -@@ -299,12 +294,11 @@ static void print_irb_err(Irb *irb) - if (irb->scsw.cstat & SCSW_CSTAT_CHAINCHK) { - strcat(msgline, " [Chaining-Check]"); - } -- strcat(msgline, "\n"); -- sclp_print(msgline); -+ puts(msgline); - -- print_int(" cpa=", irb->scsw.cpa); -- print_int(" prev_ccw=", prev_ccw); -- print_int(" this_ccw=", this_ccw); -+ printf(" cpa= 0x%X\n", irb->scsw.cpa); -+ printf(" prev_ccw= 0x%llX\n", prev_ccw); -+ printf(" this_ccw= 0x%llX\n", this_ccw); - } - - /* -@@ -341,7 +335,7 @@ static int __do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt, Irb *irb) - return -1; - } - if (rc) { -- print_int("ssch failed with cc=", rc); -+ printf("ssch failed with cc= 0x%x\n", rc); - return rc; - } - -@@ -350,7 +344,7 @@ static int __do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt, Irb *irb) - /* collect status */ - rc = tsch(schid, irb); - if (rc) { -- print_int("tsch failed with cc=", rc); -+ printf("tsch failed with cc= 0x%X\n", rc); - } - - return rc; -@@ -406,12 +400,12 @@ int do_cio(SubChannelId schid, uint16_t cutype, uint32_t ccw_addr, int fmt) - continue; - } - -- sclp_print("cio device error\n"); -- print_int(" ssid ", schid.ssid); -- print_int(" cssid ", schid.cssid); -- print_int(" sch_no", schid.sch_no); -- print_int(" ctrl-unit type", cutype); -- sclp_print("\n"); -+ printf("cio device error\n"); -+ printf(" ssid 0x%X\n", schid.ssid); -+ printf(" cssid 0x%X\n", schid.cssid); -+ printf(" sch_no 0x%X\n", schid.sch_no); -+ printf(" ctrl-unit type 0x%X\n", cutype); -+ printf("\n"); - print_irb_err(&irb); - if (cutype == CU_TYPE_DASD_3990 || cutype == CU_TYPE_DASD_2107 || - cutype == CU_TYPE_UNKNOWN) { -diff --git a/pc-bios/s390-ccw/dasd-ipl.c b/pc-bios/s390-ccw/dasd-ipl.c -index 254bb1a15e..ae751adec1 100644 ---- a/pc-bios/s390-ccw/dasd-ipl.c -+++ b/pc-bios/s390-ccw/dasd-ipl.c -@@ -8,7 +8,8 @@ - * directory. - */ - --#include "libc.h" -+#include -+#include - #include "s390-ccw.h" - #include "s390-arch.h" - #include "dasd-ipl.h" -@@ -82,7 +83,7 @@ static int run_dynamic_ccw_program(SubChannelId schid, uint16_t cutype, - do { - has_next = dynamic_cp_fixup(cpa, &next_cpa); - -- print_int("executing ccw chain at ", cpa); -+ printf("executing ccw chain at 0x%X\n", cpa); - enable_prefixing(); - rc = do_cio(schid, cutype, cpa, CCW_FMT0); - disable_prefixing(); -diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c -index 78f5f46533..80b7f6a1f3 100644 ---- a/pc-bios/s390-ccw/jump2ipl.c -+++ b/pc-bios/s390-ccw/jump2ipl.c -@@ -6,7 +6,8 @@ - * directory. - */ - --#include "libc.h" -+#include -+#include - #include "s390-ccw.h" - #include "s390-arch.h" - -@@ -57,7 +58,7 @@ void jump_to_IPL_code(uint64_t address) - debug_print_int("set IPL addr to", address ?: *reset_psw & PSW_MASK_SHORT_ADDR); - - /* Ensure the guest output starts fresh */ -- sclp_print("\n"); -+ printf("\n"); - - /* - * HACK ALERT. -diff --git a/pc-bios/s390-ccw/libc.c b/pc-bios/s390-ccw/libc.c -deleted file mode 100644 -index 3187923950..0000000000 ---- a/pc-bios/s390-ccw/libc.c -+++ /dev/null -@@ -1,88 +0,0 @@ --/* -- * libc-style definitions and functions -- * -- * Copyright 2018 IBM Corp. -- * Author(s): Collin L. Walling -- * -- * This code is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License as published by the -- * Free Software Foundation; either version 2 of the License, or (at your -- * option) any later version. -- */ -- --#include "libc.h" --#include "s390-ccw.h" -- --/** -- * atoui: -- * @str: the string to be converted. -- * -- * Given a string @str, convert it to an integer. Leading spaces are -- * ignored. Any other non-numerical value will terminate the conversion -- * and return 0. This function only handles numbers between 0 and -- * UINT64_MAX inclusive. -- * -- * Returns: an integer converted from the string @str, or the number 0 -- * if an error occurred. -- */ --uint64_t atoui(const char *str) --{ -- int val = 0; -- -- if (!str || !str[0]) { -- return 0; -- } -- -- while (*str == ' ') { -- str++; -- } -- -- while (*str) { -- if (!isdigit(*(unsigned char *)str)) { -- break; -- } -- val = val * 10 + *str - '0'; -- str++; -- } -- -- return val; --} -- --/** -- * uitoa: -- * @num: an integer (base 10) to be converted. -- * @str: a pointer to a string to store the conversion. -- * @len: the length of the passed string. -- * -- * Given an integer @num, convert it to a string. The string @str must be -- * allocated beforehand. The resulting string will be null terminated and -- * returned. This function only handles numbers between 0 and UINT64_MAX -- * inclusive. -- * -- * Returns: the string @str of the converted integer @num -- */ --char *uitoa(uint64_t num, char *str, size_t len) --{ -- long num_idx = 1; /* account for NUL */ -- uint64_t tmp = num; -- -- IPL_assert(str != NULL, "uitoa: no space allocated to store string"); -- -- /* Count indices of num */ -- while ((tmp /= 10) != 0) { -- num_idx++; -- } -- -- /* Check if we have enough space for num and NUL */ -- IPL_assert(len > num_idx, "uitoa: array too small for conversion"); -- -- str[num_idx--] = '\0'; -- -- /* Convert int to string */ -- while (num_idx >= 0) { -- str[num_idx--] = num % 10 + '0'; -- num /= 10; -- } -- -- return str; --} -diff --git a/pc-bios/s390-ccw/libc.h b/pc-bios/s390-ccw/libc.h -deleted file mode 100644 -index bcdc45732d..0000000000 ---- a/pc-bios/s390-ccw/libc.h -+++ /dev/null -@@ -1,89 +0,0 @@ --/* -- * libc-style definitions and functions -- * -- * Copyright (c) 2013 Alexander Graf -- * -- * This code is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License as published by the -- * Free Software Foundation; either version 2 of the License, or (at your -- * option) any later version. -- */ -- --#ifndef S390_CCW_LIBC_H --#define S390_CCW_LIBC_H -- --typedef unsigned long size_t; --typedef int bool; --typedef unsigned char uint8_t; --typedef unsigned short uint16_t; --typedef unsigned int uint32_t; --typedef unsigned long long uint64_t; -- --static inline void *memset(void *s, int c, size_t n) --{ -- size_t i; -- unsigned char *p = s; -- -- for (i = 0; i < n; i++) { -- p[i] = c; -- } -- -- return s; --} -- --static inline void *memcpy(void *s1, const void *s2, size_t n) --{ -- uint8_t *dest = s1; -- const uint8_t *src = s2; -- size_t i; -- -- for (i = 0; i < n; i++) { -- dest[i] = src[i]; -- } -- -- return s1; --} -- --static inline int memcmp(const void *s1, const void *s2, size_t n) --{ -- size_t i; -- const uint8_t *p1 = s1, *p2 = s2; -- -- for (i = 0; i < n; i++) { -- if (p1[i] != p2[i]) { -- return p1[i] > p2[i] ? 1 : -1; -- } -- } -- -- return 0; --} -- --static inline size_t strlen(const char *str) --{ -- size_t i; -- for (i = 0; *str; i++) { -- str++; -- } -- return i; --} -- --static inline char *strcat(char *dest, const char *src) --{ -- int i; -- char *dest_end = dest + strlen(dest); -- -- for (i = 0; i <= strlen(src); i++) { -- dest_end[i] = src[i]; -- } -- return dest; --} -- --static inline int isdigit(int c) --{ -- return (c >= '0') && (c <= '9'); --} -- --uint64_t atoui(const char *str); --char *uitoa(uint64_t num, char *str, size_t len); -- --#endif -diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c -index 5506798098..203df20965 100644 ---- a/pc-bios/s390-ccw/main.c -+++ b/pc-bios/s390-ccw/main.c -@@ -8,7 +8,9 @@ - * directory. - */ - --#include "libc.h" -+#include -+#include -+#include - #include "helper.h" - #include "s390-arch.h" - #include "s390-ccw.h" -@@ -50,7 +52,7 @@ void write_iplb_location(void) - - unsigned int get_loadparm_index(void) - { -- return atoui(loadparm_str); -+ return atoi(loadparm_str); - } - - static int is_dev_possibly_bootable(int dev_no, int sch_no) -@@ -176,7 +178,7 @@ static void boot_setup(void) - - sclp_get_loadparm_ascii(loadparm_str); - memcpy(lpmsg + 10, loadparm_str, 8); -- sclp_print(lpmsg); -+ puts(lpmsg); - - /* - * Clear out any potential S390EP magic (see jump_to_low_kernel()), -@@ -228,7 +230,7 @@ static int virtio_setup(void) - - switch (vdev->senseid.cu_model) { - case VIRTIO_ID_NET: -- sclp_print("Network boot device detected\n"); -+ puts("Network boot device detected"); - vdev->netboot_start_addr = qipl.netboot_start_addr; - return 0; - case VIRTIO_ID_BLOCK: -@@ -261,7 +263,7 @@ static void ipl_boot_device(void) - } - break; - default: -- print_int("Attempting to boot from unexpected device type", cutype); -+ printf("Attempting to boot from unexpected device type 0x%X\n", cutype); - panic("\nBoot failed.\n"); - } - } -@@ -287,7 +289,7 @@ static void probe_boot_device(void) - } - } - -- sclp_print("Could not find a suitable boot device (none specified)\n"); -+ puts("Could not find a suitable boot device (none specified)"); - } - - void main(void) -diff --git a/pc-bios/s390-ccw/menu.c b/pc-bios/s390-ccw/menu.c -index d601952d3e..84062e94af 100644 ---- a/pc-bios/s390-ccw/menu.c -+++ b/pc-bios/s390-ccw/menu.c -@@ -9,7 +9,10 @@ - * directory. - */ - --#include "libc.h" -+#include -+#include -+#include -+#include - #include "s390-ccw.h" - #include "sclp.h" - #include "s390-time.h" -@@ -93,7 +96,7 @@ static int read_prompt(char *buf, size_t len) - case KEYCODE_BACKSP: - if (idx > 0) { - buf[--idx] = 0; -- sclp_print("\b \b"); -+ printf("\b \b"); - } - continue; - case KEYCODE_ENTER: -@@ -103,7 +106,7 @@ static int read_prompt(char *buf, size_t len) - /* Echo input and add to buffer */ - if (idx < len) { - buf[idx++] = inp[0]; -- sclp_print(inp); -+ printf("%s", inp); - } - } - } -@@ -140,22 +143,19 @@ static int get_index(void) - } - } - -- return atoui(buf); -+ return atoi(buf); - } - - static void boot_menu_prompt(bool retry) - { -- char tmp[11]; -- - if (retry) { -- sclp_print("\nError: undefined configuration" -+ printf("\nError: undefined configuration" - "\nPlease choose:\n"); - } else if (timeout > 0) { -- sclp_print("Please choose (default will boot in "); -- sclp_print(uitoa(timeout / 1000, tmp, sizeof(tmp))); -- sclp_print(" seconds):\n"); -+ printf("Please choose (default will boot in %d seconds):\n", -+ (int)(timeout / 1000)); - } else { -- sclp_print("Please choose:\n"); -+ puts("Please choose:"); - } - } - -@@ -163,7 +163,6 @@ static int get_boot_index(bool *valid_entries) - { - int boot_index; - bool retry = false; -- char tmp[5]; - - do { - boot_menu_prompt(retry); -@@ -172,8 +171,7 @@ static int get_boot_index(bool *valid_entries) - } while (boot_index < 0 || boot_index >= MAX_BOOT_ENTRIES || - !valid_entries[boot_index]); - -- sclp_print("\nBooting entry #"); -- sclp_print(uitoa(boot_index, tmp, sizeof(tmp))); -+ printf("\nBooting entry #%d", boot_index); - - return boot_index; - } -@@ -187,9 +185,9 @@ static int zipl_print_entry(const char *data, size_t len) - buf[len] = '\n'; - buf[len + 1] = '\0'; - -- sclp_print(buf); -+ printf("%s", buf); - -- return buf[0] == ' ' ? atoui(buf + 1) : atoui(buf); -+ return buf[0] == ' ' ? atoi(buf + 1) : atoi(buf); - } - - int menu_get_zipl_boot_index(const char *menu_data) -@@ -209,7 +207,7 @@ int menu_get_zipl_boot_index(const char *menu_data) - } - - /* Print banner */ -- sclp_print("s390-ccw zIPL Boot Menu\n\n"); -+ puts("s390-ccw zIPL Boot Menu\n"); - menu_data += strlen(menu_data) + 1; - - /* Print entries */ -@@ -221,37 +219,34 @@ int menu_get_zipl_boot_index(const char *menu_data) - valid_entries[entry] = true; - - if (entry == 0) { -- sclp_print("\n"); -+ printf("\n"); - } - } - -- sclp_print("\n"); -+ printf("\n"); - return get_boot_index(valid_entries); - } - - int menu_get_enum_boot_index(bool *valid_entries) - { -- char tmp[3]; - int i; - -- sclp_print("s390-ccw Enumerated Boot Menu.\n\n"); -+ puts("s390-ccw Enumerated Boot Menu.\n"); - - for (i = 0; i < MAX_BOOT_ENTRIES; i++) { - if (valid_entries[i]) { - if (i < 10) { -- sclp_print(" "); -+ printf(" "); - } -- sclp_print("["); -- sclp_print(uitoa(i, tmp, sizeof(tmp))); -- sclp_print("]"); -+ printf("[%d]", i); - if (i == 0) { -- sclp_print(" default\n"); -+ printf(" default\n"); - } -- sclp_print("\n"); -+ printf("\n"); - } - } - -- sclp_print("\n"); -+ printf("\n"); - return get_boot_index(valid_entries); - } - -diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak -index 046aa35587..d2b3d8ee74 100644 ---- a/pc-bios/s390-ccw/netboot.mak -+++ b/pc-bios/s390-ccw/netboot.mak -@@ -1,9 +1,6 @@ - --SLOF_DIR := $(SRC_PATH)/../../roms/SLOF -- - NETOBJS := start.o sclp.o cio.o virtio.o virtio-net.o jump2ipl.o netmain.o - --LIBC_INC := -nostdinc -I$(SLOF_DIR)/lib/libc/include - LIBNET_INC := -I$(SLOF_DIR)/lib/libnet - - NETLDFLAGS := $(LDFLAGS) -Wl,-Ttext=0x7800000 -diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c -index 5cd619b2d6..509119be15 100644 ---- a/pc-bios/s390-ccw/netmain.c -+++ b/pc-bios/s390-ccw/netmain.c -@@ -293,7 +293,7 @@ static int load_kernel_with_initrd(filename_ip_t *fn_ip, - printf("Loading pxelinux.cfg entry '%s'\n", entry->label); - - if (!entry->kernel) { -- printf("Kernel entry is missing!\n"); -+ puts("Kernel entry is missing!\n"); - return -1; - } - -@@ -515,13 +515,13 @@ void main(void) - int rc, fnlen; - - sclp_setup(); -- sclp_print("Network boot starting...\n"); -+ puts("Network boot starting..."); - - virtio_setup(); - - rc = net_init(&fn_ip); - if (rc) { -- panic("Network initialization failed. Halting.\n"); -+ panic("Network initialization failed. Halting."); - } - - fnlen = strlen(fn_ip.filename); -@@ -535,9 +535,9 @@ void main(void) - net_release(&fn_ip); - - if (rc > 0) { -- sclp_print("Network loading done, starting kernel...\n"); -+ puts("Network loading done, starting kernel..."); - jump_to_low_kernel(); - } - -- panic("Failed to load OS from network\n"); -+ panic("Failed to load OS from network."); - } -diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h -index c977a52b50..6f6d95d170 100644 ---- a/pc-bios/s390-ccw/s390-ccw.h -+++ b/pc-bios/s390-ccw/s390-ccw.h -@@ -13,6 +13,11 @@ - - /* #define DEBUG */ - -+#include -+#include -+#include -+#include -+ - typedef unsigned char u8; - typedef unsigned short u16; - typedef unsigned int u32; -@@ -26,9 +31,6 @@ typedef unsigned long long u64; - #define EBUSY 2 - #define ENODEV 3 - --#ifndef NULL --#define NULL 0 --#endif - #ifndef MIN - #define MIN(a, b) (((a) < (b)) ? (a) : (b)) - #endif -@@ -87,7 +89,7 @@ bool menu_is_enabled_enum(void); - __attribute__ ((__noreturn__)) - static inline void panic(const char *string) - { -- sclp_print(string); -+ printf("ERROR: %s\n ", string); - disabled_wait(); - } - -@@ -109,20 +111,10 @@ static inline void fill_hex_val(char *out, void *ptr, unsigned size) - } - } - --static inline void print_int(const char *desc, u64 addr) --{ -- char out[] = ": 0xffffffffffffffff\n"; -- -- fill_hex_val(&out[4], &addr, sizeof(addr)); -- -- sclp_print(desc); -- sclp_print(out); --} -- - static inline void debug_print_int(const char *desc, u64 addr) - { - #ifdef DEBUG -- print_int(desc, addr); -+ printf("%s 0x%X\n", desc, addr); - #endif - } - -@@ -147,18 +139,14 @@ static inline void debug_print_addr(const char *desc, void *p) - static inline void IPL_assert(bool term, const char *message) - { - if (!term) { -- sclp_print("\n! "); -- sclp_print(message); -- panic(" !\n"); /* no return */ -+ panic(message); /* no return */ - } - } - - static inline void IPL_check(bool term, const char *message) - { - if (!term) { -- sclp_print("\n! WARNING: "); -- sclp_print(message); -- sclp_print(" !\n"); -+ printf("WARNING: %s\n", message); - } - } - -diff --git a/pc-bios/s390-ccw/sclp.c b/pc-bios/s390-ccw/sclp.c -index 7251f9af4d..4a07de018d 100644 ---- a/pc-bios/s390-ccw/sclp.c -+++ b/pc-bios/s390-ccw/sclp.c -@@ -8,7 +8,7 @@ - * directory. - */ - --#include "libc.h" -+#include - #include "s390-ccw.h" - #include "sclp.h" - -@@ -101,11 +101,6 @@ long write(int fd, const void *str, size_t len) - return len; - } - --void sclp_print(const char *str) --{ -- write(1, str, strlen(str)); --} -- - void sclp_get_loadparm_ascii(char *loadparm) - { - -diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c -index a81207b52e..2666326801 100644 ---- a/pc-bios/s390-ccw/virtio-blkdev.c -+++ b/pc-bios/s390-ccw/virtio-blkdev.c -@@ -8,7 +8,7 @@ - * directory. - */ - --#include "libc.h" -+#include - #include "s390-ccw.h" - #include "virtio.h" - #include "virtio-scsi.h" -@@ -76,7 +76,7 @@ unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list - return -1; - } - -- sclp_print("."); -+ printf("."); - status = virtio_read_many(sec, (void *)addr, sec_num); - if (status) { - panic("I/O Error"); -@@ -230,7 +230,7 @@ int virtio_blk_setup_device(SubChannelId schid) - vdev->schid = schid; - virtio_setup_ccw(vdev); - -- sclp_print("Using virtio-blk.\n"); -+ puts("Using virtio-blk."); - - return 0; - } -diff --git a/pc-bios/s390-ccw/virtio-scsi.c b/pc-bios/s390-ccw/virtio-scsi.c -index d1a84b937c..6b4a1caf8a 100644 ---- a/pc-bios/s390-ccw/virtio-scsi.c -+++ b/pc-bios/s390-ccw/virtio-scsi.c -@@ -9,7 +9,8 @@ - * directory. - */ - --#include "libc.h" -+#include -+#include - #include "s390-ccw.h" - #include "virtio.h" - #include "scsi.h" -@@ -30,9 +31,9 @@ static inline void vs_assert(bool term, const char **msgs) - if (!term) { - int i = 0; - -- sclp_print("\n! "); -+ printf("\n! "); - while (msgs[i]) { -- sclp_print(msgs[i++]); -+ printf("%s", msgs[i++]); - } - panic(" !\n"); - } -@@ -236,11 +237,11 @@ static int virtio_scsi_locate_device(VDev *vdev) - if (resp.response == VIRTIO_SCSI_S_BAD_TARGET) { - continue; - } -- print_int("target", target); -+ printf("target 0x%X\n", target); - virtio_scsi_verify_response(&resp, "SCSI cannot report LUNs"); - } - if (r->lun_list_len == 0) { -- print_int("no LUNs for target", target); -+ printf("no LUNs for target 0x%X\n", target); - continue; - } - luns = r->lun_list_len / 8; -@@ -264,7 +265,7 @@ static int virtio_scsi_locate_device(VDev *vdev) - } - } - -- sclp_print("Warning: Could not locate a usable virtio-scsi device\n"); -+ puts("Warning: Could not locate a usable virtio-scsi device"); - return -ENODEV; - } - -@@ -379,7 +380,7 @@ static int virtio_scsi_setup(VDev *vdev) - } - - if (virtio_scsi_inquiry_response_is_cdrom(scsi_inquiry_std_response)) { -- sclp_print("SCSI CD-ROM detected.\n"); -+ puts("SCSI CD-ROM detected."); - vdev->is_cdrom = true; - vdev->scsi_block_size = VIRTIO_ISO_BLOCK_SIZE; - } -@@ -443,7 +444,7 @@ int virtio_scsi_setup_device(SubChannelId schid) - IPL_assert(vdev->config.scsi.cdb_size == VIRTIO_SCSI_CDB_SIZE, - "Config: CDB size mismatch"); - -- sclp_print("Using virtio-scsi.\n"); -+ puts("Using virtio-scsi."); - - return virtio_scsi_setup(vdev); - } -diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c -index 5edd058d88..8c6b0a8a92 100644 ---- a/pc-bios/s390-ccw/virtio.c -+++ b/pc-bios/s390-ccw/virtio.c -@@ -8,7 +8,7 @@ - * directory. - */ - --#include "libc.h" -+#include - #include "s390-ccw.h" - #include "cio.h" - #include "virtio.h" -diff --git a/tests/tcg/s390x/Makefile.softmmu-target b/tests/tcg/s390x/Makefile.softmmu-target -index f60f94b090..90964a2ccb 100644 ---- a/tests/tcg/s390x/Makefile.softmmu-target -+++ b/tests/tcg/s390x/Makefile.softmmu-target -@@ -2,7 +2,7 @@ S390X_SRC=$(SRC_PATH)/tests/tcg/s390x - VPATH+=$(S390X_SRC) - QEMU_OPTS+=-action panic=exit-failure -nographic $(EXTFLAGS) -kernel - LINK_SCRIPT=$(S390X_SRC)/softmmu.ld --CFLAGS+=-ggdb -O0 -+CFLAGS+=-ggdb -O0 -I$(SRC_PATH)/include/hw/s390x/ipl/ - LDFLAGS=-nostdlib -static - - %.o: %.S -diff --git a/tests/tcg/s390x/console.c b/tests/tcg/s390x/console.c -index d43ce3f44b..6c26f04949 100644 ---- a/tests/tcg/s390x/console.c -+++ b/tests/tcg/s390x/console.c -@@ -4,7 +4,10 @@ - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ -+ - #include "../../../pc-bios/s390-ccw/sclp.c" -+#include "../../../roms/SLOF/lib/libc/string/memset.c" -+#include "../../../roms/SLOF/lib/libc/string/memcpy.c" - - void __sys_outc(char c) - { --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-netmain-Fix-error-messages-with-reg.patch b/kvm-pc-bios-s390-ccw-netmain-Fix-error-messages-with-reg.patch deleted file mode 100644 index 9213f65..0000000 --- a/kvm-pc-bios-s390-ccw-netmain-Fix-error-messages-with-reg.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 3f7951b9a46772a1c942aed1fe87fc7461acb197 Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Thu, 16 Jan 2025 12:58:26 +0100 -Subject: [PATCH 5/6] pc-bios/s390-ccw/netmain: Fix error messages with regards - to the TFTP server -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 331: Fix boot problems when falling back from network to another boot device on s390x [RHEL10] -RH-Jira: RHEL-72717 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [4/4] 5b87d859a69ff0f399ba516a87c847a0f3942666 (thuth/qemu-kvm-cs) - -The code in net_init_ip() currently bails out early if "rc" is less -than 0, so the if-statements that check for negative "rc" codes to -print out some specific error messages with regards to the TFTP server -are never reached. Move them earlier to bring that dead code back to -life. - -Reviewed-by: Jared Rossi -Reviewed-by: Eric Farman -Tested-by: Jared Rossi -Message-ID: <20250116115826.192047-4-thuth@redhat.com> -Signed-off-by: Thomas Huth -(cherry picked from commit bbfa7f8558d5346b6884108ad50df3517fe17358) ---- - pc-bios/s390-ccw/netmain.c | 19 ++++++++----------- - 1 file changed, 8 insertions(+), 11 deletions(-) - -diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c -index 335ea9b63e..719a547ada 100644 ---- a/pc-bios/s390-ccw/netmain.c -+++ b/pc-bios/s390-ccw/netmain.c -@@ -168,6 +168,14 @@ static int net_init_ip(filename_ip_t *fn_ip) - if (fn_ip->ip_version == 4) { - set_ipv4_address(fn_ip->own_ip); - } -+ } else if (rc == -2) { -+ printf("ARP request to TFTP server (%d.%d.%d.%d) failed\n", -+ (fn_ip->server_ip >> 24) & 0xFF, (fn_ip->server_ip >> 16) & 0xFF, -+ (fn_ip->server_ip >> 8) & 0xFF, fn_ip->server_ip & 0xFF); -+ return -102; -+ } else if (rc == -4 || rc == -3) { -+ puts("Can't obtain TFTP server IP address"); -+ return -107; - } else { - puts("Could not get IP address"); - return -101; -@@ -183,17 +191,6 @@ static int net_init_ip(filename_ip_t *fn_ip) - printf(" Using IPv6 address: %s\n", ip6_str); - } - -- if (rc == -2) { -- printf("ARP request to TFTP server (%d.%d.%d.%d) failed\n", -- (fn_ip->server_ip >> 24) & 0xFF, (fn_ip->server_ip >> 16) & 0xFF, -- (fn_ip->server_ip >> 8) & 0xFF, fn_ip->server_ip & 0xFF); -- return -102; -- } -- if (rc == -4 || rc == -3) { -- puts("Can't obtain TFTP server IP address"); -- return -107; -- } -- - printf(" Using TFTP server: "); - if (fn_ip->ip_version == 4) { - printf("%d.%d.%d.%d\n", --- -2.39.3 - diff --git a/kvm-pc-bios-s390-ccw-virtio-Add-a-function-to-reset-a-vi.patch b/kvm-pc-bios-s390-ccw-virtio-Add-a-function-to-reset-a-vi.patch deleted file mode 100644 index 020e9d3..0000000 --- a/kvm-pc-bios-s390-ccw-virtio-Add-a-function-to-reset-a-vi.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 75a9cc1fb986e96ad5ee9df22daf93afb4624bd3 Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Thu, 16 Jan 2025 12:58:24 +0100 -Subject: [PATCH 3/6] pc-bios/s390-ccw/virtio: Add a function to reset a virtio - device -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 331: Fix boot problems when falling back from network to another boot device on s390x [RHEL10] -RH-Jira: RHEL-72717 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [2/4] 96435852a2dc8955f9deef6d82c7fac90ce90e96 (thuth/qemu-kvm-cs) - -To be able to properly silence a virtio device after using it, -we need a global function to reset the device. - -Reviewed-by: Jared Rossi -Reviewed-by: Eric Farman -Tested-by: Jared Rossi -Message-ID: <20250116115826.192047-2-thuth@redhat.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 3936d0556383829b8db9518aed8badfed6513953) ---- - pc-bios/s390-ccw/virtio.c | 7 ++++++- - pc-bios/s390-ccw/virtio.h | 1 + - 2 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c -index 8b5a370bb3..cd6c99c7e3 100644 ---- a/pc-bios/s390-ccw/virtio.c -+++ b/pc-bios/s390-ccw/virtio.c -@@ -217,6 +217,11 @@ int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd) - return 0; - } - -+int virtio_reset(VDev *vdev) -+{ -+ return run_ccw(vdev, CCW_CMD_VDEV_RESET, NULL, 0, false); -+} -+ - int virtio_setup_ccw(VDev *vdev) - { - int i, cfg_size = 0; -@@ -235,7 +240,7 @@ int virtio_setup_ccw(VDev *vdev) - vdev->config.blk.blk_size = 0; /* mark "illegal" - setup started... */ - vdev->guessed_disk_nature = VIRTIO_GDN_NONE; - -- run_ccw(vdev, CCW_CMD_VDEV_RESET, NULL, 0, false); -+ virtio_reset(vdev); - - status = VIRTIO_CONFIG_S_ACKNOWLEDGE; - if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) { -diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h -index 9faf3986b1..f13fa6f5fe 100644 ---- a/pc-bios/s390-ccw/virtio.h -+++ b/pc-bios/s390-ccw/virtio.h -@@ -274,6 +274,7 @@ void vring_send_buf(VRing *vr, void *p, int len, int flags); - int vr_poll(VRing *vr); - int vring_wait_reply(void); - int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd); -+int virtio_reset(VDev *vdev); - int virtio_setup_ccw(VDev *vdev); - - int virtio_net_init(void *mac_addr); --- -2.39.3 - diff --git a/kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch b/kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch deleted file mode 100644 index edf9dd9..0000000 --- a/kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch +++ /dev/null @@ -1,227 +0,0 @@ -From 9facd91b090c8b63cb06da93c2b2ea51f26a3310 Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:51 -0400 -Subject: [PATCH 19/38] pc-bios/s390x: Enable multi-device boot loop -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [18/23] 809cf0c60e4323a1260194e482f6b077f54af90a (thuth/qemu-kvm-cs9) - -Allow attempts to boot from multiple IPL devices. If the first device fails to -IPL, select the pre-built IPLB for the next device in the boot order and attempt -to IPL from it. Continue this process until IPL is successful or there are no -devices left to try. - -Signed-off-by: Jared Rossi -Reviewed-by: Thomas Huth -Message-ID: <20241020012953.1380075-18-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit f697bed22f58eff9b2893ac2fe3d511847398400) ---- - pc-bios/s390-ccw/iplb.h | 24 ++++++++++++++++++++ - pc-bios/s390-ccw/jump2ipl.c | 7 +++--- - pc-bios/s390-ccw/main.c | 45 +++++++++++++++++++++++-------------- - pc-bios/s390-ccw/netmain.c | 2 +- - 4 files changed, 57 insertions(+), 21 deletions(-) - -diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h -index 16643f5879..08f259ff31 100644 ---- a/pc-bios/s390-ccw/iplb.h -+++ b/pc-bios/s390-ccw/iplb.h -@@ -17,9 +17,11 @@ - #endif - - #include -+#include - - extern QemuIplParameters qipl; - extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); -+extern bool have_iplb; - - #define S390_IPL_TYPE_FCP 0x00 - #define S390_IPL_TYPE_CCW 0x02 -@@ -49,4 +51,26 @@ static inline bool set_iplb(IplParameterBlock *iplb) - return manage_iplb(iplb, false); - } - -+/* -+ * The IPL started on the device, but failed in some way. If the IPLB chain -+ * still has more devices left to try, use the next device in order. -+ */ -+static inline bool load_next_iplb(void) -+{ -+ IplParameterBlock *next_iplb; -+ -+ if (qipl.chain_len < 1) { -+ return false; -+ } -+ -+ qipl.index++; -+ next_iplb = (IplParameterBlock *) qipl.next_iplb; -+ memcpy(&iplb, next_iplb, sizeof(IplParameterBlock)); -+ -+ qipl.chain_len--; -+ qipl.next_iplb = qipl.next_iplb + sizeof(IplParameterBlock); -+ -+ return true; -+} -+ - #endif /* IPLB_H */ -diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c -index 99d18947d1..86321d0f46 100644 ---- a/pc-bios/s390-ccw/jump2ipl.c -+++ b/pc-bios/s390-ccw/jump2ipl.c -@@ -45,9 +45,10 @@ int jump_to_IPL_code(uint64_t address) - */ - if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) { - iplb.devno = qipl.index; -- if (!set_iplb(&iplb)) { -- panic("Failed to set IPLB"); -- } -+ } -+ -+ if (have_iplb && !set_iplb(&iplb)) { -+ panic("Failed to set IPLB"); - } - - /* -diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c -index ab4709e16e..a4d1c05aac 100644 ---- a/pc-bios/s390-ccw/main.c -+++ b/pc-bios/s390-ccw/main.c -@@ -23,7 +23,7 @@ static SubChannelId blk_schid = { .one = 1 }; - static char loadparm_str[LOADPARM_LEN + 1]; - QemuIplParameters qipl; - IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); --static bool have_iplb; -+bool have_iplb; - static uint16_t cutype; - LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */ - -@@ -55,6 +55,12 @@ void write_iplb_location(void) - } - } - -+static void copy_qipl(void) -+{ -+ QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS; -+ memcpy(&qipl, early_qipl, sizeof(QemuIplParameters)); -+} -+ - unsigned int get_loadparm_index(void) - { - return atoi(loadparm_str); -@@ -152,6 +158,7 @@ static void menu_setup(void) - - /* If loadparm was set to any other value, then do not enable menu */ - if (memcmp(loadparm_str, LOADPARM_EMPTY, LOADPARM_LEN) != 0) { -+ menu_set_parms(qipl.qipl_flags & ~BOOT_MENU_FLAG_MASK, 0); - return; - } - -@@ -183,7 +190,6 @@ static void css_setup(void) - static void boot_setup(void) - { - char lpmsg[] = "LOADPARM=[________]\n"; -- have_iplb = store_iplb(&iplb); - - if (memcmp(iplb.loadparm, NO_LOADPARM, LOADPARM_LEN) != 0) { - ebcdic_to_ascii((char *) iplb.loadparm, loadparm_str, LOADPARM_LEN); -@@ -191,6 +197,10 @@ static void boot_setup(void) - sclp_get_loadparm_ascii(loadparm_str); - } - -+ if (have_iplb) { -+ menu_setup(); -+ } -+ - memcpy(lpmsg + 10, loadparm_str, 8); - puts(lpmsg); - -@@ -208,6 +218,7 @@ static bool find_boot_device(void) - - switch (iplb.pbt) { - case S390_IPL_TYPE_CCW: -+ vdev->scsi_device_selected = false; - debug_print_int("device no. ", iplb.ccw.devno); - blk_schid.ssid = iplb.ccw.ssid & 0x3; - debug_print_int("ssid ", blk_schid.ssid); -@@ -231,15 +242,8 @@ static bool find_boot_device(void) - static int virtio_setup(void) - { - VDev *vdev = virtio_get_device(); -- QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS; - int ret; - -- memcpy(&qipl, early_qipl, sizeof(QemuIplParameters)); -- -- if (have_iplb) { -- menu_setup(); -- } -- - switch (vdev->senseid.cu_model) { - case VIRTIO_ID_NET: - puts("Network boot device detected"); -@@ -271,10 +275,9 @@ static void ipl_boot_device(void) - dasd_ipl(blk_schid, cutype); - break; - case CU_TYPE_VIRTIO: -- if (virtio_setup()) { -- return; /* Only returns in case of errors */ -+ if (virtio_setup() == 0) { -+ zipl_load(); - } -- zipl_load(); - break; - default: - printf("Attempting to boot from unexpected device type 0x%X\n", cutype); -@@ -307,14 +310,22 @@ static void probe_boot_device(void) - - void main(void) - { -+ copy_qipl(); - sclp_setup(); - css_setup(); -- boot_setup(); -- if (have_iplb && find_boot_device()) { -- ipl_boot_device(); -- } else { -+ have_iplb = store_iplb(&iplb); -+ if (!have_iplb) { - probe_boot_device(); - } - -- panic("Failed to IPL. Halting..."); -+ while (have_iplb) { -+ boot_setup(); -+ if (have_iplb && find_boot_device()) { -+ ipl_boot_device(); -+ } -+ have_iplb = load_next_iplb(); -+ } -+ -+ panic("No suitable device for IPL. Halting..."); -+ - } -diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c -index d1a6c9a91c..e46e470db4 100644 ---- a/pc-bios/s390-ccw/netmain.c -+++ b/pc-bios/s390-ccw/netmain.c -@@ -478,7 +478,7 @@ static bool virtio_setup(void) - */ - enable_mss_facility(); - -- if (store_iplb(&iplb)) { -+ if (have_iplb || store_iplb(&iplb)) { - IPL_assert(iplb.pbt == S390_IPL_TYPE_CCW, "IPL_TYPE_CCW expected"); - dev_no = iplb.ccw.devno; - debug_print_int("device no. ", dev_no); --- -2.39.3 - diff --git a/kvm-pc-bios-s390x-Initialize-cdrom-type-to-false-for-eac.patch b/kvm-pc-bios-s390x-Initialize-cdrom-type-to-false-for-eac.patch deleted file mode 100644 index 24c9794..0000000 --- a/kvm-pc-bios-s390x-Initialize-cdrom-type-to-false-for-eac.patch +++ /dev/null @@ -1,39 +0,0 @@ -From f0e7e2ae018cabdee3a87fa562ad7a4482d235b4 Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Fri, 8 Nov 2024 14:41:36 -0500 -Subject: [PATCH 7/9] pc-bios/s390x: Initialize cdrom type to false for each - IPL device - -RH-Author: Thomas Huth -RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature -RH-Jira: RHEL-68444 -RH-Acked-by: Miroslav Rezanina -RH-Commit: [6/8] efbe12669e2a20d1c8412edfc5e2350475b84dda (thuth/qemu-kvm-cs9) - -Clear information about cdrom type so that current IPL device isn't tainted -by stale data from previous devices. - -Signed-off-by: Jared Rossi -Reviewed-by: Thomas Huth -Message-ID: <20241108194136.2833932-1-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 8c797468116d19940fb758efa749eae414616e3a) ---- - pc-bios/s390-ccw/main.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c -index a4d1c05aac..7509755e36 100644 ---- a/pc-bios/s390-ccw/main.c -+++ b/pc-bios/s390-ccw/main.c -@@ -242,6 +242,7 @@ static bool find_boot_device(void) - static int virtio_setup(void) - { - VDev *vdev = virtio_get_device(); -+ vdev->is_cdrom = false; - int ret; - - switch (vdev->senseid.cu_model) { --- -2.39.3 - diff --git a/kvm-pc-bios-s390x-Initialize-machine-loadparm-before-pro.patch b/kvm-pc-bios-s390x-Initialize-machine-loadparm-before-pro.patch deleted file mode 100644 index c9fa0a7..0000000 --- a/kvm-pc-bios-s390x-Initialize-machine-loadparm-before-pro.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 2d9158563e5d34f9147e660f943f631bad80b6dd Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Thu, 14 Nov 2024 11:19:52 -0500 -Subject: [PATCH 8/9] pc-bios/s390x: Initialize machine loadparm before probing - IPL devices - -RH-Author: Thomas Huth -RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature -RH-Jira: RHEL-68444 -RH-Acked-by: Miroslav Rezanina -RH-Commit: [7/8] 7513fec6ef170ab0c2068a7641a79b77537f1608 (thuth/qemu-kvm-cs9) - -Commit bb185de423 ("s390x: Add individual loadparm assignment to -CCW device") allowed boot devices to be assigned a loadparm value independent -of the machine value, however, when no boot devices are defined, the machine -loadparm becomes ignored. Therefore, let's check the machine loadparm -prior to probing the devices. - -Signed-off-by: Jared Rossi -Reviewed-by: Thomas Huth -Message-ID: <20241114161952.3508554-1-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 1056ca1e70dc6e0458238141bcebfb7810cede6d) ---- - pc-bios/s390-ccw/main.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c -index 7509755e36..76bf743900 100644 ---- a/pc-bios/s390-ccw/main.c -+++ b/pc-bios/s390-ccw/main.c -@@ -191,7 +191,7 @@ static void boot_setup(void) - { - char lpmsg[] = "LOADPARM=[________]\n"; - -- if (memcmp(iplb.loadparm, NO_LOADPARM, LOADPARM_LEN) != 0) { -+ if (have_iplb && memcmp(iplb.loadparm, NO_LOADPARM, LOADPARM_LEN) != 0) { - ebcdic_to_ascii((char *) iplb.loadparm, loadparm_str, LOADPARM_LEN); - } else { - sclp_get_loadparm_ascii(loadparm_str); -@@ -316,6 +316,7 @@ void main(void) - css_setup(); - have_iplb = store_iplb(&iplb); - if (!have_iplb) { -+ boot_setup(); - probe_boot_device(); - } - --- -2.39.3 - diff --git a/kvm-pc-q35-Bump-max_cpus-to-4096-vcpus.patch b/kvm-pc-q35-Bump-max_cpus-to-4096-vcpus.patch deleted file mode 100644 index 2764ab4..0000000 --- a/kvm-pc-q35-Bump-max_cpus-to-4096-vcpus.patch +++ /dev/null @@ -1,72 +0,0 @@ -From b270420c34cd990b1bcbe506c3fb0ef6f76d21a8 Mon Sep 17 00:00:00 2001 -From: Ani Sinha -Date: Wed, 8 Jan 2025 15:10:22 +0530 -Subject: [PATCH 5/7] pc: q35: Bump max_cpus to 4096 vcpus - -RH-Author: Ani Sinha -RH-MergeRequest: 317: pc: q35: Bump max_cpus to 4096 vcpus -RH-Jira: RHEL-57668 -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/1] 35242a1fa8fc21f7d73422d23074cd8da5f74781 (anisinha/centos-qemu-kvm) - -This is the downstream change equivalent of the upstream QEMU commit -e4e98c7e ("pc: q35: Bump max_cpus to 4096 vcpus") - -Since upstream Linux kernel commit -f10a570b093e6 ("KVM: x86: Add CONFIG_KVM_MAX_NR_VCPUS to allow up to 4096 vCPUs") -Linux kernel can support upto a maximum number of 4096 vcpus when MAXSMP is -enabled in the kernel. This upstream change has been backported to c9s kernel -already. Please see JIRA https://issues.redhat.com/browse/RHEL-11579 and the -following commit authored by Vitaly Kuznetsov: -a85f846be686b0a ("KVM: x86: Add CONFIG_KVM_MAX_NR_VCPUS to allow up to 4096 vCPUs") - -At present, QEMU has been tested to correctly boot a linux guest with 4096 -vcpus using edk2 that has the fixes corresponding to the following two upstream -edk2 PRs: - -https://github.com/tianocore/edk2/pull/5410 -https://github.com/tianocore/edk2/pull/5418 - -The changes corresponding to the above two upstream edk2 PRs has been included -in the downstream c9s edk2 with the following MR: -https://gitlab.com/redhat/centos-stream/src/edk2/-/merge_requests/59 - -So bump up the value max_cpus to 4096 for RHEL q35 machines versions 9.6 and -newer. Q35 RHEL machines versions 9.4 and older continue to support 710 maximum -vcpus as before for compatibility reasons. - -See also -https://gitlab.com/redhat/centos-stream/src/qemu-kvm/-/merge_requests/236 -https://gitlab.com/redhat/centos-stream/src/qemu-kvm/-/merge_requests/273 - -Signed-off-by: Ani Sinha ---- - hw/i386/pc_q35.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 37f54062c8..506f9dc0c0 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -344,7 +344,7 @@ static void pc_q35_machine_options(MachineClass *m) - m->default_display = "std"; - m->default_nic = "e1000e"; - m->no_floppy = 1; -- m->max_cpus = 710; -+ m->max_cpus = 4096; - m->no_parallel = 1; - machine_class_allow_dynamic_sysbus_dev(m, TYPE_AMD_IOMMU_DEVICE); - machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE); -@@ -698,6 +698,9 @@ 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"; --- -2.39.3 - diff --git a/kvm-pci-ensure-valid-link-status-bits-for-downstream-por.patch b/kvm-pci-ensure-valid-link-status-bits-for-downstream-por.patch deleted file mode 100644 index 6618d59..0000000 --- a/kvm-pci-ensure-valid-link-status-bits-for-downstream-por.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 765eed6ea5144c19658897e852efcd24fbebaf87 Mon Sep 17 00:00:00 2001 -From: Sebastian Ott -Date: Tue, 3 Dec 2024 13:19:28 +0100 -Subject: [PATCH 1/6] pci: ensure valid link status bits for downstream ports - -RH-Author: Sebastian Ott -RH-MergeRequest: 328: pci: ensure valid link status bits for downstream ports -RH-Jira: RHEL-65618 -RH-Acked-by: Eric Auger -RH-Acked-by: Gavin Shan -RH-Acked-by: Cornelia Huck -RH-Acked-by: Kashyap Chamarthy -RH-Commit: [1/1] fe92e0cd7ab04bfede6d1bf416b1080061cca172 (seott1/cos-qemu-kvm) - -PCI hotplug for downstream endpoints on arm fails because Linux' -PCIe hotplug driver doesn't like the QEMU provided LNKSTA: - - pcieport 0000:08:01.0: pciehp: Slot(2): Card present - pcieport 0000:08:01.0: pciehp: Slot(2): Link Up - pcieport 0000:08:01.0: pciehp: Slot(2): Cannot train link: status 0x2000 - -There's 2 cases where LNKSTA isn't setup properly: -* the downstream device has no express capability -* max link width of the bridge is 0 - -Move the sanity checks added via 88c869198aa63 -("pci: Sanity test minimum downstream LNKSTA") outside of the -branch to make sure downstream ports always have a valid LNKSTA. - -Signed-off-by: Sebastian Ott -Tested-by: Zhenyu Zhang -Message-Id: <20241203121928.14861-1-sebott@redhat.com> -Reviewed-by: Alex Williamson -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry picked from commit 694632fd44987cc4618612a38ad151047524a590) -JIRA: https://issues.redhat.com/browse/RHEL-65618 -Signed-off-by: Sebastian Ott ---- - hw/pci/pcie.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c -index 4b2f0805c6..9cb137c30f 100644 ---- a/hw/pci/pcie.c -+++ b/hw/pci/pcie.c -@@ -1080,18 +1080,22 @@ void pcie_sync_bridge_lnk(PCIDevice *bridge_dev) - if ((lnksta & PCI_EXP_LNKSTA_NLW) > (lnkcap & PCI_EXP_LNKCAP_MLW)) { - lnksta &= ~PCI_EXP_LNKSTA_NLW; - lnksta |= lnkcap & PCI_EXP_LNKCAP_MLW; -- } else if (!(lnksta & PCI_EXP_LNKSTA_NLW)) { -- lnksta |= QEMU_PCI_EXP_LNKSTA_NLW(QEMU_PCI_EXP_LNK_X1); - } - - if ((lnksta & PCI_EXP_LNKSTA_CLS) > (lnkcap & PCI_EXP_LNKCAP_SLS)) { - lnksta &= ~PCI_EXP_LNKSTA_CLS; - lnksta |= lnkcap & PCI_EXP_LNKCAP_SLS; -- } else if (!(lnksta & PCI_EXP_LNKSTA_CLS)) { -- lnksta |= QEMU_PCI_EXP_LNKSTA_CLS(QEMU_PCI_EXP_LNK_2_5GT); - } - } - -+ if (!(lnksta & PCI_EXP_LNKSTA_NLW)) { -+ lnksta |= QEMU_PCI_EXP_LNKSTA_NLW(QEMU_PCI_EXP_LNK_X1); -+ } -+ -+ if (!(lnksta & PCI_EXP_LNKSTA_CLS)) { -+ lnksta |= QEMU_PCI_EXP_LNKSTA_CLS(QEMU_PCI_EXP_LNK_2_5GT); -+ } -+ - pci_word_test_and_clear_mask(exp_cap + PCI_EXP_LNKSTA, - PCI_EXP_LNKSTA_CLS | PCI_EXP_LNKSTA_NLW); - pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA, lnksta & --- -2.39.3 - diff --git a/kvm-physmem-Support-coordinated-discarding-of-RAM-with-g.patch b/kvm-physmem-Support-coordinated-discarding-of-RAM-with-g.patch new file mode 100644 index 0000000..ca29c3d --- /dev/null +++ b/kvm-physmem-Support-coordinated-discarding-of-RAM-with-g.patch @@ -0,0 +1,119 @@ +From 42752be7d13e5e104a398576e4ca281a96fccbde Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 25 Jul 2025 16:43:19 +0200 +Subject: [PATCH 100/100] physmem: Support coordinated discarding of RAM with + guest_memfd + +A new field, attributes, was introduced in RAMBlock to link to a +RamBlockAttributes object, which centralizes all guest_memfd related +information (such as fd and status bitmap) within a RAMBlock. + +Create and initialize the RamBlockAttributes object upon ram_block_add(). +Meanwhile, register the object in the target RAMBlock's MemoryRegion. +After that, guest_memfd-backed RAMBlock is associated with the +RamDiscardManager interface, and the users can execute RamDiscardManager +specific handling. For example, VFIO will register the +RamDiscardListener and get notifications when the state_change() helper +invokes. + +As coordinate discarding of RAM with guest_memfd is now supported, only +block uncoordinated discard. + +Tested-by: Alexey Kardashevskiy +Reviewed-by: Alexey Kardashevskiy +Acked-by: David Hildenbrand +Signed-off-by: Chenyi Qiang +Link: https://lore.kernel.org/r/20250612082747.51539-6-chenyi.qiang@intel.com +Signed-off-by: Peter Xu +(cherry picked from commit 2fde3fb916079ee0ff0fc26d9446c813b1d5cc28) +Signed-off-by: Paolo Bonzini +--- + accel/kvm/kvm-all.c | 9 +++++++++ + include/system/ramblock.h | 1 + + system/physmem.c | 23 +++++++++++++++++++++-- + 3 files changed, 31 insertions(+), 2 deletions(-) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index e59d98c22f..0234865860 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -3080,6 +3080,15 @@ int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private) + addr = memory_region_get_ram_ptr(mr) + section.offset_within_region; + rb = qemu_ram_block_from_host(addr, false, &offset); + ++ ret = ram_block_attributes_state_change(RAM_BLOCK_ATTRIBUTES(mr->rdm), ++ offset, size, to_private); ++ if (ret) { ++ error_report("Failed to notify the listener the state change of " ++ "(0x%"HWADDR_PRIx" + 0x%"HWADDR_PRIx") to %s", ++ start, size, to_private ? "private" : "shared"); ++ goto out_unref; ++ } ++ + if (to_private) { + if (rb->page_size != qemu_real_host_page_size()) { + /* +diff --git a/include/system/ramblock.h b/include/system/ramblock.h +index 1bab9e2dac..87e847e184 100644 +--- a/include/system/ramblock.h ++++ b/include/system/ramblock.h +@@ -46,6 +46,7 @@ struct RAMBlock { + int fd; + uint64_t fd_offset; + int guest_memfd; ++ RamBlockAttributes *attributes; + size_t page_size; + /* dirty bitmap used during migration */ + unsigned long *bmap; +diff --git a/system/physmem.c b/system/physmem.c +index 307d0764b6..00734c418d 100644 +--- a/system/physmem.c ++++ b/system/physmem.c +@@ -1894,7 +1894,7 @@ static void ram_block_add(RAMBlock *new_block, Error **errp) + } + assert(new_block->guest_memfd < 0); + +- ret = ram_block_discard_require(true); ++ ret = ram_block_coordinated_discard_require(true); + if (ret < 0) { + error_setg_errno(errp, -ret, + "cannot set up private guest memory: discard currently blocked"); +@@ -1909,6 +1909,24 @@ static void ram_block_add(RAMBlock *new_block, Error **errp) + goto out_free; + } + ++ /* ++ * The attribute bitmap of the RamBlockAttributes is default to ++ * discarded, which mimics the behavior of kvm_set_phys_mem() when it ++ * calls kvm_set_memory_attributes_private(). This leads to a brief ++ * period of inconsistency between the creation of the RAMBlock and its ++ * mapping into the physical address space. However, this is not ++ * problematic, as no users rely on the attribute status to perform ++ * any actions during this interval. ++ */ ++ new_block->attributes = ram_block_attributes_create(new_block); ++ if (!new_block->attributes) { ++ error_setg(errp, "Failed to create ram block attribute"); ++ close(new_block->guest_memfd); ++ ram_block_coordinated_discard_require(false); ++ qemu_mutex_unlock_ramlist(); ++ goto out_free; ++ } ++ + /* + * Add a specific guest_memfd blocker if a generic one would not be + * added by ram_block_add_cpr_blocker. +@@ -2264,8 +2282,9 @@ static void reclaim_ramblock(RAMBlock *block) + } + + if (block->guest_memfd >= 0) { ++ ram_block_attributes_destroy(block->attributes); + close(block->guest_memfd); +- ram_block_discard_require(false); ++ ram_block_coordinated_discard_require(false); + } + + g_free(block); +-- +2.47.3 + diff --git a/kvm-qdev-Fix-set_pci_devfn-to-visit-option-only-once.patch b/kvm-qdev-Fix-set_pci_devfn-to-visit-option-only-once.patch deleted file mode 100644 index c58f4f5..0000000 --- a/kvm-qdev-Fix-set_pci_devfn-to-visit-option-only-once.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 33607f8bd2e0d56e854131c4e70c770b88fa5441 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Tue, 19 Nov 2024 13:03:53 +0100 -Subject: [PATCH 1/7] qdev: Fix set_pci_devfn() to visit option only once - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 312: qdev-monitor: avoid QemuOpts in QMP device_add -RH-Jira: RHEL-43412 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [1/4] 4d9ce49f16904d34d4f751f1dec3a53abfe8c8a8 (stefanha/centos-stream-qemu-kvm) - -pci_devfn properties accept either a string or an integer as input. To -implement this, set_pci_devfn() first tries to visit the option as a -string, and if that fails, it visits it as an integer instead. While the -QemuOpts visitor happens to accept this, it is invalid according to the -visitor interface. QObject input visitors run into an assertion failure -when this is done. - -QObject input visitors are used with the JSON syntax version of -device -on the command line: - -$ ./qemu-system-x86_64 -enable-kvm -M q35 -device pcie-pci-bridge,id=pci.1,bus=pcie.0 -blockdev null-co,node-name=disk -device '{ "driver": "virtio-blk-pci", "drive": "disk", "id": "virtio-disk0", "bus": "pci.1", "addr": 1 }' -qemu-system-x86_64: ../qapi/qobject-input-visitor.c:143: QObject *qobject_input_try_get_object(QObjectInputVisitor *, const char *, _Bool): Assertion `removed' failed. - -The proper way to accept both strings and integers is using the -alternate mechanism, which tells us the type of the input before it's -visited. With this information, we can directly visit it as the right -type. - -This fixes set_pci_devfn() by using the alternate mechanism. - -Cc: qemu-stable@nongnu.org -Reported-by: Peter Maydell -Signed-off-by: Kevin Wolf -Message-ID: <20241119120353.57812-1-kwolf@redhat.com> -Acked-by: Paolo Bonzini -Reviewed-by: Markus Armbruster -Signed-off-by: Kevin Wolf -(cherry picked from commit 5102f9df4a9a7adfbd902f9515c3f8f53dba288e) -Signed-off-by: Stefan Hajnoczi ---- - hw/core/qdev-properties-system.c | 54 +++++++++++++++++++++----------- - 1 file changed, 36 insertions(+), 18 deletions(-) - -diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c -index 5cd527cdba..b182dc293a 100644 ---- a/hw/core/qdev-properties-system.c -+++ b/hw/core/qdev-properties-system.c -@@ -820,39 +820,57 @@ static void set_pci_devfn(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) - { - Property *prop = opaque; -+ g_autofree GenericAlternate *alt; - int32_t value, *ptr = object_field_prop_ptr(obj, prop); - unsigned int slot, fn, n; -- char *str; -+ g_autofree char *str = NULL; -+ -+ if (!visit_start_alternate(v, name, &alt, sizeof(*alt), errp)) { -+ return; -+ } -+ -+ switch (alt->type) { -+ case QTYPE_QSTRING: -+ if (!visit_type_str(v, name, &str, errp)) { -+ goto out; -+ } - -- if (!visit_type_str(v, name, &str, NULL)) { -+ if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) { -+ fn = 0; -+ if (sscanf(str, "%x%n", &slot, &n) != 1) { -+ goto invalid; -+ } -+ } -+ if (str[n] != '\0' || fn > 7 || slot > 31) { -+ goto invalid; -+ } -+ *ptr = slot << 3 | fn; -+ break; -+ -+ case QTYPE_QNUM: - if (!visit_type_int32(v, name, &value, errp)) { -- return; -+ goto out; - } - if (value < -1 || value > 255) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, - name ? name : "null", "a value between -1 and 255"); -- return; -+ goto out; - } - *ptr = value; -- return; -- } -+ break; - -- if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) { -- fn = 0; -- if (sscanf(str, "%x%n", &slot, &n) != 1) { -- goto invalid; -- } -- } -- if (str[n] != '\0' || fn > 7 || slot > 31) { -- goto invalid; -+ default: -+ error_setg(errp, "Invalid parameter type for '%s', expected int or str", -+ name ? name : "null"); -+ goto out; - } -- *ptr = slot << 3 | fn; -- g_free(str); -- return; -+ -+ goto out; - - invalid: - error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str); -- g_free(str); -+out: -+ visit_end_alternate(v, (void **) &alt); - } - - static int print_pci_devfn(Object *obj, Property *prop, char *dest, --- -2.39.3 - diff --git a/kvm-qdev-monitor-avoid-QemuOpts-in-QMP-device_add.patch b/kvm-qdev-monitor-avoid-QemuOpts-in-QMP-device_add.patch deleted file mode 100644 index 9de3875..0000000 --- a/kvm-qdev-monitor-avoid-QemuOpts-in-QMP-device_add.patch +++ /dev/null @@ -1,131 +0,0 @@ -From de4f7c3b6dbba3eb8450cd7714ae93787009cd17 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 27 Aug 2024 15:27:50 -0400 -Subject: [PATCH 3/7] qdev-monitor: avoid QemuOpts in QMP device_add -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 312: qdev-monitor: avoid QemuOpts in QMP device_add -RH-Jira: RHEL-43412 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [3/4] 7c45f3791491cd66ec2476ef0aa515b5bffba456 (stefanha/centos-stream-qemu-kvm) - -The QMP device_add monitor command converts the QDict arguments to -QemuOpts and then back again to QDict. This process only supports scalar -types. Device properties like virtio-blk-pci's iothread-vq-mapping (an -array of objects) are silently dropped by qemu_opts_from_qdict() during -the QemuOpts conversion even though QAPI is capable of validating them. -As a result, hotplugging virtio-blk-pci devices with the -iothread-vq-mapping property does not work as expected (the property is -ignored). - -Get rid of the QemuOpts conversion in qmp_device_add() and call -qdev_device_add_from_qdict() with from_json=true. Using the QMP -command's QDict arguments directly allows non-scalar properties. - -The HMP is also adjusted since qmp_device_add()'s now expects properly -typed JSON arguments and cannot be used from HMP anymore. Move the code -that was previously in qmp_device_add() (with QemuOpts conversion and -from_json=false) into hmp_device_add() so that its behavior is -unchanged. - -This patch changes the behavior of QMP device_add but not HMP -device_add. QMP clients that sent incorrectly typed device_add QMP -commands no longer work. This is a breaking change but clients should be -using the correct types already. See the netdev_add QAPIfication in -commit db2a380c8457 for similar reasoning and object-add in commit -9151e59a8b6e. Unlike those commits, we continue to rely on 'gen': false -for the time being. - -Markus helped me figure this out and even provided a draft patch. The -code ended up very close to what he suggested. - -Suggested-by: Markus Armbruster -Cc: Daniel P. BerrangĂ© -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240827192751.948633-2-stefanha@redhat.com> -Reviewed-by: Daniel P. BerrangĂ© -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit be93fd53723cbdca675bd9ed112dae5cabbe1e91) -Signed-off-by: Stefan Hajnoczi ---- - system/qdev-monitor.c | 42 ++++++++++++++++++++++++++++-------------- - 1 file changed, 28 insertions(+), 14 deletions(-) - -diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c -index 6af6ef7d66..8b27cc42b0 100644 ---- a/system/qdev-monitor.c -+++ b/system/qdev-monitor.c -@@ -849,18 +849,9 @@ void hmp_info_qdm(Monitor *mon, const QDict *qdict) - - void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp) - { -- QemuOpts *opts; - DeviceState *dev; - -- opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, errp); -- if (!opts) { -- return; -- } -- if (!monitor_cur_is_qmp() && qdev_device_help(opts)) { -- qemu_opts_del(opts); -- return; -- } -- dev = qdev_device_add(opts, errp); -+ dev = qdev_device_add_from_qdict(qdict, true, errp); - if (!dev) { - /* - * Drain all pending RCU callbacks. This is done because -@@ -872,9 +863,6 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp) - * to the user - */ - drain_call_rcu(); -- -- qemu_opts_del(opts); -- return; - } - object_unref(OBJECT(dev)); - } -@@ -967,8 +955,34 @@ void qmp_device_del(const char *id, Error **errp) - void hmp_device_add(Monitor *mon, const QDict *qdict) - { - Error *err = NULL; -+ QemuOpts *opts; -+ DeviceState *dev; - -- qmp_device_add((QDict *)qdict, NULL, &err); -+ opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &err); -+ if (!opts) { -+ goto out; -+ } -+ if (qdev_device_help(opts)) { -+ qemu_opts_del(opts); -+ return; -+ } -+ dev = qdev_device_add(opts, &err); -+ if (!dev) { -+ /* -+ * Drain all pending RCU callbacks. This is done because -+ * some bus related operations can delay a device removal -+ * (in this case this can happen if device is added and then -+ * removed due to a configuration error) -+ * to a RCU callback, but user might expect that this interface -+ * will finish its job completely once qmp command returns result -+ * to the user -+ */ -+ drain_call_rcu(); -+ -+ qemu_opts_del(opts); -+ } -+ object_unref(dev); -+out: - hmp_handle_error(mon, err); - } - --- -2.39.3 - diff --git a/kvm-qemu-ga-Optimize-freeze-hook-script-logic-of-logging.patch b/kvm-qemu-ga-Optimize-freeze-hook-script-logic-of-logging.patch deleted file mode 100644 index 51eda58..0000000 --- a/kvm-qemu-ga-Optimize-freeze-hook-script-logic-of-logging.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 14fc984df8059560815cc1f55f058569fe480832 Mon Sep 17 00:00:00 2001 -From: Dehan Meng -Date: Wed, 25 Dec 2024 16:37:44 +0800 -Subject: [PATCH 4/4] qemu-ga: Optimize freeze-hook script logic of logging - error - -RH-Author: 6-dehan -RH-MergeRequest: 326: qemu-ga: Optimize freeze-hook script logic of logging error -RH-Jira: RHEL-74461 -RH-Acked-by: Konstantin Kostiuk -RH-Acked-by: Yan Vugenfirer -RH-Commit: [1/1] f133428aa9b511a93e528823e8253a41d46e1de5 (6-dehan/centos-qemu-kvm) - -Make sure the error log of fsfreeze hooks -when freeze/thaw/snapshot could be logged -to system logs if the default logfile of -qga can't be written or other situations - -Reviewed-by: Konstantin Kostiuk -Reviewed-by: Yan Vugenfirer -Signed-off-by: Dehan Meng ---- - scripts/qemu-guest-agent/fsfreeze-hook | 36 +++++++++++++++++++++++--- - 1 file changed, 32 insertions(+), 4 deletions(-) - -diff --git a/scripts/qemu-guest-agent/fsfreeze-hook b/scripts/qemu-guest-agent/fsfreeze-hook -index 70536ba3e3..d5d8d4daf8 100755 ---- a/scripts/qemu-guest-agent/fsfreeze-hook -+++ b/scripts/qemu-guest-agent/fsfreeze-hook -@@ -19,15 +19,43 @@ is_ignored_file() { - return 1 - } - -+USE_SYSLOG=0 -+# if log file is not writable, fallback to syslog -+[ ! -w "$LOGFILE" ] && USE_SYSLOG=1 -+# try to update log file and fallback to syslog if it fails -+touch "$LOGFILE" &>/dev/null || USE_SYSLOG=1 -+ -+# Ensure the log file is writable, fallback to syslog if not -+log_message() { -+ local message="$1" -+ if [ "$USE_SYSLOG" -eq 0 ]; then -+ printf "%s: %s\n" "$(date)" "$message" >>"$LOGFILE" -+ else -+ logger -t qemu-ga-freeze-hook "$message" -+ fi -+} -+ - # Iterate executables in directory "fsfreeze-hook.d" with the specified args - [ ! -d "$FSFREEZE_D" ] && exit 0 -+ - for file in "$FSFREEZE_D"/* ; do - is_ignored_file "$file" && continue - [ -x "$file" ] || continue -- printf "$(date): execute $file $@\n" >>$LOGFILE -- "$file" "$@" >>$LOGFILE 2>&1 -- STATUS=$? -- printf "$(date): $file finished with status=$STATUS\n" >>$LOGFILE -+ -+ log_message "Executing $file $@" -+ if [ "$USE_SYSLOG" -eq 0 ]; then -+ "$file" "$@" >>"$LOGFILE" 2>&1 -+ STATUS=$? -+ else -+ "$file" "$@" 2>&1 | logger -t qemu-ga-freeze-hook -+ STATUS=${PIPESTATUS[0]} -+ fi -+ -+ if [ $STATUS -ne 0 ]; then -+ log_message "Error: $file finished with status=$STATUS" -+ else -+ log_message "$file finished successfully" -+ fi - done - - exit 0 --- -2.39.3 - diff --git a/kvm-qemu-guest-agent-Update-the-logfile-path-of-qga-fsfr.patch b/kvm-qemu-guest-agent-Update-the-logfile-path-of-qga-fsfr.patch deleted file mode 100644 index 08328b0..0000000 --- a/kvm-qemu-guest-agent-Update-the-logfile-path-of-qga-fsfr.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 18c53acff0c50491dddac1e9d023b9ad5f540f7f Mon Sep 17 00:00:00 2001 -From: Dehan Meng -Date: Wed, 4 Sep 2024 16:39:51 +0800 -Subject: [PATCH 9/9] qemu-guest-agent: Update the logfile path of - qga-fsfreeze-hook.log - -RH-Author: Dehan Meng -RH-MergeRequest: 269: qemu-guest-agent: Update the logfile path of qga-fsfreeze-hook.log -RH-Jira: RHEL-57028 -RH-Acked-by: Miroslav Rezanina -RH-Commit: [45/45] eebec1989edade851807d775de75d4d14da01cf2 (6-dehan/src_centosupstream_qemu-kvm) - -Since '/var/log/qga-fsfreeze-hook.log' is not included to proper -selinux context 'system_u:object_r:virt_qemu_ga_log_t:s0', it -should be changed to '/var/log/qemu-ga/qga-fsfreeze-hook.log'. And -it's worth to mention that this is RHEL-only change for matching -existing SELinux boolean and policy. - -Signed-off-by: Dehan Meng ---- - scripts/qemu-guest-agent/fsfreeze-hook | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/scripts/qemu-guest-agent/fsfreeze-hook b/scripts/qemu-guest-agent/fsfreeze-hook -index e9b84ec028..70536ba3e3 100755 ---- a/scripts/qemu-guest-agent/fsfreeze-hook -+++ b/scripts/qemu-guest-agent/fsfreeze-hook -@@ -7,7 +7,7 @@ - # "freeze" argument before the filesystem is frozen. And for fsfreeze-thaw - # request, it is issued with "thaw" argument after filesystem is thawed. - --LOGFILE=/var/log/qga-fsfreeze-hook.log -+LOGFILE=/var/log/qemu-ga/qga-fsfreeze-hook.log - FSFREEZE_D=$(dirname -- "$(realpath $0)")/fsfreeze-hook.d - - # Check whether file $1 is a backup or rpm-generated file and should be ignored --- -2.39.3 - diff --git a/kvm-qga-Add-log-to-guest-fsfreeze-thaw-command.patch b/kvm-qga-Add-log-to-guest-fsfreeze-thaw-command.patch deleted file mode 100644 index ae1d2c6..0000000 --- a/kvm-qga-Add-log-to-guest-fsfreeze-thaw-command.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 53cc229c86bd0c555cdf68adb75918bec6c525fb Mon Sep 17 00:00:00 2001 -From: Konstantin Kostiuk -Date: Mon, 16 Dec 2024 17:45:52 +0200 -Subject: [PATCH 3/4] qga: Add log to guest-fsfreeze-thaw command -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: 6-dehan -RH-MergeRequest: 325: qga: Add log to guest-fsfreeze-thaw command -RH-Jira: RHEL-74361 -RH-Acked-by: Konstantin Kostiuk -RH-Acked-by: Yan Vugenfirer -RH-Commit: [1/1] a6f5a87f592136857fb76b8261d1de98f1d28772 (6-dehan/centos-qemu-kvm) - -Signed-off-by: Konstantin Kostiuk -Reviewed-by: Daniel P. BerrangĂ© ---- - qga/commands-posix.c | 2 ++ - qga/commands-win32.c | 3 +++ - 2 files changed, 5 insertions(+) - -diff --git a/qga/commands-posix.c b/qga/commands-posix.c -index c2bd0b4316..49e40f9127 100644 ---- a/qga/commands-posix.c -+++ b/qga/commands-posix.c -@@ -806,8 +806,10 @@ int64_t qmp_guest_fsfreeze_thaw(Error **errp) - int ret; - - ret = qmp_guest_fsfreeze_do_thaw(errp); -+ - if (ret >= 0) { - ga_unset_frozen(ga_state); -+ slog("guest-fsthaw called"); - execute_fsfreeze_hook(FSFREEZE_HOOK_THAW, errp); - } else { - ret = 0; -diff --git a/qga/commands-win32.c b/qga/commands-win32.c -index 61b36da469..1aea6cd167 100644 ---- a/qga/commands-win32.c -+++ b/qga/commands-win32.c -@@ -1273,6 +1273,9 @@ int64_t qmp_guest_fsfreeze_thaw(Error **errp) - qga_vss_fsfreeze(&i, false, NULL, errp); - - ga_unset_frozen(ga_state); -+ -+ slog("guest-fsthaw called"); -+ - return i; - } - --- -2.39.3 - diff --git a/kvm-qga-skip-bind-mounts-in-fs-list.patch b/kvm-qga-skip-bind-mounts-in-fs-list.patch deleted file mode 100644 index e7bddde..0000000 --- a/kvm-qga-skip-bind-mounts-in-fs-list.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 5aec8bc4d0458e6011f5e0242a8f18bdba835af8 Mon Sep 17 00:00:00 2001 -From: Jean-Louis Dupond -Date: Wed, 2 Oct 2024 12:06:35 +0200 -Subject: [PATCH 17/18] qga: skip bind mounts in fs list - -RH-Author: Konstantin Kostiuk -RH-MergeRequest: 307: qga: skip bind mounts in fs list -RH-Jira: RHEL-71939 -RH-Acked-by: yvugenfi -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/1] 787cdc9477275959892800418ea37b76fce28ac3 (kkostiuk/redhat-centos-stream-src-qemu-kvm) - -The filesystem list in build_fs_mount_list should skip bind mounts. -This because we end up in locking situations when doing fsFreeze. Like -mentioned in [1] and [2]. - -Next to that, the build_fs_mount_list call did a fallback via -build_fs_mount_list_from_mtab if mountinfo did not exist. -There it skipped bind mounts, but this is broken for newer OS. -This as mounts does not return the path of the bind mount but the -underlying dev/partition, so S_ISDIR will never return true in -dev_major_minor call. - -This patch simply checks the existing devmajor:devminor tuple in the -mounts, and if it already exists, this means we have the same devices -mounted again, a bind mount. So skip this. - -Same approach is used in open-vm-tools [3]. - -[1]: https://gitlab.com/qemu-project/qemu/-/issues/592 -[2]: https://gitlab.com/qemu-project/qemu/-/issues/520 -[3]: https://github.com/vmware/open-vm-tools/commit/d58847b497e212737007958c945af1df22a8ab58 - -Signed-off-by: Jean-Louis Dupond -Reviewed-by: Konstantin Kostiuk -Link: https://lore.kernel.org/r/20241002100634.162499-2-jean-louis@dupond.be -Signed-off-by: Konstantin Kostiuk ---- - qga/commands-linux.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - -diff --git a/qga/commands-linux.c b/qga/commands-linux.c -index 51d5e3d927..426b040ab8 100644 ---- a/qga/commands-linux.c -+++ b/qga/commands-linux.c -@@ -59,6 +59,22 @@ static int dev_major_minor(const char *devpath, - return -1; - } - -+/* -+ * Check if we already have the devmajor:devminor in the mounts -+ * If thats the case return true. -+ */ -+static bool dev_exists(FsMountList *mounts, unsigned int devmajor, unsigned int devminor) -+{ -+ FsMount *mount; -+ -+ QTAILQ_FOREACH(mount, mounts, next) { -+ if (mount->devmajor == devmajor && mount->devminor == devminor) { -+ return true; -+ } -+ } -+ return false; -+} -+ - static bool build_fs_mount_list_from_mtab(FsMountList *mounts, Error **errp) - { - struct mntent *ment; -@@ -89,6 +105,10 @@ static bool build_fs_mount_list_from_mtab(FsMountList *mounts, Error **errp) - /* Skip bind mounts */ - continue; - } -+ if (dev_exists(mounts, devmajor, devminor)) { -+ /* Skip already existing devices (bind mounts) */ -+ continue; -+ } - - mount = g_new0(FsMount, 1); - mount->dirname = g_strdup(ment->mnt_dir); -@@ -172,6 +192,11 @@ bool build_fs_mount_list(FsMountList *mounts, Error **errp) - } - } - -+ if (dev_exists(mounts, devmajor, devminor)) { -+ /* Skip already existing devices (bind mounts) */ -+ continue; -+ } -+ - mount = g_new0(FsMount, 1); - mount->dirname = g_strdup(line + dir_s); - mount->devtype = g_strdup(dash + type_s); --- -2.39.3 - diff --git a/kvm-qmp-cont-Only-activate-disks-if-migration-completed.patch b/kvm-qmp-cont-Only-activate-disks-if-migration-completed.patch deleted file mode 100644 index 5967f47..0000000 --- a/kvm-qmp-cont-Only-activate-disks-if-migration-completed.patch +++ /dev/null @@ -1,73 +0,0 @@ -From fd5603e42b6287c849bfed700d34c817b4b93891 Mon Sep 17 00:00:00 2001 -From: Peter Xu -Date: Fri, 6 Dec 2024 18:08:34 -0500 -Subject: [PATCH 02/22] qmp/cont: Only activate disks if migration completed - -RH-Author: Kevin Wolf -RH-MergeRequest: 340: QMP command for block device reactivation after migration -RH-Jira: RHEL-54670 -RH-Acked-by: Eric Blake -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [2/22] 554508370a344aa69e0e8888c0567d353cbcfe94 (kmwolf/centos-qemu-kvm) - -As the comment says, the activation of disks is for the case where -migration has completed, rather than when QEMU is still during -migration (RUN_STATE_INMIGRATE). - -Move the code over to reflect what the comment is describing. - -Cc: Kevin Wolf -Cc: Markus Armbruster -Signed-off-by: Peter Xu -Reviewed-by: Fabiano Rosas -Message-Id: <20241206230838.1111496-3-peterx@redhat.com> -Signed-off-by: Fabiano Rosas -(cherry picked from commit e4e5e89bbd8e731e86735d9d25b7b5f49e8f08b6) -Signed-off-by: Kevin Wolf ---- - monitor/qmp-cmds.c | 26 ++++++++++++++------------ - 1 file changed, 14 insertions(+), 12 deletions(-) - -diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c -index f84a0dc523..76f21e8af3 100644 ---- a/monitor/qmp-cmds.c -+++ b/monitor/qmp-cmds.c -@@ -96,21 +96,23 @@ void qmp_cont(Error **errp) - } - } - -- /* Continuing after completed migration. Images have been inactivated to -- * allow the destination to take control. Need to get control back now. -- * -- * If there are no inactive block nodes (e.g. because the VM was just -- * paused rather than completing a migration), bdrv_inactivate_all() simply -- * doesn't do anything. */ -- bdrv_activate_all(&local_err); -- if (local_err) { -- error_propagate(errp, local_err); -- return; -- } -- - if (runstate_check(RUN_STATE_INMIGRATE)) { - autostart = 1; - } else { -+ /* -+ * Continuing after completed migration. Images have been -+ * inactivated to allow the destination to take control. Need to -+ * get control back now. -+ * -+ * If there are no inactive block nodes (e.g. because the VM was -+ * just paused rather than completing a migration), -+ * bdrv_inactivate_all() simply doesn't do anything. -+ */ -+ bdrv_activate_all(&local_err); -+ if (local_err) { -+ error_propagate(errp, local_err); -+ return; -+ } - vm_start(); - } - } --- -2.39.3 - diff --git a/kvm-qom-reverse-order-of-instance_post_init-calls.patch b/kvm-qom-reverse-order-of-instance_post_init-calls.patch new file mode 100644 index 0000000..c5d19e2 --- /dev/null +++ b/kvm-qom-reverse-order-of-instance_post_init-calls.patch @@ -0,0 +1,71 @@ +From 167eea3f06a278ddfa5dbfa62618bf06b1fdf291 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:44 +0200 +Subject: [PATCH 003/100] qom: reverse order of instance_post_init calls +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently, the instance_post_init calls are performed from the leaf +class and all the way up to Object. This is incorrect because the +leaf class cannot observe property values applied by the superclasses; +for example, a compat property will be set on a device *after* +the class's post_init callback has run. + +In particular this makes it impossible for implementations of +accel_cpu_instance_init() to operate based on the actual values of +the properties, though it seems that cxl_dsp_instance_post_init and +rp_instance_post_init might have similar issues. + +Follow instead the same order as instance_init, starting with Object +and running the child class's instance_post_init after the parent. + +Reviewed-by: Philippe Mathieu-DaudĂ© +Reviewed-by: Alistair Francis +Signed-off-by: Paolo Bonzini +(cherry picked from commit 220c739903cec99df032219ac94c45b5269a0ab5) +Signed-off-by: Paolo Bonzini +--- + include/qom/object.h | 3 ++- + qom/object.c | 8 ++++---- + 2 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/include/qom/object.h b/include/qom/object.h +index 9192265db7..c87a392259 100644 +--- a/include/qom/object.h ++++ b/include/qom/object.h +@@ -445,7 +445,8 @@ struct Object + * class will have already been initialized so the type is only responsible + * for initializing its own members. + * @instance_post_init: This function is called to finish initialization of +- * an object, after all @instance_init functions were called. ++ * an object, after all @instance_init functions were called, as well as ++ * @instance_post_init functions for the parent classes. + * @instance_finalize: This function is called during object destruction. This + * is called before the parent @instance_finalize function has been called. + * An object should only free the members that are unique to its type in this +diff --git a/qom/object.c b/qom/object.c +index 01618d06bd..4f769f779a 100644 +--- a/qom/object.c ++++ b/qom/object.c +@@ -431,13 +431,13 @@ static void object_init_with_type(Object *obj, TypeImpl *ti) + + static void object_post_init_with_type(Object *obj, TypeImpl *ti) + { +- if (ti->instance_post_init) { +- ti->instance_post_init(obj); +- } +- + if (type_has_parent(ti)) { + object_post_init_with_type(obj, type_get_parent(ti)); + } ++ ++ if (ti->instance_post_init) { ++ ti->instance_post_init(obj); ++ } + } + + bool object_apply_global_props(Object *obj, const GPtrArray *props, +-- +2.47.3 + diff --git a/kvm-qtest-migration-rdma-Add-test-for-rdma-migration-wit.patch b/kvm-qtest-migration-rdma-Add-test-for-rdma-migration-wit.patch new file mode 100644 index 0000000..33482c9 --- /dev/null +++ b/kvm-qtest-migration-rdma-Add-test-for-rdma-migration-wit.patch @@ -0,0 +1,212 @@ +From 879b050c6cef5cf2ae1944ffb8b203faeca62f1a Mon Sep 17 00:00:00 2001 +From: Li Zhijian +Date: Tue, 13 May 2025 09:22:07 +0800 +Subject: [PATCH 10/33] qtest/migration/rdma: Add test for rdma migration with + ipv6 + +RH-Author: Prasad Pandit +RH-MergeRequest: 390: migration: allow to enable multifd+postcopy features together, but use multifd during precopy only +RH-Jira: RHEL-59697 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Miroslav Rezanina +RH-Commit: [10/11] d2dd06604b461abf0c6d47dc860b1bb925889133 (pjp/cs-qemu-kvm) + +Recently, we removed ipv6 restriction[0] from RDMA migration, add a +test for it. + +[0] https://lore.kernel.org/qemu-devel/20250326095224.9918-1-jinpu.wang@ionos.com/ + +Jira: https://issues.redhat.com/browse/RHEL-59697 +Cc: Jack Wang +Cc: Michael R. Galaxy +Cc: Peter Xu +Cc: Yu Zhang +Reviewed-by: Jack Wang +Signed-off-by: Li Zhijian +Link: https://lore.kernel.org/r/20250513012207.2867069-1-lizhijian@fujitsu.com +[peterx: Fix over long lines] +Signed-off-by: Peter Xu +(cherry picked from commit 6b84c46e8e0ef6f83f33657a29a8abb2b8362d02) +Signed-off-by: Prasad Pandit +--- + scripts/rdma-migration-helper.sh | 57 ++++++++++++++++++++++----- + tests/qtest/migration/precopy-tests.c | 21 ++++++++-- + 2 files changed, 65 insertions(+), 13 deletions(-) + +diff --git a/scripts/rdma-migration-helper.sh b/scripts/rdma-migration-helper.sh +index a39f2fb0e5..d784d1566a 100755 +--- a/scripts/rdma-migration-helper.sh ++++ b/scripts/rdma-migration-helper.sh +@@ -8,23 +8,44 @@ get_ipv4_addr() + head -1 | tr -d '\n' + } + ++get_ipv6_addr() { ++ ipv6=$(ip -6 -o addr show dev "$1" | ++ sed -n 's/.*[[:blank:]]inet6[[:blank:]]*\([^[:blank:]/]*\).*/\1/p' | ++ head -1 | tr -d '\n') ++ ++ [ $? -eq 0 ] || return ++ ++ if [[ "$ipv6" =~ ^fe80: ]]; then ++ echo -n "[$ipv6%$1]" ++ else ++ echo -n "[$ipv6]" ++ fi ++} ++ + # existing rdma interfaces + rdma_interfaces() + { +- rdma link show | sed -nE 's/^link .* netdev ([^ ]+).*$/\1 /p' ++ rdma link show | sed -nE 's/^link .* netdev ([^ ]+).*$/\1 /p' | ++ grep -Ev '^(lo|tun|tap)' + } + + # existing valid ipv4 interfaces + ipv4_interfaces() + { +- ip -o addr show | awk '/inet / {print $2}' | grep -v -w lo ++ ip -o addr show | awk '/inet / {print $2}' | grep -Ev '^(lo|tun|tap)' ++} ++ ++ipv6_interfaces() ++{ ++ ip -o addr show | awk '/inet6 / {print $2}' | grep -Ev '^(lo|tun|tap)' + } + + rdma_rxe_detect() + { ++ family=$1 + for r in $(rdma_interfaces) + do +- ipv4_interfaces | grep -qw $r && get_ipv4_addr $r && return ++ "$family"_interfaces | grep -qw $r && get_"$family"_addr $r && return + done + + return 1 +@@ -32,16 +53,23 @@ rdma_rxe_detect() + + rdma_rxe_setup() + { +- for i in $(ipv4_interfaces) ++ family=$1 ++ for i in $("$family"_interfaces) + do +- rdma_interfaces | grep -qw $i && continue ++ if rdma_interfaces | grep -qw $i; then ++ echo "$family: Reuse the existing rdma/rxe ${i}_rxe" \ ++ "for $i with $(get_"$family"_addr $i)" ++ return ++ fi ++ + rdma link add "${i}_rxe" type rxe netdev "$i" && { +- echo "Setup new rdma/rxe ${i}_rxe for $i with $(get_ipv4_addr $i)" ++ echo "$family: Setup new rdma/rxe ${i}_rxe" \ ++ "for $i with $(get_"$family"_addr $i)" + return + } + done + +- echo "Failed to setup any new rdma/rxe link" >&2 ++ echo "$family: Failed to setup any new rdma/rxe link" >&2 + return 1 + } + +@@ -50,6 +78,12 @@ rdma_rxe_clean() + modprobe -r rdma_rxe + } + ++IP_FAMILY=${IP_FAMILY:-ipv4} ++if [ "$IP_FAMILY" != "ipv6" ] && [ "$IP_FAMILY" != "ipv4" ]; then ++ echo "Unknown ip family '$IP_FAMILY', only ipv4 or ipv6 is supported." >&2 ++ exit 1 ++fi ++ + operation=${1:-detect} + + command -v rdma >/dev/null || { +@@ -62,9 +96,14 @@ if [ "$operation" == "setup" ] || [ "$operation" == "clean" ]; then + echo "Root privilege is required to setup/clean a rdma/rxe link" >&2 + exit 1 + } +- rdma_rxe_"$operation" ++ if [ "$operation" == "setup" ]; then ++ rdma_rxe_setup ipv4 ++ rdma_rxe_setup ipv6 ++ else ++ rdma_rxe_clean ++ fi + elif [ "$operation" == "detect" ]; then +- rdma_rxe_detect ++ rdma_rxe_detect "$IP_FAMILY" + else + echo "Usage: $0 [setup | detect | clean]" + fi +diff --git a/tests/qtest/migration/precopy-tests.c b/tests/qtest/migration/precopy-tests.c +index 5be1cd5742..a62d3c5378 100644 +--- a/tests/qtest/migration/precopy-tests.c ++++ b/tests/qtest/migration/precopy-tests.c +@@ -131,12 +131,13 @@ static bool mlock_check(void) + } + + #define RDMA_MIGRATION_HELPER "scripts/rdma-migration-helper.sh" +-static int new_rdma_link(char *buffer) ++static int new_rdma_link(char *buffer, bool ipv6) + { + char cmd[256]; + bool verbose = g_getenv("QTEST_LOG"); + +- snprintf(cmd, sizeof(cmd), "%s detect %s", RDMA_MIGRATION_HELPER, ++ snprintf(cmd, sizeof(cmd), "IP_FAMILY=%s %s detect %s", ++ ipv6 ? "ipv6" : "ipv4", RDMA_MIGRATION_HELPER, + verbose ? "" : "2>/dev/null"); + + FILE *pipe = popen(cmd, "r"); +@@ -161,7 +162,7 @@ static int new_rdma_link(char *buffer) + return -1; + } + +-static void test_precopy_rdma_plain(void) ++static void __test_precopy_rdma_plain(bool ipv6) + { + char buffer[128] = {}; + +@@ -170,7 +171,7 @@ static void test_precopy_rdma_plain(void) + return; + } + +- if (new_rdma_link(buffer)) { ++ if (new_rdma_link(buffer, ipv6)) { + g_test_skip("No rdma link available\n" + "# To enable the test:\n" + "# Run \'" RDMA_MIGRATION_HELPER " setup\' with root to " +@@ -193,6 +194,16 @@ static void test_precopy_rdma_plain(void) + + test_precopy_common(&args); + } ++ ++static void test_precopy_rdma_plain(void) ++{ ++ __test_precopy_rdma_plain(false); ++} ++ ++static void test_precopy_rdma_plain_ipv6(void) ++{ ++ __test_precopy_rdma_plain(true); ++} + #endif + + static void test_precopy_tcp_plain(void) +@@ -1226,6 +1237,8 @@ static void migration_test_add_precopy_smoke(MigrationTestEnv *env) + #ifdef CONFIG_RDMA + migration_test_add("/migration/precopy/rdma/plain", + test_precopy_rdma_plain); ++ migration_test_add("/migration/precopy/rdma/plain/ipv6", ++ test_precopy_rdma_plain_ipv6); + #endif + } + +-- +2.39.3 + diff --git a/kvm-qtest-migration-rdma-Enforce-RLIMIT_MEMLOCK-128MB-re.patch b/kvm-qtest-migration-rdma-Enforce-RLIMIT_MEMLOCK-128MB-re.patch new file mode 100644 index 0000000..88cceb0 --- /dev/null +++ b/kvm-qtest-migration-rdma-Enforce-RLIMIT_MEMLOCK-128MB-re.patch @@ -0,0 +1,94 @@ +From f65658024595c8fa58c5f9a6a8892d230e68e4c7 Mon Sep 17 00:00:00 2001 +From: Li Zhijian +Date: Fri, 9 May 2025 09:42:10 +0800 +Subject: [PATCH 09/33] qtest/migration/rdma: Enforce RLIMIT_MEMLOCK >= 128MB + requirement + +RH-Author: Prasad Pandit +RH-MergeRequest: 390: migration: allow to enable multifd+postcopy features together, but use multifd during precopy only +RH-Jira: RHEL-59697 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Miroslav Rezanina +RH-Commit: [9/11] bc8b4e4e55e119d1ba1e5567dfe69fe675a5f52e (pjp/cs-qemu-kvm) + +Ensure successful migration over RDMA by verifying that RLIMIT_MEMLOCK is +set to at least 128MB. This allocation is necessary due to the requirement +to pin significant portions of guest memory, typically exceeding 100MB +in this test, while the remainder is transmitted as compressed zero pages. + +Otherwise, it will fail with: +stderr: +qemu-system-x86_64: cannot get rkey +qemu-system-x86_64: error while loading state section id 2(ram) +qemu-system-x86_64: load of migration failed: Operation not permitted +qemu-system-x86_64: rdma migration: recv polling control error! +qemu-system-x86_64: RDMA is in an error state waiting migration to abort! +qemu-system-x86_64: failed to save SaveStateEntry with id(name): 2(ram): -1 +qemu-system-x86_64: Channel error: Operation not permitted + +Jira: https://issues.redhat.com/browse/RHEL-59697 +Reported-by: Peter Xu +Signed-off-by: Li Zhijian +Link: https://lore.kernel.org/r/20250509014211.1272640-1-lizhijian@fujitsu.com +Signed-off-by: Peter Xu +(cherry picked from commit 7b2e4f788d60a8ec25efbf1e6bb6552ee0cef17c) +Signed-off-by: Prasad Pandit +--- + tests/qtest/migration/precopy-tests.c | 34 +++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + +diff --git a/tests/qtest/migration/precopy-tests.c b/tests/qtest/migration/precopy-tests.c +index 87b0a7e8ef..5be1cd5742 100644 +--- a/tests/qtest/migration/precopy-tests.c ++++ b/tests/qtest/migration/precopy-tests.c +@@ -101,6 +101,35 @@ static void test_precopy_unix_dirty_ring(void) + + #ifdef CONFIG_RDMA + ++#include ++ ++/* ++ * During migration over RDMA, it will try to pin portions of guest memory, ++ * typically exceeding 100MB in this test, while the remainder will be ++ * transmitted as compressed zero pages. ++ * ++ * REQUIRED_MEMLOCK_SZ indicates the minimal mlock size in the current context. ++ */ ++#define REQUIRED_MEMLOCK_SZ (128 << 20) /* 128MB */ ++ ++/* check 'ulimit -l' */ ++static bool mlock_check(void) ++{ ++ uid_t uid; ++ struct rlimit rlim; ++ ++ uid = getuid(); ++ if (uid == 0) { ++ return true; ++ } ++ ++ if (getrlimit(RLIMIT_MEMLOCK, &rlim) != 0) { ++ return false; ++ } ++ ++ return rlim.rlim_cur >= REQUIRED_MEMLOCK_SZ; ++} ++ + #define RDMA_MIGRATION_HELPER "scripts/rdma-migration-helper.sh" + static int new_rdma_link(char *buffer) + { +@@ -136,6 +165,11 @@ static void test_precopy_rdma_plain(void) + { + char buffer[128] = {}; + ++ if (!mlock_check()) { ++ g_test_skip("'ulimit -l' is too small, require >=128M"); ++ return; ++ } ++ + if (new_rdma_link(buffer)) { + g_test_skip("No rdma link available\n" + "# To enable the test:\n" +-- +2.39.3 + diff --git a/kvm-ram-block-attributes-Introduce-RamBlockAttributes-to.patch b/kvm-ram-block-attributes-Introduce-RamBlockAttributes-to.patch new file mode 100644 index 0000000..a29aa3b --- /dev/null +++ b/kvm-ram-block-attributes-Introduce-RamBlockAttributes-to.patch @@ -0,0 +1,604 @@ +From 1b895d075eec7f0537f2631f485ef3048d215508 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 25 Jul 2025 17:47:13 +0200 +Subject: [PATCH 099/100] ram-block-attributes: Introduce RamBlockAttributes to + manage RAMBlock with guest_memfd + +Commit 852f0048f3 ("RAMBlock: make guest_memfd require uncoordinated +discard") highlighted that subsystems like VFIO may disable RAM block +discard. However, guest_memfd relies on discard operations for page +conversion between private and shared memory, potentially leading to +the stale IOMMU mapping issue when assigning hardware devices to +confidential VMs via shared memory. To address this and allow shared +device assignement, it is crucial to ensure the VFIO system refreshes +its IOMMU mappings. + +RamDiscardManager is an existing interface (used by virtio-mem) to +adjust VFIO mappings in relation to VM page assignment. Effectively page +conversion is similar to hot-removing a page in one mode and adding it +back in the other. Therefore, similar actions are required for page +conversion events. Introduce the RamDiscardManager to guest_memfd to +facilitate this process. + +Since guest_memfd is not an object, it cannot directly implement the +RamDiscardManager interface. Implementing it in HostMemoryBackend is +not appropriate because guest_memfd is per RAMBlock, and some RAMBlocks +have a memory backend while others do not. Notably, virtual BIOS +RAMBlocks using memory_region_init_ram_guest_memfd() do not have a +backend. + +To manage RAMBlocks with guest_memfd, define a new object named +RamBlockAttributes to implement the RamDiscardManager interface. This +object can store the guest_memfd information such as the bitmap for +shared memory and the registered listeners for event notifications. A +new state_change() helper function is provided to notify listeners, such +as VFIO, allowing VFIO to do dynamically DMA map and unmap for the shared +memory according to conversion events. Note that in the current context +of RamDiscardManager for guest_memfd, the shared state is analogous to +being populated, while the private state can be considered discarded for +simplicity. In the future, it would be more complicated if considering +more states like private/shared/discarded at the same time. + +In current implementation, memory state tracking is performed at the +host page size granularity, as the minimum conversion size can be one +page per request. Additionally, VFIO expected the DMA mapping for a +specific IOVA to be mapped and unmapped with the same granularity. +Confidential VMs may perform partial conversions, such as conversions on +small regions within a larger one. To prevent such invalid cases and +until support for DMA mapping cut operations is available, all +operations are performed with 4K granularity. + +In addition, memory conversion failures cause QEMU to quit rather than +resuming the guest or retrying the operation at present. It would be +future work to add more error handling or rollback mechanisms once +conversion failures are allowed. For example, in-place conversion of +guest_memfd could retry the unmap operation during the conversion from +shared to private. For now, keep the complex error handling out of the +picture as it is not required. + +Tested-by: Alexey Kardashevskiy +Reviewed-by: Alexey Kardashevskiy +Reviewed-by: Pankaj Gupta +Signed-off-by: Chenyi Qiang +Link: https://lore.kernel.org/r/20250612082747.51539-5-chenyi.qiang@intel.com +[peterx: squash fixup from Chenyi to fix builds] +Signed-off-by: Peter Xu +(cherry picked from commit 5d6483edaa9232d8f3709f68c8eab4bc2033fb70) +Signed-off-by: Paolo Bonzini + +Conflicts: context in system/meson.build and MAINTAINERS; + class_init second argument is not const +--- + MAINTAINERS | 1 + + include/system/ramblock.h | 21 ++ + system/meson.build | 1 + + system/ram-block-attributes.c | 444 ++++++++++++++++++++++++++++++++++ + system/trace-events | 3 + + 5 files changed, 470 insertions(+) + create mode 100644 system/ram-block-attributes.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index 9016c2ede2..6d7e90a813 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -3117,6 +3117,7 @@ F: system/memory.c + F: system/memory_mapping.c + F: system/physmem.c + F: include/exec/memory-internal.h ++F: system/ram-block-attributes.c + F: scripts/coccinelle/memory-region-housekeeping.cocci + + Memory devices +diff --git a/include/system/ramblock.h b/include/system/ramblock.h +index d8a116ba99..1bab9e2dac 100644 +--- a/include/system/ramblock.h ++++ b/include/system/ramblock.h +@@ -22,6 +22,10 @@ + #include "exec/cpu-common.h" + #include "qemu/rcu.h" + #include "exec/ramlist.h" ++#include "system/hostmem.h" ++ ++#define TYPE_RAM_BLOCK_ATTRIBUTES "ram-block-attributes" ++OBJECT_DECLARE_SIMPLE_TYPE(RamBlockAttributes, RAM_BLOCK_ATTRIBUTES) + + struct RAMBlock { + struct rcu_head rcu; +@@ -91,4 +95,21 @@ struct RAMBlock { + ram_addr_t postcopy_length; + }; + ++struct RamBlockAttributes { ++ Object parent; ++ ++ RAMBlock *ram_block; ++ ++ /* 1-setting of the bitmap represents ram is populated (shared) */ ++ unsigned bitmap_size; ++ unsigned long *bitmap; ++ ++ QLIST_HEAD(, RamDiscardListener) rdl_list; ++}; ++ ++RamBlockAttributes *ram_block_attributes_create(RAMBlock *ram_block); ++void ram_block_attributes_destroy(RamBlockAttributes *attr); ++int ram_block_attributes_state_change(RamBlockAttributes *attr, uint64_t offset, ++ uint64_t size, bool to_discard); ++ + #endif +diff --git a/system/meson.build b/system/meson.build +index eec07a9451..a495f28698 100644 +--- a/system/meson.build ++++ b/system/meson.build +@@ -15,6 +15,7 @@ system_ss.add(files( + 'dirtylimit.c', + 'dma-helpers.c', + 'globals.c', ++ 'ram-block-attributes.c', + 'memory_mapping.c', + 'qdev-monitor.c', + 'qtest.c', +diff --git a/system/ram-block-attributes.c b/system/ram-block-attributes.c +new file mode 100644 +index 0000000000..4ebf242ae1 +--- /dev/null ++++ b/system/ram-block-attributes.c +@@ -0,0 +1,444 @@ ++/* ++ * QEMU ram block attributes ++ * ++ * Copyright Intel ++ * ++ * Author: ++ * Chenyi Qiang ++ * ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ */ ++ ++#include "qemu/osdep.h" ++#include "qemu/error-report.h" ++#include "system/ramblock.h" ++#include "trace.h" ++ ++OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(RamBlockAttributes, ++ ram_block_attributes, ++ RAM_BLOCK_ATTRIBUTES, ++ OBJECT, ++ { TYPE_RAM_DISCARD_MANAGER }, ++ { }) ++ ++static size_t ++ram_block_attributes_get_block_size(const RamBlockAttributes *attr) ++{ ++ /* ++ * Because page conversion could be manipulated in the size of at least 4K ++ * or 4K aligned, Use the host page size as the granularity to track the ++ * memory attribute. ++ */ ++ g_assert(attr && attr->ram_block); ++ g_assert(attr->ram_block->page_size == qemu_real_host_page_size()); ++ return attr->ram_block->page_size; ++} ++ ++ ++static bool ++ram_block_attributes_rdm_is_populated(const RamDiscardManager *rdm, ++ const MemoryRegionSection *section) ++{ ++ const RamBlockAttributes *attr = RAM_BLOCK_ATTRIBUTES(rdm); ++ const size_t block_size = ram_block_attributes_get_block_size(attr); ++ const uint64_t first_bit = section->offset_within_region / block_size; ++ const uint64_t last_bit = ++ first_bit + int128_get64(section->size) / block_size - 1; ++ unsigned long first_discarded_bit; ++ ++ first_discarded_bit = find_next_zero_bit(attr->bitmap, last_bit + 1, ++ first_bit); ++ return first_discarded_bit > last_bit; ++} ++ ++typedef int (*ram_block_attributes_section_cb)(MemoryRegionSection *s, ++ void *arg); ++ ++static int ++ram_block_attributes_notify_populate_cb(MemoryRegionSection *section, ++ void *arg) ++{ ++ RamDiscardListener *rdl = arg; ++ ++ return rdl->notify_populate(rdl, section); ++} ++ ++static int ++ram_block_attributes_notify_discard_cb(MemoryRegionSection *section, ++ void *arg) ++{ ++ RamDiscardListener *rdl = arg; ++ ++ rdl->notify_discard(rdl, section); ++ return 0; ++} ++ ++static int ++ram_block_attributes_for_each_populated_section(const RamBlockAttributes *attr, ++ MemoryRegionSection *section, ++ void *arg, ++ ram_block_attributes_section_cb cb) ++{ ++ unsigned long first_bit, last_bit; ++ uint64_t offset, size; ++ const size_t block_size = ram_block_attributes_get_block_size(attr); ++ int ret = 0; ++ ++ first_bit = section->offset_within_region / block_size; ++ first_bit = find_next_bit(attr->bitmap, attr->bitmap_size, ++ first_bit); ++ ++ while (first_bit < attr->bitmap_size) { ++ MemoryRegionSection tmp = *section; ++ ++ offset = first_bit * block_size; ++ last_bit = find_next_zero_bit(attr->bitmap, attr->bitmap_size, ++ first_bit + 1) - 1; ++ size = (last_bit - first_bit + 1) * block_size; ++ ++ if (!memory_region_section_intersect_range(&tmp, offset, size)) { ++ break; ++ } ++ ++ ret = cb(&tmp, arg); ++ if (ret) { ++ error_report("%s: Failed to notify RAM discard listener: %s", ++ __func__, strerror(-ret)); ++ break; ++ } ++ ++ first_bit = find_next_bit(attr->bitmap, attr->bitmap_size, ++ last_bit + 2); ++ } ++ ++ return ret; ++} ++ ++static int ++ram_block_attributes_for_each_discarded_section(const RamBlockAttributes *attr, ++ MemoryRegionSection *section, ++ void *arg, ++ ram_block_attributes_section_cb cb) ++{ ++ unsigned long first_bit, last_bit; ++ uint64_t offset, size; ++ const size_t block_size = ram_block_attributes_get_block_size(attr); ++ int ret = 0; ++ ++ first_bit = section->offset_within_region / block_size; ++ first_bit = find_next_zero_bit(attr->bitmap, attr->bitmap_size, ++ first_bit); ++ ++ while (first_bit < attr->bitmap_size) { ++ MemoryRegionSection tmp = *section; ++ ++ offset = first_bit * block_size; ++ last_bit = find_next_bit(attr->bitmap, attr->bitmap_size, ++ first_bit + 1) - 1; ++ size = (last_bit - first_bit + 1) * block_size; ++ ++ if (!memory_region_section_intersect_range(&tmp, offset, size)) { ++ break; ++ } ++ ++ ret = cb(&tmp, arg); ++ if (ret) { ++ error_report("%s: Failed to notify RAM discard listener: %s", ++ __func__, strerror(-ret)); ++ break; ++ } ++ ++ first_bit = find_next_zero_bit(attr->bitmap, ++ attr->bitmap_size, ++ last_bit + 2); ++ } ++ ++ return ret; ++} ++ ++static uint64_t ++ram_block_attributes_rdm_get_min_granularity(const RamDiscardManager *rdm, ++ const MemoryRegion *mr) ++{ ++ const RamBlockAttributes *attr = RAM_BLOCK_ATTRIBUTES(rdm); ++ ++ g_assert(mr == attr->ram_block->mr); ++ return ram_block_attributes_get_block_size(attr); ++} ++ ++static void ++ram_block_attributes_rdm_register_listener(RamDiscardManager *rdm, ++ RamDiscardListener *rdl, ++ MemoryRegionSection *section) ++{ ++ RamBlockAttributes *attr = RAM_BLOCK_ATTRIBUTES(rdm); ++ int ret; ++ ++ g_assert(section->mr == attr->ram_block->mr); ++ rdl->section = memory_region_section_new_copy(section); ++ ++ QLIST_INSERT_HEAD(&attr->rdl_list, rdl, next); ++ ++ ret = ram_block_attributes_for_each_populated_section(attr, section, rdl, ++ ram_block_attributes_notify_populate_cb); ++ if (ret) { ++ error_report("%s: Failed to register RAM discard listener: %s", ++ __func__, strerror(-ret)); ++ exit(1); ++ } ++} ++ ++static void ++ram_block_attributes_rdm_unregister_listener(RamDiscardManager *rdm, ++ RamDiscardListener *rdl) ++{ ++ RamBlockAttributes *attr = RAM_BLOCK_ATTRIBUTES(rdm); ++ int ret; ++ ++ g_assert(rdl->section); ++ g_assert(rdl->section->mr == attr->ram_block->mr); ++ ++ if (rdl->double_discard_supported) { ++ rdl->notify_discard(rdl, rdl->section); ++ } else { ++ ret = ram_block_attributes_for_each_populated_section(attr, ++ rdl->section, rdl, ram_block_attributes_notify_discard_cb); ++ if (ret) { ++ error_report("%s: Failed to unregister RAM discard listener: %s", ++ __func__, strerror(-ret)); ++ exit(1); ++ } ++ } ++ ++ memory_region_section_free_copy(rdl->section); ++ rdl->section = NULL; ++ QLIST_REMOVE(rdl, next); ++} ++ ++typedef struct RamBlockAttributesReplayData { ++ ReplayRamDiscardState fn; ++ void *opaque; ++} RamBlockAttributesReplayData; ++ ++static int ram_block_attributes_rdm_replay_cb(MemoryRegionSection *section, ++ void *arg) ++{ ++ RamBlockAttributesReplayData *data = arg; ++ ++ return data->fn(section, data->opaque); ++} ++ ++static int ++ram_block_attributes_rdm_replay_populated(const RamDiscardManager *rdm, ++ MemoryRegionSection *section, ++ ReplayRamDiscardState replay_fn, ++ void *opaque) ++{ ++ RamBlockAttributes *attr = RAM_BLOCK_ATTRIBUTES(rdm); ++ RamBlockAttributesReplayData data = { .fn = replay_fn, .opaque = opaque }; ++ ++ g_assert(section->mr == attr->ram_block->mr); ++ return ram_block_attributes_for_each_populated_section(attr, section, &data, ++ ram_block_attributes_rdm_replay_cb); ++} ++ ++static int ++ram_block_attributes_rdm_replay_discarded(const RamDiscardManager *rdm, ++ MemoryRegionSection *section, ++ ReplayRamDiscardState replay_fn, ++ void *opaque) ++{ ++ RamBlockAttributes *attr = RAM_BLOCK_ATTRIBUTES(rdm); ++ RamBlockAttributesReplayData data = { .fn = replay_fn, .opaque = opaque }; ++ ++ g_assert(section->mr == attr->ram_block->mr); ++ return ram_block_attributes_for_each_discarded_section(attr, section, &data, ++ ram_block_attributes_rdm_replay_cb); ++} ++ ++static bool ++ram_block_attributes_is_valid_range(RamBlockAttributes *attr, uint64_t offset, ++ uint64_t size) ++{ ++ MemoryRegion *mr = attr->ram_block->mr; ++ ++ g_assert(mr); ++ ++ uint64_t region_size = memory_region_size(mr); ++ const size_t block_size = ram_block_attributes_get_block_size(attr); ++ ++ if (!QEMU_IS_ALIGNED(offset, block_size) || ++ !QEMU_IS_ALIGNED(size, block_size)) { ++ return false; ++ } ++ if (offset + size <= offset) { ++ return false; ++ } ++ if (offset + size > region_size) { ++ return false; ++ } ++ return true; ++} ++ ++static void ram_block_attributes_notify_discard(RamBlockAttributes *attr, ++ uint64_t offset, ++ uint64_t size) ++{ ++ RamDiscardListener *rdl; ++ ++ QLIST_FOREACH(rdl, &attr->rdl_list, next) { ++ MemoryRegionSection tmp = *rdl->section; ++ ++ if (!memory_region_section_intersect_range(&tmp, offset, size)) { ++ continue; ++ } ++ rdl->notify_discard(rdl, &tmp); ++ } ++} ++ ++static int ++ram_block_attributes_notify_populate(RamBlockAttributes *attr, ++ uint64_t offset, uint64_t size) ++{ ++ RamDiscardListener *rdl; ++ int ret = 0; ++ ++ QLIST_FOREACH(rdl, &attr->rdl_list, next) { ++ MemoryRegionSection tmp = *rdl->section; ++ ++ if (!memory_region_section_intersect_range(&tmp, offset, size)) { ++ continue; ++ } ++ ret = rdl->notify_populate(rdl, &tmp); ++ if (ret) { ++ break; ++ } ++ } ++ ++ return ret; ++} ++ ++int ram_block_attributes_state_change(RamBlockAttributes *attr, ++ uint64_t offset, uint64_t size, ++ bool to_discard) ++{ ++ const size_t block_size = ram_block_attributes_get_block_size(attr); ++ const unsigned long first_bit = offset / block_size; ++ const unsigned long nbits = size / block_size; ++ const unsigned long last_bit = first_bit + nbits - 1; ++ const bool is_discarded = find_next_bit(attr->bitmap, attr->bitmap_size, ++ first_bit) > last_bit; ++ const bool is_populated = find_next_zero_bit(attr->bitmap, ++ attr->bitmap_size, first_bit) > last_bit; ++ unsigned long bit; ++ int ret = 0; ++ ++ if (!ram_block_attributes_is_valid_range(attr, offset, size)) { ++ error_report("%s, invalid range: offset 0x%" PRIx64 ", size " ++ "0x%" PRIx64, __func__, offset, size); ++ return -EINVAL; ++ } ++ ++ trace_ram_block_attributes_state_change(offset, size, ++ is_discarded ? "discarded" : ++ is_populated ? "populated" : ++ "mixture", ++ to_discard ? "discarded" : ++ "populated"); ++ if (to_discard) { ++ if (is_discarded) { ++ /* Already private */ ++ } else if (is_populated) { ++ /* Completely shared */ ++ bitmap_clear(attr->bitmap, first_bit, nbits); ++ ram_block_attributes_notify_discard(attr, offset, size); ++ } else { ++ /* Unexpected mixture: process individual blocks */ ++ for (bit = first_bit; bit < first_bit + nbits; bit++) { ++ if (!test_bit(bit, attr->bitmap)) { ++ continue; ++ } ++ clear_bit(bit, attr->bitmap); ++ ram_block_attributes_notify_discard(attr, bit * block_size, ++ block_size); ++ } ++ } ++ } else { ++ if (is_populated) { ++ /* Already shared */ ++ } else if (is_discarded) { ++ /* Completely private */ ++ bitmap_set(attr->bitmap, first_bit, nbits); ++ ret = ram_block_attributes_notify_populate(attr, offset, size); ++ } else { ++ /* Unexpected mixture: process individual blocks */ ++ for (bit = first_bit; bit < first_bit + nbits; bit++) { ++ if (test_bit(bit, attr->bitmap)) { ++ continue; ++ } ++ set_bit(bit, attr->bitmap); ++ ret = ram_block_attributes_notify_populate(attr, ++ bit * block_size, ++ block_size); ++ if (ret) { ++ break; ++ } ++ } ++ } ++ } ++ ++ return ret; ++} ++ ++RamBlockAttributes *ram_block_attributes_create(RAMBlock *ram_block) ++{ ++ const int block_size = qemu_real_host_page_size(); ++ RamBlockAttributes *attr; ++ MemoryRegion *mr = ram_block->mr; ++ ++ attr = RAM_BLOCK_ATTRIBUTES(object_new(TYPE_RAM_BLOCK_ATTRIBUTES)); ++ ++ attr->ram_block = ram_block; ++ if (memory_region_set_ram_discard_manager(mr, RAM_DISCARD_MANAGER(attr))) { ++ object_unref(OBJECT(attr)); ++ return NULL; ++ } ++ attr->bitmap_size = ++ ROUND_UP(int128_get64(mr->size), block_size) / block_size; ++ attr->bitmap = bitmap_new(attr->bitmap_size); ++ ++ return attr; ++} ++ ++void ram_block_attributes_destroy(RamBlockAttributes *attr) ++{ ++ g_assert(attr); ++ ++ g_free(attr->bitmap); ++ memory_region_set_ram_discard_manager(attr->ram_block->mr, NULL); ++ object_unref(OBJECT(attr)); ++} ++ ++static void ram_block_attributes_init(Object *obj) ++{ ++ RamBlockAttributes *attr = RAM_BLOCK_ATTRIBUTES(obj); ++ ++ QLIST_INIT(&attr->rdl_list); ++} ++ ++static void ram_block_attributes_finalize(Object *obj) ++{ ++} ++ ++static void ram_block_attributes_class_init(ObjectClass *klass, ++ void *data) ++{ ++ RamDiscardManagerClass *rdmc = RAM_DISCARD_MANAGER_CLASS(klass); ++ ++ rdmc->get_min_granularity = ram_block_attributes_rdm_get_min_granularity; ++ rdmc->register_listener = ram_block_attributes_rdm_register_listener; ++ rdmc->unregister_listener = ram_block_attributes_rdm_unregister_listener; ++ rdmc->is_populated = ram_block_attributes_rdm_is_populated; ++ rdmc->replay_populated = ram_block_attributes_rdm_replay_populated; ++ rdmc->replay_discarded = ram_block_attributes_rdm_replay_discarded; ++} +diff --git a/system/trace-events b/system/trace-events +index be12ebfb41..82856e44f2 100644 +--- a/system/trace-events ++++ b/system/trace-events +@@ -52,3 +52,6 @@ dirtylimit_state_finalize(void) + dirtylimit_throttle_pct(int cpu_index, uint64_t pct, int64_t time_us) "CPU[%d] throttle percent: %" PRIu64 ", throttle adjust time %"PRIi64 " us" + dirtylimit_set_vcpu(int cpu_index, uint64_t quota) "CPU[%d] set dirty page rate limit %"PRIu64 + dirtylimit_vcpu_execute(int cpu_index, int64_t sleep_time_us) "CPU[%d] sleep %"PRIi64 " us" ++ ++# ram-block-attributes.c ++ram_block_attributes_state_change(uint64_t offset, uint64_t size, const char *from, const char *to) "offset 0x%"PRIx64" size 0x%"PRIx64" from '%s' to '%s'" +-- +2.47.3 + diff --git a/kvm-rbd-Fix-.bdrv_get_specific_info-implementation.patch b/kvm-rbd-Fix-.bdrv_get_specific_info-implementation.patch index e075b2e..67f27e7 100644 --- a/kvm-rbd-Fix-.bdrv_get_specific_info-implementation.patch +++ b/kvm-rbd-Fix-.bdrv_get_specific_info-implementation.patch @@ -1,14 +1,14 @@ -From 5e740433a670589d7aa42132d26cb273774180f7 Mon Sep 17 00:00:00 2001 +From 1fe4e3379f5f3ae4e5554b18b4b8c50fedd9203f Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Mon, 11 Aug 2025 15:40:10 +0200 Subject: [PATCH] rbd: Fix .bdrv_get_specific_info implementation RH-Author: Kevin Wolf -RH-MergeRequest: 472: rbd: Fix .bdrv_get_specific_info implementation -RH-Jira: RHEL-108727 -RH-Acked-by: Stefan Hajnoczi +RH-MergeRequest: 399: rbd: Fix .bdrv_get_specific_info implementation +RH-Jira: RHEL-105440 RH-Acked-by: Hanna Czenczek -RH-Commit: [1/1] 07a51d085cfceef48592cee7227a7151c6eb6c04 (kmwolf/rhel-qemu-kvm) +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [1/1] 840c954c84c97f768ae6cfb4aa0e2766b22a6f06 (kmwolf/centos-qemu-kvm) qemu_rbd_get_specific_info() has at least two problems: @@ -57,7 +57,7 @@ Signed-off-by: Kevin Wolf 2 files changed, 76 insertions(+), 37 deletions(-) diff --git a/block/rbd.c b/block/rbd.c -index 9c0fd0cb3f..fa9aab12ab 100644 +index 4f3d42a8e7..9b7b834f04 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -99,6 +99,14 @@ typedef struct BDRVRBDState { @@ -249,7 +249,7 @@ index 9c0fd0cb3f..fa9aab12ab 100644 return spec_info; diff --git a/qapi/block-core.json b/qapi/block-core.json -index c1af3d1f7d..a2fa277245 100644 +index 7f70ec6d3c..d00161af87 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -158,7 +158,14 @@ diff --git a/kvm-redhat-allow-5-level-paging-for-TDX-VMs.patch b/kvm-redhat-allow-5-level-paging-for-TDX-VMs.patch new file mode 100644 index 0000000..378c9a5 --- /dev/null +++ b/kvm-redhat-allow-5-level-paging-for-TDX-VMs.patch @@ -0,0 +1,25 @@ +From e4f00a4fc134fd14a63fa189d6f8c5054eb5ebcf Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:50 +0200 +Subject: [PATCH 095/100] redhat: allow 5-level paging for TDX VMs + +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index cc46c0e2f1..33223a550d 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -754,6 +754,7 @@ static void tdx_cpu_instance_init(X86ConfidentialGuest *cg, CPUState *cpu) + } + + object_property_set_bool(OBJECT(cpu), "pmu", false, &error_abort); ++ object_property_set_int(OBJECT(cpu), "host-phys-bits-limit", 0, &error_abort); + + /* invtsc is fixed1 for TD guest */ + object_property_set_bool(OBJECT(cpu), "invtsc", true, &error_abort); +-- +2.47.3 + diff --git a/kvm-redhat-enable-CONFIG_TDX.patch b/kvm-redhat-enable-CONFIG_TDX.patch new file mode 100644 index 0000000..2a6686f --- /dev/null +++ b/kvm-redhat-enable-CONFIG_TDX.patch @@ -0,0 +1,25 @@ +From 7c2bff201e7b6cba8300658114667dd453c29f02 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:50 +0200 +Subject: [PATCH 094/100] redhat: enable CONFIG_TDX + +Signed-off-by: Paolo Bonzini +--- + 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 828cb8aa6f..c8dac4d083 100644 +--- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak ++++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak +@@ -74,6 +74,7 @@ CONFIG_SERIAL_PCI=y + CONFIG_SEV=y + CONFIG_SMBIOS=y + CONFIG_SMBUS_EEPROM=y ++CONFIG_TDX=y + CONFIG_TEST_DEVICES=y + CONFIG_USB=y + CONFIG_USB_EHCI=y +-- +2.47.3 + diff --git a/kvm-remove-stale-compat-definitions.patch b/kvm-remove-stale-compat-definitions.patch deleted file mode 100644 index cc1180f..0000000 --- a/kvm-remove-stale-compat-definitions.patch +++ /dev/null @@ -1,425 +0,0 @@ -From 3cb4688b0b353296724b75772725e80fe2486958 Mon Sep 17 00:00:00 2001 -From: Sebastian Ott -Date: Fri, 19 Apr 2024 17:20:49 +0200 -Subject: [PATCH 7/9] remove stale compat definitions - -RH-Author: Sebastian Ott -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 -RH-Acked-by: Cornelia Huck -RH-Acked-by: Eric Auger -RH-Commit: [7/7] b8dd0980c40974787ed80ccd216c299f0a1aefb7 (seott1/cos-qemu-kvm) - -Get rid of unused [pc|hw_compat]_rhel_[7|8]* definitions. - -Signed-off-by: Sebastian Ott ---- - hw/core/machine.c | 196 ------------------------------------------- - hw/i386/pc.c | 115 ------------------------- - include/hw/boards.h | 24 ------ - include/hw/i386/pc.h | 21 ----- - 4 files changed, 356 deletions(-) - -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 9cf8242b32..d95f246f66 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -407,202 +407,6 @@ GlobalProperty hw_compat_rhel_9_0[] = { - }; - const size_t hw_compat_rhel_9_0_len = G_N_ELEMENTS(hw_compat_rhel_9_0); - --GlobalProperty hw_compat_rhel_8_6[] = { -- /* hw_compat_rhel_8_6 bz 2065589 */ -- /* -- * vhost-vsock device in RHEL 8 kernels doesn't support seqpacket, so -- * we need do disable it downstream on the latest hw_compat_rhel_8. -- */ -- { "vhost-vsock-device", "seqpacket", "off" }, --}; --const size_t hw_compat_rhel_8_6_len = G_N_ELEMENTS(hw_compat_rhel_8_6); -- --/* -- * Mostly the same as hw_compat_6_0 and hw_compat_6_1 -- */ --GlobalProperty hw_compat_rhel_8_5[] = { -- /* hw_compat_rhel_8_5 from hw_compat_6_0 */ -- { "gpex-pcihost", "allow-unmapped-accesses", "false" }, -- /* hw_compat_rhel_8_5 from hw_compat_6_0 */ -- { "i8042", "extended-state", "false"}, -- /* hw_compat_rhel_8_5 from hw_compat_6_0 */ -- { "nvme-ns", "eui64-default", "off"}, -- /* hw_compat_rhel_8_5 from hw_compat_6_0 */ -- { "e1000", "init-vet", "off" }, -- /* hw_compat_rhel_8_5 from hw_compat_6_0 */ -- { "e1000e", "init-vet", "off" }, -- /* hw_compat_rhel_8_5 from hw_compat_6_0 */ -- { "vhost-vsock-device", "seqpacket", "off" }, -- /* hw_compat_rhel_8_5 from hw_compat_6_1 */ -- { "vhost-user-vsock-device", "seqpacket", "off" }, -- /* hw_compat_rhel_8_5 from hw_compat_6_1 */ -- { "nvme-ns", "shared", "off" }, --}; --const size_t hw_compat_rhel_8_5_len = G_N_ELEMENTS(hw_compat_rhel_8_5); -- --/* -- * Mostly the same as hw_compat_5_2 -- */ --GlobalProperty hw_compat_rhel_8_4[] = { -- /* hw_compat_rhel_8_4 from hw_compat_5_2 */ -- { "ICH9-LPC", "smm-compat", "on"}, -- /* hw_compat_rhel_8_4 from hw_compat_5_2 */ -- { "PIIX4_PM", "smm-compat", "on"}, -- /* hw_compat_rhel_8_4 from hw_compat_5_2 */ -- { "virtio-blk-device", "report-discard-granularity", "off" }, -- /* hw_compat_rhel_8_4 from hw_compat_5_2 */ -- /* -- * Upstream incorrectly had "virtio-net-pci" instead of "virtio-net-pci-base", -- * (https://bugzilla.redhat.com/show_bug.cgi?id=1999141) -- */ -- { "virtio-net-pci-base", "vectors", "3"}, --}; --const size_t hw_compat_rhel_8_4_len = G_N_ELEMENTS(hw_compat_rhel_8_4); -- --/* -- * Mostly the same as hw_compat_5_1 -- */ --GlobalProperty hw_compat_rhel_8_3[] = { -- /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -- { "vhost-scsi", "num_queues", "1"}, -- /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -- { "vhost-user-blk", "num-queues", "1"}, -- /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -- { "vhost-user-scsi", "num_queues", "1"}, -- /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -- { "virtio-blk-device", "num-queues", "1"}, -- /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -- { "virtio-scsi-device", "num_queues", "1"}, -- /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -- { "nvme", "use-intel-id", "on"}, -- /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -- { "pvpanic", "events", "1"}, /* PVPANIC_PANICKED */ -- /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -- { "pl011", "migrate-clk", "off" }, -- /* hw_compat_rhel_8_3 bz 1912846 */ -- { "pci-xhci", "x-rh-late-msi-cap", "off" }, -- /* hw_compat_rhel_8_3 from hw_compat_5_1 */ -- { "virtio-pci", "x-ats-page-aligned", "off"}, --}; --const size_t hw_compat_rhel_8_3_len = G_N_ELEMENTS(hw_compat_rhel_8_3); -- --/* -- * The same as hw_compat_4_2 + hw_compat_5_0 -- */ --GlobalProperty hw_compat_rhel_8_2[] = { -- /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -- { "virtio-blk-device", "queue-size", "128"}, -- /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -- { "virtio-scsi-device", "virtqueue_size", "128"}, -- /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -- { "virtio-blk-device", "x-enable-wce-if-config-wce", "off" }, -- /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -- { "virtio-blk-device", "seg-max-adjust", "off"}, -- /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -- { "virtio-scsi-device", "seg_max_adjust", "off"}, -- /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -- { "vhost-blk-device", "seg_max_adjust", "off"}, -- /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -- { "usb-host", "suppress-remote-wake", "off" }, -- /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -- { "usb-redir", "suppress-remote-wake", "off" }, -- /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -- { "qxl", "revision", "4" }, -- /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -- { "qxl-vga", "revision", "4" }, -- /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -- { "fw_cfg", "acpi-mr-restore", "false" }, -- /* hw_compat_rhel_8_2 from hw_compat_4_2 */ -- { "virtio-device", "use-disabled-flag", "false" }, -- /* hw_compat_rhel_8_2 from hw_compat_5_0 */ -- { "pci-host-bridge", "x-config-reg-migration-enabled", "off" }, -- /* hw_compat_rhel_8_2 from hw_compat_5_0 */ -- { "virtio-balloon-device", "page-poison", "false" }, -- /* hw_compat_rhel_8_2 from hw_compat_5_0 */ -- { "vmport", "x-read-set-eax", "off" }, -- /* hw_compat_rhel_8_2 from hw_compat_5_0 */ -- { "vmport", "x-signal-unsupported-cmd", "off" }, -- /* hw_compat_rhel_8_2 from hw_compat_5_0 */ -- { "vmport", "x-report-vmx-type", "off" }, -- /* hw_compat_rhel_8_2 from hw_compat_5_0 */ -- { "vmport", "x-cmds-v2", "off" }, -- /* hw_compat_rhel_8_2 from hw_compat_5_0 */ -- { "virtio-device", "x-disable-legacy-check", "true" }, --}; --const size_t hw_compat_rhel_8_2_len = G_N_ELEMENTS(hw_compat_rhel_8_2); -- --/* -- * The same as hw_compat_4_1 -- */ --GlobalProperty hw_compat_rhel_8_1[] = { -- /* hw_compat_rhel_8_1 from hw_compat_4_1 */ -- { "virtio-pci", "x-pcie-flr-init", "off" }, --}; --const size_t hw_compat_rhel_8_1_len = G_N_ELEMENTS(hw_compat_rhel_8_1); -- --/* The same as hw_compat_3_1 -- * format of array has been changed by: -- * 6c36bddf5340 ("machine: Use shorter format for GlobalProperty arrays") -- */ --GlobalProperty hw_compat_rhel_8_0[] = { -- /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -- { "pcie-root-port", "x-speed", "2_5" }, -- /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -- { "pcie-root-port", "x-width", "1" }, -- /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -- { "memory-backend-file", "x-use-canonical-path-for-ramblock-id", "true" }, -- /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -- { "memory-backend-memfd", "x-use-canonical-path-for-ramblock-id", "true" }, -- /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -- { "tpm-crb", "ppi", "false" }, -- /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -- { "tpm-tis", "ppi", "false" }, -- /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -- { "usb-kbd", "serial", "42" }, -- /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -- { "usb-mouse", "serial", "42" }, -- /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -- { "usb-tablet", "serial", "42" }, -- /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -- { "virtio-blk-device", "discard", "false" }, -- /* hw_compat_rhel_8_0 from hw_compat_3_1 */ -- { "virtio-blk-device", "write-zeroes", "false" }, -- /* hw_compat_rhel_8_0 from hw_compat_4_0 */ -- { "VGA", "edid", "false" }, -- /* hw_compat_rhel_8_0 from hw_compat_4_0 */ -- { "secondary-vga", "edid", "false" }, -- /* hw_compat_rhel_8_0 from hw_compat_4_0 */ -- { "bochs-display", "edid", "false" }, -- /* hw_compat_rhel_8_0 from hw_compat_4_0 */ -- { "virtio-vga", "edid", "false" }, -- /* hw_compat_rhel_8_0 from hw_compat_4_0 */ -- { "virtio-gpu-device", "edid", "false" }, -- /* hw_compat_rhel_8_0 from hw_compat_4_0 */ -- { "virtio-device", "use-started", "false" }, -- /* hw_compat_rhel_8_0 from hw_compat_3_1 - that was added in 4.1 */ -- { "pcie-root-port-base", "disable-acs", "true" }, --}; --const size_t hw_compat_rhel_8_0_len = G_N_ELEMENTS(hw_compat_rhel_8_0); -- --/* The same as hw_compat_3_0 + hw_compat_2_12 -- * except that -- * there's nothing in 3_0 -- * migration.decompress-error-check=off was in 7.5 from bz 1584139 -- */ --GlobalProperty hw_compat_rhel_7_6[] = { -- /* hw_compat_rhel_7_6 from hw_compat_2_12 */ -- { "hda-audio", "use-timer", "false" }, -- /* hw_compat_rhel_7_6 from hw_compat_2_12 */ -- { "cirrus-vga", "global-vmstate", "true" }, -- /* hw_compat_rhel_7_6 from hw_compat_2_12 */ -- { "VGA", "global-vmstate", "true" }, -- /* hw_compat_rhel_7_6 from hw_compat_2_12 */ -- { "vmware-svga", "global-vmstate", "true" }, -- /* hw_compat_rhel_7_6 from hw_compat_2_12 */ -- { "qxl-vga", "global-vmstate", "true" }, --}; --const size_t hw_compat_rhel_7_6_len = G_N_ELEMENTS(hw_compat_rhel_7_6); -- - MachineState *current_machine; - - static char *machine_get_kernel(Object *obj, Error **errp) -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index a49d346d2e..7af762065f 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -316,121 +316,6 @@ GlobalProperty pc_rhel_9_0_compat[] = { - }; - const size_t pc_rhel_9_0_compat_len = G_N_ELEMENTS(pc_rhel_9_0_compat); - --GlobalProperty pc_rhel_8_5_compat[] = { -- /* pc_rhel_8_5_compat from pc_compat_6_0 */ -- { "qemu64" "-" TYPE_X86_CPU, "family", "6" }, -- /* pc_rhel_8_5_compat from pc_compat_6_0 */ -- { "qemu64" "-" TYPE_X86_CPU, "model", "6" }, -- /* pc_rhel_8_5_compat from pc_compat_6_0 */ -- { "qemu64" "-" TYPE_X86_CPU, "stepping", "3" }, -- /* pc_rhel_8_5_compat from pc_compat_6_0 */ -- { TYPE_X86_CPU, "x-vendor-cpuid-only", "off" }, -- /* pc_rhel_8_5_compat from pc_compat_6_0 */ -- { "ICH9-LPC", ACPI_PM_PROP_ACPI_PCIHP_BRIDGE, "off" }, -- -- /* pc_rhel_8_5_compat from pc_compat_6_1 */ -- { TYPE_X86_CPU, "hv-version-id-build", "0x1bbc" }, -- /* pc_rhel_8_5_compat from pc_compat_6_1 */ -- { TYPE_X86_CPU, "hv-version-id-major", "0x0006" }, -- /* pc_rhel_8_5_compat from pc_compat_6_1 */ -- { TYPE_X86_CPU, "hv-version-id-minor", "0x0001" }, --}; --const size_t pc_rhel_8_5_compat_len = G_N_ELEMENTS(pc_rhel_8_5_compat); -- --GlobalProperty pc_rhel_8_4_compat[] = { -- /* pc_rhel_8_4_compat from pc_compat_5_2 */ -- { "ICH9-LPC", "x-smi-cpu-hotunplug", "off" }, -- { TYPE_X86_CPU, "kvm-asyncpf-int", "off" }, --}; --const size_t pc_rhel_8_4_compat_len = G_N_ELEMENTS(pc_rhel_8_4_compat); -- --GlobalProperty pc_rhel_8_3_compat[] = { -- /* pc_rhel_8_3_compat from pc_compat_5_1 */ -- { "ICH9-LPC", "x-smi-cpu-hotplug", "off" }, --}; --const size_t pc_rhel_8_3_compat_len = G_N_ELEMENTS(pc_rhel_8_3_compat); -- --GlobalProperty pc_rhel_8_2_compat[] = { -- /* pc_rhel_8_2_compat from pc_compat_4_2 */ -- { "mch", "smbase-smram", "off" }, --}; --const size_t pc_rhel_8_2_compat_len = G_N_ELEMENTS(pc_rhel_8_2_compat); -- --/* pc_rhel_8_1_compat is empty since pc_4_1_compat is */ --GlobalProperty pc_rhel_8_1_compat[] = { }; --const size_t pc_rhel_8_1_compat_len = G_N_ELEMENTS(pc_rhel_8_1_compat); -- --GlobalProperty pc_rhel_8_0_compat[] = { -- /* pc_rhel_8_0_compat from pc_compat_3_1 */ -- { "intel-iommu", "dma-drain", "off" }, -- /* pc_rhel_8_0_compat from pc_compat_3_1 */ -- { "Opteron_G3" "-" TYPE_X86_CPU, "rdtscp", "off" }, -- /* pc_rhel_8_0_compat from pc_compat_3_1 */ -- { "Opteron_G4" "-" TYPE_X86_CPU, "rdtscp", "off" }, -- /* pc_rhel_8_0_compat from pc_compat_3_1 */ -- { "Opteron_G4" "-" TYPE_X86_CPU, "npt", "off" }, -- /* pc_rhel_8_0_compat from pc_compat_3_1 */ -- { "Opteron_G4" "-" TYPE_X86_CPU, "nrip-save", "off" }, -- /* pc_rhel_8_0_compat from pc_compat_3_1 */ -- { "Opteron_G5" "-" TYPE_X86_CPU, "rdtscp", "off" }, -- /* pc_rhel_8_0_compat from pc_compat_3_1 */ -- { "Opteron_G5" "-" TYPE_X86_CPU, "npt", "off" }, -- /* pc_rhel_8_0_compat from pc_compat_3_1 */ -- { "Opteron_G5" "-" TYPE_X86_CPU, "nrip-save", "off" }, -- /* pc_rhel_8_0_compat from pc_compat_3_1 */ -- { "EPYC" "-" TYPE_X86_CPU, "npt", "off" }, -- /* pc_rhel_8_0_compat from pc_compat_3_1 */ -- { "EPYC" "-" TYPE_X86_CPU, "nrip-save", "off" }, -- /* pc_rhel_8_0_compat from pc_compat_3_1 */ -- { "EPYC-IBPB" "-" TYPE_X86_CPU, "npt", "off" }, -- /* pc_rhel_8_0_compat from pc_compat_3_1 */ -- { "EPYC-IBPB" "-" TYPE_X86_CPU, "nrip-save", "off" }, -- /** The mpx=on entries from pc_compat_3_1 are in pc_rhel_7_6_compat **/ -- /* pc_rhel_8_0_compat from pc_compat_3_1 */ -- { "Cascadelake-Server" "-" TYPE_X86_CPU, "stepping", "5" }, -- /* pc_rhel_8_0_compat from pc_compat_3_1 */ -- { TYPE_X86_CPU, "x-intel-pt-auto-level", "off" }, --}; --const size_t pc_rhel_8_0_compat_len = G_N_ELEMENTS(pc_rhel_8_0_compat); -- --/* Similar to PC_COMPAT_3_0 + PC_COMPAT_2_12, but: -- * all of the 2_12 stuff was already in 7.6 from bz 1481253 -- * x-migrate-smi-count comes from PC_COMPAT_2_11 but -- * is really tied to kernel version so keep it off on 7.x -- * machine types irrespective of host. -- */ --GlobalProperty pc_rhel_7_6_compat[] = { -- /* pc_rhel_7_6_compat from pc_compat_3_0 */ -- { TYPE_X86_CPU, "x-hv-synic-kvm-only", "on" }, -- /* pc_rhel_7_6_compat from pc_compat_3_0 */ -- { "Skylake-Server" "-" TYPE_X86_CPU, "pku", "off" }, -- /* pc_rhel_7_6_compat from pc_compat_3_0 */ -- { "Skylake-Server-IBRS" "-" TYPE_X86_CPU, "pku", "off" }, -- /* pc_rhel_7_6_compat from pc_compat_2_11 */ -- { TYPE_X86_CPU, "x-migrate-smi-count", "off" }, -- /* pc_rhel_7_6_compat from pc_compat_2_11 */ -- { "Skylake-Client" "-" TYPE_X86_CPU, "mpx", "on" }, -- /* pc_rhel_7_6_compat from pc_compat_2_11 */ -- { "Skylake-Client-IBRS" "-" TYPE_X86_CPU, "mpx", "on" }, -- /* pc_rhel_7_6_compat from pc_compat_2_11 */ -- { "Skylake-Server" "-" TYPE_X86_CPU, "mpx", "on" }, -- /* pc_rhel_7_6_compat from pc_compat_2_11 */ -- { "Skylake-Server-IBRS" "-" TYPE_X86_CPU, "mpx", "on" }, -- /* pc_rhel_7_6_compat from pc_compat_2_11 */ -- { "Cascadelake-Server" "-" TYPE_X86_CPU, "mpx", "on" }, -- /* pc_rhel_7_6_compat from pc_compat_2_11 */ -- { "Icelake-Client" "-" TYPE_X86_CPU, "mpx", "on" }, -- /* pc_rhel_7_6_compat from pc_compat_2_11 */ -- { "Icelake-Server" "-" TYPE_X86_CPU, "mpx", "on" }, --}; --const size_t pc_rhel_7_6_compat_len = G_N_ELEMENTS(pc_rhel_7_6_compat); -- --/* -- * The PC_RHEL_*_COMPAT serve the same purpose for RHEL-7 machine -- * types as the PC_COMPAT_* do for upstream types. -- * PC_RHEL_7_*_COMPAT apply both to i440fx and q35 types. -- */ -- - GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled) - { - GSIState *s; -diff --git a/include/hw/boards.h b/include/hw/boards.h -index 6d98aaf4c7..ac917b87fb 100644 ---- a/include/hw/boards.h -+++ b/include/hw/boards.h -@@ -823,29 +823,5 @@ extern const size_t hw_compat_rhel_9_1_len; - extern GlobalProperty hw_compat_rhel_9_0[]; - extern const size_t hw_compat_rhel_9_0_len; - --extern GlobalProperty hw_compat_rhel_8_6[]; --extern const size_t hw_compat_rhel_8_6_len; -- --extern GlobalProperty hw_compat_rhel_8_5[]; --extern const size_t hw_compat_rhel_8_5_len; -- --extern GlobalProperty hw_compat_rhel_8_4[]; --extern const size_t hw_compat_rhel_8_4_len; -- --extern GlobalProperty hw_compat_rhel_8_3[]; --extern const size_t hw_compat_rhel_8_3_len; -- --extern GlobalProperty hw_compat_rhel_8_2[]; --extern const size_t hw_compat_rhel_8_2_len; -- --extern GlobalProperty hw_compat_rhel_8_1[]; --extern const size_t hw_compat_rhel_8_1_len; -- --extern GlobalProperty hw_compat_rhel_8_0[]; --extern const size_t hw_compat_rhel_8_0_len; -- --extern GlobalProperty hw_compat_rhel_7_6[]; --extern const size_t hw_compat_rhel_7_6_len; -- - extern const char *rhel_old_machine_deprecation; - #endif -diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index 8e9597f40f..61609027d0 100644 ---- a/include/hw/i386/pc.h -+++ b/include/hw/i386/pc.h -@@ -314,27 +314,6 @@ extern const size_t pc_rhel_9_2_compat_len; - extern GlobalProperty pc_rhel_9_0_compat[]; - extern const size_t pc_rhel_9_0_compat_len; - --extern GlobalProperty pc_rhel_8_5_compat[]; --extern const size_t pc_rhel_8_5_compat_len; -- --extern GlobalProperty pc_rhel_8_4_compat[]; --extern const size_t pc_rhel_8_4_compat_len; -- --extern GlobalProperty pc_rhel_8_3_compat[]; --extern const size_t pc_rhel_8_3_compat_len; -- --extern GlobalProperty pc_rhel_8_2_compat[]; --extern const size_t pc_rhel_8_2_compat_len; -- --extern GlobalProperty pc_rhel_8_1_compat[]; --extern const size_t pc_rhel_8_1_compat_len; -- --extern GlobalProperty pc_rhel_8_0_compat[]; --extern const size_t pc_rhel_8_0_compat_len; -- --extern GlobalProperty pc_rhel_7_6_compat[]; --extern const size_t pc_rhel_7_6_compat_len; -- - #define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \ - static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *data) \ - { \ --- -2.39.3 - diff --git a/kvm-rocker-do-not-pollute-the-namespace.patch b/kvm-rocker-do-not-pollute-the-namespace.patch new file mode 100644 index 0000000..1848d7b --- /dev/null +++ b/kvm-rocker-do-not-pollute-the-namespace.patch @@ -0,0 +1,233 @@ +From b2cacb9603fbccfe18e2801e763f4a50737ff7c3 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:45 +0200 +Subject: [PATCH 006/100] rocker: do not pollute the namespace + +Do not leave the __le* macros defined, in fact do not use them at all. Fixes a +build failure on Alpine with the TDX patches: + +In file included from ../hw/net/rocker/rocker_of_dpa.c:25: +../hw/net/rocker/rocker_hw.h:14:16: error: conflicting types for 'uint64_t'; have '__u64' {aka 'long long unsigned int'} + 14 | #define __le64 uint64_t + | ^~~~~~~~ +In file included from /usr/include/stdint.h:20, + from ../include/qemu/osdep.h:111, + from ../hw/net/rocker/rocker_of_dpa.c:17: +/usr/include/bits/alltypes.h:136:25: note: previous declaration of 'uint64_t' with type 'uint64_t' {aka 'long unsigned int'} + 136 | typedef unsigned _Int64 uint64_t; + | ^~~~~~~~ + +because the Linux headers include a typedef of __leNN. + +Signed-off-by: Paolo Bonzini +(cherry picked from commit 5150004ccf5fe72c35b3263fbed6f4d06ed3cc6a) +Signed-off-by: Paolo Bonzini +--- + hw/net/rocker/rocker.h | 14 +++--------- + hw/net/rocker/rocker_hw.h | 20 +++++++----------- + hw/net/rocker/rocker_of_dpa.c | 40 +++++++++++++++++------------------ + 3 files changed, 31 insertions(+), 43 deletions(-) + +diff --git a/hw/net/rocker/rocker.h b/hw/net/rocker/rocker.h +index 6e0962f47a..ae06c1c72a 100644 +--- a/hw/net/rocker/rocker.h ++++ b/hw/net/rocker/rocker.h +@@ -36,15 +36,7 @@ static inline G_GNUC_PRINTF(1, 2) int DPRINTF(const char *fmt, ...) + } + #endif + +-#define __le16 uint16_t +-#define __le32 uint32_t +-#define __le64 uint64_t +- +-#define __be16 uint16_t +-#define __be32 uint32_t +-#define __be64 uint64_t +- +-static inline bool ipv4_addr_is_multicast(__be32 addr) ++static inline bool ipv4_addr_is_multicast(uint32_t addr) + { + return (addr & htonl(0xf0000000)) == htonl(0xe0000000); + } +@@ -52,8 +44,8 @@ static inline bool ipv4_addr_is_multicast(__be32 addr) + typedef struct ipv6_addr { + union { + uint8_t addr8[16]; +- __be16 addr16[8]; +- __be32 addr32[4]; ++ uint16_t addr16[8]; ++ uint32_t addr32[4]; + }; + } Ipv6Addr; + +diff --git a/hw/net/rocker/rocker_hw.h b/hw/net/rocker/rocker_hw.h +index 1786323fa4..7ec6bfbcb9 100644 +--- a/hw/net/rocker/rocker_hw.h ++++ b/hw/net/rocker/rocker_hw.h +@@ -9,10 +9,6 @@ + #ifndef ROCKER_HW_H + #define ROCKER_HW_H + +-#define __le16 uint16_t +-#define __le32 uint32_t +-#define __le64 uint64_t +- + /* + * Return codes + */ +@@ -124,12 +120,12 @@ enum { + */ + + typedef struct rocker_desc { +- __le64 buf_addr; ++ uint64_t buf_addr; + uint64_t cookie; +- __le16 buf_size; +- __le16 tlv_size; +- __le16 rsvd[5]; /* pad to 32 bytes */ +- __le16 comp_err; ++ uint16_t buf_size; ++ uint16_t tlv_size; ++ uint16_t rsvd[5]; /* pad to 32 bytes */ ++ uint16_t comp_err; + } __attribute__((packed, aligned(8))) RockerDesc; + + /* +@@ -137,9 +133,9 @@ typedef struct rocker_desc { + */ + + typedef struct rocker_tlv { +- __le32 type; +- __le16 len; +- __le16 rsvd; ++ uint32_t type; ++ uint16_t len; ++ uint16_t rsvd; + } __attribute__((packed, aligned(8))) RockerTlv; + + /* cmd msg */ +diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c +index 3378f63110..4aed178756 100644 +--- a/hw/net/rocker/rocker_of_dpa.c ++++ b/hw/net/rocker/rocker_of_dpa.c +@@ -52,10 +52,10 @@ typedef struct of_dpa_flow_key { + uint32_t tunnel_id; /* overlay tunnel id */ + uint32_t tbl_id; /* table id */ + struct { +- __be16 vlan_id; /* 0 if no VLAN */ ++ uint16_t vlan_id; /* 0 if no VLAN */ + MACAddr src; /* ethernet source address */ + MACAddr dst; /* ethernet destination address */ +- __be16 type; /* ethernet frame type */ ++ uint16_t type; /* ethernet frame type */ + } eth; + struct { + uint8_t proto; /* IP protocol or ARP opcode */ +@@ -66,14 +66,14 @@ typedef struct of_dpa_flow_key { + union { + struct { + struct { +- __be32 src; /* IP source address */ +- __be32 dst; /* IP destination address */ ++ uint32_t src; /* IP source address */ ++ uint32_t dst; /* IP destination address */ + } addr; + union { + struct { +- __be16 src; /* TCP/UDP/SCTP source port */ +- __be16 dst; /* TCP/UDP/SCTP destination port */ +- __be16 flags; /* TCP flags */ ++ uint16_t src; /* TCP/UDP/SCTP source port */ ++ uint16_t dst; /* TCP/UDP/SCTP destination port */ ++ uint16_t flags; /* TCP flags */ + } tp; + struct { + MACAddr sha; /* ARP source hardware address */ +@@ -86,11 +86,11 @@ typedef struct of_dpa_flow_key { + Ipv6Addr src; /* IPv6 source address */ + Ipv6Addr dst; /* IPv6 destination address */ + } addr; +- __be32 label; /* IPv6 flow label */ ++ uint32_t label; /* IPv6 flow label */ + struct { +- __be16 src; /* TCP/UDP/SCTP source port */ +- __be16 dst; /* TCP/UDP/SCTP destination port */ +- __be16 flags; /* TCP flags */ ++ uint16_t src; /* TCP/UDP/SCTP source port */ ++ uint16_t dst; /* TCP/UDP/SCTP destination port */ ++ uint16_t flags; /* TCP flags */ + } tp; + struct { + Ipv6Addr target; /* ND target address */ +@@ -112,13 +112,13 @@ typedef struct of_dpa_flow_action { + struct { + uint32_t group_id; + uint32_t tun_log_lport; +- __be16 vlan_id; ++ uint16_t vlan_id; + } write; + struct { +- __be16 new_vlan_id; ++ uint16_t new_vlan_id; + uint32_t out_pport; + uint8_t copy_to_cpu; +- __be16 vlan_id; ++ uint16_t vlan_id; + } apply; + } OfDpaFlowAction; + +@@ -143,7 +143,7 @@ typedef struct of_dpa_flow { + typedef struct of_dpa_flow_pkt_fields { + uint32_t tunnel_id; + struct eth_header *ethhdr; +- __be16 *h_proto; ++ uint16_t *h_proto; + struct vlan_header *vlanhdr; + struct ip_header *ipv4hdr; + struct ip6_header *ipv6hdr; +@@ -180,7 +180,7 @@ typedef struct of_dpa_group { + uint32_t group_id; + MACAddr src_mac; + MACAddr dst_mac; +- __be16 vlan_id; ++ uint16_t vlan_id; + } l2_rewrite; + struct { + uint16_t group_count; +@@ -190,13 +190,13 @@ typedef struct of_dpa_group { + uint32_t group_id; + MACAddr src_mac; + MACAddr dst_mac; +- __be16 vlan_id; ++ uint16_t vlan_id; + uint8_t ttl_check; + } l3_unicast; + }; + } OfDpaGroup; + +-static int of_dpa_mask2prefix(__be32 mask) ++static int of_dpa_mask2prefix(uint32_t mask) + { + int i; + int count = 32; +@@ -451,7 +451,7 @@ static void of_dpa_flow_pkt_parse(OfDpaFlowContext *fc, + fc->iovcnt = iovcnt + 2; + } + +-static void of_dpa_flow_pkt_insert_vlan(OfDpaFlowContext *fc, __be16 vlan_id) ++static void of_dpa_flow_pkt_insert_vlan(OfDpaFlowContext *fc, uint16_t vlan_id) + { + OfDpaFlowPktFields *fields = &fc->fields; + uint16_t h_proto = fields->ethhdr->h_proto; +@@ -486,7 +486,7 @@ static void of_dpa_flow_pkt_strip_vlan(OfDpaFlowContext *fc) + + static void of_dpa_flow_pkt_hdr_rewrite(OfDpaFlowContext *fc, + uint8_t *src_mac, uint8_t *dst_mac, +- __be16 vlan_id) ++ uint16_t vlan_id) + { + OfDpaFlowPktFields *fields = &fc->fields; + +-- +2.47.3 + diff --git a/kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch b/kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch deleted file mode 100644 index b14ddcd..0000000 --- a/kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch +++ /dev/null @@ -1,362 +0,0 @@ -From 2cbfea2082fdb4b6687b1ee7ad31826dcae6e5ca Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:48 -0400 -Subject: [PATCH 16/38] s390x: Add individual loadparm assignment to CCW device -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [15/23] fe8aa289e564c45e589c9ecb131af60d4d914919 (thuth/qemu-kvm-cs9) - -Add a loadparm property to the VirtioCcwDevice object so that different -loadparms can be defined on a per-device basis for CCW boot devices. - -The machine/global loadparm is still supported. If both a global and per-device -loadparm are defined, the per-device value will override the global value for -that device, but any other devices that do not specify a per-device loadparm -will still use the global loadparm. - -It is invalid to assign a loadparm to a non-boot device. - -Signed-off-by: Jared Rossi -Reviewed-by: Thomas Huth -Message-ID: <20241020012953.1380075-15-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit bb185de42339025db9bbd5aa11f3f644c2a077f8) ---- - hw/s390x/ccw-device.c | 46 +++++++++++++++++++++++++ - hw/s390x/ccw-device.h | 2 ++ - hw/s390x/ipl.c | 68 ++++++++++++++++++++++--------------- - hw/s390x/ipl.h | 3 +- - hw/s390x/s390-virtio-ccw.c | 18 +--------- - hw/s390x/sclp.c | 9 ++--- - include/hw/s390x/ipl/qipl.h | 1 + - pc-bios/s390-ccw/main.c | 10 ++++-- - 8 files changed, 102 insertions(+), 55 deletions(-) - -diff --git a/hw/s390x/ccw-device.c b/hw/s390x/ccw-device.c -index a7d682e5af..4e54f34b1c 100644 ---- a/hw/s390x/ccw-device.c -+++ b/hw/s390x/ccw-device.c -@@ -13,6 +13,10 @@ - #include "ccw-device.h" - #include "hw/qdev-properties.h" - #include "qemu/module.h" -+#include "ipl.h" -+#include "qapi/visitor.h" -+#include "qemu/ctype.h" -+#include "qapi/error.h" - - static void ccw_device_refill_ids(CcwDevice *dev) - { -@@ -37,10 +41,52 @@ static bool ccw_device_realize(CcwDevice *dev, Error **errp) - return true; - } - -+static void ccw_device_get_loadparm(Object *obj, Visitor *v, -+ const char *name, void *opaque, -+ Error **errp) -+{ -+ CcwDevice *dev = CCW_DEVICE(obj); -+ char *str = g_strndup((char *) dev->loadparm, sizeof(dev->loadparm)); -+ -+ visit_type_str(v, name, &str, errp); -+ g_free(str); -+} -+ -+static void ccw_device_set_loadparm(Object *obj, Visitor *v, -+ const char *name, void *opaque, -+ Error **errp) -+{ -+ CcwDevice *dev = CCW_DEVICE(obj); -+ char *val; -+ int index; -+ -+ index = object_property_get_int(obj, "bootindex", NULL); -+ -+ if (index < 0) { -+ error_setg(errp, "LOADPARM is only valid for boot devices!"); -+ } -+ -+ if (!visit_type_str(v, name, &val, errp)) { -+ return; -+ } -+ -+ s390_ipl_fmt_loadparm(dev->loadparm, val, errp); -+} -+ -+static const PropertyInfo ccw_loadparm = { -+ .name = "ccw_loadparm", -+ .description = "Up to 8 chars in set of [A-Za-z0-9. ] to pass" -+ " to the guest loader/kernel", -+ .get = ccw_device_get_loadparm, -+ .set = ccw_device_set_loadparm, -+}; -+ - static Property ccw_device_properties[] = { - DEFINE_PROP_CSS_DEV_ID("devno", CcwDevice, devno), - DEFINE_PROP_CSS_DEV_ID_RO("dev_id", CcwDevice, dev_id), - DEFINE_PROP_CSS_DEV_ID_RO("subch_id", CcwDevice, subch_id), -+ DEFINE_PROP("loadparm", CcwDevice, loadparm, ccw_loadparm, -+ typeof(uint8_t[8])), - DEFINE_PROP_END_OF_LIST(), - }; - -diff --git a/hw/s390x/ccw-device.h b/hw/s390x/ccw-device.h -index 5feeb0ee7a..1e1737c0f3 100644 ---- a/hw/s390x/ccw-device.h -+++ b/hw/s390x/ccw-device.h -@@ -26,6 +26,8 @@ struct CcwDevice { - CssDevId dev_id; - /* The actual busid of the virtual subchannel. */ - CssDevId subch_id; -+ /* If set, use this loadparm value when device is boot target */ -+ uint8_t loadparm[8]; - }; - typedef struct CcwDevice CcwDevice; - -diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c -index 8a0a3e6961..d83832d975 100644 ---- a/hw/s390x/ipl.c -+++ b/hw/s390x/ipl.c -@@ -34,6 +34,7 @@ - #include "qemu/config-file.h" - #include "qemu/cutils.h" - #include "qemu/option.h" -+#include "qemu/ctype.h" - #include "standard-headers/linux/virtio_ids.h" - - #define KERN_IMAGE_START 0x010000UL -@@ -397,12 +398,43 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st, int *devtype) - return ccw_dev; - } - -+void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp) -+{ -+ int i; -+ -+ /* Initialize the loadparm with spaces */ -+ memset(loadparm, ' ', LOADPARM_LEN); -+ for (i = 0; i < LOADPARM_LEN && str[i]; i++) { -+ uint8_t c = qemu_toupper(str[i]); /* mimic HMC */ -+ -+ if (qemu_isalnum(c) || c == '.' || c == ' ') { -+ loadparm[i] = c; -+ } else { -+ error_setg(errp, "LOADPARM: invalid character '%c' (ASCII 0x%02x)", -+ c, c); -+ return; -+ } -+ } -+} -+ -+void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp) -+{ -+ int i; -+ -+ /* Initialize the loadparm with EBCDIC spaces (0x40) */ -+ memset(ebcdic_lp, '@', LOADPARM_LEN); -+ for (i = 0; i < LOADPARM_LEN && ascii_lp[i]; i++) { -+ ebcdic_lp[i] = ascii2ebcdic[(uint8_t) ascii_lp[i]]; -+ } -+} -+ - static bool s390_gen_initial_iplb(S390IPLState *ipl) - { - DeviceState *dev_st; - CcwDevice *ccw_dev = NULL; - SCSIDevice *sd; - int devtype; -+ uint8_t *lp; - - dev_st = get_boot_device(0); - if (dev_st) { -@@ -413,6 +445,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl) - * Currently allow IPL only from CCW devices. - */ - if (ccw_dev) { -+ lp = ccw_dev->loadparm; -+ - switch (devtype) { - case CCW_DEVTYPE_SCSI: - sd = SCSI_DEVICE(dev_st); -@@ -445,40 +479,20 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl) - break; - } - -- if (!s390_ipl_set_loadparm(ipl->iplb.loadparm)) { -- ipl->iplb.flags |= DIAG308_FLAGS_LP_VALID; -+ /* If the device loadparm is empty use the global machine loadparm */ -+ if (memcmp(lp, NO_LOADPARM, 8) == 0) { -+ lp = S390_CCW_MACHINE(qdev_get_machine())->loadparm; - } - -+ s390_ipl_convert_loadparm((char *)lp, ipl->iplb.loadparm); -+ ipl->iplb.flags |= DIAG308_FLAGS_LP_VALID; -+ - return true; - } - - return false; - } - --int s390_ipl_set_loadparm(uint8_t *loadparm) --{ -- MachineState *machine = MACHINE(qdev_get_machine()); -- char *lp = object_property_get_str(OBJECT(machine), "loadparm", NULL); -- -- if (lp) { -- int i; -- -- /* lp is an uppercase string without leading/embedded spaces */ -- for (i = 0; i < 8 && lp[i]; i++) { -- loadparm[i] = ascii2ebcdic[(uint8_t) lp[i]]; -- } -- -- if (i < 8) { -- memset(loadparm + i, 0x40, 8 - i); /* fill with EBCDIC spaces */ -- } -- -- g_free(lp); -- return 0; -- } -- -- return -1; --} -- - static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb, - int virtio_id) - { -@@ -534,7 +548,7 @@ static void update_machine_ipl_properties(IplParameterBlock *iplb) - ascii_loadparm[i] = 0; - object_property_set_str(machine, "loadparm", ascii_loadparm, &err); - } else { -- object_property_set_str(machine, "loadparm", "", &err); -+ object_property_set_str(machine, "loadparm", " ", &err); - } - if (err) { - warn_report_err(err); -diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h -index fa394c339d..b670bad551 100644 ---- a/hw/s390x/ipl.h -+++ b/hw/s390x/ipl.h -@@ -21,7 +21,8 @@ - - #define DIAG308_FLAGS_LP_VALID 0x80 - --int s390_ipl_set_loadparm(uint8_t *loadparm); -+void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp); -+void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp); - void s390_ipl_update_diag308(IplParameterBlock *iplb); - int s390_ipl_prepare_pv_header(Error **errp); - int s390_ipl_pv_unpack(void); -diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c -index 29a89a0c31..0347dc69ca 100644 ---- a/hw/s390x/s390-virtio-ccw.c -+++ b/hw/s390x/s390-virtio-ccw.c -@@ -724,28 +724,12 @@ static void machine_set_loadparm(Object *obj, Visitor *v, - { - S390CcwMachineState *ms = S390_CCW_MACHINE(obj); - char *val; -- int i; - - if (!visit_type_str(v, name, &val, errp)) { - return; - } - -- for (i = 0; i < sizeof(ms->loadparm) && val[i]; i++) { -- uint8_t c = qemu_toupper(val[i]); /* mimic HMC */ -- -- if (('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || (c == '.') || -- (c == ' ')) { -- ms->loadparm[i] = c; -- } else { -- error_setg(errp, "LOADPARM: invalid character '%c' (ASCII 0x%02x)", -- c, c); -- return; -- } -- } -- -- for (; i < sizeof(ms->loadparm); i++) { -- ms->loadparm[i] = ' '; /* pad right with spaces */ -- } -+ s390_ipl_fmt_loadparm(ms->loadparm, val, errp); - } - - static void ccw_machine_class_init(ObjectClass *oc, void *data) -diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c -index e725dcd5fd..8757626b5c 100644 ---- a/hw/s390x/sclp.c -+++ b/hw/s390x/sclp.c -@@ -110,7 +110,6 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb) - MachineState *machine = MACHINE(qdev_get_machine()); - int cpu_count; - int rnsize, rnmax; -- IplParameterBlock *ipib = s390_ipl_get_iplb(); - int required_len = SCCB_REQ_LEN(ReadInfo, machine->possible_cpus->len); - int offset_cpu = s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) ? - offsetof(ReadInfo, entries) : -@@ -171,12 +170,8 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb) - read_info->rnmax2 = cpu_to_be64(rnmax); - } - -- if (ipib && ipib->flags & DIAG308_FLAGS_LP_VALID) { -- memcpy(&read_info->loadparm, &ipib->loadparm, -- sizeof(read_info->loadparm)); -- } else { -- s390_ipl_set_loadparm(read_info->loadparm); -- } -+ s390_ipl_convert_loadparm((char *)S390_CCW_MACHINE(machine)->loadparm, -+ read_info->loadparm); - - sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION); - } -diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h -index 0ef04af027..b67d2ae061 100644 ---- a/include/hw/s390x/ipl/qipl.h -+++ b/include/hw/s390x/ipl/qipl.h -@@ -18,6 +18,7 @@ - - #define QIPL_ADDRESS 0xcc - #define LOADPARM_LEN 8 -+#define NO_LOADPARM "\0\0\0\0\0\0\0\0" - - /* - * The QEMU IPL Parameters will be stored at absolute address -diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c -index 34ef27d7a6..ab4709e16e 100644 ---- a/pc-bios/s390-ccw/main.c -+++ b/pc-bios/s390-ccw/main.c -@@ -183,8 +183,14 @@ static void css_setup(void) - static void boot_setup(void) - { - char lpmsg[] = "LOADPARM=[________]\n"; -+ have_iplb = store_iplb(&iplb); -+ -+ if (memcmp(iplb.loadparm, NO_LOADPARM, LOADPARM_LEN) != 0) { -+ ebcdic_to_ascii((char *) iplb.loadparm, loadparm_str, LOADPARM_LEN); -+ } else { -+ sclp_get_loadparm_ascii(loadparm_str); -+ } - -- sclp_get_loadparm_ascii(loadparm_str); - memcpy(lpmsg + 10, loadparm_str, 8); - puts(lpmsg); - -@@ -193,8 +199,6 @@ static void boot_setup(void) - * so we don't taint our decision-making process during a reboot. - */ - memset((char *)S390EP, 0, 6); -- -- have_iplb = store_iplb(&iplb); - } - - static bool find_boot_device(void) --- -2.39.3 - diff --git a/kvm-s390x-Fix-leak-in-machine_set_loadparm.patch b/kvm-s390x-Fix-leak-in-machine_set_loadparm.patch new file mode 100644 index 0000000..18ac593 --- /dev/null +++ b/kvm-s390x-Fix-leak-in-machine_set_loadparm.patch @@ -0,0 +1,60 @@ +From 24605a535cf850b11fd5910045d5a9a494a0857d Mon Sep 17 00:00:00 2001 +From: Fabiano Rosas +Date: Fri, 9 May 2025 14:49:38 -0300 +Subject: [PATCH 01/43] s390x: Fix leak in machine_set_loadparm +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 386: s390x: Fix memory leaks related to loadparm [rhel-10] +RH-Jira: RHEL-98555 +RH-Acked-by: CĂ©dric Le Goater +RH-Acked-by: Kevin Wolf +RH-Commit: [1/2] 04997385648ba61cc55c1c6a11ba553b65bf9fe9 (thuth/qemu-kvm-cs) + +ASAN spotted a leaking string in machine_set_loadparm(): + +Direct leak of 9 byte(s) in 1 object(s) allocated from: + #0 0x560ffb5bb379 in malloc ../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:69:3 + #1 0x7f1aca926518 in g_malloc ../glib/gmem.c:106 + #2 0x7f1aca94113e in g_strdup ../glib/gstrfuncs.c:364 + #3 0x560ffc8afbf9 in qobject_input_type_str ../qapi/qobject-input-visitor.c:542:12 + #4 0x560ffc8a80ff in visit_type_str ../qapi/qapi-visit-core.c:349:10 + #5 0x560ffbe6053a in machine_set_loadparm ../hw/s390x/s390-virtio-ccw.c:802:10 + #6 0x560ffc0c5e52 in object_property_set ../qom/object.c:1450:5 + #7 0x560ffc0d4175 in object_property_set_qobject ../qom/qom-qobject.c:28:10 + #8 0x560ffc0c6004 in object_property_set_str ../qom/object.c:1458:15 + #9 0x560ffbe2ae60 in update_machine_ipl_properties ../hw/s390x/ipl.c:569:9 + #10 0x560ffbe2aa65 in s390_ipl_update_diag308 ../hw/s390x/ipl.c:594:5 + #11 0x560ffbdee132 in handle_diag_308 ../target/s390x/diag.c:147:9 + #12 0x560ffbebb956 in helper_diag ../target/s390x/tcg/misc_helper.c:137:9 + #13 0x7f1a3c51c730 (/memfd:tcg-jit (deleted)+0x39730) + +Cc: qemu-stable@nongnu.org +Signed-off-by: Fabiano Rosas +Message-ID: <20250509174938.25935-1-farosas@suse.de> +Fixes: 1fd396e3228 ("s390x: Register TYPE_S390_CCW_MACHINE properties as class properties") +Reviewed-by: Thomas Huth +Reviewed-by: Philippe Mathieu-DaudĂ© +Signed-off-by: Thomas Huth +(cherry picked from commit bdf12f2a56bf3f13c52eb51f0a994bbfe40706b2) +--- + hw/s390x/s390-virtio-ccw.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c +index 59b545740e..dd3fc13683 100644 +--- a/hw/s390x/s390-virtio-ccw.c ++++ b/hw/s390x/s390-virtio-ccw.c +@@ -804,6 +804,7 @@ static void machine_set_loadparm(Object *obj, Visitor *v, + } + + s390_ipl_fmt_loadparm(ms->loadparm, val, errp); ++ g_free(val); + } + + static void ccw_machine_class_init(ObjectClass *oc, void *data) +-- +2.39.3 + diff --git a/kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch b/kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch deleted file mode 100644 index 11fa6c5..0000000 --- a/kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch +++ /dev/null @@ -1,264 +0,0 @@ -From ad587091d8716dbc118776b8edb61db12f6da122 Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:50 -0400 -Subject: [PATCH 18/38] s390x: Rebuild IPLB for SCSI device directly from - DIAG308 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [17/23] 8267b7ecd71f2af5409e2e41890b6e5bb56fabd2 (thuth/qemu-kvm-cs9) - -Because virtio-scsi type devices use a non-architected IPLB pbt code they cannot -be set and stored normally. Instead, the IPLB must be rebuilt during re-ipl. - -As s390x does not natively support multiple boot devices, the devno field is -used to store the position in the boot order for the device. - -Handling the rebuild as part of DIAG308 removes the need to check the devices -for invalid IPLBs later in the IPL. - -Signed-off-by: Jared Rossi -Acked-by: Thomas Huth -Message-ID: <20241020012953.1380075-17-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 455e3bc3f74ee76964efec2e0c646db15095d0d2) ---- - hw/s390x/ipl.c | 74 ++++++------------------------------- - hw/s390x/ipl.h | 11 ++++-- - include/hw/s390x/ipl/qipl.h | 3 +- - pc-bios/s390-ccw/jump2ipl.c | 11 ++++-- - target/s390x/diag.c | 9 ++++- - 5 files changed, 38 insertions(+), 70 deletions(-) - -diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c -index f4576f8822..5fbd43c346 100644 ---- a/hw/s390x/ipl.c -+++ b/hw/s390x/ipl.c -@@ -448,7 +448,6 @@ void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp) - - static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb) - { -- S390IPLState *ipl = get_ipl_device(); - CcwDevice *ccw_dev = NULL; - SCSIDevice *sd; - int devtype; -@@ -481,9 +480,6 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb) - iplb->ccw.ssid = ccw_dev->sch->ssid & 3; - break; - case CCW_DEVTYPE_VIRTIO_NET: -- /* The S390IPLState netboot is true if ANY IPLB may use netboot */ -- ipl->netboot = true; -- /* Fall through to CCW_DEVTYPE_VIRTIO case */ - case CCW_DEVTYPE_VIRTIO: - iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); - iplb->blk0_len = -@@ -508,6 +504,16 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb) - return false; - } - -+void s390_rebuild_iplb(uint16_t dev_index, IplParameterBlock *iplb) -+{ -+ S390IPLState *ipl = get_ipl_device(); -+ uint16_t index; -+ index = ipl->rebuilt_iplb ? ipl->iplb_index : dev_index; -+ -+ ipl->rebuilt_iplb = s390_build_iplb(get_boot_device(index), iplb); -+ ipl->iplb_index = index; -+} -+ - static bool s390_init_all_iplbs(S390IPLState *ipl) - { - int iplb_num = 0; -@@ -564,44 +570,6 @@ static bool s390_init_all_iplbs(S390IPLState *ipl) - return iplb_num; - } - --static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb, -- int virtio_id) --{ -- uint8_t cssid; -- uint8_t ssid; -- uint16_t devno; -- uint16_t schid; -- SubchDev *sch = NULL; -- -- if (iplb->pbt != S390_IPL_TYPE_CCW) { -- return false; -- } -- -- devno = be16_to_cpu(iplb->ccw.devno); -- ssid = iplb->ccw.ssid & 3; -- -- for (schid = 0; schid < MAX_SCHID; schid++) { -- for (cssid = 0; cssid < MAX_CSSID; cssid++) { -- sch = css_find_subch(1, cssid, ssid, schid); -- -- if (sch && sch->devno == devno) { -- return sch->id.cu_model == virtio_id; -- } -- } -- } -- return false; --} -- --static bool is_virtio_net_device(IplParameterBlock *iplb) --{ -- return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_NET); --} -- --static bool is_virtio_scsi_device(IplParameterBlock *iplb) --{ -- return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_SCSI); --} -- - static void update_machine_ipl_properties(IplParameterBlock *iplb) - { - Object *machine = qdev_get_machine(); -@@ -641,7 +609,7 @@ void s390_ipl_update_diag308(IplParameterBlock *iplb) - ipl->iplb = *iplb; - ipl->iplb_valid = true; - } -- ipl->netboot = is_virtio_net_device(iplb); -+ - update_machine_ipl_properties(iplb); - } - -@@ -668,32 +636,14 @@ IplParameterBlock *s390_ipl_get_iplb(void) - void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type) - { - S390IPLState *ipl = get_ipl_device(); -- - if (reset_type == S390_RESET_EXTERNAL || reset_type == S390_RESET_REIPL) { - /* use CPU 0 for full resets */ - ipl->reset_cpu_index = 0; - } else { - ipl->reset_cpu_index = cs->cpu_index; - } -- ipl->reset_type = reset_type; - -- if (reset_type == S390_RESET_REIPL && -- ipl->iplb_valid && -- !ipl->netboot && -- ipl->iplb.pbt == S390_IPL_TYPE_CCW && -- is_virtio_scsi_device(&ipl->iplb)) { -- CcwDevice *ccw_dev = s390_get_ccw_device(get_boot_device(0), NULL); -- -- if (ccw_dev && -- cpu_to_be16(ccw_dev->sch->devno) == ipl->iplb.ccw.devno && -- (ccw_dev->sch->ssid & 3) == ipl->iplb.ccw.ssid) { -- /* -- * this is the original boot device's SCSI -- * so restore IPL parameter info from it -- */ -- ipl->iplb_valid = s390_build_iplb(get_boot_device(0), &ipl->iplb); -- } -- } -+ ipl->reset_type = reset_type; - if (reset_type == S390_RESET_MODIFIED_CLEAR || - reset_type == S390_RESET_LOAD_NORMAL || - reset_type == S390_RESET_PV) { -diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h -index 54eb48fd6e..d7d0b7bfd2 100644 ---- a/hw/s390x/ipl.h -+++ b/hw/s390x/ipl.h -@@ -24,6 +24,7 @@ - - void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp); - void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp); -+void s390_rebuild_iplb(uint16_t index, IplParameterBlock *iplb); - void s390_ipl_update_diag308(IplParameterBlock *iplb); - int s390_ipl_prepare_pv_header(Error **errp); - int s390_ipl_pv_unpack(void); -@@ -65,7 +66,8 @@ struct S390IPLState { - bool enforce_bios; - bool iplb_valid; - bool iplb_valid_pv; -- bool netboot; -+ bool rebuilt_iplb; -+ uint16_t iplb_index; - /* reset related properties don't have to be migrated or reset */ - enum s390_reset reset_type; - int reset_cpu_index; -@@ -172,11 +174,14 @@ static inline bool iplb_valid_pv(IplParameterBlock *iplb) - - static inline bool iplb_valid(IplParameterBlock *iplb) - { -+ uint32_t len = be32_to_cpu(iplb->len); -+ - switch (iplb->pbt) { - case S390_IPL_TYPE_FCP: -- return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN; -+ return len >= S390_IPLB_MIN_FCP_LEN; - case S390_IPL_TYPE_CCW: -- return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN; -+ return len >= S390_IPLB_MIN_CCW_LEN; -+ case S390_IPL_TYPE_QEMU_SCSI: - default: - return false; - } -diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h -index 1da4f75aa8..6824391111 100644 ---- a/include/hw/s390x/ipl/qipl.h -+++ b/include/hw/s390x/ipl/qipl.h -@@ -29,7 +29,8 @@ - */ - struct QemuIplParameters { - uint8_t qipl_flags; -- uint8_t reserved1[3]; -+ uint8_t index; -+ uint8_t reserved1[2]; - uint64_t reserved2; - uint32_t boot_menu_timeout; - uint8_t reserved3[2]; -diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c -index 8db1764ff3..99d18947d1 100644 ---- a/pc-bios/s390-ccw/jump2ipl.c -+++ b/pc-bios/s390-ccw/jump2ipl.c -@@ -39,10 +39,15 @@ int jump_to_IPL_code(uint64_t address) - write_subsystem_identification(); - write_iplb_location(); - -- /* prevent unknown IPL types in the guest */ -+ /* -+ * The IPLB for QEMU SCSI type devices must be rebuilt during re-ipl. The -+ * iplb.devno is set to the boot position of the target SCSI device. -+ */ - if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) { -- iplb.pbt = S390_IPL_TYPE_CCW; -- set_iplb(&iplb); -+ iplb.devno = qipl.index; -+ if (!set_iplb(&iplb)) { -+ panic("Failed to set IPLB"); -+ } - } - - /* -diff --git a/target/s390x/diag.c b/target/s390x/diag.c -index 27ffd48576..a1fd54ddac 100644 ---- a/target/s390x/diag.c -+++ b/target/s390x/diag.c -@@ -133,7 +133,14 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra) - - valid = subcode == DIAG308_PV_SET ? iplb_valid_pv(iplb) : iplb_valid(iplb); - if (!valid) { -- env->regs[r1 + 1] = DIAG_308_RC_INVALID; -+ if (subcode == DIAG308_SET && iplb->pbt == S390_IPL_TYPE_QEMU_SCSI) { -+ s390_rebuild_iplb(iplb->devno, iplb); -+ s390_ipl_update_diag308(iplb); -+ env->regs[r1 + 1] = DIAG_308_RC_OK; -+ } else { -+ env->regs[r1 + 1] = DIAG_308_RC_INVALID; -+ } -+ - goto out; - } - --- -2.39.3 - diff --git a/kvm-s390x-cpumodel-Add-PLO-extension-facility.patch b/kvm-s390x-cpumodel-Add-PLO-extension-facility.patch deleted file mode 100644 index 1134828..0000000 --- a/kvm-s390x-cpumodel-Add-PLO-extension-facility.patch +++ /dev/null @@ -1,221 +0,0 @@ -From e4bdbc368426bc9aeb6dbfeeb2de46de1256861d Mon Sep 17 00:00:00 2001 -From: Hendrik Brueckner -Date: Fri, 6 Dec 2024 13:27:50 +0100 -Subject: [PATCH 15/18] s390x/cpumodel: Add PLO-extension facility -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [15/16] 6e8bb7b1f0e8c84ba0c3cd7e7714d22642402513 (thuth/qemu-kvm-cs9) - -The PLO-extension facility introduces numerous locking related -subfunctions. - -Signed-off-by: Hendrik Brueckner -Reviewed-by: Janosch Frank -Message-ID: <20241206122751.189721-15-brueckner@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 393c835e341e8921d1d6ae45da308e85176c4f00) ---- - target/s390x/cpu_features.c | 1 + - target/s390x/cpu_features_def.h.inc | 39 +++++++++++++++++++++++++ - target/s390x/cpu_models.c | 38 ++++++++++++++++++++++++ - target/s390x/gen-features.c | 45 +++++++++++++++++++++++++++++ - 4 files changed, 123 insertions(+) - -diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c -index 5f8b02f12c..4b5be6798e 100644 ---- a/target/s390x/cpu_features.c -+++ b/target/s390x/cpu_features.c -@@ -240,6 +240,7 @@ void s390_get_deprecated_features(S390FeatBitmap features) - /* indexed by feature group number for easy lookup */ - static S390FeatGroupDef s390_feature_groups[] = { - FEAT_GROUP_INIT("plo", PLO, "Perform-locked-operation facility"), -+ FEAT_GROUP_INIT("plo_ext", PLO_EXT, "PLO-extension facility"), - FEAT_GROUP_INIT("tods", TOD_CLOCK_STEERING, "Tod-clock-steering facility"), - FEAT_GROUP_INIT("gen13ptff", GEN13_PTFF, "PTFF enhancements introduced with z13"), - FEAT_GROUP_INIT("gen17ptff", GEN17_PTFF, "PTFF enhancements introduced with gen17"), -diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc -index fe7e1bd19c..e23e603a79 100644 ---- a/target/s390x/cpu_features_def.h.inc -+++ b/target/s390x/cpu_features_def.h.inc -@@ -93,6 +93,7 @@ DEF_FEAT(BPB, "bpb", STFL, 82, "Branch prediction blocking") - DEF_FEAT(MISC_INSTRUCTION_EXT4, "minste4", STFL, 84, "Miscellaneous-Instruction-Extensions Facility 4") - DEF_FEAT(SIF, "sif", STFL, 85, "Sequential-instruction-fetching facility") - DEF_FEAT(MSA_EXT_12, "msa12-base", STFL, 86, "Message-security-assist-extension-12 facility (excluding subfunctions)") -+DEF_FEAT(PLO_EXT, "plo-ext", STFL, 87, "PLO-extension facility") - DEF_FEAT(VECTOR, "vx", STFL, 129, "Vector facility") - DEF_FEAT(INSTRUCTION_EXEC_PROT, "iep", STFL, 130, "Instruction-execution-protection facility") - DEF_FEAT(SIDE_EFFECT_ACCESS_ESOP2, "sea_esop2", STFL, 131, "Side-effect-access facility and Enhanced-suppression-on-protection facility 2") -@@ -180,6 +181,44 @@ DEF_FEAT(PLO_CSTST, "plo-cstst", PLO, 20, "PLO Compare and swap and triple store - DEF_FEAT(PLO_CSTSTG, "plo-cststg", PLO, 21, "PLO Compare and swap and triple store (64 bit in parameter list)") - DEF_FEAT(PLO_CSTSTGR, "plo-cststgr", PLO, 22, "PLO Compare and swap and triple store (64 bit in general registers)") - DEF_FEAT(PLO_CSTSTX, "plo-cststx", PLO, 23, "PLO Compare and swap and triple store (128 bit in parameter list)") -+DEF_FEAT(PLO_CLO, "plo-clo", PLO, 24, "PLO Compare and load (256 bit in parameter list)") -+DEF_FEAT(PLO_CSO, "plo-cso", PLO, 25, "PLO Compare and swap (256 bit in parameter list)") -+DEF_FEAT(PLO_DCSO, "plo-dcso", PLO, 26, "PLO Double compare and swap (256 bit in parameter list)") -+DEF_FEAT(PLO_CSSTO, "plo-cssto", PLO, 27, "PLO Compare and swap and store (256 bit in parameter list)") -+DEF_FEAT(PLO_CSDSTO, "plo-csdsto", PLO, 28, "PLO Compare and swap and double store (256 bit in parameter list)") -+DEF_FEAT(PLO_CSTSTO, "plo-cststo", PLO, 29, "PLO Compare and swap and trible store (256 bit in parameter list)") -+DEF_FEAT(PLO_TCS, "plo-tcs", PLO, 30, "Triple compare and swap (32 bit in parameter list)") -+DEF_FEAT(PLO_TCSG, "plo-tcsg", PLO, 31, "Triple compare and swap (64 bit in parameter list)") -+DEF_FEAT(PLO_TCSX, "plo-tcsx", PLO, 32, "Triple compare and swap (128 bit in parameter list)") -+DEF_FEAT(PLO_TCSO, "plo-tcso", PLO, 33, "Triple compare and swap (256 bit in parameter list)") -+DEF_FEAT(PLO_QCS, "plo-qcs", PLO, 34, "Quadruple compare and swap (32 bit in parameter list)") -+DEF_FEAT(PLO_QCSG, "plo-qcsg", PLO, 35, "Quadruple compare and swap (64 bit in parameter list)") -+DEF_FEAT(PLO_QCSX, "plo-qcsx", PLO, 36, "Quadruple compare and swap (128 bit in parameter list)") -+DEF_FEAT(PLO_QCSO, "plo-qcso", PLO, 37, "Quadruple compare and swap (256 bit in parameter list)") -+DEF_FEAT(PLO_LO, "plo-lo", PLO, 38, "Load (256 bit in parameter list)") -+DEF_FEAT(PLO_DLX, "plo-dlx", PLO, 39, "Double load (128 bit in parameter list)") -+DEF_FEAT(PLO_DLO, "plo-dlo", PLO, 40, "Double load (256 bit in parameter list)") -+DEF_FEAT(PLO_TL, "plo-tl", PLO, 41, "Triple load (32 bit in parameter list)") -+DEF_FEAT(PLO_TLG, "plo-tlg", PLO, 42, "Triple load (64 bit in parameter list)") -+DEF_FEAT(PLO_TLX, "plo-tlx", PLO, 43, "Triple load (128 bit in parameter list)") -+DEF_FEAT(PLO_TLO, "plo-tlo", PLO, 44, "Triple load (256 bit in parameter list)") -+DEF_FEAT(PLO_QL, "plo-ql", PLO, 45, "Quadruple load (32 bit in parameter list)") -+DEF_FEAT(PLO_QLG, "plo-qlg", PLO, 46, "Quadruple load (64 bit in parameter list)") -+DEF_FEAT(PLO_QLX, "plo-qlx", PLO, 47, "Quadruple load (128 bit in parameter list)") -+DEF_FEAT(PLO_QLO, "plo-qlo", PLO, 48, "Quadruple load (256 bit in parameter list)") -+DEF_FEAT(PLO_STO, "plo-sto", PLO, 49, "Store (256 bit in parameter list)") -+DEF_FEAT(PLO_DST, "plo-dst", PLO, 50, "Double store (32 bit in parameter list)") -+DEF_FEAT(PLO_DSTG, "plo-dstg", PLO, 51, "Double store (64 bit in parameter list)") -+DEF_FEAT(PLO_DSTX, "plo-dstx", PLO, 52, "Double store (128 bit in parameter list)") -+DEF_FEAT(PLO_DSTO, "plo-dsto", PLO, 53, "Double store (256 bit in parameter list)") -+DEF_FEAT(PLO_TST, "plo-tst", PLO, 54, "Triple store (32 bit in parameter list)") -+DEF_FEAT(PLO_TSTG, "plo-tstg", PLO, 55, "Triple store (64 bit in parameter list)") -+DEF_FEAT(PLO_TSTX, "plo-tstx", PLO, 56, "Triple store (128 bit in parameter list)") -+DEF_FEAT(PLO_TSTO, "plo-tsto", PLO, 57, "Triple store (256 bit in parameter list)") -+DEF_FEAT(PLO_QST, "plo-qst", PLO, 58, "Quadruple store (32 bit in parameter list)") -+DEF_FEAT(PLO_QSTG, "plo-qstg", PLO, 59, "Quadruple store (64 bit in parameter list)") -+DEF_FEAT(PLO_QSTX, "plo-qstx", PLO, 60, "Quadruple store (128 bit in parameter list)") -+DEF_FEAT(PLO_QSTO, "plo-qsto", PLO, 61, "Quadruple store (256 bit in parameter list)") - - /* Features exposed via the PTFF instruction. */ - DEF_FEAT(PTFF_QTO, "ptff-qto", PTFF, 1, "PTFF Query TOD Offset") -diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c -index 9e9f6dae07..3fb5b0980e 100644 ---- a/target/s390x/cpu_models.c -+++ b/target/s390x/cpu_models.c -@@ -516,6 +516,44 @@ static void check_consistency(const S390CPUModel *model) - { S390_FEAT_PFCR_CSTST, S390_FEAT_CCF_BASE }, - { S390_FEAT_PFCR_CSTSTG, S390_FEAT_CCF_BASE }, - { S390_FEAT_INEFF_NC_TX, S390_FEAT_TRANSACTIONAL_EXE }, -+ { S390_FEAT_PLO_CLO, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_CSO, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_DCSO, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_CSSTO, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_CSDSTO, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_CSTSTO, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_TCS, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_TCSG, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_TCSX, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_TCSO, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_QCS, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_QCSG, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_QCSX, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_QCSO, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_LO, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_DLX, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_DLO, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_TL, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_TLG, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_TLX, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_TLO, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_QL, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_QLG, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_QLX, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_QLO, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_STO, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_DST, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_DSTG, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_DSTX, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_DSTO, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_TST, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_TSTG, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_TSTX, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_TSTO, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_QST, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_QSTG, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_QSTX, S390_FEAT_PLO_EXT }, -+ { S390_FEAT_PLO_QSTO, S390_FEAT_PLO_EXT }, - }; - int i; - -diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c -index 6d00ffcda7..680d45d303 100644 ---- a/target/s390x/gen-features.c -+++ b/target/s390x/gen-features.c -@@ -46,6 +46,47 @@ - S390_FEAT_PLO_CSTSTGR, \ - S390_FEAT_PLO_CSTSTX - -+#define S390_FEAT_GROUP_PLO_EXT \ -+ S390_FEAT_PLO_EXT, \ -+ S390_FEAT_PLO_CLO, \ -+ S390_FEAT_PLO_CSO, \ -+ S390_FEAT_PLO_DCSO, \ -+ S390_FEAT_PLO_CSSTO, \ -+ S390_FEAT_PLO_CSDSTO, \ -+ S390_FEAT_PLO_CSTSTO, \ -+ S390_FEAT_PLO_TCS, \ -+ S390_FEAT_PLO_TCSG, \ -+ S390_FEAT_PLO_TCSX, \ -+ S390_FEAT_PLO_TCSO, \ -+ S390_FEAT_PLO_QCS, \ -+ S390_FEAT_PLO_QCSG, \ -+ S390_FEAT_PLO_QCSX, \ -+ S390_FEAT_PLO_QCSO, \ -+ S390_FEAT_PLO_LO, \ -+ S390_FEAT_PLO_DLX, \ -+ S390_FEAT_PLO_DLO, \ -+ S390_FEAT_PLO_TL, \ -+ S390_FEAT_PLO_TLG, \ -+ S390_FEAT_PLO_TLX, \ -+ S390_FEAT_PLO_TLO, \ -+ S390_FEAT_PLO_QL, \ -+ S390_FEAT_PLO_QLG, \ -+ S390_FEAT_PLO_QLX, \ -+ S390_FEAT_PLO_QLO, \ -+ S390_FEAT_PLO_STO, \ -+ S390_FEAT_PLO_DST, \ -+ S390_FEAT_PLO_DSTG, \ -+ S390_FEAT_PLO_DSTX, \ -+ S390_FEAT_PLO_DSTO, \ -+ S390_FEAT_PLO_TST, \ -+ S390_FEAT_PLO_TSTG, \ -+ S390_FEAT_PLO_TSTX, \ -+ S390_FEAT_PLO_TSTO, \ -+ S390_FEAT_PLO_QST, \ -+ S390_FEAT_PLO_QSTG, \ -+ S390_FEAT_PLO_QSTX, \ -+ S390_FEAT_PLO_QSTO -+ - #define S390_FEAT_GROUP_TOD_CLOCK_STEERING \ - S390_FEAT_TOD_CLOCK_STEERING, \ - S390_FEAT_PTFF_QTO, \ -@@ -320,6 +361,9 @@ - static uint16_t group_PLO[] = { - S390_FEAT_GROUP_PLO, - }; -+static uint16_t group_PLO_EXT[] = { -+ S390_FEAT_GROUP_PLO_EXT, -+}; - static uint16_t group_TOD_CLOCK_STEERING[] = { - S390_FEAT_GROUP_TOD_CLOCK_STEERING, - }; -@@ -936,6 +980,7 @@ typedef struct { - *******************************/ - static FeatGroupDefSpec FeatGroupDef[] = { - FEAT_GROUP_INITIALIZER(PLO), -+ FEAT_GROUP_INITIALIZER(PLO_EXT), - FEAT_GROUP_INITIALIZER(TOD_CLOCK_STEERING), - FEAT_GROUP_INITIALIZER(GEN13_PTFF), - FEAT_GROUP_INITIALIZER(GEN17_PTFF), --- -2.39.3 - diff --git a/kvm-s390x-cpumodel-Add-Sequential-Instruction-Fetching-f.patch b/kvm-s390x-cpumodel-Add-Sequential-Instruction-Fetching-f.patch deleted file mode 100644 index 05dece7..0000000 --- a/kvm-s390x-cpumodel-Add-Sequential-Instruction-Fetching-f.patch +++ /dev/null @@ -1,43 +0,0 @@ -From dcfaf859fa755f9c75b1e848f1b61b293b500d0d Mon Sep 17 00:00:00 2001 -From: Hendrik Brueckner -Date: Fri, 6 Dec 2024 13:27:48 +0100 -Subject: [PATCH 13/18] s390x/cpumodel: Add Sequential-Instruction-Fetching - facility -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [13/16] 5f8facceda9ecad3b417ed3da2d360fdd480f6d4 (thuth/qemu-kvm-cs9) - -The sequential instruction fetching facility provides few guarantees, -for example, to avoid stop machine calls on enabling/disabling kprobes. - -Signed-off-by: Hendrik Brueckner -Reviewed-by: Janosch Frank -Message-ID: <20241206122751.189721-13-brueckner@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit a5fa8bee72847406bfc32e15c8e41c0a2a0812e1) ---- - target/s390x/cpu_features_def.h.inc | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc -index 2c1d1cd98a..09a80844a7 100644 ---- a/target/s390x/cpu_features_def.h.inc -+++ b/target/s390x/cpu_features_def.h.inc -@@ -91,6 +91,7 @@ DEF_FEAT(DFP_PACKED_CONVERSION, "dfppc", STFL, 80, "Decimal-floating-point packe - DEF_FEAT(PPA15, "ppa15", STFL, 81, "PPA15 is installed") - DEF_FEAT(BPB, "bpb", STFL, 82, "Branch prediction blocking") - DEF_FEAT(MISC_INSTRUCTION_EXT4, "minste4", STFL, 84, "Miscellaneous-Instruction-Extensions Facility 4") -+DEF_FEAT(SIF, "sif", STFL, 85, "Sequential-instruction-fetching facility") - DEF_FEAT(MSA_EXT_12, "msa12-base", STFL, 86, "Message-security-assist-extension-12 facility (excluding subfunctions)") - DEF_FEAT(VECTOR, "vx", STFL, 129, "Vector facility") - DEF_FEAT(INSTRUCTION_EXEC_PROT, "iep", STFL, 130, "Instruction-execution-protection facility") --- -2.39.3 - diff --git a/kvm-s390x-cpumodel-Add-ptff-Query-Time-Stamp-Event-QTSE-.patch b/kvm-s390x-cpumodel-Add-ptff-Query-Time-Stamp-Event-QTSE-.patch deleted file mode 100644 index 9a0c5de..0000000 --- a/kvm-s390x-cpumodel-Add-ptff-Query-Time-Stamp-Event-QTSE-.patch +++ /dev/null @@ -1,90 +0,0 @@ -From d1313d94cb0a2b69b18cf7e7531945cb131c23c2 Mon Sep 17 00:00:00 2001 -From: Hendrik Brueckner -Date: Fri, 6 Dec 2024 13:27:41 +0100 -Subject: [PATCH 06/18] s390x/cpumodel: Add ptff Query Time-Stamp Event (QTSE) - support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [6/16] f5642cffc8deb0caf96d59da72e82db435e28205 (thuth/qemu-kvm-cs9) - -Introduce a new PTFF subfunction to query-stamp events. - -Signed-off-by: Hendrik Brueckner -Reviewed-by: Janosch Frank -Message-ID: <20241206122751.189721-6-brueckner@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit eba6f49128fbcf75d19acb6aef250d0664d03e9e) ---- - target/s390x/cpu_features.c | 1 + - target/s390x/cpu_features_def.h.inc | 1 + - target/s390x/gen-features.c | 9 +++++++++ - 3 files changed, 11 insertions(+) - -diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c -index 9ba127e386..385a2ff860 100644 ---- a/target/s390x/cpu_features.c -+++ b/target/s390x/cpu_features.c -@@ -241,6 +241,7 @@ static S390FeatGroupDef s390_feature_groups[] = { - FEAT_GROUP_INIT("plo", PLO, "Perform-locked-operation facility"), - FEAT_GROUP_INIT("tods", TOD_CLOCK_STEERING, "Tod-clock-steering facility"), - FEAT_GROUP_INIT("gen13ptff", GEN13_PTFF, "PTFF enhancements introduced with z13"), -+ FEAT_GROUP_INIT("gen17ptff", GEN17_PTFF, "PTFF enhancements introduced with gen17"), - FEAT_GROUP_INIT("msa", MSA, "Message-security-assist facility"), - FEAT_GROUP_INIT("msa1", MSA_EXT_1, "Message-security-assist-extension 1 facility"), - FEAT_GROUP_INIT("msa2", MSA_EXT_2, "Message-security-assist-extension 2 facility"), -diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc -index 2132837ffe..f96cb5a7d8 100644 ---- a/target/s390x/cpu_features_def.h.inc -+++ b/target/s390x/cpu_features_def.h.inc -@@ -181,6 +181,7 @@ DEF_FEAT(PTFF_QSI, "ptff-qsi", PTFF, 2, "PTFF Query Steering Information") - DEF_FEAT(PTFF_QPT, "ptff-qpc", PTFF, 3, "PTFF Query Physical Clock") - DEF_FEAT(PTFF_QUI, "ptff-qui", PTFF, 4, "PTFF Query UTC Information") - DEF_FEAT(PTFF_QTOU, "ptff-qtou", PTFF, 5, "PTFF Query TOD Offset User") -+DEF_FEAT(PTFF_QTSE, "ptff-qtse", PTFF, 6, "PTFF Query Time-Stamp Event") - DEF_FEAT(PTFF_QSIE, "ptff-qsie", PTFF, 10, "PTFF Query Steering Information Extended") - DEF_FEAT(PTFF_QTOUE, "ptff-qtoue", PTFF, 13, "PTFF Query TOD Offset User Extended") - DEF_FEAT(PTFF_STO, "ptff-sto", PTFF, 65, "PTFF Set TOD Offset") -diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c -index 3326e7df43..302b653214 100644 ---- a/target/s390x/gen-features.c -+++ b/target/s390x/gen-features.c -@@ -64,6 +64,9 @@ - S390_FEAT_PTFF_STOE, \ - S390_FEAT_PTFF_STOUE - -+#define S390_FEAT_GROUP_GEN17_PTFF \ -+ S390_FEAT_PTFF_QTSE -+ - #define S390_FEAT_GROUP_MSA \ - S390_FEAT_MSA, \ - S390_FEAT_KMAC_DEA, \ -@@ -318,6 +321,11 @@ static uint16_t group_GEN13_PTFF[] = { - static uint16_t group_MULTIPLE_EPOCH_PTFF[] = { - S390_FEAT_GROUP_MULTIPLE_EPOCH_PTFF, - }; -+ -+static uint16_t group_GEN17_PTFF[] = { -+ S390_FEAT_GROUP_GEN17_PTFF, -+}; -+ - static uint16_t group_MSA[] = { - S390_FEAT_GROUP_MSA, - }; -@@ -918,6 +926,7 @@ static FeatGroupDefSpec FeatGroupDef[] = { - FEAT_GROUP_INITIALIZER(PLO), - FEAT_GROUP_INITIALIZER(TOD_CLOCK_STEERING), - FEAT_GROUP_INITIALIZER(GEN13_PTFF), -+ FEAT_GROUP_INITIALIZER(GEN17_PTFF), - FEAT_GROUP_INITIALIZER(MSA), - FEAT_GROUP_INITIALIZER(MSA_EXT_1), - FEAT_GROUP_INITIALIZER(MSA_EXT_2), --- -2.39.3 - diff --git a/kvm-s390x-cpumodel-add-Concurrent-functions-facility-sup.patch b/kvm-s390x-cpumodel-add-Concurrent-functions-facility-sup.patch deleted file mode 100644 index bb5c4c5..0000000 --- a/kvm-s390x-cpumodel-add-Concurrent-functions-facility-sup.patch +++ /dev/null @@ -1,169 +0,0 @@ -From 66725d6be2ad779432d3b02a0ad20a415bd37f1f Mon Sep 17 00:00:00 2001 -From: Hendrik Brueckner -Date: Fri, 6 Dec 2024 13:27:43 +0100 -Subject: [PATCH 08/18] s390x/cpumodel: add Concurrent-functions facility - support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [8/16] 891c3efec3d7dbce03e01f0fcb61cca9669570eb (thuth/qemu-kvm-cs9) - -The Concurrent-functions facility introduces the new instruction -Perform Functions with Concurrent Results (PFCR) with few subfunctions. - -Signed-off-by: Hendrik Brueckner -Reviewed-by: Janosch Frank -Message-ID: <20241206122751.189721-8-brueckner@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit c9ea365dce32bc114dacd7cfca7c478a82459b47) ---- - target/s390x/cpu_features.c | 2 ++ - target/s390x/cpu_features.h | 1 + - target/s390x/cpu_features_def.h.inc | 8 ++++++++ - target/s390x/cpu_models.c | 5 +++++ - target/s390x/gen-features.c | 13 +++++++++++++ - target/s390x/kvm/kvm.c | 6 ++++++ - 6 files changed, 35 insertions(+) - -diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c -index 385a2ff860..5f8b02f12c 100644 ---- a/target/s390x/cpu_features.c -+++ b/target/s390x/cpu_features.c -@@ -93,6 +93,7 @@ void s390_fill_feat_block(const S390FeatBitmap features, S390FeatType type, - case S390_FEAT_TYPE_KDSA: - case S390_FEAT_TYPE_SORTL: - case S390_FEAT_TYPE_DFLTCC: -+ case S390_FEAT_TYPE_PFCR: - set_be_bit(0, data); /* query is always available */ - break; - default: -@@ -263,6 +264,7 @@ static S390FeatGroupDef s390_feature_groups[] = { - FEAT_GROUP_INIT("mepochptff", MULTIPLE_EPOCH_PTFF, "PTFF enhancements introduced with Multiple-epoch facility"), - FEAT_GROUP_INIT("esort", ENH_SORT, "Enhanced-sort facility"), - FEAT_GROUP_INIT("deflate", DEFLATE_CONVERSION, "Deflate-conversion facility"), -+ FEAT_GROUP_INIT("ccf", CONCURRENT_FUNCTIONS, "Concurrent-functions facility"), - }; - - const S390FeatGroupDef *s390_feat_group_def(S390FeatGroup group) -diff --git a/target/s390x/cpu_features.h b/target/s390x/cpu_features.h -index 661a8cd6db..5635839d03 100644 ---- a/target/s390x/cpu_features.h -+++ b/target/s390x/cpu_features.h -@@ -44,6 +44,7 @@ typedef enum { - S390_FEAT_TYPE_SORTL, - S390_FEAT_TYPE_DFLTCC, - S390_FEAT_TYPE_UV_FEAT_GUEST, -+ S390_FEAT_TYPE_PFCR, - } S390FeatType; - - /* Definition of a CPU feature */ -diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc -index f96cb5a7d8..09872ab3d8 100644 ---- a/target/s390x/cpu_features_def.h.inc -+++ b/target/s390x/cpu_features_def.h.inc -@@ -116,6 +116,7 @@ DEF_FEAT(BEAR_ENH, "beareh", STFL, 193, "BEAR-enhancement facility") - DEF_FEAT(RDP, "rdp", STFL, 194, "Reset-DAT-protection facility") - DEF_FEAT(PAI, "pai", STFL, 196, "Processor-Activity-Instrumentation facility") - DEF_FEAT(PAIE, "paie", STFL, 197, "Processor-Activity-Instrumentation extension-1") -+DEF_FEAT(CCF_BASE, "ccf-base", STFL, 201, "Concurrent-Functions facility") - - /* Features exposed via SCLP SCCB Byte 80 - 98 (bit numbers relative to byte-80) */ - DEF_FEAT(SIE_GSLS, "gsls", SCLP_CONF_CHAR, 40, "SIE: Guest-storage-limit-suppression facility") -@@ -413,3 +414,10 @@ DEF_FEAT(DEFLATE_F0, "dfltcc-f0", DFLTCC, 192, "DFLTCC format 0 parameter-block" - /* Features exposed via the UV-CALL instruction */ - DEF_FEAT(UV_FEAT_AP, "appv", UV_FEAT_GUEST, 4, "AP instructions installed for secure guests") - DEF_FEAT(UV_FEAT_AP_INTR, "appvi", UV_FEAT_GUEST, 5, "AP instructions interruption support for secure guests") -+ -+/* Features exposed via the PFCR instruction (concurrent-functions facility). */ -+DEF_FEAT(PFCR_QAF, "pfcr-qaf", PFCR, 0, "PFCR Query-Available-Functions") -+DEF_FEAT(PFCR_CSDST, "pfcr-csdst", PFCR, 1, "PFCR Compare-and-Swap-and-Double-Store (32)") -+DEF_FEAT(PFCR_CSDSTG, "pfcr-csdstg", PFCR, 2, "PFCR Compare-and-Swap-and-Double-Store (64)") -+DEF_FEAT(PFCR_CSTST, "pfcr-cstst", PFCR, 3, "PFCR Compare-and-Swap-and-Triple-Store (32)") -+DEF_FEAT(PFCR_CSTSTG, "pfcr-cststg", PFCR, 4, "PFCR Compare-and-Swap-and-Triple-Store (64)") -diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c -index da441b7b10..cb45911ac0 100644 ---- a/target/s390x/cpu_models.c -+++ b/target/s390x/cpu_models.c -@@ -507,6 +507,11 @@ static void check_consistency(const S390CPUModel *model) - { S390_FEAT_RDP, S390_FEAT_LOCAL_TLB_CLEARING }, - { S390_FEAT_UV_FEAT_AP, S390_FEAT_AP }, - { S390_FEAT_UV_FEAT_AP_INTR, S390_FEAT_UV_FEAT_AP }, -+ { S390_FEAT_PFCR_QAF, S390_FEAT_CCF_BASE }, -+ { S390_FEAT_PFCR_CSDST, S390_FEAT_CCF_BASE }, -+ { S390_FEAT_PFCR_CSDSTG, S390_FEAT_CCF_BASE }, -+ { S390_FEAT_PFCR_CSTST, S390_FEAT_CCF_BASE }, -+ { S390_FEAT_PFCR_CSTSTG, S390_FEAT_CCF_BASE }, - }; - int i; - -diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c -index 302b653214..6d00ffcda7 100644 ---- a/target/s390x/gen-features.c -+++ b/target/s390x/gen-features.c -@@ -308,6 +308,14 @@ - S390_FEAT_DEFLATE_XPND, \ - S390_FEAT_DEFLATE_F0 - -+#define S390_FEAT_GROUP_CONCURRENT_FUNCTIONS \ -+ S390_FEAT_CCF_BASE, \ -+ S390_FEAT_PFCR_QAF, \ -+ S390_FEAT_PFCR_CSDST, \ -+ S390_FEAT_PFCR_CSDSTG, \ -+ S390_FEAT_PFCR_CSTST, \ -+ S390_FEAT_PFCR_CSTSTG -+ - /* cpu feature groups */ - static uint16_t group_PLO[] = { - S390_FEAT_GROUP_PLO, -@@ -398,6 +406,10 @@ static uint16_t group_DEFLATE_CONVERSION[] = { - S390_FEAT_GROUP_DEFLATE_CONVERSION, - }; - -+static uint16_t group_CONCURRENT_FUNCTIONS[] = { -+ S390_FEAT_GROUP_CONCURRENT_FUNCTIONS, -+}; -+ - /* Base features (in order of release) - * Only non-hypervisor managed features belong here. - * Base feature sets are static meaning they do not change in future QEMU -@@ -948,6 +960,7 @@ static FeatGroupDefSpec FeatGroupDef[] = { - FEAT_GROUP_INITIALIZER(MULTIPLE_EPOCH_PTFF), - FEAT_GROUP_INITIALIZER(ENH_SORT), - FEAT_GROUP_INITIALIZER(DEFLATE_CONVERSION), -+ FEAT_GROUP_INITIALIZER(CONCURRENT_FUNCTIONS), - }; - - #define QEMU_FEAT_INITIALIZER(_name) \ -diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c -index 8ffe0159d8..dd0322c43a 100644 ---- a/target/s390x/kvm/kvm.c -+++ b/target/s390x/kvm/kvm.c -@@ -2195,6 +2195,9 @@ static int query_cpu_subfunc(S390FeatBitmap features) - if (test_bit(S390_FEAT_DEFLATE_BASE, features)) { - s390_add_from_feat_block(features, S390_FEAT_TYPE_DFLTCC, prop.dfltcc); - } -+ if (test_bit(S390_FEAT_CCF_BASE, features)) { -+ s390_add_from_feat_block(features, S390_FEAT_TYPE_PFCR, prop.pfcr); -+ } - return 0; - } - -@@ -2248,6 +2251,9 @@ static int configure_cpu_subfunc(const S390FeatBitmap features) - if (test_bit(S390_FEAT_DEFLATE_BASE, features)) { - s390_fill_feat_block(features, S390_FEAT_TYPE_DFLTCC, prop.dfltcc); - } -+ if (test_bit(S390_FEAT_CCF_BASE, features)) { -+ s390_fill_feat_block(features, S390_FEAT_TYPE_PFCR, prop.pfcr); -+ } - return kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr); - } - --- -2.39.3 - diff --git a/kvm-s390x-cpumodel-add-Ineffective-nonconstrained-transa.patch b/kvm-s390x-cpumodel-add-Ineffective-nonconstrained-transa.patch deleted file mode 100644 index 45cacc4..0000000 --- a/kvm-s390x-cpumodel-add-Ineffective-nonconstrained-transa.patch +++ /dev/null @@ -1,56 +0,0 @@ -From e54ca265e81453305c96adce3e521d543ac124a6 Mon Sep 17 00:00:00 2001 -From: Hendrik Brueckner -Date: Fri, 6 Dec 2024 13:27:47 +0100 -Subject: [PATCH 12/18] s390x/cpumodel: add - Ineffective-nonconstrained-transaction facility -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [12/16] 1a5530bb0a42f5771a46bb21934b77035d26aa54 (thuth/qemu-kvm-cs9) - -This facility indicates reduced support for noncontrained -transactional-execution. - -Signed-off-by: Hendrik Brueckner -Reviewed-by: Janosch Frank -Message-ID: <20241206122751.189721-12-brueckner@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 12417b713c1fffc26c680e99e3429f055eb9af2e) ---- - target/s390x/cpu_features_def.h.inc | 1 + - target/s390x/cpu_models.c | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc -index df154d145f..2c1d1cd98a 100644 ---- a/target/s390x/cpu_features_def.h.inc -+++ b/target/s390x/cpu_features_def.h.inc -@@ -112,6 +112,7 @@ DEF_FEAT(MSA_EXT_9, "msa9-base", STFL, 155, "Message-security-assist-extension-9 - DEF_FEAT(ETOKEN, "etoken", STFL, 156, "Etoken facility") - DEF_FEAT(UNPACK, "unpack", STFL, 161, "Unpack facility") - DEF_FEAT(NNPA, "nnpa", STFL, 165, "NNPA facility") -+DEF_FEAT(INEFF_NC_TX, "ineff_nc_tx", STFL, 170, "Ineffective-nonconstrained-transaction facility") - DEF_FEAT(VECTOR_PACKED_DECIMAL_ENH2, "vxpdeh2", STFL, 192, "Vector-Packed-Decimal-Enhancement facility 2") - DEF_FEAT(BEAR_ENH, "beareh", STFL, 193, "BEAR-enhancement facility") - DEF_FEAT(RDP, "rdp", STFL, 194, "Reset-DAT-protection facility") -diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c -index 94cc6a0f3e..9e9f6dae07 100644 ---- a/target/s390x/cpu_models.c -+++ b/target/s390x/cpu_models.c -@@ -515,6 +515,7 @@ static void check_consistency(const S390CPUModel *model) - { S390_FEAT_PFCR_CSDSTG, S390_FEAT_CCF_BASE }, - { S390_FEAT_PFCR_CSTST, S390_FEAT_CCF_BASE }, - { S390_FEAT_PFCR_CSTSTG, S390_FEAT_CCF_BASE }, -+ { S390_FEAT_INEFF_NC_TX, S390_FEAT_TRANSACTIONAL_EXE }, - }; - int i; - --- -2.39.3 - diff --git a/kvm-s390x-cpumodel-add-Miscellaneous-Instruction-Extensi.patch b/kvm-s390x-cpumodel-add-Miscellaneous-Instruction-Extensi.patch deleted file mode 100644 index 645294c..0000000 --- a/kvm-s390x-cpumodel-add-Miscellaneous-Instruction-Extensi.patch +++ /dev/null @@ -1,42 +0,0 @@ -From f836a70baeebc6cfff87f3b8cf39bc82225cd88f Mon Sep 17 00:00:00 2001 -From: Hendrik Brueckner -Date: Fri, 6 Dec 2024 13:27:45 +0100 -Subject: [PATCH 10/18] s390x/cpumodel: add - Miscellaneous-Instruction-Extensions Facility 4 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [10/16] 375acf46d9a9950c939e0bf95c6512f6df3b3b3d (thuth/qemu-kvm-cs9) - -This facility introduces few new instructions. - -Signed-off-by: Hendrik Brueckner -Reviewed-by: Janosch Frank -Message-ID: <20241206122751.189721-10-brueckner@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit e68e5ea6fe87c0177ea6421045c1d46f223a861e) ---- - target/s390x/cpu_features_def.h.inc | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc -index 0b7be0e6e9..8be2e0e46d 100644 ---- a/target/s390x/cpu_features_def.h.inc -+++ b/target/s390x/cpu_features_def.h.inc -@@ -90,6 +90,7 @@ DEF_FEAT(EDAT_2, "edat2", STFL, 78, "Enhanced-DAT facility 2") - DEF_FEAT(DFP_PACKED_CONVERSION, "dfppc", STFL, 80, "Decimal-floating-point packed-conversion facility") - DEF_FEAT(PPA15, "ppa15", STFL, 81, "PPA15 is installed") - DEF_FEAT(BPB, "bpb", STFL, 82, "Branch prediction blocking") -+DEF_FEAT(MISC_INSTRUCTION_EXT4, "minste4", STFL, 84, "Miscellaneous-Instruction-Extensions Facility 4") - DEF_FEAT(MSA_EXT_12, "msa12-base", STFL, 86, "Message-security-assist-extension-12 facility (excluding subfunctions)") - DEF_FEAT(VECTOR, "vx", STFL, 129, "Vector facility") - DEF_FEAT(INSTRUCTION_EXEC_PROT, "iep", STFL, 130, "Instruction-execution-protection facility") --- -2.39.3 - diff --git a/kvm-s390x-cpumodel-add-Vector-Enhancements-facility-3.patch b/kvm-s390x-cpumodel-add-Vector-Enhancements-facility-3.patch deleted file mode 100644 index fe6327e..0000000 --- a/kvm-s390x-cpumodel-add-Vector-Enhancements-facility-3.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 38d15311c53d6f973ad6bcffe5a851fed58d82cf Mon Sep 17 00:00:00 2001 -From: Hendrik Brueckner -Date: Fri, 6 Dec 2024 13:27:44 +0100 -Subject: [PATCH 09/18] s390x/cpumodel: add Vector Enhancements facility 3 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [9/16] 0e28c1a3a458b035a165e6d0f6e65290efce4cf0 (thuth/qemu-kvm-cs9) - -The Vector Enhancements facility 3 introduces new instructions and -extends support for doubleword/quadword elements. - -Signed-off-by: Hendrik Brueckner -Reviewed-by: Janosch Frank -Message-ID: <20241206122751.189721-9-brueckner@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 0b2c66a3fa5ccecf26ea011d97d65a986b42b4d8) ---- - target/s390x/cpu_features_def.h.inc | 1 + - target/s390x/cpu_models.c | 2 ++ - 2 files changed, 3 insertions(+) - -diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc -index 09872ab3d8..0b7be0e6e9 100644 ---- a/target/s390x/cpu_features_def.h.inc -+++ b/target/s390x/cpu_features_def.h.inc -@@ -116,6 +116,7 @@ DEF_FEAT(BEAR_ENH, "beareh", STFL, 193, "BEAR-enhancement facility") - DEF_FEAT(RDP, "rdp", STFL, 194, "Reset-DAT-protection facility") - DEF_FEAT(PAI, "pai", STFL, 196, "Processor-Activity-Instrumentation facility") - DEF_FEAT(PAIE, "paie", STFL, 197, "Processor-Activity-Instrumentation extension-1") -+DEF_FEAT(VECTOR_ENH3, "vxeh3", STFL, 198, "Vector Enhancements facility 3") - DEF_FEAT(CCF_BASE, "ccf-base", STFL, 201, "Concurrent-Functions facility") - - /* Features exposed via SCLP SCCB Byte 80 - 98 (bit numbers relative to byte-80) */ -diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c -index cb45911ac0..5fb5c6f38e 100644 ---- a/target/s390x/cpu_models.c -+++ b/target/s390x/cpu_models.c -@@ -461,6 +461,8 @@ static void check_consistency(const S390CPUModel *model) - { S390_FEAT_VECTOR_PACKED_DECIMAL_ENH, S390_FEAT_VECTOR_PACKED_DECIMAL }, - { S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH }, - { S390_FEAT_VECTOR_ENH, S390_FEAT_VECTOR }, -+ { S390_FEAT_VECTOR_ENH2, S390_FEAT_VECTOR_ENH }, -+ { S390_FEAT_VECTOR_ENH3, S390_FEAT_VECTOR_ENH2 }, - { S390_FEAT_INSTRUCTION_EXEC_PROT, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2 }, - { S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2, S390_FEAT_ESOP }, - { S390_FEAT_CMM_NT, S390_FEAT_CMM }, --- -2.39.3 - diff --git a/kvm-s390x-cpumodel-add-Vector-Packed-Decimal-Enhancement.patch b/kvm-s390x-cpumodel-add-Vector-Packed-Decimal-Enhancement.patch deleted file mode 100644 index 4dd3499..0000000 --- a/kvm-s390x-cpumodel-add-Vector-Packed-Decimal-Enhancement.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 846d00e369c2ff33201c4a7ae4a303f4feb82c8f Mon Sep 17 00:00:00 2001 -From: Hendrik Brueckner -Date: Fri, 6 Dec 2024 13:27:46 +0100 -Subject: [PATCH 11/18] s390x/cpumodel: add Vector-Packed-Decimal-Enhancement - facility 3 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [11/16] 4ab6618fe8fda8277fc92d0de6505df034f8c9fe (thuth/qemu-kvm-cs9) - -This facility introduces new capabilities for the signed-pack-decimal -format. - -Signed-off-by: Hendrik Brueckner -Reviewed-by: Janosch Frank -Message-ID: <20241206122751.189721-11-brueckner@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit db4c208abde53a7ed16d566bf63a3520894bba8d) ---- - target/s390x/cpu_features_def.h.inc | 1 + - target/s390x/cpu_models.c | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc -index 8be2e0e46d..df154d145f 100644 ---- a/target/s390x/cpu_features_def.h.inc -+++ b/target/s390x/cpu_features_def.h.inc -@@ -118,6 +118,7 @@ DEF_FEAT(RDP, "rdp", STFL, 194, "Reset-DAT-protection facility") - DEF_FEAT(PAI, "pai", STFL, 196, "Processor-Activity-Instrumentation facility") - DEF_FEAT(PAIE, "paie", STFL, 197, "Processor-Activity-Instrumentation extension-1") - DEF_FEAT(VECTOR_ENH3, "vxeh3", STFL, 198, "Vector Enhancements facility 3") -+DEF_FEAT(VECTOR_PACKED_DECIMAL_ENH3, "vxpdeh3", STFL, 199, "Vector-Packed-Decimal-Enhancement facility 3") - DEF_FEAT(CCF_BASE, "ccf-base", STFL, 201, "Concurrent-Functions facility") - - /* Features exposed via SCLP SCCB Byte 80 - 98 (bit numbers relative to byte-80) */ -diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c -index 5fb5c6f38e..94cc6a0f3e 100644 ---- a/target/s390x/cpu_models.c -+++ b/target/s390x/cpu_models.c -@@ -460,6 +460,7 @@ static void check_consistency(const S390CPUModel *model) - { S390_FEAT_VECTOR_PACKED_DECIMAL, S390_FEAT_VECTOR }, - { S390_FEAT_VECTOR_PACKED_DECIMAL_ENH, S390_FEAT_VECTOR_PACKED_DECIMAL }, - { S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH }, -+ { S390_FEAT_VECTOR_PACKED_DECIMAL_ENH3, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2 }, - { S390_FEAT_VECTOR_ENH, S390_FEAT_VECTOR }, - { S390_FEAT_VECTOR_ENH2, S390_FEAT_VECTOR_ENH }, - { S390_FEAT_VECTOR_ENH3, S390_FEAT_VECTOR_ENH2 }, --- -2.39.3 - diff --git a/kvm-s390x-cpumodel-add-msa10-subfunctions.patch b/kvm-s390x-cpumodel-add-msa10-subfunctions.patch deleted file mode 100644 index c0a15bc..0000000 --- a/kvm-s390x-cpumodel-add-msa10-subfunctions.patch +++ /dev/null @@ -1,133 +0,0 @@ -From be8c87d33304948258dad5e46582c588ff795344 Mon Sep 17 00:00:00 2001 -From: Hendrik Brueckner -Date: Fri, 6 Dec 2024 13:27:37 +0100 -Subject: [PATCH 02/18] s390x/cpumodel: add msa10 subfunctions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [2/16] 967e78e0d496cf5241bfcee7b96b0308b5cedbda (thuth/qemu-kvm-cs9) - -MSA10 introduces new AES XTS subfunctions. - -Signed-off-by: Hendrik Brueckner -Reviewed-by: Christian Borntraeger -Message-ID: <20241206122751.189721-2-brueckner@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 1029cd5b9827ba6aa7f5e02eed1928a928e2fa5e) ---- - target/s390x/cpu_features.c | 2 ++ - target/s390x/cpu_features_def.h.inc | 6 ++++++ - target/s390x/cpu_models.c | 4 ++++ - target/s390x/gen-features.c | 20 ++++++++++++++++++++ - 4 files changed, 32 insertions(+) - -diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c -index cb4e2b8920..a3c239595a 100644 ---- a/target/s390x/cpu_features.c -+++ b/target/s390x/cpu_features.c -@@ -252,6 +252,8 @@ static S390FeatGroupDef s390_feature_groups[] = { - FEAT_GROUP_INIT("msa8", MSA_EXT_8, "Message-security-assist-extension 8 facility"), - FEAT_GROUP_INIT("msa9", MSA_EXT_9, "Message-security-assist-extension 9 facility"), - FEAT_GROUP_INIT("msa9_pckmo", MSA_EXT_9_PCKMO, "Message-security-assist-extension 9 PCKMO subfunctions"), -+ FEAT_GROUP_INIT("msa10", MSA_EXT_10, "Message-security-assist-extension 10 facility"), -+ FEAT_GROUP_INIT("msa10_pckmo", MSA_EXT_10_PCKMO, "Message-security-assist-extension 10 PCKMO subfunctions"), - FEAT_GROUP_INIT("mepochptff", MULTIPLE_EPOCH_PTFF, "PTFF enhancements introduced with Multiple-epoch facility"), - FEAT_GROUP_INIT("esort", ENH_SORT, "Enhanced-sort facility"), - FEAT_GROUP_INIT("deflate", DEFLATE_CONVERSION, "Deflate-conversion facility"), -diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc -index c53ac13352..104d186c3f 100644 ---- a/target/s390x/cpu_features_def.h.inc -+++ b/target/s390x/cpu_features_def.h.inc -@@ -233,6 +233,10 @@ DEF_FEAT(KM_XTS_AES_128, "km-xts-aes-128", KM, 50, "KM XTS-AES-128") - DEF_FEAT(KM_XTS_AES_256, "km-xts-aes-256", KM, 52, "KM XTS-AES-256") - DEF_FEAT(KM_XTS_EAES_128, "km-xts-eaes-128", KM, 58, "KM XTS-Encrypted-AES-128") - DEF_FEAT(KM_XTS_EAES_256, "km-xts-eaes-256", KM, 60, "KM XTS-Encrypted-AES-256") -+DEF_FEAT(KM_FULL_XTS_AES_128, "km-full-xts-aes-128", KM, 82, "KM Full-XTS-AES-128") -+DEF_FEAT(KM_FULL_XTS_AES_256, "km-full-xts-aes-256", KM, 84, "KM Full-XTS-AES-256") -+DEF_FEAT(KM_FULL_XTS_EAES_128, "km-full-xts-eaes-128", KM, 90, "KM Full-XTS-Encrypted-AES-128") -+DEF_FEAT(KM_FULL_XTS_EAES_256, "km-full-xts-eaes-256", KM, 92, "KM Full-XTS-Encrypted-AES-256") - - /* Features exposed via the KIMD instruction. */ - DEF_FEAT(KIMD_SHA_1, "kimd-sha-1", KIMD, 1, "KIMD SHA-1") -@@ -264,6 +268,8 @@ DEF_FEAT(PCKMO_ETDEA_256, "pckmo-etdea-192", PCKMO, 3, "PCKMO Encrypted-TDEA-192 - DEF_FEAT(PCKMO_AES_128, "pckmo-aes-128", PCKMO, 18, "PCKMO Encrypted-AES-128-Key") - DEF_FEAT(PCKMO_AES_192, "pckmo-aes-192", PCKMO, 19, "PCKMO Encrypted-AES-192-Key") - DEF_FEAT(PCKMO_AES_256, "pckmo-aes-256", PCKMO, 20, "PCKMO Encrypted-AES-256-Key") -+DEF_FEAT(PCKMO_AES_XTS_128_DK, "pckmo-aes-xts-128-dk", PCKMO, 21, "PCKMO Encrypt-AES-XTS-128-Double-Key") -+DEF_FEAT(PCKMO_AES_XTS_256_DK, "pckmo-aes-xts-256-dk", PCKMO, 22, "PCKMO Encrypt-AES-XTS-256-Double-Key") - DEF_FEAT(PCKMO_ECC_P256, "pckmo-ecc-p256", PCKMO, 32, "PCKMO Encrypt-ECC-P256-Key") - DEF_FEAT(PCKMO_ECC_P384, "pckmo-ecc-p384", PCKMO, 33, "PCKMO Encrypt-ECC-P384-Key") - DEF_FEAT(PCKMO_ECC_P521, "pckmo-ecc-p521", PCKMO, 34, "PCKMO Encrypt-ECC-P521-Key") -diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c -index 8afa9af1a5..e71c445379 100644 ---- a/target/s390x/cpu_models.c -+++ b/target/s390x/cpu_models.c -@@ -480,6 +480,10 @@ static void check_consistency(const S390CPUModel *model) - { S390_FEAT_KLMD_SHA3_512, S390_FEAT_MSA }, - { S390_FEAT_KLMD_SHAKE_128, S390_FEAT_MSA }, - { S390_FEAT_KLMD_SHAKE_256, S390_FEAT_MSA }, -+ { S390_FEAT_KM_FULL_XTS_AES_128, S390_FEAT_MSA_EXT_4 }, -+ { S390_FEAT_KM_FULL_XTS_AES_256, S390_FEAT_MSA_EXT_4 }, -+ { S390_FEAT_KM_FULL_XTS_EAES_128, S390_FEAT_MSA_EXT_4 }, -+ { S390_FEAT_KM_FULL_XTS_EAES_256, S390_FEAT_MSA_EXT_4 }, - { S390_FEAT_PRNO_TRNG_QRTCR, S390_FEAT_MSA_EXT_5 }, - { S390_FEAT_PRNO_TRNG, S390_FEAT_MSA_EXT_5 }, - { S390_FEAT_SIE_KSS, S390_FEAT_SIE_F2 }, -diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c -index 2b2bfc3736..06c3bf64f3 100644 ---- a/target/s390x/gen-features.c -+++ b/target/s390x/gen-features.c -@@ -246,6 +246,16 @@ - S390_FEAT_PCKMO_ECC_ED25519, \ - S390_FEAT_PCKMO_ECC_ED448 - -+#define S390_FEAT_GROUP_MSA_EXT_10 \ -+ S390_FEAT_KM_FULL_XTS_AES_128, \ -+ S390_FEAT_KM_FULL_XTS_AES_256, \ -+ S390_FEAT_KM_FULL_XTS_EAES_128, \ -+ S390_FEAT_KM_FULL_XTS_EAES_256 -+ -+#define S390_FEAT_GROUP_MSA_EXT_10_PCKMO \ -+ S390_FEAT_PCKMO_AES_XTS_128_DK, \ -+ S390_FEAT_PCKMO_AES_XTS_256_DK -+ - #define S390_FEAT_GROUP_ENH_SORT \ - S390_FEAT_ESORT_BASE, \ - S390_FEAT_SORTL_SFLR, \ -@@ -307,10 +317,18 @@ static uint16_t group_MSA_EXT_9[] = { - S390_FEAT_GROUP_MSA_EXT_9, - }; - -+static uint16_t group_MSA_EXT_10[] = { -+ S390_FEAT_GROUP_MSA_EXT_10, -+}; -+ - static uint16_t group_MSA_EXT_9_PCKMO[] = { - S390_FEAT_GROUP_MSA_EXT_9_PCKMO, - }; - -+static uint16_t group_MSA_EXT_10_PCKMO[] = { -+ S390_FEAT_GROUP_MSA_EXT_10_PCKMO, -+}; -+ - static uint16_t group_ENH_SORT[] = { - S390_FEAT_GROUP_ENH_SORT, - }; -@@ -858,6 +876,8 @@ static FeatGroupDefSpec FeatGroupDef[] = { - FEAT_GROUP_INITIALIZER(MSA_EXT_8), - FEAT_GROUP_INITIALIZER(MSA_EXT_9), - FEAT_GROUP_INITIALIZER(MSA_EXT_9_PCKMO), -+ FEAT_GROUP_INITIALIZER(MSA_EXT_10), -+ FEAT_GROUP_INITIALIZER(MSA_EXT_10_PCKMO), - FEAT_GROUP_INITIALIZER(MULTIPLE_EPOCH_PTFF), - FEAT_GROUP_INITIALIZER(ENH_SORT), - FEAT_GROUP_INITIALIZER(DEFLATE_CONVERSION), --- -2.39.3 - diff --git a/kvm-s390x-cpumodel-add-msa11-subfunctions.patch b/kvm-s390x-cpumodel-add-msa11-subfunctions.patch deleted file mode 100644 index 59d7369..0000000 --- a/kvm-s390x-cpumodel-add-msa11-subfunctions.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 328b55dd31fce9e849d8dd10124cda47013d3035 Mon Sep 17 00:00:00 2001 -From: Hendrik Brueckner -Date: Fri, 6 Dec 2024 13:27:38 +0100 -Subject: [PATCH 03/18] s390x/cpumodel: add msa11 subfunctions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [3/16] 8b4158361a17d973fa30a7bcb9d911a2c5a42b14 (thuth/qemu-kvm-cs9) - -MSA11 introduces new HMAC subfunctions. - -Signed-off-by: Hendrik Brueckner -Reviewed-by: Christian Borntraeger -Message-ID: <20241206122751.189721-3-brueckner@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 11dc9020824c81552b021fbe0e2910e0348e7f8e) ---- - target/s390x/cpu_features.c | 2 ++ - target/s390x/cpu_features_def.h.inc | 10 ++++++++++ - target/s390x/cpu_models.c | 8 ++++++++ - target/s390x/gen-features.c | 24 ++++++++++++++++++++++++ - 4 files changed, 44 insertions(+) - -diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c -index a3c239595a..36930feccd 100644 ---- a/target/s390x/cpu_features.c -+++ b/target/s390x/cpu_features.c -@@ -254,6 +254,8 @@ static S390FeatGroupDef s390_feature_groups[] = { - FEAT_GROUP_INIT("msa9_pckmo", MSA_EXT_9_PCKMO, "Message-security-assist-extension 9 PCKMO subfunctions"), - FEAT_GROUP_INIT("msa10", MSA_EXT_10, "Message-security-assist-extension 10 facility"), - FEAT_GROUP_INIT("msa10_pckmo", MSA_EXT_10_PCKMO, "Message-security-assist-extension 10 PCKMO subfunctions"), -+ FEAT_GROUP_INIT("msa11", MSA_EXT_11, "Message-security-assist-extension 11 facility"), -+ FEAT_GROUP_INIT("msa11_pckmo", MSA_EXT_11_PCKMO, "Message-security-assist-extension 11 PCKMO subfunctions"), - FEAT_GROUP_INIT("mepochptff", MULTIPLE_EPOCH_PTFF, "PTFF enhancements introduced with Multiple-epoch facility"), - FEAT_GROUP_INIT("esort", ENH_SORT, "Enhanced-sort facility"), - FEAT_GROUP_INIT("deflate", DEFLATE_CONVERSION, "Deflate-conversion facility"), -diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc -index 104d186c3f..15ea51fc54 100644 ---- a/target/s390x/cpu_features_def.h.inc -+++ b/target/s390x/cpu_features_def.h.inc -@@ -200,6 +200,14 @@ DEF_FEAT(KMAC_AES_256, "kmac-aes-256", KMAC, 20, "KMAC AES-256") - DEF_FEAT(KMAC_EAES_128, "kmac-eaes-128", KMAC, 26, "KMAC Encrypted-AES-128") - DEF_FEAT(KMAC_EAES_192, "kmac-eaes-192", KMAC, 27, "KMAC Encrypted-AES-192") - DEF_FEAT(KMAC_EAES_256, "kmac-eaes-256", KMAC, 28, "KMAC Encrypted-AES-256") -+DEF_FEAT(KMAC_HMAC_SHA_224, "kmac-hmac-sha-224", KMAC, 112, "KMAC HMAC-SHA-224") -+DEF_FEAT(KMAC_HMAC_SHA_256, "kmac-hmac-sha-246", KMAC, 113, "KMAC HMAC-SHA-256") -+DEF_FEAT(KMAC_HMAC_SHA_384, "kmac-hmac-sha-384", KMAC, 114, "KMAC HMAC-SHA-384") -+DEF_FEAT(KMAC_HMAC_SHA_512, "kmac-hmac-sha-512", KMAC, 115, "KMAC HMAC-SHA-512") -+DEF_FEAT(KMAC_HMAC_ESHA_224, "kmac-hmac-esha-224", KMAC, 120, "KMAC HMAC-Encrypted-SHA-224") -+DEF_FEAT(KMAC_HMAC_ESHA_256, "kmac-hmac-esha-246", KMAC, 121, "KMAC HMAC-Encrypted-SHA-256") -+DEF_FEAT(KMAC_HMAC_ESHA_384, "kmac-hmac-esha-384", KMAC, 122, "KMAC HMAC-Encrypted-SHA-384") -+DEF_FEAT(KMAC_HMAC_ESHA_512, "kmac-hmac-esha-512", KMAC, 123, "KMAC HMAC-Encrypted-SHA-512") - - /* Features exposed via the KMC instruction. */ - DEF_FEAT(KMC_DEA, "kmc-dea", KMC, 1, "KMC DEA") -@@ -275,6 +283,8 @@ DEF_FEAT(PCKMO_ECC_P384, "pckmo-ecc-p384", PCKMO, 33, "PCKMO Encrypt-ECC-P384-Ke - DEF_FEAT(PCKMO_ECC_P521, "pckmo-ecc-p521", PCKMO, 34, "PCKMO Encrypt-ECC-P521-Key") - DEF_FEAT(PCKMO_ECC_ED25519, "pckmo-ecc-ed25519", PCKMO, 40 , "PCKMO Encrypt-ECC-Ed25519-Key") - DEF_FEAT(PCKMO_ECC_ED448, "pckmo-ecc-ed448", PCKMO, 41 , "PCKMO Encrypt-ECC-Ed448-Key") -+DEF_FEAT(PCKMO_HMAC_512, "pckmo-hmac-512", PCKMO, 118, "PCKMO Encrypt-HMAC-512-Key") -+DEF_FEAT(PCKMO_HMAC_1024, "pckmo-hmac-1024", PCKMO, 122, "PCKMO Encrypt-HMAC-1024-Key") - - /* Features exposed via the KMCTR instruction. */ - DEF_FEAT(KMCTR_DEA, "kmctr-dea", KMCTR, 1, "KMCTR DEA") -diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c -index e71c445379..da441b7b10 100644 ---- a/target/s390x/cpu_models.c -+++ b/target/s390x/cpu_models.c -@@ -480,6 +480,14 @@ static void check_consistency(const S390CPUModel *model) - { S390_FEAT_KLMD_SHA3_512, S390_FEAT_MSA }, - { S390_FEAT_KLMD_SHAKE_128, S390_FEAT_MSA }, - { S390_FEAT_KLMD_SHAKE_256, S390_FEAT_MSA }, -+ { S390_FEAT_KMAC_HMAC_SHA_224, S390_FEAT_MSA_EXT_3 }, -+ { S390_FEAT_KMAC_HMAC_SHA_256, S390_FEAT_MSA_EXT_3 }, -+ { S390_FEAT_KMAC_HMAC_SHA_384, S390_FEAT_MSA_EXT_3 }, -+ { S390_FEAT_KMAC_HMAC_SHA_512, S390_FEAT_MSA_EXT_3 }, -+ { S390_FEAT_KMAC_HMAC_ESHA_224, S390_FEAT_MSA_EXT_3 }, -+ { S390_FEAT_KMAC_HMAC_ESHA_256, S390_FEAT_MSA_EXT_3 }, -+ { S390_FEAT_KMAC_HMAC_ESHA_384, S390_FEAT_MSA_EXT_3 }, -+ { S390_FEAT_KMAC_HMAC_ESHA_512, S390_FEAT_MSA_EXT_3 }, - { S390_FEAT_KM_FULL_XTS_AES_128, S390_FEAT_MSA_EXT_4 }, - { S390_FEAT_KM_FULL_XTS_AES_256, S390_FEAT_MSA_EXT_4 }, - { S390_FEAT_KM_FULL_XTS_EAES_128, S390_FEAT_MSA_EXT_4 }, -diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c -index 06c3bf64f3..d6305f945a 100644 ---- a/target/s390x/gen-features.c -+++ b/target/s390x/gen-features.c -@@ -256,6 +256,20 @@ - S390_FEAT_PCKMO_AES_XTS_128_DK, \ - S390_FEAT_PCKMO_AES_XTS_256_DK - -+#define S390_FEAT_GROUP_MSA_EXT_11 \ -+ S390_FEAT_KMAC_HMAC_SHA_224, \ -+ S390_FEAT_KMAC_HMAC_SHA_256, \ -+ S390_FEAT_KMAC_HMAC_SHA_384, \ -+ S390_FEAT_KMAC_HMAC_SHA_512, \ -+ S390_FEAT_KMAC_HMAC_ESHA_224, \ -+ S390_FEAT_KMAC_HMAC_ESHA_256, \ -+ S390_FEAT_KMAC_HMAC_ESHA_384, \ -+ S390_FEAT_KMAC_HMAC_ESHA_512 -+ -+#define S390_FEAT_GROUP_MSA_EXT_11_PCKMO \ -+ S390_FEAT_PCKMO_HMAC_512, \ -+ S390_FEAT_PCKMO_HMAC_1024 -+ - #define S390_FEAT_GROUP_ENH_SORT \ - S390_FEAT_ESORT_BASE, \ - S390_FEAT_SORTL_SFLR, \ -@@ -321,6 +335,10 @@ static uint16_t group_MSA_EXT_10[] = { - S390_FEAT_GROUP_MSA_EXT_10, - }; - -+static uint16_t group_MSA_EXT_11[] = { -+ S390_FEAT_GROUP_MSA_EXT_11, -+}; -+ - static uint16_t group_MSA_EXT_9_PCKMO[] = { - S390_FEAT_GROUP_MSA_EXT_9_PCKMO, - }; -@@ -329,6 +347,10 @@ static uint16_t group_MSA_EXT_10_PCKMO[] = { - S390_FEAT_GROUP_MSA_EXT_10_PCKMO, - }; - -+static uint16_t group_MSA_EXT_11_PCKMO[] = { -+ S390_FEAT_GROUP_MSA_EXT_11_PCKMO, -+}; -+ - static uint16_t group_ENH_SORT[] = { - S390_FEAT_GROUP_ENH_SORT, - }; -@@ -878,6 +900,8 @@ static FeatGroupDefSpec FeatGroupDef[] = { - FEAT_GROUP_INITIALIZER(MSA_EXT_9_PCKMO), - FEAT_GROUP_INITIALIZER(MSA_EXT_10), - FEAT_GROUP_INITIALIZER(MSA_EXT_10_PCKMO), -+ FEAT_GROUP_INITIALIZER(MSA_EXT_11), -+ FEAT_GROUP_INITIALIZER(MSA_EXT_11_PCKMO), - FEAT_GROUP_INITIALIZER(MULTIPLE_EPOCH_PTFF), - FEAT_GROUP_INITIALIZER(ENH_SORT), - FEAT_GROUP_INITIALIZER(DEFLATE_CONVERSION), --- -2.39.3 - diff --git a/kvm-s390x-cpumodel-add-msa12-changes.patch b/kvm-s390x-cpumodel-add-msa12-changes.patch deleted file mode 100644 index 44a1bef..0000000 --- a/kvm-s390x-cpumodel-add-msa12-changes.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 2016aa4ba5c5aecae350ce6ea81462c9ab5956c3 Mon Sep 17 00:00:00 2001 -From: Hendrik Brueckner -Date: Fri, 6 Dec 2024 13:27:39 +0100 -Subject: [PATCH 04/18] s390x/cpumodel: add msa12 changes -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [4/16] c878296ee5c4f99f67f1c68172536b521be60e04 (thuth/qemu-kvm-cs9) - -MSA12 changes the KIMD/KLMD instruction format for SHA3/SHAKE. - -Signed-off-by: Hendrik Brueckner -Reviewed-by: Christian Borntraeger -Message-ID: <20241206122751.189721-4-brueckner@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 496fc02e0e532f8917fa96e45fa531231e821c31) ---- - target/s390x/cpu_features.c | 1 + - target/s390x/cpu_features_def.h.inc | 1 + - target/s390x/gen-features.c | 8 ++++++++ - 3 files changed, 10 insertions(+) - -diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c -index 36930feccd..0e0b37ab95 100644 ---- a/target/s390x/cpu_features.c -+++ b/target/s390x/cpu_features.c -@@ -256,6 +256,7 @@ static S390FeatGroupDef s390_feature_groups[] = { - FEAT_GROUP_INIT("msa10_pckmo", MSA_EXT_10_PCKMO, "Message-security-assist-extension 10 PCKMO subfunctions"), - FEAT_GROUP_INIT("msa11", MSA_EXT_11, "Message-security-assist-extension 11 facility"), - FEAT_GROUP_INIT("msa11_pckmo", MSA_EXT_11_PCKMO, "Message-security-assist-extension 11 PCKMO subfunctions"), -+ FEAT_GROUP_INIT("msa12", MSA_EXT_12, "Message-security-assist-extension 12 facility"), - FEAT_GROUP_INIT("mepochptff", MULTIPLE_EPOCH_PTFF, "PTFF enhancements introduced with Multiple-epoch facility"), - FEAT_GROUP_INIT("esort", ENH_SORT, "Enhanced-sort facility"), - FEAT_GROUP_INIT("deflate", DEFLATE_CONVERSION, "Deflate-conversion facility"), -diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc -index 15ea51fc54..2e5dc96984 100644 ---- a/target/s390x/cpu_features_def.h.inc -+++ b/target/s390x/cpu_features_def.h.inc -@@ -90,6 +90,7 @@ DEF_FEAT(EDAT_2, "edat2", STFL, 78, "Enhanced-DAT facility 2") - DEF_FEAT(DFP_PACKED_CONVERSION, "dfppc", STFL, 80, "Decimal-floating-point packed-conversion facility") - DEF_FEAT(PPA15, "ppa15", STFL, 81, "PPA15 is installed") - DEF_FEAT(BPB, "bpb", STFL, 82, "Branch prediction blocking") -+DEF_FEAT(MSA_EXT_12, "msa12-base", STFL, 86, "Message-security-assist-extension-12 facility (excluding subfunctions)") - DEF_FEAT(VECTOR, "vx", STFL, 129, "Vector facility") - DEF_FEAT(INSTRUCTION_EXEC_PROT, "iep", STFL, 130, "Instruction-execution-protection facility") - DEF_FEAT(SIDE_EFFECT_ACCESS_ESOP2, "sea_esop2", STFL, 131, "Side-effect-access facility and Enhanced-suppression-on-protection facility 2") -diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c -index d6305f945a..ab9ad51d5e 100644 ---- a/target/s390x/gen-features.c -+++ b/target/s390x/gen-features.c -@@ -270,6 +270,9 @@ - S390_FEAT_PCKMO_HMAC_512, \ - S390_FEAT_PCKMO_HMAC_1024 - -+#define S390_FEAT_GROUP_MSA_EXT_12 \ -+ S390_FEAT_MSA_EXT_12 -+ - #define S390_FEAT_GROUP_ENH_SORT \ - S390_FEAT_ESORT_BASE, \ - S390_FEAT_SORTL_SFLR, \ -@@ -339,6 +342,10 @@ static uint16_t group_MSA_EXT_11[] = { - S390_FEAT_GROUP_MSA_EXT_11, - }; - -+static uint16_t group_MSA_EXT_12[] = { -+ S390_FEAT_GROUP_MSA_EXT_12, -+}; -+ - static uint16_t group_MSA_EXT_9_PCKMO[] = { - S390_FEAT_GROUP_MSA_EXT_9_PCKMO, - }; -@@ -902,6 +909,7 @@ static FeatGroupDefSpec FeatGroupDef[] = { - FEAT_GROUP_INITIALIZER(MSA_EXT_10_PCKMO), - FEAT_GROUP_INITIALIZER(MSA_EXT_11), - FEAT_GROUP_INITIALIZER(MSA_EXT_11_PCKMO), -+ FEAT_GROUP_INITIALIZER(MSA_EXT_12), - FEAT_GROUP_INITIALIZER(MULTIPLE_EPOCH_PTFF), - FEAT_GROUP_INITIALIZER(ENH_SORT), - FEAT_GROUP_INITIALIZER(DEFLATE_CONVERSION), --- -2.39.3 - diff --git a/kvm-s390x-cpumodel-add-msa13-subfunctions.patch b/kvm-s390x-cpumodel-add-msa13-subfunctions.patch deleted file mode 100644 index 98d9932..0000000 --- a/kvm-s390x-cpumodel-add-msa13-subfunctions.patch +++ /dev/null @@ -1,200 +0,0 @@ -From 003efbebc77300d3004f4613255e04058165ff33 Mon Sep 17 00:00:00 2001 -From: Hendrik Brueckner -Date: Fri, 6 Dec 2024 13:27:40 +0100 -Subject: [PATCH 05/18] s390x/cpumodel: add msa13 subfunctions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [5/16] b3f42a4a831bc0582e3c14da6387d7db440c3c41 (thuth/qemu-kvm-cs9) - -MSA13 introduces query authentication information (QAI) subfunctions. - -Signed-off-by: Hendrik Brueckner -Reviewed-by: Janosch Frank -Message-ID: <20241206122751.189721-5-brueckner@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit ba4614fdacc2ea55060ddb48bdb2ebd21d0c3464) ---- - target/s390x/cpu_features.c | 2 ++ - target/s390x/cpu_features_def.h.inc | 12 ++++++++++++ - target/s390x/gen-features.c | 26 ++++++++++++++++++++++++++ - 3 files changed, 40 insertions(+) - -diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c -index 0e0b37ab95..9ba127e386 100644 ---- a/target/s390x/cpu_features.c -+++ b/target/s390x/cpu_features.c -@@ -257,6 +257,8 @@ static S390FeatGroupDef s390_feature_groups[] = { - FEAT_GROUP_INIT("msa11", MSA_EXT_11, "Message-security-assist-extension 11 facility"), - FEAT_GROUP_INIT("msa11_pckmo", MSA_EXT_11_PCKMO, "Message-security-assist-extension 11 PCKMO subfunctions"), - FEAT_GROUP_INIT("msa12", MSA_EXT_12, "Message-security-assist-extension 12 facility"), -+ FEAT_GROUP_INIT("msa13", MSA_EXT_13, "Message-security-assist-extension 13 facility"), -+ FEAT_GROUP_INIT("msa13_pckmo", MSA_EXT_13_PCKMO, "Message-security-assist-extension 13 PCKMO subfunctions"), - FEAT_GROUP_INIT("mepochptff", MULTIPLE_EPOCH_PTFF, "PTFF enhancements introduced with Multiple-epoch facility"), - FEAT_GROUP_INIT("esort", ENH_SORT, "Enhanced-sort facility"), - FEAT_GROUP_INIT("deflate", DEFLATE_CONVERSION, "Deflate-conversion facility"), -diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc -index 2e5dc96984..2132837ffe 100644 ---- a/target/s390x/cpu_features_def.h.inc -+++ b/target/s390x/cpu_features_def.h.inc -@@ -209,6 +209,7 @@ DEF_FEAT(KMAC_HMAC_ESHA_224, "kmac-hmac-esha-224", KMAC, 120, "KMAC HMAC-Encrypt - DEF_FEAT(KMAC_HMAC_ESHA_256, "kmac-hmac-esha-246", KMAC, 121, "KMAC HMAC-Encrypted-SHA-256") - DEF_FEAT(KMAC_HMAC_ESHA_384, "kmac-hmac-esha-384", KMAC, 122, "KMAC HMAC-Encrypted-SHA-384") - DEF_FEAT(KMAC_HMAC_ESHA_512, "kmac-hmac-esha-512", KMAC, 123, "KMAC HMAC-Encrypted-SHA-512") -+DEF_FEAT(KMAC_QAI, "kmac-qai", KMAC, 127, "KMAC Query-Authentication-Information") - - /* Features exposed via the KMC instruction. */ - DEF_FEAT(KMC_DEA, "kmc-dea", KMC, 1, "KMC DEA") -@@ -246,6 +247,7 @@ DEF_FEAT(KM_FULL_XTS_AES_128, "km-full-xts-aes-128", KM, 82, "KM Full-XTS-AES-12 - DEF_FEAT(KM_FULL_XTS_AES_256, "km-full-xts-aes-256", KM, 84, "KM Full-XTS-AES-256") - DEF_FEAT(KM_FULL_XTS_EAES_128, "km-full-xts-eaes-128", KM, 90, "KM Full-XTS-Encrypted-AES-128") - DEF_FEAT(KM_FULL_XTS_EAES_256, "km-full-xts-eaes-256", KM, 92, "KM Full-XTS-Encrypted-AES-256") -+DEF_FEAT(KM_QAI, "km-qai", KM, 127, "KM Query-Authentication-Information") - - /* Features exposed via the KIMD instruction. */ - DEF_FEAT(KIMD_SHA_1, "kimd-sha-1", KIMD, 1, "KIMD SHA-1") -@@ -258,6 +260,7 @@ DEF_FEAT(KIMD_SHA3_512, "kimd-sha3-512", KIMD, 35, "KIMD SHA3-512") - DEF_FEAT(KIMD_SHAKE_128, "kimd-shake-128", KIMD, 36, "KIMD SHAKE-128") - DEF_FEAT(KIMD_SHAKE_256, "kimd-shake-256", KIMD, 37, "KIMD SHAKE-256") - DEF_FEAT(KIMD_GHASH, "kimd-ghash", KIMD, 65, "KIMD GHASH") -+DEF_FEAT(KIMD_QAI, "kimd-qai", KIMD, 127, "KIMD Query-Authentication-Information") - - /* Features exposed via the KLMD instruction. */ - DEF_FEAT(KLMD_SHA_1, "klmd-sha-1", KLMD, 1, "KLMD SHA-1") -@@ -269,6 +272,7 @@ DEF_FEAT(KLMD_SHA3_384, "klmd-sha3-384", KLMD, 34, "KLMD SHA3-384") - DEF_FEAT(KLMD_SHA3_512, "klmd-sha3-512", KLMD, 35, "KLMD SHA3-512") - DEF_FEAT(KLMD_SHAKE_128, "klmd-shake-128", KLMD, 36, "KLMD SHAKE-128") - DEF_FEAT(KLMD_SHAKE_256, "klmd-shake-256", KLMD, 37, "KLMD SHAKE-256") -+DEF_FEAT(KLMD_QAI, "klmd-qai", KLMD, 127, "KLMD Query-Authentication-Information") - - /* Features exposed via the PCKMO instruction. */ - DEF_FEAT(PCKMO_EDEA, "pckmo-edea", PCKMO, 1, "PCKMO Encrypted-DEA-Key") -@@ -286,6 +290,7 @@ DEF_FEAT(PCKMO_ECC_ED25519, "pckmo-ecc-ed25519", PCKMO, 40 , "PCKMO Encrypt-ECC- - DEF_FEAT(PCKMO_ECC_ED448, "pckmo-ecc-ed448", PCKMO, 41 , "PCKMO Encrypt-ECC-Ed448-Key") - DEF_FEAT(PCKMO_HMAC_512, "pckmo-hmac-512", PCKMO, 118, "PCKMO Encrypt-HMAC-512-Key") - DEF_FEAT(PCKMO_HMAC_1024, "pckmo-hmac-1024", PCKMO, 122, "PCKMO Encrypt-HMAC-1024-Key") -+DEF_FEAT(PCKMO_QAI, "pckmo-qai", PCKMO, 127, "PCKMO Query-Authentication-Information") - - /* Features exposed via the KMCTR instruction. */ - DEF_FEAT(KMCTR_DEA, "kmctr-dea", KMCTR, 1, "KMCTR DEA") -@@ -300,6 +305,7 @@ DEF_FEAT(KMCTR_AES_256, "kmctr-aes-256", KMCTR, 20, "KMCTR AES-256") - DEF_FEAT(KMCTR_EAES_128, "kmctr-eaes-128", KMCTR, 26, "KMCTR Encrypted-AES-128") - DEF_FEAT(KMCTR_EAES_192, "kmctr-eaes-192", KMCTR, 27, "KMCTR Encrypted-AES-192") - DEF_FEAT(KMCTR_EAES_256, "kmctr-eaes-256", KMCTR, 28, "KMCTR Encrypted-AES-256") -+DEF_FEAT(KMCTR_QAI, "kmctr-qai", KMCTR, 127, "KMCTR Query-Authentication-Information") - - /* Features exposed via the KMF instruction. */ - DEF_FEAT(KMF_DEA, "kmf-dea", KMF, 1, "KMF DEA") -@@ -314,6 +320,7 @@ DEF_FEAT(KMF_AES_256, "kmf-aes-256", KMF, 20, "KMF AES-256") - DEF_FEAT(KMF_EAES_128, "kmf-eaes-128", KMF, 26, "KMF Encrypted-AES-128") - DEF_FEAT(KMF_EAES_192, "kmf-eaes-192", KMF, 27, "KMF Encrypted-AES-192") - DEF_FEAT(KMF_EAES_256, "kmf-eaes-256", KMF, 28, "KMF Encrypted-AES-256") -+DEF_FEAT(KMF_QAI, "kmf-qai", KMF, 127, "KMF Query-Authentication-Information") - - /* Features exposed via the KMO instruction. */ - DEF_FEAT(KMO_DEA, "kmo-dea", KMO, 1, "KMO DEA") -@@ -328,6 +335,7 @@ DEF_FEAT(KMO_AES_256, "kmo-aes-256", KMO, 20, "KMO AES-256") - DEF_FEAT(KMO_EAES_128, "kmo-eaes-128", KMO, 26, "KMO Encrypted-AES-128") - DEF_FEAT(KMO_EAES_192, "kmo-eaes-192", KMO, 27, "KMO Encrypted-AES-192") - DEF_FEAT(KMO_EAES_256, "kmo-eaes-256", KMO, 28, "KMO Encrypted-AES-256") -+DEF_FEAT(KMO_QAI, "kmo-qai", KMO, 127, "KMO Query-Authentication-Information") - - /* Features exposed via the PCC instruction. */ - DEF_FEAT(PCC_CMAC_DEA, "pcc-cmac-dea", PCC, 1, "PCC Compute-Last-Block-CMAC-Using-DEA") -@@ -353,11 +361,13 @@ DEF_FEAT(PCC_SCALAR_MULT_ED25519, "pcc-scalar-mult-ed25519", PCC, 72, "PCC Scala - DEF_FEAT(PCC_SCALAR_MULT_ED448, "pcc-scalar-mult-ed448", PCC, 73, "PCC Scalar-Multiply-Ed448") - DEF_FEAT(PCC_SCALAR_MULT_X25519, "pcc-scalar-mult-x25519", PCC, 80, "PCC Scalar-Multiply-X25519") - DEF_FEAT(PCC_SCALAR_MULT_X448, "pcc-scalar-mult-x448", PCC, 81, "PCC Scalar-Multiply-X448") -+DEF_FEAT(PCC_QAI, "pcc-qai", PCC, 127, "PCC Query-Authentication-Information") - - /* Features exposed via the PPNO/PRNO instruction. */ - DEF_FEAT(PPNO_SHA_512_DRNG, "ppno-sha-512-drng", PPNO, 3, "PPNO SHA-512-DRNG") - DEF_FEAT(PRNO_TRNG_QRTCR, "prno-trng-qrtcr", PPNO, 112, "PRNO TRNG-Query-Raw-to-Conditioned-Ratio") - DEF_FEAT(PRNO_TRNG, "prno-trng", PPNO, 114, "PRNO TRNG") -+DEF_FEAT(PRNO_QAI, "prno-qai", PPNO, 127, "PRNO Query-Authentication-Information") - - /* Features exposed via the KMA instruction. */ - DEF_FEAT(KMA_GCM_AES_128, "kma-gcm-aes-128", KMA, 18, "KMA GCM-AES-128") -@@ -366,6 +376,7 @@ DEF_FEAT(KMA_GCM_AES_256, "kma-gcm-aes-256", KMA, 20, "KMA GCM-AES-256") - DEF_FEAT(KMA_GCM_EAES_128, "kma-gcm-eaes-128", KMA, 26, "KMA GCM-Encrypted-AES-128") - DEF_FEAT(KMA_GCM_EAES_192, "kma-gcm-eaes-192", KMA, 27, "KMA GCM-Encrypted-AES-192") - DEF_FEAT(KMA_GCM_EAES_256, "kma-gcm-eaes-256", KMA, 28, "KMA GCM-Encrypted-AES-256") -+DEF_FEAT(KMA_QAI, "kma-qai", KMA, 127, "KMA Query-Authentication-Information") - - /* Features exposed via the KDSA instruction. */ - DEF_FEAT(KDSA_ECDSA_VERIFY_P256, "kdsa-ecdsa-verify-p256", KDSA, 1, "KDSA ECDSA-Verify-P256") -@@ -383,6 +394,7 @@ DEF_FEAT(KDSA_EDDSA_SIGN_ED25519, "kdsa-eddsa-sign-ed25519", KDSA, 40, "KDSA EdD - DEF_FEAT(KDSA_EDDSA_SIGN_ED448, "kdsa-eddsa-sign-ed448", KDSA, 44, "KDSA EdDSA-Sign-Ed448") - DEF_FEAT(KDSA_EEDDSA_SIGN_ED25519, "kdsa-eeddsa-sign-ed25519", KDSA, 48, "KDSA Encrypted-EdDSA-Sign-Ed25519") - DEF_FEAT(KDSA_EEDDSA_SIGN_ED448, "kdsa-eeddsa-sign-ed448", KDSA, 52, "KDSA Encrypted-EdDSA-Sign-Ed448") -+DEF_FEAT(KDSA_QAI, "kdsa-qai", KDSA, 127, "KDSA Query-Authentication-Information") - - /* Features exposed via the SORTL instruction. */ - DEF_FEAT(SORTL_SFLR, "sortl-sflr", SORTL, 1, "SORTL SFLR") -diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c -index ab9ad51d5e..3326e7df43 100644 ---- a/target/s390x/gen-features.c -+++ b/target/s390x/gen-features.c -@@ -273,6 +273,22 @@ - #define S390_FEAT_GROUP_MSA_EXT_12 \ - S390_FEAT_MSA_EXT_12 - -+#define S390_FEAT_GROUP_MSA_EXT_13 \ -+ S390_FEAT_KDSA_QAI, \ -+ S390_FEAT_KIMD_QAI, \ -+ S390_FEAT_KLMD_QAI, \ -+ S390_FEAT_KMAC_QAI, \ -+ S390_FEAT_KMA_QAI, \ -+ S390_FEAT_KMCTR_QAI, \ -+ S390_FEAT_KMF_QAI, \ -+ S390_FEAT_KMO_QAI, \ -+ S390_FEAT_KM_QAI, \ -+ S390_FEAT_PCC_QAI, \ -+ S390_FEAT_PRNO_QAI -+ -+#define S390_FEAT_GROUP_MSA_EXT_13_PCKMO \ -+ S390_FEAT_PCKMO_QAI -+ - #define S390_FEAT_GROUP_ENH_SORT \ - S390_FEAT_ESORT_BASE, \ - S390_FEAT_SORTL_SFLR, \ -@@ -346,6 +362,10 @@ static uint16_t group_MSA_EXT_12[] = { - S390_FEAT_GROUP_MSA_EXT_12, - }; - -+static uint16_t group_MSA_EXT_13[] = { -+ S390_FEAT_GROUP_MSA_EXT_13, -+}; -+ - static uint16_t group_MSA_EXT_9_PCKMO[] = { - S390_FEAT_GROUP_MSA_EXT_9_PCKMO, - }; -@@ -358,6 +378,10 @@ static uint16_t group_MSA_EXT_11_PCKMO[] = { - S390_FEAT_GROUP_MSA_EXT_11_PCKMO, - }; - -+static uint16_t group_MSA_EXT_13_PCKMO[] = { -+ S390_FEAT_GROUP_MSA_EXT_13_PCKMO, -+}; -+ - static uint16_t group_ENH_SORT[] = { - S390_FEAT_GROUP_ENH_SORT, - }; -@@ -910,6 +934,8 @@ static FeatGroupDefSpec FeatGroupDef[] = { - FEAT_GROUP_INITIALIZER(MSA_EXT_11), - FEAT_GROUP_INITIALIZER(MSA_EXT_11_PCKMO), - FEAT_GROUP_INITIALIZER(MSA_EXT_12), -+ FEAT_GROUP_INITIALIZER(MSA_EXT_13), -+ FEAT_GROUP_INITIALIZER(MSA_EXT_13_PCKMO), - FEAT_GROUP_INITIALIZER(MULTIPLE_EPOCH_PTFF), - FEAT_GROUP_INITIALIZER(ENH_SORT), - FEAT_GROUP_INITIALIZER(DEFLATE_CONVERSION), --- -2.39.3 - diff --git a/kvm-s390x-cpumodel-correct-PLO-feature-wording.patch b/kvm-s390x-cpumodel-correct-PLO-feature-wording.patch deleted file mode 100644 index da0855a..0000000 --- a/kvm-s390x-cpumodel-correct-PLO-feature-wording.patch +++ /dev/null @@ -1,69 +0,0 @@ -From bec777b1ca5107cea4f4104c58cdd0c5d9613e33 Mon Sep 17 00:00:00 2001 -From: Hendrik Brueckner -Date: Fri, 6 Dec 2024 13:27:49 +0100 -Subject: [PATCH 14/18] s390x/cpumodel: correct PLO feature wording -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [14/16] 346fd03bd68222125b0b04113a432ae739af84f1 (thuth/qemu-kvm-cs9) - -The PLO functions 0, 4, 8, 12, 16, and 20 use 32-bit registers -values. The plo-*gr variants use 64-bit instead and, thus, correct -the wording. - -Signed-off-by: Hendrik Brueckner -Reviewed-by: Janosch Frank -Message-ID: <20241206122751.189721-14-brueckner@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 5a0a136df71b858d01f346af4a30ae1da23e8b3c) ---- - target/s390x/cpu_features_def.h.inc | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc -index 09a80844a7..fe7e1bd19c 100644 ---- a/target/s390x/cpu_features_def.h.inc -+++ b/target/s390x/cpu_features_def.h.inc -@@ -158,27 +158,27 @@ DEF_FEAT(AP, "ap", MISC, 0, "AP instructions installed") - /* Features exposed via the PLO instruction. */ - DEF_FEAT(PLO_CL, "plo-cl", PLO, 0, "PLO Compare and load (32 bit in general registers)") - DEF_FEAT(PLO_CLG, "plo-clg", PLO, 1, "PLO Compare and load (64 bit in parameter list)") --DEF_FEAT(PLO_CLGR, "plo-clgr", PLO, 2, "PLO Compare and load (32 bit in general registers)") -+DEF_FEAT(PLO_CLGR, "plo-clgr", PLO, 2, "PLO Compare and load (64 bit in general registers)") - DEF_FEAT(PLO_CLX, "plo-clx", PLO, 3, "PLO Compare and load (128 bit in parameter list)") - DEF_FEAT(PLO_CS, "plo-cs", PLO, 4, "PLO Compare and swap (32 bit in general registers)") - DEF_FEAT(PLO_CSG, "plo-csg", PLO, 5, "PLO Compare and swap (64 bit in parameter list)") --DEF_FEAT(PLO_CSGR, "plo-csgr", PLO, 6, "PLO Compare and swap (32 bit in general registers)") -+DEF_FEAT(PLO_CSGR, "plo-csgr", PLO, 6, "PLO Compare and swap (64 bit in general registers)") - DEF_FEAT(PLO_CSX, "plo-csx", PLO, 7, "PLO Compare and swap (128 bit in parameter list)") - DEF_FEAT(PLO_DCS, "plo-dcs", PLO, 8, "PLO Double compare and swap (32 bit in general registers)") - DEF_FEAT(PLO_DCSG, "plo-dcsg", PLO, 9, "PLO Double compare and swap (64 bit in parameter list)") --DEF_FEAT(PLO_DCSGR, "plo-dcsgr", PLO, 10, "PLO Double compare and swap (32 bit in general registers)") -+DEF_FEAT(PLO_DCSGR, "plo-dcsgr", PLO, 10, "PLO Double compare and swap (64 bit in general registers)") - DEF_FEAT(PLO_DCSX, "plo-dcsx", PLO, 11, "PLO Double compare and swap (128 bit in parameter list)") - DEF_FEAT(PLO_CSST, "plo-csst", PLO, 12, "PLO Compare and swap and store (32 bit in general registers)") - DEF_FEAT(PLO_CSSTG, "plo-csstg", PLO, 13, "PLO Compare and swap and store (64 bit in parameter list)") --DEF_FEAT(PLO_CSSTGR, "plo-csstgr", PLO, 14, "PLO Compare and swap and store (32 bit in general registers)") -+DEF_FEAT(PLO_CSSTGR, "plo-csstgr", PLO, 14, "PLO Compare and swap and store (64 bit in general registers)") - DEF_FEAT(PLO_CSSTX, "plo-csstx", PLO, 15, "PLO Compare and swap and store (128 bit in parameter list)") - DEF_FEAT(PLO_CSDST, "plo-csdst", PLO, 16, "PLO Compare and swap and double store (32 bit in general registers)") - DEF_FEAT(PLO_CSDSTG, "plo-csdstg", PLO, 17, "PLO Compare and swap and double store (64 bit in parameter list)") --DEF_FEAT(PLO_CSDSTGR, "plo-csdstgr", PLO, 18, "PLO Compare and swap and double store (32 bit in general registers)") -+DEF_FEAT(PLO_CSDSTGR, "plo-csdstgr", PLO, 18, "PLO Compare and swap and double store (64 bit in general registers)") - DEF_FEAT(PLO_CSDSTX, "plo-csdstx", PLO, 19, "PLO Compare and swap and double store (128 bit in parameter list)") - DEF_FEAT(PLO_CSTST, "plo-cstst", PLO, 20, "PLO Compare and swap and triple store (32 bit in general registers)") - DEF_FEAT(PLO_CSTSTG, "plo-cststg", PLO, 21, "PLO Compare and swap and triple store (64 bit in parameter list)") --DEF_FEAT(PLO_CSTSTGR, "plo-cststgr", PLO, 22, "PLO Compare and swap and triple store (32 bit in general registers)") -+DEF_FEAT(PLO_CSTSTGR, "plo-cststgr", PLO, 22, "PLO Compare and swap and triple store (64 bit in general registers)") - DEF_FEAT(PLO_CSTSTX, "plo-cststx", PLO, 23, "PLO Compare and swap and triple store (128 bit in parameter list)") - - /* Features exposed via the PTFF instruction. */ --- -2.39.3 - diff --git a/kvm-s390x-cpumodel-gen17-model.patch b/kvm-s390x-cpumodel-gen17-model.patch deleted file mode 100644 index 7fc91ae..0000000 --- a/kvm-s390x-cpumodel-gen17-model.patch +++ /dev/null @@ -1,107 +0,0 @@ -From bf9dd3db72e0e8cde010f649fbe484fdd929ac96 Mon Sep 17 00:00:00 2001 -From: Hendrik Brueckner -Date: Fri, 6 Dec 2024 13:27:51 +0100 -Subject: [PATCH 16/18] s390x/cpumodel: gen17 model -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 305: CPU model for new IBM Z gen17 hardware -RH-Jira: RHEL-32665 -RH-Acked-by: Cornelia Huck -RH-Acked-by: CĂ©dric Le Goater -RH-Commit: [16/16] 97b19706656f5510d1aab760f01e501c1c332bc4 (thuth/qemu-kvm-cs9) - -This commit introduces the definition of the gen17a/gen17b CPU model. - -Signed-off-by: Hendrik Brueckner -Message-ID: <20241206122751.189721-16-brueckner@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit 21b8db229901a51f16aebe342c0508f588ea5006) ---- - target/s390x/cpu_models.c | 2 ++ - target/s390x/gen-features.c | 33 +++++++++++++++++++++++++++++++++ - 2 files changed, 35 insertions(+) - -diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c -index 3fb5b0980e..c326a71237 100644 ---- a/target/s390x/cpu_models.c -+++ b/target/s390x/cpu_models.c -@@ -97,6 +97,8 @@ static S390CPUDef s390_cpu_defs[] = { - CPUDEF_INIT(0x8562, 15, 1, 47, 0x08000000U, "gen15b", "IBM z15 T02 GA1"), - CPUDEF_INIT(0x3931, 16, 1, 47, 0x08000000U, "gen16a", "IBM 3931 GA1"), - CPUDEF_INIT(0x3932, 16, 1, 47, 0x08000000U, "gen16b", "IBM 3932 GA1"), -+ CPUDEF_INIT(0x9175, 17, 1, 47, 0x08000000U, "gen17a", "IBM 9175 GA1"), -+ CPUDEF_INIT(0x9176, 17, 1, 47, 0x08000000U, "gen17b", "IBM 9176 GA1"), - }; - - #define QEMU_MAX_CPU_TYPE 0x8561 -diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c -index 680d45d303..41840677ce 100644 ---- a/target/s390x/gen-features.c -+++ b/target/s390x/gen-features.c -@@ -561,6 +561,13 @@ static uint16_t base_GEN15_GA1[] = { - - #define base_GEN16_GA1 EmptyFeat - -+static uint16_t base_GEN17_GA1[] = { -+ S390_FEAT_MISC_INSTRUCTION_EXT4, -+ S390_FEAT_SIF, -+ S390_FEAT_GROUP_MSA_EXT_12, -+ S390_FEAT_GROUP_PLO_EXT, -+}; -+ - /* Full features (in order of release) - * Automatically includes corresponding base features. - * Full features are all features this hardware supports even if kvm/QEMU do not -@@ -715,6 +722,20 @@ static uint16_t full_GEN16_GA1[] = { - S390_FEAT_UV_FEAT_AP_INTR, - }; - -+static uint16_t full_GEN17_GA1[] = { -+ S390_FEAT_VECTOR_ENH3, -+ S390_FEAT_VECTOR_PACKED_DECIMAL_ENH3, -+ S390_FEAT_INEFF_NC_TX, -+ S390_FEAT_GROUP_GEN17_PTFF, -+ S390_FEAT_GROUP_MSA_EXT_10, -+ S390_FEAT_GROUP_MSA_EXT_10_PCKMO, -+ S390_FEAT_GROUP_MSA_EXT_11, -+ S390_FEAT_GROUP_MSA_EXT_11_PCKMO, -+ S390_FEAT_GROUP_MSA_EXT_13, -+ S390_FEAT_GROUP_MSA_EXT_13_PCKMO, -+ S390_FEAT_GROUP_CONCURRENT_FUNCTIONS, -+}; -+ - - /* Default features (in order of release) - * Automatically includes corresponding base features. -@@ -810,6 +831,17 @@ static uint16_t default_GEN16_GA1[] = { - S390_FEAT_PAIE, - }; - -+static uint16_t default_GEN17_GA1[] = { -+ S390_FEAT_VECTOR_ENH3, -+ S390_FEAT_VECTOR_PACKED_DECIMAL_ENH3, -+ S390_FEAT_GROUP_MSA_EXT_10, -+ S390_FEAT_GROUP_MSA_EXT_10_PCKMO, -+ S390_FEAT_GROUP_MSA_EXT_11, -+ S390_FEAT_GROUP_MSA_EXT_11_PCKMO, -+ S390_FEAT_GROUP_MSA_EXT_13, -+ S390_FEAT_GROUP_MSA_EXT_13_PCKMO, -+}; -+ - /* QEMU (CPU model) features */ - - static uint16_t qemu_V2_11[] = { -@@ -958,6 +990,7 @@ static CpuFeatDefSpec CpuFeatDef[] = { - CPU_FEAT_INITIALIZER(GEN14_GA2), - CPU_FEAT_INITIALIZER(GEN15_GA1), - CPU_FEAT_INITIALIZER(GEN16_GA1), -+ CPU_FEAT_INITIALIZER(GEN17_GA1), - }; - - #define FEAT_GROUP_INITIALIZER(_name) \ --- -2.39.3 - diff --git a/kvm-scsi-disk-Add-native-FUA-write-support.patch b/kvm-scsi-disk-Add-native-FUA-write-support.patch new file mode 100644 index 0000000..895c735 --- /dev/null +++ b/kvm-scsi-disk-Add-native-FUA-write-support.patch @@ -0,0 +1,169 @@ +From 776febe2ec5735280ea562309cddf54b1b93a673 Mon Sep 17 00:00:00 2001 +From: Alberto Faria +Date: Fri, 2 May 2025 13:11:14 +0100 +Subject: [PATCH 1/5] scsi-disk: Add native FUA write support + +RH-Author: Alberto Faria +RH-MergeRequest: 374: scsi-disk: Add FUA write support +RH-Jira: RHEL-71962 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [1/1] c51c618a2d8f027422b603b9ced89d000cbf5fa1 + +Simply propagate the FUA flag on write requests to the driver. The block +layer will emulate it if necessary. + +Signed-off-by: Alberto Faria +Message-ID: <20250502121115.3613717-2-afaria@redhat.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit e460991883d7209d52d0fdb534d9cd8cce0f9cce) +Signed-off-by: Alberto Faria +--- + hw/scsi/scsi-disk.c | 53 +++++++++++++-------------------------------- + 1 file changed, 15 insertions(+), 38 deletions(-) + +diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c +index e59632e9b1..40cf379017 100644 +--- a/hw/scsi/scsi-disk.c ++++ b/hw/scsi/scsi-disk.c +@@ -74,7 +74,7 @@ struct SCSIDiskClass { + */ + DMAIOFunc *dma_readv; + DMAIOFunc *dma_writev; +- bool (*need_fua_emulation)(SCSICommand *cmd); ++ bool (*need_fua)(SCSICommand *cmd); + void (*update_sense)(SCSIRequest *r); + }; + +@@ -85,7 +85,7 @@ typedef struct SCSIDiskReq { + uint32_t sector_count; + uint32_t buflen; + bool started; +- bool need_fua_emulation; ++ bool need_fua; + struct iovec iov; + QEMUIOVector qiov; + BlockAcctCookie acct; +@@ -389,24 +389,6 @@ static bool scsi_is_cmd_fua(SCSICommand *cmd) + } + } + +-static void scsi_write_do_fua(SCSIDiskReq *r) +-{ +- SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); +- +- assert(r->req.aiocb == NULL); +- assert(!r->req.io_canceled); +- +- if (r->need_fua_emulation) { +- block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0, +- BLOCK_ACCT_FLUSH); +- r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_aio_complete, r); +- return; +- } +- +- scsi_req_complete(&r->req, GOOD); +- scsi_req_unref(&r->req); +-} +- + static void scsi_dma_complete_noio(SCSIDiskReq *r, int ret) + { + assert(r->req.aiocb == NULL); +@@ -416,12 +398,7 @@ static void scsi_dma_complete_noio(SCSIDiskReq *r, int ret) + + r->sector += r->sector_count; + r->sector_count = 0; +- if (r->req.cmd.mode == SCSI_XFER_TO_DEV) { +- scsi_write_do_fua(r); +- return; +- } else { +- scsi_req_complete(&r->req, GOOD); +- } ++ scsi_req_complete(&r->req, GOOD); + + done: + scsi_req_unref(&r->req); +@@ -564,7 +541,7 @@ static void scsi_read_data(SCSIRequest *req) + + first = !r->started; + r->started = true; +- if (first && r->need_fua_emulation) { ++ if (first && r->need_fua) { + block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0, + BLOCK_ACCT_FLUSH); + r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_do_read_cb, r); +@@ -589,8 +566,7 @@ static void scsi_write_complete_noio(SCSIDiskReq *r, int ret) + r->sector += n; + r->sector_count -= n; + if (r->sector_count == 0) { +- scsi_write_do_fua(r); +- return; ++ scsi_req_complete(&r->req, GOOD); + } else { + scsi_init_iovec(r, SCSI_DMA_BUF_SIZE); + trace_scsi_disk_write_complete_noio(r->req.tag, r->qiov.size); +@@ -623,6 +599,7 @@ static void scsi_write_data(SCSIRequest *req) + SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); + SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s)); ++ BlockCompletionFunc *cb; + + /* No data transfer may already be in progress */ + assert(r->req.aiocb == NULL); +@@ -648,11 +625,10 @@ static void scsi_write_data(SCSIRequest *req) + + if (r->req.cmd.buf[0] == VERIFY_10 || r->req.cmd.buf[0] == VERIFY_12 || + r->req.cmd.buf[0] == VERIFY_16) { +- if (r->req.sg) { +- scsi_dma_complete_noio(r, 0); +- } else { +- scsi_write_complete_noio(r, 0); +- } ++ block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0, ++ BLOCK_ACCT_FLUSH); ++ cb = r->req.sg ? scsi_dma_complete : scsi_write_complete; ++ r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, cb, r); + return; + } + +@@ -2391,7 +2367,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf) + scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE)); + return 0; + } +- r->need_fua_emulation = sdc->need_fua_emulation(&r->req.cmd); ++ r->need_fua = sdc->need_fua(&r->req.cmd); + if (r->sector_count == 0) { + scsi_req_complete(&r->req, GOOD); + } +@@ -3137,7 +3113,8 @@ BlockAIOCB *scsi_dma_writev(int64_t offset, QEMUIOVector *iov, + { + SCSIDiskReq *r = opaque; + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); +- return blk_aio_pwritev(s->qdev.conf.blk, offset, iov, 0, cb, cb_opaque); ++ int flags = r->need_fua ? BDRV_REQ_FUA : 0; ++ return blk_aio_pwritev(s->qdev.conf.blk, offset, iov, flags, cb, cb_opaque); + } + + static char *scsi_property_get_loadparm(Object *obj, Error **errp) +@@ -3186,7 +3163,7 @@ static void scsi_disk_base_class_initfn(ObjectClass *klass, void *data) + device_class_set_legacy_reset(dc, scsi_disk_reset); + sdc->dma_readv = scsi_dma_readv; + sdc->dma_writev = scsi_dma_writev; +- sdc->need_fua_emulation = scsi_is_cmd_fua; ++ sdc->need_fua = scsi_is_cmd_fua; + } + + static const TypeInfo scsi_disk_base_info = { +@@ -3338,7 +3315,7 @@ static void scsi_block_class_initfn(ObjectClass *klass, void *data) + sdc->dma_readv = scsi_block_dma_readv; + sdc->dma_writev = scsi_block_dma_writev; + sdc->update_sense = scsi_block_update_sense; +- sdc->need_fua_emulation = scsi_block_no_fua; ++ sdc->need_fua = scsi_block_no_fua; + dc->desc = "SCSI block device passthrough"; + device_class_set_props(dc, scsi_block_properties); + dc->vmsd = &vmstate_scsi_disk_state; +-- +2.39.3 + diff --git a/kvm-scsi-fix-allocation-for-s390x-loadparm.patch b/kvm-scsi-fix-allocation-for-s390x-loadparm.patch deleted file mode 100644 index 8c58632..0000000 --- a/kvm-scsi-fix-allocation-for-s390x-loadparm.patch +++ /dev/null @@ -1,44 +0,0 @@ -From f03d8c917543a5b92e26fcd8bd7c1cf006ea37df Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Tue, 19 Nov 2024 22:31:22 +0100 -Subject: [PATCH 6/9] scsi: fix allocation for s390x loadparm - -RH-Author: Thomas Huth -RH-MergeRequest: 297: [c10s] Fixes for the new s390x "boot order" feature -RH-Jira: RHEL-68444 -RH-Acked-by: Miroslav Rezanina -RH-Commit: [5/8] b5a906d74fb4ad5a89e1880f07447bd3a5b3f2e9 (thuth/qemu-kvm-cs9) - -Coverity reports a possible buffer overrun due to a non-NUL-terminated -string in scsi_property_set_loadparm(). While things are not so easy, -because qdev_prop_sanitize_s390x_loadparm is designed to operate on a -buffer that is not NUL-terminated, in this case the string *does* have -to be NUL-terminated because it is read by scsi_property_get_loadparm -and s390_build_iplb. - -Reviewed-by: jrossi@linux.ibm.com -Cc: thuth@redhat.com -Fixes: 429442e52d9 ("hw: Add "loadparm" property to scsi disk devices for booting on s390x", 2024-11-18) -Signed-off-by: Paolo Bonzini -(cherry picked from commit b73d7eff1eedb2399cd594bc872d5db13506d951) -Signed-off-by: Thomas Huth ---- - hw/scsi/scsi-disk.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c -index 7566a5f531..de0c295173 100644 ---- a/hw/scsi/scsi-disk.c -+++ b/hw/scsi/scsi-disk.c -@@ -3152,7 +3152,7 @@ static void scsi_property_set_loadparm(Object *obj, const char *value, - return; - } - -- lp_str = g_malloc0(strlen(value)); -+ lp_str = g_malloc0(strlen(value) + 1); - if (!qdev_prop_sanitize_s390x_loadparm(lp_str, value, errp)) { - g_free(lp_str); - return; --- -2.39.3 - diff --git a/kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch b/kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch deleted file mode 100644 index 81565b3..0000000 --- a/kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch +++ /dev/null @@ -1,56 +0,0 @@ -From a246db2fbd892b572fced12da843628f1aab8cd2 Mon Sep 17 00:00:00 2001 -From: Tao Su -Date: Thu, 31 Oct 2024 16:52:32 +0800 -Subject: [PATCH 36/38] target/i386: Add AVX512 state when AVX10 is supported - -RH-Author: Paolo Bonzini -RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets -RH-Jira: RHEL-30315 RHEL-45110 -RH-Acked-by: Vitaly Kuznetsov -RH-Acked-by: Miroslav Rezanina -RH-Commit: [7/9] 6f791fae9a3255140795b709435b25159226becf (bonzini/rhel-qemu-kvm) - -AVX10 state enumeration in CPUID leaf D and enabling in XCR0 register -are identical to AVX512 state regardless of the supported vector lengths. - -Given that some E-cores will support AVX10 but not support AVX512, add -AVX512 state components to guest when AVX10 is enabled. - -Based on a patch by Tao Su - -Signed-off-by: Paolo Bonzini -Reviewed-by: Zhao Liu -Tested-by: Xuelian Guo -Signed-off-by: Tao Su -Link: https://lore.kernel.org/r/20241031085233.425388-8-tao1.su@linux.intel.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit 0d7475be3b402c25d74c5a4573cbeb733c8f3559) -Signed-off-by: Paolo Bonzini ---- - target/i386/cpu.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index a740429fdd..ddec461dd4 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -7140,7 +7140,15 @@ static bool cpuid_has_xsave_feature(CPUX86State *env, const ExtSaveArea *esa) - return false; - } - -- return (env->features[esa->feature] & esa->bits); -+ if (env->features[esa->feature] & esa->bits) { -+ return true; -+ } -+ if (esa->feature == FEAT_7_0_EBX && esa->bits == CPUID_7_0_EBX_AVX512F -+ && (env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_AVX10)) { -+ return true; -+ } -+ -+ return false; - } - - static void x86_cpu_reset_hold(Object *obj, ResetType type) --- -2.39.3 - diff --git a/kvm-target-i386-Add-couple-of-feature-bits-in-CPUID_Fn80.patch b/kvm-target-i386-Add-couple-of-feature-bits-in-CPUID_Fn80.patch new file mode 100644 index 0000000..9199986 --- /dev/null +++ b/kvm-target-i386-Add-couple-of-feature-bits-in-CPUID_Fn80.patch @@ -0,0 +1,81 @@ +From d2fcec417c3ce57ef25f8eea957a5fef9c2866bf Mon Sep 17 00:00:00 2001 +From: Babu Moger +Date: Thu, 8 May 2025 14:58:02 -0500 +Subject: [PATCH 06/43] target/i386: Add couple of feature bits in + CPUID_Fn80000021_EAX + +RH-Author: John Allen +RH-MergeRequest: 377: Update EPYC Models and Feature Bits +RH-Jira: RHEL-52650 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [4/6] 568d79477d85be653fa580d329495193c24e1500 (johnalle/qemu-kvm-fork) + +Add CPUID bit indicates that a WRMSR to MSR_FS_BASE, MSR_GS_BASE, or +MSR_KERNEL_GS_BASE is non-serializing amd PREFETCHI that the indicates +support for IC prefetch. + +CPUID_Fn80000021_EAX +Bit Feature description +20 Indicates support for IC prefetch. +1 FsGsKernelGsBaseNonSerializing. + WRMSR to FS_BASE, GS_BASE and KernelGSbase are non-serializing. + +Link: https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/programmer-references/57238.zip +Signed-off-by: Babu Moger +Reviewed-by: Maksim Davydov +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/a5f6283a59579b09ac345b3f21ecb3b3b2d92451.1746734284.git.babu.moger@amd.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit dfd5b456108a75588ab094358ba5754787146d3d) + +JIRA: https://issues.redhat.com/browse/RHEL-52650 + +Signed-off-by: John Allen +--- + target/i386/cpu.c | 4 ++-- + target/i386/cpu.h | 4 ++++ + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index b3052c6c2c..dd16f885cf 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -1237,12 +1237,12 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + [FEAT_8000_0021_EAX] = { + .type = CPUID_FEATURE_WORD, + .feat_names = { +- "no-nested-data-bp", NULL, "lfence-always-serializing", NULL, ++ "no-nested-data-bp", "fs-gs-base-ns", "lfence-always-serializing", NULL, + NULL, NULL, "null-sel-clr-base", NULL, + "auto-ibrs", NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +- NULL, NULL, NULL, NULL, ++ "prefetchi", NULL, NULL, NULL, + "eraps", NULL, NULL, "sbpb", + "ibpb-brtype", "srso-no", "srso-user-kernel-no", NULL, + }, +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 76f24446a5..d7dcd59b2d 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -1074,12 +1074,16 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); + + /* Processor ignores nested data breakpoints */ + #define CPUID_8000_0021_EAX_NO_NESTED_DATA_BP (1U << 0) ++/* WRMSR to FS_BASE, GS_BASE, or KERNEL_GS_BASE is non-serializing */ ++#define CPUID_8000_0021_EAX_FS_GS_BASE_NS (1U << 1) + /* LFENCE is always serializing */ + #define CPUID_8000_0021_EAX_LFENCE_ALWAYS_SERIALIZING (1U << 2) + /* Null Selector Clears Base */ + #define CPUID_8000_0021_EAX_NULL_SEL_CLR_BASE (1U << 6) + /* Automatic IBRS */ + #define CPUID_8000_0021_EAX_AUTO_IBRS (1U << 8) ++/* Indicates support for IC prefetch */ ++#define CPUID_8000_0021_EAX_PREFETCHI (1U << 20) + /* Enhanced Return Address Predictor Scurity */ + #define CPUID_8000_0021_EAX_ERAPS (1U << 24) + /* Selective Branch Predictor Barrier */ +-- +2.39.3 + diff --git a/kvm-target-i386-Add-feature-dependencies-for-AVX10.patch b/kvm-target-i386-Add-feature-dependencies-for-AVX10.patch deleted file mode 100644 index f116f49..0000000 --- a/kvm-target-i386-Add-feature-dependencies-for-AVX10.patch +++ /dev/null @@ -1,89 +0,0 @@ -From c44f6f57898eb9f382545201033586a17bbde83c Mon Sep 17 00:00:00 2001 -From: Tao Su -Date: Thu, 31 Oct 2024 16:52:31 +0800 -Subject: [PATCH 35/38] target/i386: Add feature dependencies for AVX10 - -RH-Author: Paolo Bonzini -RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets -RH-Jira: RHEL-30315 RHEL-45110 -RH-Acked-by: Vitaly Kuznetsov -RH-Acked-by: Miroslav Rezanina -RH-Commit: [6/9] 38b1a79032d7acdb264a6403fd4d8239d89b68c4 (bonzini/rhel-qemu-kvm) - -Since the highest supported vector length for a processor implies that -all lesser vector lengths are also supported, add the dependencies of -the supported vector lengths. If all vector lengths aren't supported, -clear AVX10 enable bit as well. - -Note that the order of AVX10 related dependencies should be kept as: - CPUID_24_0_EBX_AVX10_128 -> CPUID_24_0_EBX_AVX10_256, - CPUID_24_0_EBX_AVX10_256 -> CPUID_24_0_EBX_AVX10_512, - CPUID_24_0_EBX_AVX10_VL_MASK -> CPUID_7_1_EDX_AVX10, - CPUID_7_1_EDX_AVX10 -> CPUID_24_0_EBX, -so that prevent user from setting weird CPUID combinations, e.g. 256-bits -and 512-bits are supported but 128-bits is not, no vector lengths are -supported but AVX10 enable bit is still set. - -Since AVX10_128 will be reserved as 1, adding these dependencies has the -bonus that when user sets -cpu host,-avx10-128, CPUID_7_1_EDX_AVX10 and -CPUID_24_0_EBX will be disabled automatically. - -Tested-by: Xuelian Guo -Signed-off-by: Tao Su -Link: https://lore.kernel.org/r/20241028024512.156724-5-tao1.su@linux.intel.com -Reviewed-by: Zhao Liu -Signed-off-by: Paolo Bonzini -Link: https://lore.kernel.org/r/20241031085233.425388-7-tao1.su@linux.intel.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit 150ab84b2d0083e6af344cca70290614d4fe568d) -Signed-off-by: Paolo Bonzini ---- - target/i386/cpu.c | 16 ++++++++++++++++ - target/i386/cpu.h | 4 ++++ - 2 files changed, 20 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 958cbff54d..a740429fdd 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -1766,6 +1766,22 @@ static FeatureDep feature_dependencies[] = { - .from = { FEAT_7_0_EBX, CPUID_7_0_EBX_SGX }, - .to = { FEAT_SGX_12_1_EAX, ~0ull }, - }, -+ { -+ .from = { FEAT_24_0_EBX, CPUID_24_0_EBX_AVX10_128 }, -+ .to = { FEAT_24_0_EBX, CPUID_24_0_EBX_AVX10_256 }, -+ }, -+ { -+ .from = { FEAT_24_0_EBX, CPUID_24_0_EBX_AVX10_256 }, -+ .to = { FEAT_24_0_EBX, CPUID_24_0_EBX_AVX10_512 }, -+ }, -+ { -+ .from = { FEAT_24_0_EBX, CPUID_24_0_EBX_AVX10_VL_MASK }, -+ .to = { FEAT_7_1_EDX, CPUID_7_1_EDX_AVX10 }, -+ }, -+ { -+ .from = { FEAT_7_1_EDX, CPUID_7_1_EDX_AVX10 }, -+ .to = { FEAT_24_0_EBX, ~0ull }, -+ }, - }; - - typedef struct X86RegisterInfo32 { -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index c60290b8d5..4da9ed5930 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -997,6 +997,10 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); - #define CPUID_24_0_EBX_AVX10_256 (1U << 17) - /* AVX10 512-bit vector support is present */ - #define CPUID_24_0_EBX_AVX10_512 (1U << 18) -+/* AVX10 vector length support mask */ -+#define CPUID_24_0_EBX_AVX10_VL_MASK (CPUID_24_0_EBX_AVX10_128 | \ -+ CPUID_24_0_EBX_AVX10_256 | \ -+ CPUID_24_0_EBX_AVX10_512) - - /* RAS Features */ - #define CPUID_8000_0007_EBX_OVERFLOW_RECOV (1U << 0) --- -2.39.3 - diff --git a/kvm-target-i386-Add-support-for-EPYC-Turin-model.patch b/kvm-target-i386-Add-support-for-EPYC-Turin-model.patch new file mode 100644 index 0000000..4afe216 --- /dev/null +++ b/kvm-target-i386-Add-support-for-EPYC-Turin-model.patch @@ -0,0 +1,200 @@ +From 6a86e17bd55a867b903e14a6cff3d985a046a794 Mon Sep 17 00:00:00 2001 +From: Babu Moger +Date: Thu, 8 May 2025 14:58:04 -0500 +Subject: [PATCH 08/43] target/i386: Add support for EPYC-Turin model + +RH-Author: John Allen +RH-MergeRequest: 377: Update EPYC Models and Feature Bits +RH-Jira: RHEL-52650 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [6/6] 3d8805bafc53da2bd5a2b2b96cc892ea7ca9f2b3 (johnalle/qemu-kvm-fork) + +Add the support for AMD EPYC zen 5 processors (EPYC-Turin). + +Add the following new feature bits on top of the feature bits from +the previous generation EPYC models. + +movdiri : Move Doubleword as Direct Store Instruction +movdir64b : Move 64 Bytes as Direct Store Instruction +avx512-vp2intersect : AVX512 Vector Pair Intersection to a Pair + of Mask Register +avx-vnni : AVX VNNI Instruction +prefetchi : Indicates support for IC prefetch +sbpb : Selective Branch Predictor Barrier +ibpb-brtype : IBPB includes branch type prediction flushing +srso-user-kernel-no : Not vulnerable to SRSO at the user-kernel boundary + +Link: https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/programmer-references/57238.zip +Link: https://www.amd.com/content/dam/amd/en/documents/corporate/cr/speculative-return-stack-overflow-whitepaper.pdf +Signed-off-by: Babu Moger +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/b4fa7708a0e1453d2e9b8ec3dc881feb92eeca0b.1746734284.git.babu.moger@amd.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 3771a4daa273ba17cb27309984413790d1df5651) + +JIRA: https://issues.redhat.com/browse/RHEL-52650 + +Signed-off-by: John Allen +--- + target/i386/cpu.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 138 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 523ac08a07..3e31999d19 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -2668,6 +2668,61 @@ static const CPUCaches epyc_genoa_v2_cache_info = { + .share_level = CPU_TOPOLOGY_LEVEL_DIE, + }, + }; ++ ++static const CPUCaches epyc_turin_cache_info = { ++ .l1d_cache = &(CPUCacheInfo) { ++ .type = DATA_CACHE, ++ .level = 1, ++ .size = 48 * KiB, ++ .line_size = 64, ++ .associativity = 12, ++ .partitions = 1, ++ .sets = 64, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .share_level = CPU_TOPOLOGY_LEVEL_CORE, ++ }, ++ .l1i_cache = &(CPUCacheInfo) { ++ .type = INSTRUCTION_CACHE, ++ .level = 1, ++ .size = 32 * KiB, ++ .line_size = 64, ++ .associativity = 8, ++ .partitions = 1, ++ .sets = 64, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .share_level = CPU_TOPOLOGY_LEVEL_CORE, ++ }, ++ .l2_cache = &(CPUCacheInfo) { ++ .type = UNIFIED_CACHE, ++ .level = 2, ++ .size = 1 * MiB, ++ .line_size = 64, ++ .associativity = 16, ++ .partitions = 1, ++ .sets = 1024, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .inclusive = true, ++ .share_level = CPU_TOPOLOGY_LEVEL_CORE, ++ }, ++ .l3_cache = &(CPUCacheInfo) { ++ .type = UNIFIED_CACHE, ++ .level = 3, ++ .size = 32 * MiB, ++ .line_size = 64, ++ .associativity = 16, ++ .partitions = 1, ++ .sets = 32768, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .no_invd_sharing = true, ++ .complex_indexing = false, ++ .share_level = CPU_TOPOLOGY_LEVEL_DIE, ++ }, ++}; ++ + /* The following VMX features are not supported by KVM and are left out in the + * CPU definitions: + * +@@ -5937,6 +5992,89 @@ static const X86CPUDefinition builtin_x86_defs[] = { + .model_id = "Zhaoxin YongFeng Processor", + }, + #endif ++ { ++ .name = "EPYC-Turin", ++ .level = 0xd, ++ .vendor = CPUID_VENDOR_AMD, ++ .family = 26, ++ .model = 0, ++ .stepping = 0, ++ .features[FEAT_1_ECX] = ++ CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX | ++ CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT | ++ CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | ++ CPUID_EXT_PCID | CPUID_EXT_CX16 | CPUID_EXT_FMA | ++ CPUID_EXT_SSSE3 | CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | ++ CPUID_EXT_SSE3, ++ .features[FEAT_1_EDX] = ++ CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH | ++ CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE | ++ CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE | ++ CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE | ++ CPUID_VME | CPUID_FP87, ++ .features[FEAT_6_EAX] = ++ CPUID_6_EAX_ARAT, ++ .features[FEAT_7_0_EBX] = ++ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 | ++ CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | ++ CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_AVX512F | ++ CPUID_7_0_EBX_AVX512DQ | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | ++ CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_AVX512IFMA | ++ CPUID_7_0_EBX_CLFLUSHOPT | CPUID_7_0_EBX_CLWB | ++ CPUID_7_0_EBX_AVX512CD | CPUID_7_0_EBX_SHA_NI | ++ CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL, ++ .features[FEAT_7_0_ECX] = ++ CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | ++ CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI | ++ CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ | ++ CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG | ++ CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57 | ++ CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_MOVDIRI | ++ CPUID_7_0_ECX_MOVDIR64B, ++ .features[FEAT_7_0_EDX] = ++ CPUID_7_0_EDX_FSRM | CPUID_7_0_EDX_AVX512_VP2INTERSECT, ++ .features[FEAT_7_1_EAX] = ++ CPUID_7_1_EAX_AVX_VNNI | CPUID_7_1_EAX_AVX512_BF16, ++ .features[FEAT_8000_0001_ECX] = ++ CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH | ++ CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | ++ CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM | ++ CPUID_EXT3_TOPOEXT | CPUID_EXT3_PERFCORE, ++ .features[FEAT_8000_0001_EDX] = ++ CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB | ++ CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX | ++ CPUID_EXT2_SYSCALL, ++ .features[FEAT_8000_0007_EBX] = ++ CPUID_8000_0007_EBX_OVERFLOW_RECOV | CPUID_8000_0007_EBX_SUCCOR, ++ .features[FEAT_8000_0008_EBX] = ++ CPUID_8000_0008_EBX_CLZERO | CPUID_8000_0008_EBX_XSAVEERPTR | ++ CPUID_8000_0008_EBX_WBNOINVD | CPUID_8000_0008_EBX_IBPB | ++ CPUID_8000_0008_EBX_IBRS | CPUID_8000_0008_EBX_STIBP | ++ CPUID_8000_0008_EBX_STIBP_ALWAYS_ON | ++ CPUID_8000_0008_EBX_AMD_SSBD | CPUID_8000_0008_EBX_AMD_PSFD, ++ .features[FEAT_8000_0021_EAX] = ++ CPUID_8000_0021_EAX_NO_NESTED_DATA_BP | ++ CPUID_8000_0021_EAX_FS_GS_BASE_NS | ++ CPUID_8000_0021_EAX_LFENCE_ALWAYS_SERIALIZING | ++ CPUID_8000_0021_EAX_NULL_SEL_CLR_BASE | ++ CPUID_8000_0021_EAX_AUTO_IBRS | CPUID_8000_0021_EAX_PREFETCHI | ++ CPUID_8000_0021_EAX_SBPB | CPUID_8000_0021_EAX_IBPB_BRTYPE | ++ CPUID_8000_0021_EAX_SRSO_USER_KERNEL_NO, ++ .features[FEAT_8000_0022_EAX] = ++ CPUID_8000_0022_EAX_PERFMON_V2, ++ .features[FEAT_XSAVE] = ++ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | ++ CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES, ++ .features[FEAT_SVM] = ++ CPUID_SVM_NPT | CPUID_SVM_LBRV | CPUID_SVM_NRIPSAVE | ++ CPUID_SVM_TSCSCALE | CPUID_SVM_VMCBCLEAN | CPUID_SVM_FLUSHASID | ++ CPUID_SVM_PAUSEFILTER | CPUID_SVM_PFTHRESHOLD | ++ CPUID_SVM_V_VMSAVE_VMLOAD | CPUID_SVM_VGIF | ++ CPUID_SVM_VNMI | CPUID_SVM_SVME_ADDR_CHK, ++ .xlevel = 0x80000022, ++ .model_id = "AMD EPYC-Turin Processor", ++ .cache_info = &epyc_turin_cache_info, ++ }, + }; + + /* +-- +2.39.3 + diff --git a/kvm-target-i386-Introduce-GraniteRapids-v2-model.patch b/kvm-target-i386-Introduce-GraniteRapids-v2-model.patch deleted file mode 100644 index d9a94af..0000000 --- a/kvm-target-i386-Introduce-GraniteRapids-v2-model.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 32437dacd0f0d5076af2d549317b92432ee52abd Mon Sep 17 00:00:00 2001 -From: Tao Su -Date: Thu, 31 Oct 2024 16:52:33 +0800 -Subject: [PATCH 37/38] target/i386: Introduce GraniteRapids-v2 model - -RH-Author: Paolo Bonzini -RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets -RH-Jira: RHEL-30315 RHEL-45110 -RH-Acked-by: Vitaly Kuznetsov -RH-Acked-by: Miroslav Rezanina -RH-Commit: [8/9] c53ba67dd616c9f376db0ab4f1478dd50f5dd874 (bonzini/rhel-qemu-kvm) - -Update GraniteRapids CPU model to add AVX10 and the missing features(ss, -tsc-adjust, cldemote, movdiri, movdir64b). - -Tested-by: Xuelian Guo -Signed-off-by: Tao Su -Link: https://lore.kernel.org/r/20241028024512.156724-7-tao1.su@linux.intel.com -Reviewed-by: Zhao Liu -Signed-off-by: Paolo Bonzini -Link: https://lore.kernel.org/r/20241031085233.425388-9-tao1.su@linux.intel.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit 1a519388a882fbb352e49cbebb0ed8f62d05842d) -Signed-off-by: Paolo Bonzini ---- - target/i386/cpu.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index ddec461dd4..e7367cfe82 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -4385,6 +4385,23 @@ static const X86CPUDefinition builtin_x86_defs[] = { - .model_id = "Intel Xeon Processor (GraniteRapids)", - .versions = (X86CPUVersionDefinition[]) { - { .version = 1 }, -+ { -+ .version = 2, -+ .props = (PropValue[]) { -+ { "ss", "on" }, -+ { "tsc-adjust", "on" }, -+ { "cldemote", "on" }, -+ { "movdiri", "on" }, -+ { "movdir64b", "on" }, -+ { "avx10", "on" }, -+ { "avx10-128", "on" }, -+ { "avx10-256", "on" }, -+ { "avx10-512", "on" }, -+ { "avx10-version", "1" }, -+ { "stepping", "1" }, -+ { /* end of list */ } -+ } -+ }, - { /* end of list */ }, - }, - }, --- -2.39.3 - diff --git a/kvm-target-i386-Make-sure-SynIC-state-is-really-updated-.patch b/kvm-target-i386-Make-sure-SynIC-state-is-really-updated-.patch deleted file mode 100644 index fd18705..0000000 --- a/kvm-target-i386-Make-sure-SynIC-state-is-really-updated-.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 327e8c65d28dc357c02b508e6485e7c57d4d1efa Mon Sep 17 00:00:00 2001 -From: Vitaly Kuznetsov -Date: Tue, 7 Jan 2025 13:43:32 +0100 -Subject: [PATCH 1/4] target/i386: Make sure SynIC state is really updated - before KVM_RUN - -RH-Author: Vitaly Kuznetsov -RH-MergeRequest: 314: target/i386: Make sure SynIC state is really updated before KVM_RUN -RH-Jira: RHEL-73002 -RH-Acked-by: Paolo Bonzini -RH-Acked-by: Maxim Levitsky -RH-Commit: [1/1] 2d8f7605e3efd3c76d16a2cb9e7c0898786fb4e9 (vkuznets/qemu-kvm) - -'hyperv_synic' test from KVM unittests was observed to be flaky on certain -hardware (hangs sometimes). Debugging shows that the problem happens in -hyperv_sint_route_new() when the test tries to set up a new SynIC -route. The function bails out on: - - if (!synic->sctl_enabled) { - goto cleanup; - } - -but the test writes to HV_X64_MSR_SCONTROL just before it starts -establishing SINT routes. Further investigation shows that -synic_update() (called from async_synic_update()) happens after the SINT -setup attempt and not before. Apparently, the comment before -async_safe_run_on_cpu() in kvm_hv_handle_exit() does not correctly describe -the guarantees async_safe_run_on_cpu() gives. In particular, async worked -added to a CPU is actually processed from qemu_wait_io_event() which is not -always called before KVM_RUN, i.e. kvm_cpu_exec() checks whether an exit -request is pending for a CPU and if not, keeps running the vCPU until it -meets an exit it can't handle internally. Hyper-V specific MSR writes are -not automatically trigger an exit. - -Fix the issue by simply raising an exit request for the vCPU where SynIC -update was queued. This is not a performance critical path as SynIC state -does not get updated so often (and async_safe_run_on_cpu() is a big hammer -anyways). - -Reported-by: Jan Richter -Signed-off-by: Vitaly Kuznetsov -Link: https://lore.kernel.org/r/20240917160051.2637594-4-vkuznets@redhat.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit d3177e2e4353824a650434c57471615d43507500) -Signed-off-by: Vitaly Kuznetsov ---- - target/i386/kvm/hyperv.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/target/i386/kvm/hyperv.c b/target/i386/kvm/hyperv.c -index b94f12acc2..70b89cacf9 100644 ---- a/target/i386/kvm/hyperv.c -+++ b/target/i386/kvm/hyperv.c -@@ -80,6 +80,7 @@ int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit) - * necessary because memory hierarchy is being changed - */ - async_safe_run_on_cpu(CPU(cpu), async_synic_update, RUN_ON_CPU_NULL); -+ cpu_exit(CPU(cpu)); - - return EXCP_INTERRUPT; - case KVM_EXIT_HYPERV_HCALL: { --- -2.39.3 - diff --git a/kvm-target-i386-Print-CPUID-subleaf-info-for-unsupported.patch b/kvm-target-i386-Print-CPUID-subleaf-info-for-unsupported.patch new file mode 100644 index 0000000..f329a4d --- /dev/null +++ b/kvm-target-i386-Print-CPUID-subleaf-info-for-unsupported.patch @@ -0,0 +1,39 @@ +From cf4b427afee02e5d4e13778c55bda9fd5d896ffc Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:44 +0200 +Subject: [PATCH 002/100] target/i386: Print CPUID subleaf info for unsupported + feature + +Some CPUID leaves have meaningful subleaf index. Print the subleaf info +in feature_word_description for CPUID features. + +Signed-off-by: Xiaoyao Li +Reviewed-by: Eduardo Habkost +Reviewed-by: Zhao Liu +Message-ID: <20241217123932.948789-3-xiaoyao.li@intel.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 22a2a701090b83d8dd06765edc1b61f6208c76b1) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 86a7dd1c77..1e8839dd98 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -6193,8 +6193,9 @@ static char *feature_word_description(FeatureWordInfo *f) + { + const char *reg = get_register_name_32(f->cpuid.reg); + assert(reg); +- return g_strdup_printf("CPUID.%02XH:%s", +- f->cpuid.eax, reg); ++ return g_strdup_printf("CPUID.%02XH_%02XH:%s", ++ f->cpuid.eax, ++ f->cpuid.needs_ecx ? f->cpuid.ecx : 0, reg); + } + case MSR_FEATURE_WORD: + return g_strdup_printf("MSR(%02XH)", +-- +2.47.3 + diff --git a/kvm-target-i386-Remove-AccelCPUClass-cpu_class_init-need.patch b/kvm-target-i386-Remove-AccelCPUClass-cpu_class_init-need.patch new file mode 100644 index 0000000..4908cc9 --- /dev/null +++ b/kvm-target-i386-Remove-AccelCPUClass-cpu_class_init-need.patch @@ -0,0 +1,114 @@ +From 448f00eb2ca5d9be412cf448cab20e2759bc246b Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:45 +0200 +Subject: [PATCH 004/100] target/i386: Remove AccelCPUClass::cpu_class_init + need +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Expose x86_tcg_ops symbol, then directly set it as +CPUClass::tcg_ops in TYPE_X86_CPU's class_init(), +using CONFIG_TCG #ifdef'ry. No need for the +AccelCPUClass::cpu_class_init() handler anymore. + +Signed-off-by: Philippe Mathieu-DaudĂ© +Message-ID: <20250405161320.76854-3-philmd@linaro.org> +Reviewed-by: Richard Henderson +Signed-off-by: Richard Henderson +(cherry picked from commit a522b04bb9cf67789116ad7a6165946d4b214bac) +Signed-off-by: Paolo Bonzini + +Conflicts: missing one member of x86_tcg_ops +--- + target/i386/cpu.c | 4 ++++ + target/i386/tcg/tcg-cpu.c | 14 +------------- + target/i386/tcg/tcg-cpu.h | 4 ++++ + 3 files changed, 9 insertions(+), 13 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 1e8839dd98..aaa6b79410 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -42,6 +42,7 @@ + #include "hw/boards.h" + #include "hw/i386/sgx-epc.h" + #endif ++#include "tcg/tcg-cpu.h" + + #include "disas/capstone.h" + #include "cpu-internal.h" +@@ -9390,6 +9391,9 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) + #ifndef CONFIG_USER_ONLY + cc->sysemu_ops = &i386_sysemu_ops; + #endif /* !CONFIG_USER_ONLY */ ++#ifdef CONFIG_TCG ++ cc->tcg_ops = &x86_tcg_ops; ++#endif /* CONFIG_TCG */ + + cc->gdb_arch_name = x86_gdb_arch_name; + #ifdef TARGET_X86_64 +diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c +index b8aff825ee..cfe64059af 100644 +--- a/target/i386/tcg/tcg-cpu.c ++++ b/target/i386/tcg/tcg-cpu.c +@@ -107,7 +107,7 @@ static bool x86_debug_check_breakpoint(CPUState *cs) + + #include "accel/tcg/cpu-ops.h" + +-static const TCGCPUOps x86_tcg_ops = { ++const TCGCPUOps x86_tcg_ops = { + .initialize = tcg_x86_init, + .translate_code = x86_translate_code, + .synchronize_from_tb = x86_cpu_synchronize_from_tb, +@@ -130,17 +130,6 @@ static const TCGCPUOps x86_tcg_ops = { + #endif /* !CONFIG_USER_ONLY */ + }; + +-static void x86_tcg_cpu_init_ops(AccelCPUClass *accel_cpu, CPUClass *cc) +-{ +- /* for x86, all cpus use the same set of operations */ +- cc->tcg_ops = &x86_tcg_ops; +-} +- +-static void x86_tcg_cpu_class_init(CPUClass *cc) +-{ +- cc->init_accel_cpu = x86_tcg_cpu_init_ops; +-} +- + static void x86_tcg_cpu_xsave_init(void) + { + #define XO(bit, field) \ +@@ -189,7 +178,6 @@ static void x86_tcg_cpu_accel_class_init(ObjectClass *oc, void *data) + acc->cpu_target_realize = tcg_cpu_realizefn; + #endif /* CONFIG_USER_ONLY */ + +- acc->cpu_class_init = x86_tcg_cpu_class_init; + acc->cpu_instance_init = x86_tcg_cpu_instance_init; + } + static const TypeInfo x86_tcg_cpu_accel_type_info = { +diff --git a/target/i386/tcg/tcg-cpu.h b/target/i386/tcg/tcg-cpu.h +index 53a8494455..9bbf0cb875 100644 +--- a/target/i386/tcg/tcg-cpu.h ++++ b/target/i386/tcg/tcg-cpu.h +@@ -19,6 +19,8 @@ + #ifndef TCG_CPU_H + #define TCG_CPU_H + ++#include "cpu.h" ++ + #define XSAVE_FCW_FSW_OFFSET 0x000 + #define XSAVE_FTW_FOP_OFFSET 0x004 + #define XSAVE_CWD_RIP_OFFSET 0x008 +@@ -76,6 +78,8 @@ QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, zmm_hi256_state) != XSAVE_ZMM_HI256_OFF + QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, hi16_zmm_state) != XSAVE_HI16_ZMM_OFFSET); + QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, pkru_state) != XSAVE_PKRU_OFFSET); + ++extern const TCGCPUOps x86_tcg_ops; ++ + bool tcg_cpu_realizefn(CPUState *cs, Error **errp); + + #endif /* TCG_CPU_H */ +-- +2.47.3 + diff --git a/kvm-target-i386-Update-EPYC-CPU-model-for-Cache-property.patch b/kvm-target-i386-Update-EPYC-CPU-model-for-Cache-property.patch new file mode 100644 index 0000000..623736f --- /dev/null +++ b/kvm-target-i386-Update-EPYC-CPU-model-for-Cache-property.patch @@ -0,0 +1,147 @@ +From bec357aa1a80983969a1bb8524d4d649dd5ca355 Mon Sep 17 00:00:00 2001 +From: Babu Moger +Date: Thu, 8 May 2025 14:57:59 -0500 +Subject: [PATCH 03/43] target/i386: Update EPYC CPU model for Cache property, + RAS, SVM feature bits + +RH-Author: John Allen +RH-MergeRequest: 377: Update EPYC Models and Feature Bits +RH-Jira: RHEL-52650 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/6] 4d46c1c5cc85b8c5085fe1089ee34a03fcc24b71 (johnalle/qemu-kvm-fork) + +Found that some of the cache properties are not set correctly for EPYC models. + +l1d_cache.no_invd_sharing should not be true. +l1i_cache.no_invd_sharing should not be true. + +L2.self_init should be true. +L2.inclusive should be true. + +L3.inclusive should not be true. +L3.no_invd_sharing should be true. + +Fix the cache properties. + +Also add the missing RAS and SVM features bits on AMD +EPYC CPU models. The SVM feature bits are used in nested guests. + +succor : Software uncorrectable error containment and recovery capability. +overflow-recov : MCA overflow recovery support. +lbrv : LBR virtualization +tsc-scale : MSR based TSC rate control +vmcb-clean : VMCB clean bits +flushbyasid : Flush by ASID +pause-filter : Pause intercept filter +pfthreshold : PAUSE filter threshold +v-vmsave-vmload : Virtualized VMLOAD and VMSAVE +vgif : Virtualized GIF + +Signed-off-by: Babu Moger +Reviewed-by: Maksim Davydov +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/515941861700d7066186c9600bc5d96a1741ef0c.1746734284.git.babu.moger@amd.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 397db937e85d7b9f5a6f0b30764786cef09d1ff3) + +JIRA: https://issues.redhat.com/browse/RHEL-52650 + +Signed-off-by: John Allen +--- + target/i386/cpu.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 73 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 0b09990a8f..e588f81b2e 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -2183,6 +2183,60 @@ static CPUCaches epyc_v4_cache_info = { + }, + }; + ++static CPUCaches epyc_v5_cache_info = { ++ .l1d_cache = &(CPUCacheInfo) { ++ .type = DATA_CACHE, ++ .level = 1, ++ .size = 32 * KiB, ++ .line_size = 64, ++ .associativity = 8, ++ .partitions = 1, ++ .sets = 64, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .share_level = CPU_TOPOLOGY_LEVEL_CORE, ++ }, ++ .l1i_cache = &(CPUCacheInfo) { ++ .type = INSTRUCTION_CACHE, ++ .level = 1, ++ .size = 64 * KiB, ++ .line_size = 64, ++ .associativity = 4, ++ .partitions = 1, ++ .sets = 256, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .share_level = CPU_TOPOLOGY_LEVEL_CORE, ++ }, ++ .l2_cache = &(CPUCacheInfo) { ++ .type = UNIFIED_CACHE, ++ .level = 2, ++ .size = 512 * KiB, ++ .line_size = 64, ++ .associativity = 8, ++ .partitions = 1, ++ .sets = 1024, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .inclusive = true, ++ .share_level = CPU_TOPOLOGY_LEVEL_CORE, ++ }, ++ .l3_cache = &(CPUCacheInfo) { ++ .type = UNIFIED_CACHE, ++ .level = 3, ++ .size = 8 * MiB, ++ .line_size = 64, ++ .associativity = 16, ++ .partitions = 1, ++ .sets = 8192, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .no_invd_sharing = true, ++ .complex_indexing = false, ++ .share_level = CPU_TOPOLOGY_LEVEL_DIE, ++ }, ++}; ++ + static const CPUCaches epyc_rome_cache_info = { + .l1d_cache = &(CPUCacheInfo) { + .type = DATA_CACHE, +@@ -5226,6 +5280,25 @@ static const X86CPUDefinition builtin_x86_defs[] = { + }, + .cache_info = &epyc_v4_cache_info + }, ++ { ++ .version = 5, ++ .props = (PropValue[]) { ++ { "overflow-recov", "on" }, ++ { "succor", "on" }, ++ { "lbrv", "on" }, ++ { "tsc-scale", "on" }, ++ { "vmcb-clean", "on" }, ++ { "flushbyasid", "on" }, ++ { "pause-filter", "on" }, ++ { "pfthreshold", "on" }, ++ { "v-vmsave-vmload", "on" }, ++ { "vgif", "on" }, ++ { "model-id", ++ "AMD EPYC-v5 Processor" }, ++ { /* end of list */ } ++ }, ++ .cache_info = &epyc_v5_cache_info ++ }, + { /* end of list */ } + } + }, +-- +2.39.3 + diff --git a/kvm-target-i386-Update-EPYC-Genoa-for-Cache-property-per.patch b/kvm-target-i386-Update-EPYC-Genoa-for-Cache-property-per.patch new file mode 100644 index 0000000..7f9ed58 --- /dev/null +++ b/kvm-target-i386-Update-EPYC-Genoa-for-Cache-property-per.patch @@ -0,0 +1,158 @@ +From 9e8cee2f5b79e7769533b0db15cddb98acb3fabe Mon Sep 17 00:00:00 2001 +From: Babu Moger +Date: Thu, 8 May 2025 14:58:03 -0500 +Subject: [PATCH 07/43] target/i386: Update EPYC-Genoa for Cache property, + perfmon-v2, RAS and SVM feature bits + +RH-Author: John Allen +RH-MergeRequest: 377: Update EPYC Models and Feature Bits +RH-Jira: RHEL-52650 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [5/6] 1341ffa8eeda12c964d793c7c99e56c114796f04 (johnalle/qemu-kvm-fork) + +Found that some of the cache properties are not set correctly for EPYC models. +l1d_cache.no_invd_sharing should not be true. +l1i_cache.no_invd_sharing should not be true. + +L2.self_init should be true. +L2.inclusive should be true. + +L3.inclusive should not be true. +L3.no_invd_sharing should be true. + +Fix these cache properties. + +Also add the missing RAS and SVM features bits on AMD EPYC-Genoa model. +The SVM feature bits are used in nested guests. + +perfmon-v2 : Allow guests to make use of the PerfMonV2 features. +succor : Software uncorrectable error containment and recovery capability. +overflow-recov : MCA overflow recovery support. +lbrv : LBR virtualization +tsc-scale : MSR based TSC rate control +vmcb-clean : VMCB clean bits +flushbyasid : Flush by ASID +pause-filter : Pause intercept filter +pfthreshold : PAUSE filter threshold +v-vmsave-vmload: Virtualized VMLOAD and VMSAVE +vgif : Virtualized GIF +fs-gs-base-ns : WRMSR to {FS,GS,KERNEL_GS}_BASE is non-serializing + +The feature details are available in APM listed below [1]. +[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming +Publication # 24593 Revision 3.41. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=206537 +Signed-off-by: Babu Moger +Reviewed-by: Maksim Davydov +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/afe3f05d4116124fd5795f28fc23d7b396140313.1746734284.git.babu.moger@amd.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit abc92cc8488b5dbcc403b5be24d8092180605101) + +JIRA: https://issues.redhat.com/browse/RHEL-52650 + +Signed-off-by: John Allen +--- + target/i386/cpu.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 78 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index dd16f885cf..523ac08a07 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -2615,6 +2615,59 @@ static const CPUCaches epyc_genoa_cache_info = { + }, + }; + ++static const CPUCaches epyc_genoa_v2_cache_info = { ++ .l1d_cache = &(CPUCacheInfo) { ++ .type = DATA_CACHE, ++ .level = 1, ++ .size = 32 * KiB, ++ .line_size = 64, ++ .associativity = 8, ++ .partitions = 1, ++ .sets = 64, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .share_level = CPU_TOPOLOGY_LEVEL_CORE, ++ }, ++ .l1i_cache = &(CPUCacheInfo) { ++ .type = INSTRUCTION_CACHE, ++ .level = 1, ++ .size = 32 * KiB, ++ .line_size = 64, ++ .associativity = 8, ++ .partitions = 1, ++ .sets = 64, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .share_level = CPU_TOPOLOGY_LEVEL_CORE, ++ }, ++ .l2_cache = &(CPUCacheInfo) { ++ .type = UNIFIED_CACHE, ++ .level = 2, ++ .size = 1 * MiB, ++ .line_size = 64, ++ .associativity = 8, ++ .partitions = 1, ++ .sets = 2048, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .inclusive = true, ++ .share_level = CPU_TOPOLOGY_LEVEL_CORE, ++ }, ++ .l3_cache = &(CPUCacheInfo) { ++ .type = UNIFIED_CACHE, ++ .level = 3, ++ .size = 32 * MiB, ++ .line_size = 64, ++ .associativity = 16, ++ .partitions = 1, ++ .sets = 32768, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .no_invd_sharing = true, ++ .complex_indexing = false, ++ .share_level = CPU_TOPOLOGY_LEVEL_DIE, ++ }, ++}; + /* The following VMX features are not supported by KVM and are left out in the + * CPU definitions: + * +@@ -5732,6 +5785,31 @@ static const X86CPUDefinition builtin_x86_defs[] = { + .xlevel = 0x80000022, + .model_id = "AMD EPYC-Genoa Processor", + .cache_info = &epyc_genoa_cache_info, ++ .versions = (X86CPUVersionDefinition[]) { ++ { .version = 1 }, ++ { ++ .version = 2, ++ .props = (PropValue[]) { ++ { "overflow-recov", "on" }, ++ { "succor", "on" }, ++ { "lbrv", "on" }, ++ { "tsc-scale", "on" }, ++ { "vmcb-clean", "on" }, ++ { "flushbyasid", "on" }, ++ { "pause-filter", "on" }, ++ { "pfthreshold", "on" }, ++ { "v-vmsave-vmload", "on" }, ++ { "vgif", "on" }, ++ { "fs-gs-base-ns", "on" }, ++ { "perfmon-v2", "on" }, ++ { "model-id", ++ "AMD EPYC-Genoa-v2 Processor" }, ++ { /* end of list */ } ++ }, ++ .cache_info = &epyc_genoa_v2_cache_info ++ }, ++ { /* end of list */ } ++ } + }, + #if 0 // Disabled for Red Hat Enterprise Linux + { +-- +2.39.3 + diff --git a/kvm-target-i386-Update-EPYC-Milan-CPU-model-for-Cache-pr.patch b/kvm-target-i386-Update-EPYC-Milan-CPU-model-for-Cache-pr.patch new file mode 100644 index 0000000..8457fad --- /dev/null +++ b/kvm-target-i386-Update-EPYC-Milan-CPU-model-for-Cache-pr.patch @@ -0,0 +1,146 @@ +From 18fc3436b689504c353e92a0e010fc3bb6a5a4af Mon Sep 17 00:00:00 2001 +From: Babu Moger +Date: Thu, 8 May 2025 14:58:01 -0500 +Subject: [PATCH 05/43] target/i386: Update EPYC-Milan CPU model for Cache + property, RAS, SVM feature bits + +RH-Author: John Allen +RH-MergeRequest: 377: Update EPYC Models and Feature Bits +RH-Jira: RHEL-52650 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [3/6] f6f2a437a158296e884da0f4deac28d58d15ffae (johnalle/qemu-kvm-fork) + +Found that some of the cache properties are not set correctly for EPYC models. +l1d_cache.no_invd_sharing should not be true. +l1i_cache.no_invd_sharing should not be true. + +L2.self_init should be true. +L2.inclusive should be true. + +L3.inclusive should not be true. +L3.no_invd_sharing should be true. + +Fix these cache properties. + +Also add the missing RAS and SVM features bits on AMD EPYC-Milan model. +The SVM feature bits are used in nested guests. + +succor : Software uncorrectable error containment and recovery capability. +overflow-recov : MCA overflow recovery support. +lbrv : LBR virtualization +tsc-scale : MSR based TSC rate control +vmcb-clean : VMCB clean bits +flushbyasid : Flush by ASID +pause-filter : Pause intercept filter +pfthreshold : PAUSE filter threshold +v-vmsave-vmload : Virtualized VMLOAD and VMSAVE +vgif : Virtualized GIF + +Signed-off-by: Babu Moger +Reviewed-by: Maksim Davydov +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/c619c0e09a9d5d496819ed48d69181d65f416891.1746734284.git.babu.moger@amd.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit fc014d9ba5b26b27401e0e88a4e1ef827c68fe64) + +JIRA: https://issues.redhat.com/browse/RHEL-52650 + +Signed-off-by: John Allen +--- + target/i386/cpu.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 73 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 403c72ca60..b3052c6c2c 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -2507,6 +2507,60 @@ static const CPUCaches epyc_milan_v2_cache_info = { + }, + }; + ++static const CPUCaches epyc_milan_v3_cache_info = { ++ .l1d_cache = &(CPUCacheInfo) { ++ .type = DATA_CACHE, ++ .level = 1, ++ .size = 32 * KiB, ++ .line_size = 64, ++ .associativity = 8, ++ .partitions = 1, ++ .sets = 64, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .share_level = CPU_TOPOLOGY_LEVEL_CORE, ++ }, ++ .l1i_cache = &(CPUCacheInfo) { ++ .type = INSTRUCTION_CACHE, ++ .level = 1, ++ .size = 32 * KiB, ++ .line_size = 64, ++ .associativity = 8, ++ .partitions = 1, ++ .sets = 64, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .share_level = CPU_TOPOLOGY_LEVEL_CORE, ++ }, ++ .l2_cache = &(CPUCacheInfo) { ++ .type = UNIFIED_CACHE, ++ .level = 2, ++ .size = 512 * KiB, ++ .line_size = 64, ++ .associativity = 8, ++ .partitions = 1, ++ .sets = 1024, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .inclusive = true, ++ .share_level = CPU_TOPOLOGY_LEVEL_CORE, ++ }, ++ .l3_cache = &(CPUCacheInfo) { ++ .type = UNIFIED_CACHE, ++ .level = 3, ++ .size = 32 * MiB, ++ .line_size = 64, ++ .associativity = 16, ++ .partitions = 1, ++ .sets = 32768, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .no_invd_sharing = true, ++ .complex_indexing = false, ++ .share_level = CPU_TOPOLOGY_LEVEL_DIE, ++ }, ++}; ++ + static const CPUCaches epyc_genoa_cache_info = { + .l1d_cache = &(CPUCacheInfo) { + .type = DATA_CACHE, +@@ -5585,6 +5639,25 @@ static const X86CPUDefinition builtin_x86_defs[] = { + }, + .cache_info = &epyc_milan_v2_cache_info + }, ++ { ++ .version = 3, ++ .props = (PropValue[]) { ++ { "overflow-recov", "on" }, ++ { "succor", "on" }, ++ { "lbrv", "on" }, ++ { "tsc-scale", "on" }, ++ { "vmcb-clean", "on" }, ++ { "flushbyasid", "on" }, ++ { "pause-filter", "on" }, ++ { "pfthreshold", "on" }, ++ { "v-vmsave-vmload", "on" }, ++ { "vgif", "on" }, ++ { "model-id", ++ "AMD EPYC-Milan-v3 Processor" }, ++ { /* end of list */ } ++ }, ++ .cache_info = &epyc_milan_v3_cache_info ++ }, + { /* end of list */ } + } + }, +-- +2.39.3 + diff --git a/kvm-target-i386-Update-EPYC-Rome-CPU-model-for-Cache-pro.patch b/kvm-target-i386-Update-EPYC-Rome-CPU-model-for-Cache-pro.patch new file mode 100644 index 0000000..7d454bf --- /dev/null +++ b/kvm-target-i386-Update-EPYC-Rome-CPU-model-for-Cache-pro.patch @@ -0,0 +1,147 @@ +From 3f18ecff6d6cc0601662fa281551881fdf49d33a Mon Sep 17 00:00:00 2001 +From: Babu Moger +Date: Thu, 8 May 2025 14:58:00 -0500 +Subject: [PATCH 04/43] target/i386: Update EPYC-Rome CPU model for Cache + property, RAS, SVM feature bits + +RH-Author: John Allen +RH-MergeRequest: 377: Update EPYC Models and Feature Bits +RH-Jira: RHEL-52650 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [2/6] 2e08f5372c332152044332474aec4b783c121488 (johnalle/qemu-kvm-fork) + +Found that some of the cache properties are not set correctly for EPYC models. + +l1d_cache.no_invd_sharing should not be true. +l1i_cache.no_invd_sharing should not be true. + +L2.self_init should be true. +L2.inclusive should be true. + +L3.inclusive should not be true. +L3.no_invd_sharing should be true. + +Fix these cache properties. + +Also add the missing RAS and SVM features bits on AMD EPYC-Rome. The SVM +feature bits are used in nested guests. + +succor : Software uncorrectable error containment and recovery capability. +overflow-recov : MCA overflow recovery support. +lbrv : LBR virtualization +tsc-scale : MSR based TSC rate control +vmcb-clean : VMCB clean bits +flushbyasid : Flush by ASID +pause-filter : Pause intercept filter +pfthreshold : PAUSE filter threshold +v-vmsave-vmload : Virtualized VMLOAD and VMSAVE +vgif : Virtualized GIF + +Signed-off-by: Babu Moger +Reviewed-by: Maksim Davydov +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/8265af72057b84c99ac3a02a5487e32759cc69b1.1746734284.git.babu.moger@amd.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 83d940e9700527ff080416ce2fa52ee1f4771d72) + +JIRA: https://issues.redhat.com/browse/RHEL-52650 + +Signed-off-by: John Allen +--- + target/i386/cpu.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 73 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index e588f81b2e..403c72ca60 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -2345,6 +2345,60 @@ static const CPUCaches epyc_rome_v3_cache_info = { + }, + }; + ++static const CPUCaches epyc_rome_v5_cache_info = { ++ .l1d_cache = &(CPUCacheInfo) { ++ .type = DATA_CACHE, ++ .level = 1, ++ .size = 32 * KiB, ++ .line_size = 64, ++ .associativity = 8, ++ .partitions = 1, ++ .sets = 64, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .share_level = CPU_TOPOLOGY_LEVEL_CORE, ++ }, ++ .l1i_cache = &(CPUCacheInfo) { ++ .type = INSTRUCTION_CACHE, ++ .level = 1, ++ .size = 32 * KiB, ++ .line_size = 64, ++ .associativity = 8, ++ .partitions = 1, ++ .sets = 64, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .share_level = CPU_TOPOLOGY_LEVEL_CORE, ++ }, ++ .l2_cache = &(CPUCacheInfo) { ++ .type = UNIFIED_CACHE, ++ .level = 2, ++ .size = 512 * KiB, ++ .line_size = 64, ++ .associativity = 8, ++ .partitions = 1, ++ .sets = 1024, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .inclusive = true, ++ .share_level = CPU_TOPOLOGY_LEVEL_CORE, ++ }, ++ .l3_cache = &(CPUCacheInfo) { ++ .type = UNIFIED_CACHE, ++ .level = 3, ++ .size = 16 * MiB, ++ .line_size = 64, ++ .associativity = 16, ++ .partitions = 1, ++ .sets = 16384, ++ .lines_per_tag = 1, ++ .self_init = true, ++ .no_invd_sharing = true, ++ .complex_indexing = false, ++ .share_level = CPU_TOPOLOGY_LEVEL_DIE, ++ }, ++}; ++ + static const CPUCaches epyc_milan_cache_info = { + .l1d_cache = &(CPUCacheInfo) { + .type = DATA_CACHE, +@@ -5437,6 +5491,25 @@ static const X86CPUDefinition builtin_x86_defs[] = { + { /* end of list */ } + }, + }, ++ { ++ .version = 5, ++ .props = (PropValue[]) { ++ { "overflow-recov", "on" }, ++ { "succor", "on" }, ++ { "lbrv", "on" }, ++ { "tsc-scale", "on" }, ++ { "vmcb-clean", "on" }, ++ { "flushbyasid", "on" }, ++ { "pause-filter", "on" }, ++ { "pfthreshold", "on" }, ++ { "v-vmsave-vmload", "on" }, ++ { "vgif", "on" }, ++ { "model-id", ++ "AMD EPYC-Rome-v5 Processor" }, ++ { /* end of list */ } ++ }, ++ .cache_info = &epyc_rome_v5_cache_info ++ }, + { /* end of list */ } + } + }, +-- +2.39.3 + diff --git a/kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch b/kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch deleted file mode 100644 index e60ecf4..0000000 --- a/kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch +++ /dev/null @@ -1,224 +0,0 @@ -From 704bfed342ca7cfbef44b639aadfeada1841b091 Mon Sep 17 00:00:00 2001 -From: Tao Su -Date: Thu, 31 Oct 2024 16:52:29 +0800 -Subject: [PATCH 33/38] target/i386: add AVX10 feature and AVX10 version - property - -RH-Author: Paolo Bonzini -RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets -RH-Jira: RHEL-30315 RHEL-45110 -RH-Acked-by: Vitaly Kuznetsov -RH-Acked-by: Miroslav Rezanina -RH-Commit: [4/9] 8101218e0a5789770fcef7ca277f7b39df48f176 (bonzini/rhel-qemu-kvm) - -When AVX10 enable bit is set, the 0x24 leaf will be present as "AVX10 -Converged Vector ISA leaf" containing fields for the version number and -the supported vector bit lengths. - -Introduce avx10-version property so that avx10 version can be controlled -by user and cpu model. Per spec, avx10 version can never be 0, the default -value of avx10-version is set to 0 to determine whether it is specified by -user. The default can come from the device model or, for the max model, -from KVM's reported value. - -Signed-off-by: Tao Su -Link: https://lore.kernel.org/r/20241028024512.156724-3-tao1.su@linux.intel.com -Link: https://lore.kernel.org/r/20241028024512.156724-4-tao1.su@linux.intel.com -Signed-off-by: Paolo Bonzini -Tested-by: Xuelian Guo -Link: https://lore.kernel.org/r/20241031085233.425388-5-tao1.su@linux.intel.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit bccfb846fd52d6f20704ecfa4d01b60b43c6f640) -Signed-off-by: Paolo Bonzini ---- - target/i386/cpu.c | 64 ++++++++++++++++++++++++++++++++++++++----- - target/i386/cpu.h | 4 +++ - target/i386/kvm/kvm.c | 3 +- - 3 files changed, 63 insertions(+), 8 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 353f50a1b9..a2e1a18537 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -47,6 +47,9 @@ - #include "cpu-internal.h" - - static void x86_cpu_realizefn(DeviceState *dev, Error **errp); -+static void x86_cpu_get_supported_cpuid(uint32_t func, uint32_t index, -+ uint32_t *eax, uint32_t *ebx, -+ uint32_t *ecx, uint32_t *edx); - - /* Helpers for building CPUID[2] descriptors: */ - -@@ -1133,7 +1136,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - "avx-vnni-int8", "avx-ne-convert", NULL, NULL, - "amx-complex", NULL, "avx-vnni-int16", NULL, - NULL, NULL, "prefetchiti", NULL, -- NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, "avx10", - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -@@ -1961,6 +1964,7 @@ typedef struct X86CPUDefinition { - int family; - int model; - int stepping; -+ uint8_t avx10_version; - FeatureWordArray features; - const char *model_id; - const CPUCaches *const cache_info; -@@ -6326,6 +6330,9 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model) - */ - object_property_set_str(OBJECT(cpu), "vendor", def->vendor, &error_abort); - -+ object_property_set_uint(OBJECT(cpu), "avx10-version", def->avx10_version, -+ &error_abort); -+ - x86_cpu_apply_version_props(cpu, model); - - /* -@@ -6854,6 +6861,16 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - } - break; - } -+ case 0x24: { -+ *eax = 0; -+ *ebx = 0; -+ *ecx = 0; -+ *edx = 0; -+ if ((env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_AVX10) && count == 0) { -+ *ebx = env->features[FEAT_24_0_EBX] | env->avx10_version; -+ } -+ break; -+ } - case 0x40000000: - /* - * CPUID code in kvm_arch_init_vcpu() ignores stuff -@@ -7434,6 +7451,12 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) - ~env->user_features[w] & - ~feature_word_info[w].no_autoenable_flags; - } -+ -+ if ((env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_AVX10) && !env->avx10_version) { -+ uint32_t eax, ebx, ecx, edx; -+ x86_cpu_get_supported_cpuid(0x24, 0, &eax, &ebx, &ecx, &edx); -+ env->avx10_version = ebx & 0xff; -+ } - } - - for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) { -@@ -7497,6 +7520,11 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) - x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x1F); - } - -+ /* Advanced Vector Extensions 10 (AVX10) requires CPUID[0x24] */ -+ if (env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_AVX10) { -+ x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x24); -+ } -+ - /* SVM requires CPUID[0x8000000A] */ - if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) { - x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A); -@@ -7547,6 +7575,10 @@ static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose) - CPUX86State *env = &cpu->env; - FeatureWord w; - const char *prefix = NULL; -+ bool have_filtered_features; -+ -+ uint32_t eax_0, ebx_0, ecx_0, edx_0; -+ uint32_t eax_1, ebx_1, ecx_1, edx_1; - - if (verbose) { - prefix = accel_uses_host_cpuid() -@@ -7568,13 +7600,10 @@ static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose) - */ - if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) && - kvm_enabled()) { -- uint32_t eax_0, ebx_0, ecx_0, edx_0_unused; -- uint32_t eax_1, ebx_1, ecx_1_unused, edx_1_unused; -- - x86_cpu_get_supported_cpuid(0x14, 0, -- &eax_0, &ebx_0, &ecx_0, &edx_0_unused); -+ &eax_0, &ebx_0, &ecx_0, &edx_0); - x86_cpu_get_supported_cpuid(0x14, 1, -- &eax_1, &ebx_1, &ecx_1_unused, &edx_1_unused); -+ &eax_1, &ebx_1, &ecx_1, &edx_1); - - if (!eax_0 || - ((ebx_0 & INTEL_PT_MINIMAL_EBX) != INTEL_PT_MINIMAL_EBX) || -@@ -7595,7 +7624,27 @@ static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose) - } - } - -- return x86_cpu_have_filtered_features(cpu); -+ have_filtered_features = x86_cpu_have_filtered_features(cpu); -+ -+ if (env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_AVX10) { -+ x86_cpu_get_supported_cpuid(0x24, 0, -+ &eax_0, &ebx_0, &ecx_0, &edx_0); -+ uint8_t version = ebx_0 & 0xff; -+ -+ if (version < env->avx10_version) { -+ if (prefix) { -+ warn_report("%s: avx10.%d. Adjust to avx10.%d", -+ prefix, env->avx10_version, version); -+ } -+ env->avx10_version = version; -+ have_filtered_features = true; -+ } -+ } else if (env->avx10_version && prefix) { -+ warn_report("%s: avx10.%d.", prefix, env->avx10_version); -+ have_filtered_features = true; -+ } -+ -+ return have_filtered_features; - } - - static void x86_cpu_hyperv_realize(X86CPU *cpu) -@@ -8376,6 +8425,7 @@ static Property x86_cpu_properties[] = { - DEFINE_PROP_UINT32("min-level", X86CPU, env.cpuid_min_level, 0), - DEFINE_PROP_UINT32("min-xlevel", X86CPU, env.cpuid_min_xlevel, 0), - DEFINE_PROP_UINT32("min-xlevel2", X86CPU, env.cpuid_min_xlevel2, 0), -+ DEFINE_PROP_UINT8("avx10-version", X86CPU, env.avx10_version, 0), - DEFINE_PROP_UINT64("ucode-rev", X86CPU, ucode_rev, 0), - DEFINE_PROP_BOOL("full-cpuid-auto-level", X86CPU, full_cpuid_auto_level, true), - DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor), -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 14edd57a37..591113349d 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -972,6 +972,8 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); - #define CPUID_7_1_EDX_AMX_COMPLEX (1U << 8) - /* PREFETCHIT0/1 Instructions */ - #define CPUID_7_1_EDX_PREFETCHITI (1U << 14) -+/* Support for Advanced Vector Extensions 10 */ -+#define CPUID_7_1_EDX_AVX10 (1U << 19) - /* Flexible return and event delivery (FRED) */ - #define CPUID_7_1_EAX_FRED (1U << 17) - /* Load into IA32_KERNEL_GS_BASE (LKGS) */ -@@ -1914,6 +1916,8 @@ typedef struct CPUArchState { - uint32_t cpuid_vendor3; - uint32_t cpuid_version; - FeatureWordArray features; -+ /* AVX10 version */ -+ uint8_t avx10_version; - /* Features that were explicitly enabled/disabled */ - FeatureWordArray user_features; - uint32_t cpuid_model[12]; -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 814f93da19..d0329a4ed7 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -1891,7 +1891,8 @@ static uint32_t kvm_x86_build_cpuid(CPUX86State *env, - case 0x7: - case 0x14: - case 0x1d: -- case 0x1e: { -+ case 0x1e: -+ case 0x24: { - uint32_t times; - - c->function = i; --- -2.39.3 - diff --git a/kvm-target-i386-add-CPUID.24-features-for-AVX10.patch b/kvm-target-i386-add-CPUID.24-features-for-AVX10.patch deleted file mode 100644 index 36a0aff..0000000 --- a/kvm-target-i386-add-CPUID.24-features-for-AVX10.patch +++ /dev/null @@ -1,91 +0,0 @@ -From cfb4964556facf1cb4500f0e3a754e4e20c13aed Mon Sep 17 00:00:00 2001 -From: Tao Su -Date: Thu, 31 Oct 2024 16:52:30 +0800 -Subject: [PATCH 34/38] target/i386: add CPUID.24 features for AVX10 - -RH-Author: Paolo Bonzini -RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets -RH-Jira: RHEL-30315 RHEL-45110 -RH-Acked-by: Vitaly Kuznetsov -RH-Acked-by: Miroslav Rezanina -RH-Commit: [5/9] a8b6f9edc330b412fbd27eece2f4961f4f876e5b (bonzini/rhel-qemu-kvm) - -Introduce features for the supported vector bit lengths. - -Signed-off-by: Tao Su -Link: https://lore.kernel.org/r/20241028024512.156724-3-tao1.su@linux.intel.com -Link: https://lore.kernel.org/r/20241028024512.156724-4-tao1.su@linux.intel.com -Signed-off-by: Paolo Bonzini -Reviewed-by: Zhao Liu -Tested-by: Xuelian Guo -Link: https://lore.kernel.org/r/20241031085233.425388-6-tao1.su@linux.intel.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit 2d055b8fe11ee567c2ae8047311fd83697e494b6) -Signed-off-by: Paolo Bonzini ---- - target/i386/cpu.c | 15 +++++++++++++++ - target/i386/cpu.h | 8 ++++++++ - 2 files changed, 23 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index a2e1a18537..958cbff54d 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -902,6 +902,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, - #define TCG_SGX_12_0_EAX_FEATURES 0 - #define TCG_SGX_12_0_EBX_FEATURES 0 - #define TCG_SGX_12_1_EAX_FEATURES 0 -+#define TCG_24_0_EBX_FEATURES 0 - - #if defined CONFIG_USER_ONLY - #define CPUID_8000_0008_EBX_KERNEL_FEATURES (CPUID_8000_0008_EBX_IBPB | \ -@@ -1167,6 +1168,20 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - }, - .tcg_features = TCG_7_2_EDX_FEATURES, - }, -+ [FEAT_24_0_EBX] = { -+ .type = CPUID_FEATURE_WORD, -+ .feat_names = { -+ [16] = "avx10-128", -+ [17] = "avx10-256", -+ [18] = "avx10-512", -+ }, -+ .cpuid = { -+ .eax = 0x24, -+ .needs_ecx = true, .ecx = 0, -+ .reg = R_EBX, -+ }, -+ .tcg_features = TCG_24_0_EBX_FEATURES, -+ }, - [FEAT_8000_0007_EDX] = { - .type = CPUID_FEATURE_WORD, - .feat_names = { -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 591113349d..c60290b8d5 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -666,6 +666,7 @@ typedef enum FeatureWord { - FEAT_XSAVE_XSS_HI, /* CPUID[EAX=0xd,ECX=1].EDX */ - FEAT_7_1_EDX, /* CPUID[EAX=7,ECX=1].EDX */ - FEAT_7_2_EDX, /* CPUID[EAX=7,ECX=2].EDX */ -+ FEAT_24_0_EBX, /* CPUID[EAX=0x24,ECX=0].EBX */ - FEATURE_WORDS, - } FeatureWord; - -@@ -990,6 +991,13 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); - /* Packets which contain IP payload have LIP values */ - #define CPUID_14_0_ECX_LIP (1U << 31) - -+/* AVX10 128-bit vector support is present */ -+#define CPUID_24_0_EBX_AVX10_128 (1U << 16) -+/* AVX10 256-bit vector support is present */ -+#define CPUID_24_0_EBX_AVX10_256 (1U << 17) -+/* AVX10 512-bit vector support is present */ -+#define CPUID_24_0_EBX_AVX10_512 (1U << 18) -+ - /* RAS Features */ - #define CPUID_8000_0007_EBX_OVERFLOW_RECOV (1U << 0) - #define CPUID_8000_0007_EBX_SUCCOR (1U << 1) --- -2.39.3 - diff --git a/kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch b/kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch deleted file mode 100644 index 7f6c82a..0000000 --- a/kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch +++ /dev/null @@ -1,43 +0,0 @@ -From d457fd42e0752855d8370bac1cf3c07cd1fc46a3 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Wed, 3 Jul 2024 13:42:49 +0200 -Subject: [PATCH 38/38] target/i386: add sha512, sm3, sm4 feature bits - -RH-Author: Paolo Bonzini -RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets -RH-Jira: RHEL-30315 RHEL-45110 -RH-Acked-by: Vitaly Kuznetsov -RH-Acked-by: Miroslav Rezanina -RH-Commit: [9/9] 80a6ce9fe3b7225f74a2822ce263d539148cda56 (bonzini/rhel-qemu-kvm) - -Status: queued for QEMU 10.0 - -SHA512, SM3, SM4 (CPUID[EAX=7,ECX=1).EAX bits 0 to 2) is supported by -Clearwater Forest processor, add it to QEMU as it does not need any -specific enablement. - -See https://lore.kernel.org/kvm/20241105054825.870939-1-tao1.su@linux.intel.com/ -for reference. - -Reviewed-by: Tao Su -Signed-off-by: Paolo Bonzini ---- - target/i386/cpu.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index e7367cfe82..ff063a9a50 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -1114,7 +1114,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - [FEAT_7_1_EAX] = { - .type = CPUID_FEATURE_WORD, - .feat_names = { -- NULL, NULL, NULL, NULL, -+ "sha512", "sm3", "sm4", NULL, - "avx-vnni", "avx512-bf16", NULL, "cmpccxadd", - NULL, NULL, "fzrm", "fsrs", - "fsrc", NULL, NULL, NULL, --- -2.39.3 - diff --git a/kvm-target-i386-allow-reordering-max_x86_cpu_initfn-vs-a.patch b/kvm-target-i386-allow-reordering-max_x86_cpu_initfn-vs-a.patch new file mode 100644 index 0000000..9125dd9 --- /dev/null +++ b/kvm-target-i386-allow-reordering-max_x86_cpu_initfn-vs-a.patch @@ -0,0 +1,76 @@ +From 716a7480e0e8d122fdad1172dcdaf76a465f7fdb Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:49 +0200 +Subject: [PATCH 081/100] target/i386: allow reordering max_x86_cpu_initfn vs + accel CPU init + +The PMU feature is only supported by KVM, so move it there. And since +all accelerators other than TCG overwrite the vendor, set it in +max_x86_cpu_initfn only if it has not been initialized by the +superclass. This makes it possible to run max_x86_cpu_initfn +after accelerator init. + +Reviewed-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Signed-off-by: Paolo Bonzini +(cherry picked from commit 810fcc41fc572d90b3c05af3f06f451626ee6b10) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 24 ++++++++++++------------ + target/i386/kvm/kvm-cpu.c | 2 ++ + 2 files changed, 14 insertions(+), 12 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 9669f4cd98..2ccfd4a803 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -6167,21 +6167,21 @@ static void max_x86_cpu_class_init(ObjectClass *oc, void *data) + static void max_x86_cpu_initfn(Object *obj) + { + X86CPU *cpu = X86_CPU(obj); +- +- /* We can't fill the features array here because we don't know yet if +- * "migratable" is true or false. +- */ +- object_property_set_bool(OBJECT(cpu), "pmu", true, &error_abort); ++ CPUX86State *env = &cpu->env; + + /* +- * these defaults are used for TCG and all other accelerators +- * besides KVM and HVF, which overwrite these values ++ * these defaults are used for TCG, other accelerators overwrite these ++ * values + */ +- object_property_set_str(OBJECT(cpu), "vendor", CPUID_VENDOR_AMD, +- &error_abort); +- object_property_set_str(OBJECT(cpu), "model-id", +- "QEMU TCG CPU version " QEMU_HW_VERSION, +- &error_abort); ++ if (!env->cpuid_vendor1) { ++ object_property_set_str(OBJECT(cpu), "vendor", CPUID_VENDOR_AMD, ++ &error_abort); ++ } ++ if (!env->cpuid_model[0]) { ++ object_property_set_str(OBJECT(cpu), "model-id", ++ "QEMU TCG CPU version " QEMU_HW_VERSION, ++ &error_abort); ++ } + } + + static const TypeInfo max_x86_cpu_type_info = { +diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c +index 80541acc39..34e61bb4cd 100644 +--- a/target/i386/kvm/kvm-cpu.c ++++ b/target/i386/kvm/kvm-cpu.c +@@ -111,6 +111,8 @@ static void kvm_cpu_max_instance_init(X86CPU *cpu) + + host_cpu_max_instance_init(cpu); + ++ object_property_set_bool(OBJECT(cpu), "pmu", true, &error_abort); ++ + if (lmce_supported()) { + object_property_set_bool(OBJECT(cpu), "lmce", true, &error_abort); + } +-- +2.47.3 + diff --git a/kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch b/kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch deleted file mode 100644 index c385b88..0000000 --- a/kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 2424960a48dfa6bb499c4cb798b0e5c256deba10 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Thu, 31 Oct 2024 16:52:26 +0800 -Subject: [PATCH 30/38] target/i386: cpu: set correct supported XCR0 features - for TCG - -RH-Author: Paolo Bonzini -RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets -RH-Jira: RHEL-30315 RHEL-45110 -RH-Acked-by: Vitaly Kuznetsov -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/9] 0516319354addebf36f9d364fbae5cda7a98473b (bonzini/rhel-qemu-kvm) - -Signed-off-by: Paolo Bonzini -Reviewed-by: Zhao Liu -Link: https://lore.kernel.org/r/20241031085233.425388-2-tao1.su@linux.intel.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit 33098002a838a0450f243f5e17463aca700e923d) -Signed-off-by: Paolo Bonzini ---- - target/i386/cpu.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 34e0ce5e62..dbdab0f821 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -1297,7 +1297,9 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - .needs_ecx = true, .ecx = 0, - .reg = R_EAX, - }, -- .tcg_features = ~0U, -+ .tcg_features = XSTATE_FP_MASK | XSTATE_SSE_MASK | -+ XSTATE_YMM_MASK | XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK | -+ XSTATE_PKRU_MASK, - .migratable_flags = XSTATE_FP_MASK | XSTATE_SSE_MASK | - XSTATE_YMM_MASK | XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK | - XSTATE_OPMASK_MASK | XSTATE_ZMM_Hi256_MASK | XSTATE_Hi16_ZMM_MASK | -@@ -1310,7 +1312,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - .needs_ecx = true, .ecx = 0, - .reg = R_EDX, - }, -- .tcg_features = ~0U, -+ .tcg_features = 0U, - }, - /*Below are MSR exposed features*/ - [FEAT_ARCH_CAPABILITIES] = { --- -2.39.3 - diff --git a/kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch b/kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch deleted file mode 100644 index 73353ea..0000000 --- a/kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 6df46774aa41872a706f1a535d5c547a8ef73556 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Thu, 31 Oct 2024 16:52:27 +0800 -Subject: [PATCH 31/38] target/i386: do not rely on ExtSaveArea for - accelerator-supported XCR0 bits - -RH-Author: Paolo Bonzini -RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets -RH-Jira: RHEL-30315 RHEL-45110 -RH-Acked-by: Vitaly Kuznetsov -RH-Acked-by: Miroslav Rezanina -RH-Commit: [2/9] 70d54c2101fd1d30a891a414a8c50566c2ddef67 (bonzini/rhel-qemu-kvm) - -Right now, QEMU is using the "feature" and "bits" fields of ExtSaveArea -to query the accelerator for the support status of extended save areas. -This is a problem for AVX10, which attaches two feature bits (AVX512F -and AVX10) to the same extended save states. - -To keep the AVX10 hacks to the minimum, limit usage of esa->features -and esa->bits. Instead, just query the accelerator for the 0xD leaf. -Do it in common code and clear esa->size if an extended save state is -unsupported. - -Signed-off-by: Paolo Bonzini -Reviewed-by: Zhao Liu -Link: https://lore.kernel.org/r/20241031085233.425388-3-tao1.su@linux.intel.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit b888c7807049cc044d10d70139cb945202fb7cd2) -Signed-off-by: Paolo Bonzini ---- - target/i386/cpu.c | 33 +++++++++++++++++++++++++++++++-- - target/i386/kvm/kvm-cpu.c | 4 ---- - 2 files changed, 31 insertions(+), 6 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index dbdab0f821..d23f15e99a 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -7086,6 +7086,15 @@ static void x86_cpu_set_sgxlepubkeyhash(CPUX86State *env) - #endif - } - -+static bool cpuid_has_xsave_feature(CPUX86State *env, const ExtSaveArea *esa) -+{ -+ if (!esa->size) { -+ return false; -+ } -+ -+ return (env->features[esa->feature] & esa->bits); -+} -+ - static void x86_cpu_reset_hold(Object *obj, ResetType type) - { - CPUState *cs = CPU(obj); -@@ -7194,7 +7203,7 @@ static void x86_cpu_reset_hold(Object *obj, ResetType type) - if (!((1 << i) & CPUID_XSTATE_XCR0_MASK)) { - continue; - } -- if (env->features[esa->feature] & esa->bits) { -+ if (cpuid_has_xsave_feature(env, esa)) { - xcr0 |= 1ull << i; - } - } -@@ -7332,7 +7341,7 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu) - mask = 0; - for (i = 0; i < ARRAY_SIZE(x86_ext_save_areas); i++) { - const ExtSaveArea *esa = &x86_ext_save_areas[i]; -- if (env->features[esa->feature] & esa->bits) { -+ if (cpuid_has_xsave_feature(env, esa)) { - mask |= (1ULL << i); - } - } -@@ -8003,6 +8012,26 @@ static void x86_cpu_register_feature_bit_props(X86CPUClass *xcc, - - static void x86_cpu_post_initfn(Object *obj) - { -+ static bool first = true; -+ uint64_t supported_xcr0; -+ int i; -+ -+ if (first) { -+ first = false; -+ -+ supported_xcr0 = -+ ((uint64_t) x86_cpu_get_supported_feature_word(NULL, FEAT_XSAVE_XCR0_HI) << 32) | -+ x86_cpu_get_supported_feature_word(NULL, FEAT_XSAVE_XCR0_LO); -+ -+ for (i = XSTATE_SSE_BIT + 1; i < XSAVE_STATE_AREA_COUNT; i++) { -+ ExtSaveArea *esa = &x86_ext_save_areas[i]; -+ -+ if (!(supported_xcr0 & (1 << i))) { -+ esa->size = 0; -+ } -+ } -+ } -+ - accel_cpu_instance_init(CPU(obj)); - } - -diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c -index 684e731cbc..961b87e98e 100644 ---- a/target/i386/kvm/kvm-cpu.c -+++ b/target/i386/kvm/kvm-cpu.c -@@ -143,10 +143,6 @@ static void kvm_cpu_xsave_init(void) - if (!esa->size) { - continue; - } -- if ((x86_cpu_get_supported_feature_word(NULL, esa->feature) & esa->bits) -- != esa->bits) { -- continue; -- } - host_cpuid(0xd, i, &eax, &ebx, &ecx, &edx); - if (eax != 0) { - assert(esa->size == eax); --- -2.39.3 - diff --git a/kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch b/kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch deleted file mode 100644 index ceff6b7..0000000 --- a/kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 6bae9faff44415edf51bb7f919fc816f8fe3cd12 Mon Sep 17 00:00:00 2001 -From: Julia Suvorova -Date: Fri, 27 Sep 2024 12:47:41 +0200 -Subject: [PATCH 29/38] target/i386/kvm: Report which action failed in - kvm_arch_put/get_registers - -RH-Author: Julia Suvorova -RH-MergeRequest: 287: kvm: Allow kvm_arch_get/put_registers to accept Error** -RH-Jira: RHEL-20574 -RH-Acked-by: Juraj Marcin -RH-Acked-by: Peter Xu -RH-Commit: [2/2] 1e430500be009393846a19451472b3d1031c1283 - -To help debug and triage future failure reports (akin to [1,2]) that -may occur during kvm_arch_put/get_registers, the error path of each -action is accompanied by unique error message. - -[1] https://issues.redhat.com/browse/RHEL-7558 -[2] https://issues.redhat.com/browse/RHEL-21761 - -Signed-off-by: Julia Suvorova -Reviewed-by: Peter Xu -Link: https://lore.kernel.org/r/20240927104743.218468-3-jusual@redhat.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit fc058618d1596d29e89016750a1aaf64c9fe8832) ---- - target/i386/kvm/kvm.c | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 423e6922d8..814f93da19 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -5136,6 +5136,7 @@ int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp) - if (level >= KVM_PUT_RESET_STATE) { - ret = kvm_put_msr_feature_control(x86_cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to set feature control MSR"); - return ret; - } - } -@@ -5143,12 +5144,14 @@ int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp) - /* must be before kvm_put_nested_state so that EFER.SVME is set */ - ret = has_sregs2 ? kvm_put_sregs2(x86_cpu) : kvm_put_sregs(x86_cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to set special registers"); - return ret; - } - - if (level >= KVM_PUT_RESET_STATE) { - ret = kvm_put_nested_state(x86_cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to set nested state"); - return ret; - } - } -@@ -5166,6 +5169,7 @@ int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp) - if (xen_mode == XEN_EMULATE && level == KVM_PUT_FULL_STATE) { - ret = kvm_put_xen_state(cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to set Xen state"); - return ret; - } - } -@@ -5173,37 +5177,45 @@ int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp) - - ret = kvm_getput_regs(x86_cpu, 1); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to set general purpose registers"); - return ret; - } - ret = kvm_put_xsave(x86_cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to set XSAVE"); - return ret; - } - ret = kvm_put_xcrs(x86_cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to set XCRs"); - return ret; - } - ret = kvm_put_msrs(x86_cpu, level); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to set MSRs"); - return ret; - } - ret = kvm_put_vcpu_events(x86_cpu, level); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to set vCPU events"); - return ret; - } - if (level >= KVM_PUT_RESET_STATE) { - ret = kvm_put_mp_state(x86_cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to set MP state"); - return ret; - } - } - - ret = kvm_put_tscdeadline_msr(x86_cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to set TSC deadline MSR"); - return ret; - } - ret = kvm_put_debugregs(x86_cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to set debug registers"); - return ret; - } - return 0; -@@ -5218,6 +5230,7 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp) - - ret = kvm_get_vcpu_events(cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to get vCPU events"); - goto out; - } - /* -@@ -5226,44 +5239,54 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp) - */ - ret = kvm_get_mp_state(cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to get MP state"); - goto out; - } - ret = kvm_getput_regs(cpu, 0); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to get general purpose registers"); - goto out; - } - ret = kvm_get_xsave(cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to get XSAVE"); - goto out; - } - ret = kvm_get_xcrs(cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to get XCRs"); - goto out; - } - ret = has_sregs2 ? kvm_get_sregs2(cpu) : kvm_get_sregs(cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to get special registers"); - goto out; - } - ret = kvm_get_msrs(cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to get MSRs"); - goto out; - } - ret = kvm_get_apic(cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to get APIC"); - goto out; - } - ret = kvm_get_debugregs(cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to get debug registers"); - goto out; - } - ret = kvm_get_nested_state(cpu); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to get nested state"); - goto out; - } - #ifdef CONFIG_XEN_EMU - if (xen_mode == XEN_EMULATE) { - ret = kvm_get_xen_state(cs); - if (ret < 0) { -+ error_setg_errno(errp, -ret, "Failed to get Xen state"); - goto out; - } - } --- -2.39.3 - diff --git a/kvm-target-i386-merge-host_cpu_instance_init-and-host_cp.patch b/kvm-target-i386-merge-host_cpu_instance_init-and-host_cp.patch new file mode 100644 index 0000000..a65c9e1 --- /dev/null +++ b/kvm-target-i386-merge-host_cpu_instance_init-and-host_cp.patch @@ -0,0 +1,95 @@ +From d7dbe00c128a6037a5536bd5f81663e9f79285a9 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:49 +0200 +Subject: [PATCH 083/100] target/i386: merge host_cpu_instance_init() and + host_cpu_max_instance_init() + +Simplify the accelerators' cpu_instance_init callbacks by doing all +host-cpu setup in a single function. + +Based-on: <20250711000603.438312-1-pbonzini@redhat.com> +Cc: Xiaoyao Li +Signed-off-by: Paolo Bonzini +(cherry picked from commit 29f1ba338baf60a9e455b6fdc37489ca1efe25aa) +Signed-off-by: Paolo Bonzini +--- + target/i386/host-cpu.c | 28 ++++++++++++++-------------- + target/i386/hvf/hvf-cpu.c | 2 -- + target/i386/kvm/kvm-cpu.c | 2 -- + 3 files changed, 14 insertions(+), 18 deletions(-) + +diff --git a/target/i386/host-cpu.c b/target/i386/host-cpu.c +index a78be2e220..bba14e7704 100644 +--- a/target/i386/host-cpu.c ++++ b/target/i386/host-cpu.c +@@ -132,27 +132,27 @@ void host_cpu_instance_init(X86CPU *cpu) + { + X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu); + +- if (xcc->model) { +- char vendor[CPUID_VENDOR_SZ + 1]; +- +- host_cpu_vendor_fms(vendor, NULL, NULL, NULL); +- object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abort); +- } +-} +- +-void host_cpu_max_instance_init(X86CPU *cpu) +-{ + char vendor[CPUID_VENDOR_SZ + 1] = { 0 }; + char model_id[CPUID_MODEL_ID_SZ + 1] = { 0 }; + int family, model, stepping; + +- /* Use max host physical address bits if -cpu max option is applied */ +- object_property_set_bool(OBJECT(cpu), "host-phys-bits", true, &error_abort); +- ++ /* ++ * setting vendor applies to both max/host and builtin_x86_defs CPU. ++ * FIXME: this probably should warn or should be skipped if vendors do ++ * not match, because family numbers are incompatible between Intel and AMD. ++ */ + host_cpu_vendor_fms(vendor, &family, &model, &stepping); ++ object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abort); ++ ++ if (!xcc->max_features) { ++ return; ++ } ++ + host_cpu_fill_model_id(model_id); + +- object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abort); ++ /* Use max host physical address bits if -cpu max option is applied */ ++ object_property_set_bool(OBJECT(cpu), "host-phys-bits", true, &error_abort); ++ + object_property_set_int(OBJECT(cpu), "family", family, &error_abort); + object_property_set_int(OBJECT(cpu), "model", model, &error_abort); + object_property_set_int(OBJECT(cpu), "stepping", stepping, +diff --git a/target/i386/hvf/hvf-cpu.c b/target/i386/hvf/hvf-cpu.c +index 83dbd4b46a..6f94f18135 100644 +--- a/target/i386/hvf/hvf-cpu.c ++++ b/target/i386/hvf/hvf-cpu.c +@@ -21,8 +21,6 @@ static void hvf_cpu_max_instance_init(X86CPU *cpu) + { + CPUX86State *env = &cpu->env; + +- host_cpu_max_instance_init(cpu); +- + env->cpuid_min_level = + hvf_get_supported_cpuid(0x0, 0, R_EAX); + env->cpuid_min_xlevel = +diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c +index 34e61bb4cd..71944936ee 100644 +--- a/target/i386/kvm/kvm-cpu.c ++++ b/target/i386/kvm/kvm-cpu.c +@@ -109,8 +109,6 @@ static void kvm_cpu_max_instance_init(X86CPU *cpu) + CPUX86State *env = &cpu->env; + KVMState *s = kvm_state; + +- host_cpu_max_instance_init(cpu); +- + object_property_set_bool(OBJECT(cpu), "pmu", true, &error_abort); + + if (lmce_supported()) { +-- +2.47.3 + diff --git a/kvm-target-i386-move-accel_cpu_instance_init-to-.instanc.patch b/kvm-target-i386-move-accel_cpu_instance_init-to-.instanc.patch new file mode 100644 index 0000000..de3acf0 --- /dev/null +++ b/kvm-target-i386-move-accel_cpu_instance_init-to-.instanc.patch @@ -0,0 +1,60 @@ +From dc79ff0feab157aa2798da2a348eafd46385c268 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:49 +0200 +Subject: [PATCH 082/100] target/i386: move accel_cpu_instance_init to + .instance_init + +With the reordering of instance_post_init callbacks that is new in 10.1 +accel_cpu_instance_init must execute in .instance_init as is already +the case for RISC-V. Otherwise, for example, setting the vendor +property is broken when using KVM or Hypervisor.framework, because +KVM sets it *after* the user's value is set by DeviceState's +intance_post_init callback. + +Reported-by: Like Xu +Reported-by: Dongli Zhang +Reviewed-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Signed-off-by: Paolo Bonzini +(cherry picked from commit 5f158abef44c7e0945fc5f76715ef135a9bf9bd2) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 2ccfd4a803..8a8607591e 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -6170,8 +6170,8 @@ static void max_x86_cpu_initfn(Object *obj) + CPUX86State *env = &cpu->env; + + /* +- * these defaults are used for TCG, other accelerators overwrite these +- * values ++ * these defaults are used for TCG, other accelerators have overwritten ++ * these values + */ + if (!env->cpuid_vendor1) { + object_property_set_str(OBJECT(cpu), "vendor", CPUID_VENDOR_AMD, +@@ -8994,8 +8994,6 @@ static void x86_cpu_post_initfn(Object *obj) + } + } + +- accel_cpu_instance_init(CPU(obj)); +- + #ifndef CONFIG_USER_ONLY + if (current_machine && current_machine->cgs) { + x86_confidential_guest_cpu_instance_init( +@@ -9070,6 +9068,8 @@ static void x86_cpu_initfn(Object *obj) + if (xcc->model) { + x86_cpu_load_model(cpu, xcc->model); + } ++ ++ accel_cpu_instance_init(CPU(obj)); + } + + static int64_t x86_cpu_get_arch_id(CPUState *cs) +-- +2.47.3 + diff --git a/kvm-target-i386-move-max_features-to-class.patch b/kvm-target-i386-move-max_features-to-class.patch new file mode 100644 index 0000000..ca0b13a --- /dev/null +++ b/kvm-target-i386-move-max_features-to-class.patch @@ -0,0 +1,137 @@ +From 9c28945c9beb17f3ee10b524e5ac3930ed35abaa Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:49 +0200 +Subject: [PATCH 079/100] target/i386: move max_features to class + +max_features is always set to true for instances created by -cpu max or +-cpu host; it's always false for other classes. Therefore it can be +turned into a field in the X86CPUClass. + +Reviewed-by: Xiaoyao Li +Reviewed-by: Zhao Liu +Signed-off-by: Paolo Bonzini +(cherry picked from commit cb2273edf5df57cb270bc19d7e92d8be5870c17a) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 7 ++++--- + target/i386/cpu.h | 2 +- + target/i386/hvf/hvf-cpu.c | 3 ++- + target/i386/kvm/kvm-cpu.c | 5 +++-- + 4 files changed, 10 insertions(+), 7 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 7220181806..220926396b 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -6155,6 +6155,7 @@ static void max_x86_cpu_class_init(ObjectClass *oc, void *data) + + xcc->ordering = 9; + ++ xcc->max_features = true; + xcc->model_description = + "Enables all features supported by the accelerator in the current host"; + +@@ -6169,7 +6170,6 @@ static void max_x86_cpu_initfn(Object *obj) + /* We can't fill the features array here because we don't know yet if + * "migratable" is true or false. + */ +- cpu->max_features = true; + object_property_set_bool(OBJECT(cpu), "pmu", true, &error_abort); + + /* +@@ -8242,6 +8242,7 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu) + */ + void x86_cpu_expand_features(X86CPU *cpu, Error **errp) + { ++ X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu); + CPUX86State *env = &cpu->env; + FeatureWord w; + int i; +@@ -8261,12 +8262,12 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) + } + } + +- /*TODO: Now cpu->max_features doesn't overwrite features ++ /* TODO: Now xcc->max_features doesn't overwrite features + * set using QOM properties, and we can convert + * plus_features & minus_features to global properties + * inside x86_cpu_parse_featurestr() too. + */ +- if (cpu->max_features) { ++ if (xcc->max_features) { + for (w = 0; w < FEATURE_WORDS; w++) { + /* Override only features that weren't set explicitly + * by the user. +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 3038746425..761aa8889d 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -2209,7 +2209,6 @@ struct ArchCPU { + bool expose_tcg; + bool migratable; + bool migrate_smi_count; +- bool max_features; /* Enable all supported features automatically */ + uint32_t apic_id; + + /* Enables publishing of TSC increment and Local APIC bus frequencies to +@@ -2362,6 +2361,7 @@ struct X86CPUClass { + */ + const X86CPUModel *model; + ++ bool max_features; /* Enable all supported features automatically */ + bool host_cpuid_required; + int ordering; + bool migration_safe; +diff --git a/target/i386/hvf/hvf-cpu.c b/target/i386/hvf/hvf-cpu.c +index b5f4c80028..83dbd4b46a 100644 +--- a/target/i386/hvf/hvf-cpu.c ++++ b/target/i386/hvf/hvf-cpu.c +@@ -61,13 +61,14 @@ static void hvf_cpu_xsave_init(void) + static void hvf_cpu_instance_init(CPUState *cs) + { + X86CPU *cpu = X86_CPU(cs); ++ X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu); + + host_cpu_instance_init(cpu); + + /* Special cases not set in the X86CPUDefinition structs: */ + /* TODO: in-kernel irqchip for hvf */ + +- if (cpu->max_features) { ++ if (xcc->max_features) { + hvf_cpu_max_instance_init(cpu); + } + +diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c +index 8f455c24e9..80541acc39 100644 +--- a/target/i386/kvm/kvm-cpu.c ++++ b/target/i386/kvm/kvm-cpu.c +@@ -41,6 +41,7 @@ static void kvm_set_guest_phys_bits(CPUState *cs) + static bool kvm_cpu_realizefn(CPUState *cs, Error **errp) + { + X86CPU *cpu = X86_CPU(cs); ++ X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu); + CPUX86State *env = &cpu->env; + bool ret; + +@@ -63,7 +64,7 @@ static bool kvm_cpu_realizefn(CPUState *cs, Error **errp) + * check/update ucode_rev, phys_bits, guest_phys_bits, mwait + * cpu_common_realizefn() (via xcc->parent_realize) + */ +- if (cpu->max_features) { ++ if (xcc->max_features) { + if (enable_cpu_pm) { + if (kvm_has_waitpkg()) { + env->features[FEAT_7_0_ECX] |= CPUID_7_0_ECX_WAITPKG; +@@ -217,7 +218,7 @@ static void kvm_cpu_instance_init(CPUState *cs) + x86_cpu_apply_props(cpu, kvm_default_props); + } + +- if (cpu->max_features) { ++ if (xcc->max_features) { + kvm_cpu_max_instance_init(cpu); + } + +-- +2.47.3 + diff --git a/kvm-target-i386-nvmm-whpx-add-accel-CPU-class-that-sets-.patch b/kvm-target-i386-nvmm-whpx-add-accel-CPU-class-that-sets-.patch new file mode 100644 index 0000000..9f3bf50 --- /dev/null +++ b/kvm-target-i386-nvmm-whpx-add-accel-CPU-class-that-sets-.patch @@ -0,0 +1,154 @@ +From 467af02e07b1c6611612725e04f83b52b1454968 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Sat, 5 Jul 2025 14:17:30 +0200 +Subject: [PATCH 080/100] target/i386: nvmm, whpx: add accel/CPU class that + sets host vendor + +NVMM and WHPX are virtualizers, and therefore they need to use +(at least by default) the host vendor for the guest CPUID. +Add a cpu_instance_init implementation to these accelerators. + +Signed-off-by: Paolo Bonzini +(cherry picked from commit d93972d88b0984ed0a2090493f8d62cc188976d2) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 3 ++- + target/i386/meson.build | 2 ++ + target/i386/nvmm/nvmm-all.c | 25 +++++++++++++++++++++++++ + target/i386/whpx/whpx-all.c | 25 +++++++++++++++++++++++++ + 4 files changed, 54 insertions(+), 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 220926396b..9669f4cd98 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -43,6 +43,7 @@ + #include "hw/boards.h" + #include "hw/i386/sgx-epc.h" + #endif ++#include "system/qtest.h" + #include "tcg/tcg-cpu.h" + + #include "disas/capstone.h" +@@ -1905,7 +1906,7 @@ uint32_t xsave_area_size(uint64_t mask, bool compacted) + + static inline bool accel_uses_host_cpuid(void) + { +- return kvm_enabled() || hvf_enabled(); ++ return !tcg_enabled() && !qtest_enabled(); + } + + static inline uint64_t x86_cpu_xsave_xcr0_components(X86CPU *cpu) +diff --git a/target/i386/meson.build b/target/i386/meson.build +index 2e9c472f49..16dc8b7834 100644 +--- a/target/i386/meson.build ++++ b/target/i386/meson.build +@@ -11,6 +11,8 @@ i386_ss.add(when: 'CONFIG_SEV', if_true: files('host-cpu.c', 'confidential-guest + # x86 cpu type + i386_ss.add(when: 'CONFIG_KVM', if_true: files('host-cpu.c')) + i386_ss.add(when: 'CONFIG_HVF', if_true: files('host-cpu.c')) ++i386_ss.add(when: 'CONFIG_WHPX', if_true: files('host-cpu.c')) ++i386_ss.add(when: 'CONFIG_NVMM', if_true: files('host-cpu.c')) + + i386_system_ss = ss.source_set() + i386_system_ss.add(files( +diff --git a/target/i386/nvmm/nvmm-all.c b/target/i386/nvmm/nvmm-all.c +index 17394d073d..4695880b4a 100644 +--- a/target/i386/nvmm/nvmm-all.c ++++ b/target/i386/nvmm/nvmm-all.c +@@ -19,6 +19,8 @@ + #include "qemu/error-report.h" + #include "qapi/error.h" + #include "qemu/queue.h" ++#include "accel/accel-cpu-target.h" ++#include "host-cpu.h" + #include "migration/blocker.h" + #include "strings.h" + +@@ -1214,10 +1216,33 @@ static const TypeInfo nvmm_accel_type = { + .class_init = nvmm_accel_class_init, + }; + ++static void nvmm_cpu_instance_init(CPUState *cs) ++{ ++ X86CPU *cpu = X86_CPU(cs); ++ ++ host_cpu_instance_init(cpu); ++} ++ ++static void nvmm_cpu_accel_class_init(ObjectClass *oc, const void *data) ++{ ++ AccelCPUClass *acc = ACCEL_CPU_CLASS(oc); ++ ++ acc->cpu_instance_init = nvmm_cpu_instance_init; ++} ++ ++static const TypeInfo nvmm_cpu_accel_type = { ++ .name = ACCEL_CPU_NAME("nvmm"), ++ ++ .parent = TYPE_ACCEL_CPU, ++ .class_init = nvmm_cpu_accel_class_init, ++ .abstract = true, ++}; ++ + static void + nvmm_type_init(void) + { + type_register_static(&nvmm_accel_type); ++ type_register_static(&nvmm_cpu_accel_type); + } + + type_init(nvmm_type_init); +diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c +index b64852e13e..4802ea48cb 100644 +--- a/target/i386/whpx/whpx-all.c ++++ b/target/i386/whpx/whpx-all.c +@@ -26,6 +26,8 @@ + #include "qapi/qapi-types-common.h" + #include "qapi/qapi-visit-common.h" + #include "migration/blocker.h" ++#include "host-cpu.h" ++#include "accel/accel-cpu-target.h" + #include + + #include "whpx-internal.h" +@@ -2512,6 +2514,28 @@ static void whpx_set_kernel_irqchip(Object *obj, Visitor *v, + } + } + ++static void whpx_cpu_instance_init(CPUState *cs) ++{ ++ X86CPU *cpu = X86_CPU(cs); ++ ++ host_cpu_instance_init(cpu); ++} ++ ++static void whpx_cpu_accel_class_init(ObjectClass *oc, const void *data) ++{ ++ AccelCPUClass *acc = ACCEL_CPU_CLASS(oc); ++ ++ acc->cpu_instance_init = whpx_cpu_instance_init; ++} ++ ++static const TypeInfo whpx_cpu_accel_type = { ++ .name = ACCEL_CPU_NAME("whpx"), ++ ++ .parent = TYPE_ACCEL_CPU, ++ .class_init = whpx_cpu_accel_class_init, ++ .abstract = true, ++}; ++ + /* + * Partition support + */ +@@ -2742,6 +2766,7 @@ static const TypeInfo whpx_accel_type = { + static void whpx_type_init(void) + { + type_register_static(&whpx_accel_type); ++ type_register_static(&whpx_cpu_accel_type); + } + + bool init_whp_dispatch(void) +-- +2.47.3 + diff --git a/kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch b/kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch deleted file mode 100644 index e3defc5..0000000 --- a/kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch +++ /dev/null @@ -1,83 +0,0 @@ -From c4792fc23bf28618601514e3af5f331b4292bdf7 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Thu, 31 Oct 2024 16:52:28 +0800 -Subject: [PATCH 32/38] target/i386: return bool from x86_cpu_filter_features - -RH-Author: Paolo Bonzini -RH-MergeRequest: 280: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets -RH-Jira: RHEL-30315 RHEL-45110 -RH-Acked-by: Vitaly Kuznetsov -RH-Acked-by: Miroslav Rezanina -RH-Commit: [3/9] e5ae5d2050ad75411d8db6f9f9519bcaf88c4850 (bonzini/rhel-qemu-kvm) - -Prepare for filtering non-boolean features such as AVX10 version. - -Signed-off-by: Paolo Bonzini -Reviewed-by: Zhao Liu -Signed-off-by: Tao Su -Link: https://lore.kernel.org/r/20241031085233.425388-4-tao1.su@linux.intel.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit 3507c6f04606593711408a6d26141bdbceff9377) -Signed-off-by: Paolo Bonzini ---- - target/i386/cpu.c | 20 +++++++++++--------- - 1 file changed, 11 insertions(+), 9 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index d23f15e99a..353f50a1b9 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -5835,7 +5835,7 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features, - } - } - --static void x86_cpu_filter_features(X86CPU *cpu, bool verbose); -+static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose); - - /* Build a list with the name of all features on a feature word array */ - static void x86_cpu_list_feature_names(FeatureWordArray features, -@@ -7540,9 +7540,9 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) - * Finishes initialization of CPUID data, filters CPU feature - * words based on host availability of each feature. - * -- * Returns: 0 if all flags are supported by the host, non-zero otherwise. -+ * Returns: true if any flag is not supported by the host, false otherwise. - */ --static void x86_cpu_filter_features(X86CPU *cpu, bool verbose) -+static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose) - { - CPUX86State *env = &cpu->env; - FeatureWord w; -@@ -7594,6 +7594,8 @@ static void x86_cpu_filter_features(X86CPU *cpu, bool verbose) - mark_unavailable_features(cpu, FEAT_7_0_EBX, CPUID_7_0_EBX_INTEL_PT, prefix); - } - } -+ -+ return x86_cpu_have_filtered_features(cpu); - } - - static void x86_cpu_hyperv_realize(X86CPU *cpu) -@@ -7691,14 +7693,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) - } - } - -- x86_cpu_filter_features(cpu, cpu->check_cpuid || cpu->enforce_cpuid); -- -- if (cpu->enforce_cpuid && x86_cpu_have_filtered_features(cpu)) { -- error_setg(&local_err, -- accel_uses_host_cpuid() ? -+ if (x86_cpu_filter_features(cpu, cpu->check_cpuid || cpu->enforce_cpuid)) { -+ if (cpu->enforce_cpuid) { -+ error_setg(&local_err, -+ accel_uses_host_cpuid() ? - "Host doesn't support requested features" : - "TCG doesn't support requested features"); -- goto out; -+ goto out; -+ } - } - - /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on --- -2.39.3 - diff --git a/kvm-target-i386-tdx-fix-locking-for-interrupt-injection.patch b/kvm-target-i386-tdx-fix-locking-for-interrupt-injection.patch new file mode 100644 index 0000000..ad8d9bc --- /dev/null +++ b/kvm-target-i386-tdx-fix-locking-for-interrupt-injection.patch @@ -0,0 +1,54 @@ +From db5837476ede86f5660a3f337650c8cdfaf56478 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:50 +0200 +Subject: [PATCH 091/100] target/i386: tdx: fix locking for interrupt injection + +Take tdx_guest->lock when injecting the event notification interrupt into +the guest. + +Fixes CID 1612364. + +Reported-by: Peter Maydell +Cc: Xiaoyao Li +Reviewed-by: Xiaoyao Li +Signed-off-by: Paolo Bonzini +(cherry picked from commit f2b787976342a9e1d47810f3146ad74b86a5088a) +Signed-off-by: Paolo Bonzini +--- + target/i386/kvm/tdx.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c +index aad56f600d..b8084758cb 100644 +--- a/target/i386/kvm/tdx.c ++++ b/target/i386/kvm/tdx.c +@@ -1126,10 +1126,15 @@ int tdx_parse_tdvf(void *flash_ptr, int size) + return tdvf_parse_metadata(&tdx_guest->tdvf, flash_ptr, size); + } + +-static void tdx_inject_interrupt(uint32_t apicid, uint32_t vector) ++static void tdx_inject_interrupt(TdxGuest *tdx) + { + int ret; ++ uint32_t apicid, vector; + ++ qemu_mutex_lock(&tdx->lock); ++ vector = tdx->event_notify_vector; ++ apicid = tdx->event_notify_apicid; ++ qemu_mutex_unlock(&tdx->lock); + if (vector < 32 || vector > 255) { + return; + } +@@ -1179,8 +1184,7 @@ static void tdx_get_quote_completion(TdxGenerateQuoteTask *task) + error_report("TDX: get-quote: failed to update GetQuote header."); + } + +- tdx_inject_interrupt(tdx_guest->event_notify_apicid, +- tdx_guest->event_notify_vector); ++ tdx_inject_interrupt(tdx); + + g_free(task->send_data); + g_free(task->receive_buf); +-- +2.47.3 + diff --git a/kvm-tests-Add-iotest-mirror-sparse-for-recent-patches.patch b/kvm-tests-Add-iotest-mirror-sparse-for-recent-patches.patch new file mode 100644 index 0000000..70ab894 --- /dev/null +++ b/kvm-tests-Add-iotest-mirror-sparse-for-recent-patches.patch @@ -0,0 +1,545 @@ +From 2bb881df5b93f5534e5f0b91cf1ed3e0b524c2d3 Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Fri, 9 May 2025 15:40:30 -0500 +Subject: [PATCH 13/14] tests: Add iotest mirror-sparse for recent patches + +RH-Author: Eric Blake +RH-MergeRequest: 363: blockdev-mirror: More efficient handling of sparse mirrors +RH-Jira: RHEL-88435 RHEL-88437 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +RH-Commit: [13/14] 474f12dfe9161c7e9f59cafde203e5183e2fc3f5 (ebblake/centos-qemu-kvm) + +Prove that blockdev-mirror can now result in sparse raw destination +files, regardless of whether the source is raw or qcow2. By making +this a separate test, it was possible to test effects of individual +patches for the various pieces that all have to work together for a +sparse mirror to be successful. + +Note that ./check -file produces different job lengths than ./check +-qcow2 (the test uses a filter to normalize); that's because when +deciding how much of the image to be mirrored, the code looks at how +much of the source image was allocated (for qcow2, this is only the +written clusters; for raw, it is the entire file). But the important +part is that the destination file ends up smaller than 3M, rather than +the 20M it used to be before this patch series. + +Signed-off-by: Eric Blake +Message-ID: <20250509204341.3553601-28-eblake@redhat.com> +Reviewed-by: Stefan Hajnoczi +(cherry picked from commit c0ddcb2cbc146e64f666eaae4edc7b5db7e5814d) +Jira: https://issues.redhat.com/browse/RHEL-88435 +Jira: https://issues.redhat.com/browse/RHEL-88437 +Signed-off-by: Eric Blake +--- + tests/qemu-iotests/tests/mirror-sparse | 125 +++++++ + tests/qemu-iotests/tests/mirror-sparse.out | 365 +++++++++++++++++++++ + 2 files changed, 490 insertions(+) + create mode 100755 tests/qemu-iotests/tests/mirror-sparse + create mode 100644 tests/qemu-iotests/tests/mirror-sparse.out + +diff --git a/tests/qemu-iotests/tests/mirror-sparse b/tests/qemu-iotests/tests/mirror-sparse +new file mode 100755 +index 0000000000..8c52a4e244 +--- /dev/null ++++ b/tests/qemu-iotests/tests/mirror-sparse +@@ -0,0 +1,125 @@ ++#!/usr/bin/env bash ++# group: rw auto quick ++# ++# Test blockdev-mirror with raw sparse destination ++# ++# Copyright (C) 2025 Red Hat, Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# ++ ++seq="$(basename $0)" ++echo "QA output created by $seq" ++ ++status=1 # failure is the default! ++ ++_cleanup() ++{ ++ _cleanup_test_img ++ _cleanup_qemu ++} ++trap "_cleanup; exit \$status" 0 1 2 3 15 ++ ++# get standard environment, filters and checks ++cd .. ++. ./common.rc ++. ./common.filter ++. ./common.qemu ++ ++_supported_fmt qcow2 raw # Format of the source. dst is always raw file ++_supported_proto file ++_supported_os Linux ++ ++echo ++echo "=== Initial image setup ===" ++echo ++ ++TEST_IMG="$TEST_IMG.base" _make_test_img 20M ++$QEMU_IO -c 'w 8M 2M' -f $IMGFMT "$TEST_IMG.base" | _filter_qemu_io ++ ++_launch_qemu \ ++ -blockdev '{"driver":"file", "cache":{"direct":true, "no-flush":false}, ++ "filename":"'"$TEST_IMG.base"'", "node-name":"src-file"}' \ ++ -blockdev '{"driver":"'$IMGFMT'", "node-name":"src", "file":"src-file"}' ++h1=$QEMU_HANDLE ++_send_qemu_cmd $h1 '{"execute": "qmp_capabilities"}' 'return' ++ ++# Check several combinations; most should result in a sparse destination; ++# the destination should only be fully allocated if pre-allocated ++# and not punching holes due to detect-zeroes ++# do_test creation discard zeroes result ++do_test() { ++ creation=$1 ++ discard=$2 ++ zeroes=$3 ++ expected=$4 ++ ++echo ++echo "=== Testing creation=$creation discard=$discard zeroes=$zeroes ===" ++echo ++ ++rm -f $TEST_IMG ++if test $creation = external; then ++ truncate --size=20M $TEST_IMG ++else ++ _send_qemu_cmd $h1 '{"execute": "blockdev-create", "arguments": ++ {"options": {"driver":"file", "filename":"'$TEST_IMG'", ++ "size":'$((20*1024*1024))', "preallocation":"'$creation'"}, ++ "job-id":"job1"}}' 'concluded' ++ _send_qemu_cmd $h1 '{"execute": "job-dismiss", "arguments": ++ {"id": "job1"}}' 'return' ++fi ++_send_qemu_cmd $h1 '{"execute": "blockdev-add", "arguments": ++ {"node-name": "dst", "driver":"file", ++ "filename":"'$TEST_IMG'", "aio":"threads", ++ "auto-read-only":true, "discard":"'$discard'", ++ "detect-zeroes":"'$zeroes'"}}' 'return' ++_send_qemu_cmd $h1 '{"execute":"blockdev-mirror", "arguments": ++ {"sync":"full", "device":"src", "target":"dst", ++ "job-id":"job2"}}' 'return' ++_timed_wait_for $h1 '"ready"' ++_send_qemu_cmd $h1 '{"execute": "job-complete", "arguments": ++ {"id":"job2"}}' 'return' \ ++ | _filter_block_job_offset | _filter_block_job_len ++_send_qemu_cmd $h1 '{"execute": "blockdev-del", "arguments": ++ {"node-name": "dst"}}' 'return' \ ++ | _filter_block_job_offset | _filter_block_job_len ++$QEMU_IMG compare -U -f $IMGFMT -F raw $TEST_IMG.base $TEST_IMG ++result=$(disk_usage $TEST_IMG) ++if test $result -lt $((3*1024*1024)); then ++ actual=sparse ++elif test $result = $((20*1024*1024)); then ++ actual=full ++else ++ actual=unknown ++fi ++echo "Destination is $actual; expected $expected" ++} ++ ++do_test external ignore off sparse ++do_test external unmap off sparse ++do_test external unmap unmap sparse ++do_test off ignore off sparse ++do_test off unmap off sparse ++do_test off unmap unmap sparse ++do_test full ignore off full ++do_test full unmap off sparse ++do_test full unmap unmap sparse ++ ++_send_qemu_cmd $h1 '{"execute":"quit"}' '' ++ ++# success, all done ++echo '*** done' ++rm -f $seq.full ++status=0 +diff --git a/tests/qemu-iotests/tests/mirror-sparse.out b/tests/qemu-iotests/tests/mirror-sparse.out +new file mode 100644 +index 0000000000..2103b891c3 +--- /dev/null ++++ b/tests/qemu-iotests/tests/mirror-sparse.out +@@ -0,0 +1,365 @@ ++QA output created by mirror-sparse ++ ++=== Initial image setup === ++ ++Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=20971520 ++wrote 2097152/2097152 bytes at offset 8388608 ++2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ++{"execute": "qmp_capabilities"} ++{"return": {}} ++ ++=== Testing creation=external discard=ignore zeroes=off === ++ ++{"execute": "blockdev-add", "arguments": ++ {"node-name": "dst", "driver":"file", ++ "filename":"TEST_DIR/t.IMGFMT", "aio":"threads", ++ "auto-read-only":true, "discard":"ignore", ++ "detect-zeroes":"off"}} ++{"return": {}} ++{"execute":"blockdev-mirror", "arguments": ++ {"sync":"full", "device":"src", "target":"dst", ++ "job-id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job2"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job2"}} ++{"execute": "job-complete", "arguments": ++ {"id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"return": {}} ++{"execute": "blockdev-del", "arguments": ++ {"node-name": "dst"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job2"}} ++{"return": {}} ++Images are identical. ++Destination is sparse; expected sparse ++ ++=== Testing creation=external discard=unmap zeroes=off === ++ ++{"execute": "blockdev-add", "arguments": ++ {"node-name": "dst", "driver":"file", ++ "filename":"TEST_DIR/t.IMGFMT", "aio":"threads", ++ "auto-read-only":true, "discard":"unmap", ++ "detect-zeroes":"off"}} ++{"return": {}} ++{"execute":"blockdev-mirror", "arguments": ++ {"sync":"full", "device":"src", "target":"dst", ++ "job-id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job2"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job2"}} ++{"execute": "job-complete", "arguments": ++ {"id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"return": {}} ++{"execute": "blockdev-del", "arguments": ++ {"node-name": "dst"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job2"}} ++{"return": {}} ++Images are identical. ++Destination is sparse; expected sparse ++ ++=== Testing creation=external discard=unmap zeroes=unmap === ++ ++{"execute": "blockdev-add", "arguments": ++ {"node-name": "dst", "driver":"file", ++ "filename":"TEST_DIR/t.IMGFMT", "aio":"threads", ++ "auto-read-only":true, "discard":"unmap", ++ "detect-zeroes":"unmap"}} ++{"return": {}} ++{"execute":"blockdev-mirror", "arguments": ++ {"sync":"full", "device":"src", "target":"dst", ++ "job-id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job2"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job2"}} ++{"execute": "job-complete", "arguments": ++ {"id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"return": {}} ++{"execute": "blockdev-del", "arguments": ++ {"node-name": "dst"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job2"}} ++{"return": {}} ++Images are identical. ++Destination is sparse; expected sparse ++ ++=== Testing creation=off discard=ignore zeroes=off === ++ ++{"execute": "blockdev-create", "arguments": ++ {"options": {"driver":"file", "filename":"TEST_DIR/t.IMGFMT", ++ "size":20971520, "preallocation":"off"}, ++ "job-id":"job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job1"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job1"}} ++{"execute": "job-dismiss", "arguments": ++ {"id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job1"}} ++{"return": {}} ++{"execute": "blockdev-add", "arguments": ++ {"node-name": "dst", "driver":"file", ++ "filename":"TEST_DIR/t.IMGFMT", "aio":"threads", ++ "auto-read-only":true, "discard":"ignore", ++ "detect-zeroes":"off"}} ++{"return": {}} ++{"execute":"blockdev-mirror", "arguments": ++ {"sync":"full", "device":"src", "target":"dst", ++ "job-id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job2"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job2"}} ++{"execute": "job-complete", "arguments": ++ {"id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"return": {}} ++{"execute": "blockdev-del", "arguments": ++ {"node-name": "dst"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job2"}} ++{"return": {}} ++Images are identical. ++Destination is sparse; expected sparse ++ ++=== Testing creation=off discard=unmap zeroes=off === ++ ++{"execute": "blockdev-create", "arguments": ++ {"options": {"driver":"file", "filename":"TEST_DIR/t.IMGFMT", ++ "size":20971520, "preallocation":"off"}, ++ "job-id":"job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job1"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job1"}} ++{"execute": "job-dismiss", "arguments": ++ {"id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job1"}} ++{"return": {}} ++{"execute": "blockdev-add", "arguments": ++ {"node-name": "dst", "driver":"file", ++ "filename":"TEST_DIR/t.IMGFMT", "aio":"threads", ++ "auto-read-only":true, "discard":"unmap", ++ "detect-zeroes":"off"}} ++{"return": {}} ++{"execute":"blockdev-mirror", "arguments": ++ {"sync":"full", "device":"src", "target":"dst", ++ "job-id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job2"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job2"}} ++{"execute": "job-complete", "arguments": ++ {"id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"return": {}} ++{"execute": "blockdev-del", "arguments": ++ {"node-name": "dst"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job2"}} ++{"return": {}} ++Images are identical. ++Destination is sparse; expected sparse ++ ++=== Testing creation=off discard=unmap zeroes=unmap === ++ ++{"execute": "blockdev-create", "arguments": ++ {"options": {"driver":"file", "filename":"TEST_DIR/t.IMGFMT", ++ "size":20971520, "preallocation":"off"}, ++ "job-id":"job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job1"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job1"}} ++{"execute": "job-dismiss", "arguments": ++ {"id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job1"}} ++{"return": {}} ++{"execute": "blockdev-add", "arguments": ++ {"node-name": "dst", "driver":"file", ++ "filename":"TEST_DIR/t.IMGFMT", "aio":"threads", ++ "auto-read-only":true, "discard":"unmap", ++ "detect-zeroes":"unmap"}} ++{"return": {}} ++{"execute":"blockdev-mirror", "arguments": ++ {"sync":"full", "device":"src", "target":"dst", ++ "job-id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job2"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job2"}} ++{"execute": "job-complete", "arguments": ++ {"id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"return": {}} ++{"execute": "blockdev-del", "arguments": ++ {"node-name": "dst"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job2"}} ++{"return": {}} ++Images are identical. ++Destination is sparse; expected sparse ++ ++=== Testing creation=full discard=ignore zeroes=off === ++ ++{"execute": "blockdev-create", "arguments": ++ {"options": {"driver":"file", "filename":"TEST_DIR/t.IMGFMT", ++ "size":20971520, "preallocation":"full"}, ++ "job-id":"job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job1"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job1"}} ++{"execute": "job-dismiss", "arguments": ++ {"id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job1"}} ++{"return": {}} ++{"execute": "blockdev-add", "arguments": ++ {"node-name": "dst", "driver":"file", ++ "filename":"TEST_DIR/t.IMGFMT", "aio":"threads", ++ "auto-read-only":true, "discard":"ignore", ++ "detect-zeroes":"off"}} ++{"return": {}} ++{"execute":"blockdev-mirror", "arguments": ++ {"sync":"full", "device":"src", "target":"dst", ++ "job-id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job2"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job2"}} ++{"execute": "job-complete", "arguments": ++ {"id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"return": {}} ++{"execute": "blockdev-del", "arguments": ++ {"node-name": "dst"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job2"}} ++{"return": {}} ++Images are identical. ++Destination is full; expected full ++ ++=== Testing creation=full discard=unmap zeroes=off === ++ ++{"execute": "blockdev-create", "arguments": ++ {"options": {"driver":"file", "filename":"TEST_DIR/t.IMGFMT", ++ "size":20971520, "preallocation":"full"}, ++ "job-id":"job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job1"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job1"}} ++{"execute": "job-dismiss", "arguments": ++ {"id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job1"}} ++{"return": {}} ++{"execute": "blockdev-add", "arguments": ++ {"node-name": "dst", "driver":"file", ++ "filename":"TEST_DIR/t.IMGFMT", "aio":"threads", ++ "auto-read-only":true, "discard":"unmap", ++ "detect-zeroes":"off"}} ++{"return": {}} ++{"execute":"blockdev-mirror", "arguments": ++ {"sync":"full", "device":"src", "target":"dst", ++ "job-id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job2"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job2"}} ++{"execute": "job-complete", "arguments": ++ {"id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"return": {}} ++{"execute": "blockdev-del", "arguments": ++ {"node-name": "dst"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job2"}} ++{"return": {}} ++Images are identical. ++Destination is sparse; expected sparse ++ ++=== Testing creation=full discard=unmap zeroes=unmap === ++ ++{"execute": "blockdev-create", "arguments": ++ {"options": {"driver":"file", "filename":"TEST_DIR/t.IMGFMT", ++ "size":20971520, "preallocation":"full"}, ++ "job-id":"job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job1"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job1"}} ++{"execute": "job-dismiss", "arguments": ++ {"id": "job1"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job1"}} ++{"return": {}} ++{"execute": "blockdev-add", "arguments": ++ {"node-name": "dst", "driver":"file", ++ "filename":"TEST_DIR/t.IMGFMT", "aio":"threads", ++ "auto-read-only":true, "discard":"unmap", ++ "detect-zeroes":"unmap"}} ++{"return": {}} ++{"execute":"blockdev-mirror", "arguments": ++ {"sync":"full", "device":"src", "target":"dst", ++ "job-id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job2"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job2"}} ++{"execute": "job-complete", "arguments": ++ {"id":"job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"return": {}} ++{"execute": "blockdev-del", "arguments": ++ {"node-name": "dst"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job2", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job2"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job2"}} ++{"return": {}} ++Images are identical. ++Destination is sparse; expected sparse ++{"execute":"quit"} ++*** done +-- +2.39.3 + diff --git a/kvm-tests-avocado-hotplug_blk-Fix-addr-in-device_add-com.patch b/kvm-tests-avocado-hotplug_blk-Fix-addr-in-device_add-com.patch deleted file mode 100644 index 93fe1e0..0000000 --- a/kvm-tests-avocado-hotplug_blk-Fix-addr-in-device_add-com.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 693f65e183cc578eed213b1ea5dc11e9c2697f15 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Fri, 22 Nov 2024 23:40:42 +0100 -Subject: [PATCH 2/7] tests/avocado/hotplug_blk: Fix addr in device_add command - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 312: qdev-monitor: avoid QemuOpts in QMP device_add -RH-Jira: RHEL-43412 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [2/4] 7e2d360d3bb8e606d868c17d6032f9fb8ee15814 (stefanha/centos-stream-qemu-kvm) - -pci_devfn properties accept both integer and string values, but -integer 1 and string '1' have different meanings: The integer value -means device 0, function 1 whereas the string value '1' is short for -'1.0' and means device 1, function 0. - -This test wants the string version so that the device actually becomes -visible for the guest. device_add hides the problem because it goes -through QemuOpts, which turns all properties into strings - this is a -QEMU bug that we want to fix, but that cancelled out the bug in this -test. - -Fix the test first so that device_add can be fixed afterwards. - -Signed-off-by: Kevin Wolf -Message-ID: <20241122224042.149258-1-kwolf@redhat.com> -Reviewed-by: Markus Armbruster -Signed-off-by: Kevin Wolf -(cherry picked from commit 770de685353e8c495ad4773fbd4bc0db997e4dfd) -Signed-off-by: Stefan Hajnoczi ---- - tests/avocado/hotplug_blk.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/avocado/hotplug_blk.py b/tests/avocado/hotplug_blk.py -index d55ded1c1d..b36bca02ec 100644 ---- a/tests/avocado/hotplug_blk.py -+++ b/tests/avocado/hotplug_blk.py -@@ -33,7 +33,7 @@ def plug(self) -> None: - 'drive': 'disk', - 'id': 'virtio-disk0', - 'bus': 'pci.1', -- 'addr': 1 -+ 'addr': '1', - } - - self.assert_no_vda() --- -2.39.3 - diff --git a/kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch b/kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch deleted file mode 100644 index 9e993ab..0000000 --- a/kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 8b3125e03d0b20987e1b0a963c24d38cb382f99c Mon Sep 17 00:00:00 2001 -From: Jared Rossi -Date: Sat, 19 Oct 2024 21:29:53 -0400 -Subject: [PATCH 21/38] tests/qtest: Add s390x boot order tests to cdrom-test.c -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 278: Full boot order support for s390x [Centos 10] -RH-Jira: RHEL-58153 -RH-Acked-by: CĂ©dric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [20/23] 1e79fbbd76e5bbf933fadda82dabf95fb60ead8c (thuth/qemu-kvm-cs9) - -Add two new qtests to verify that a valid IPL device can successfully boot after -failed IPL attempts from one or more invalid devices. - -cdrom-test/as-fallback-device: Defines the primary boot target as a device that -is invalid for IPL and a second boot target that is valid for IPL. Ensures that -the valid device will be selected after the initial failed IPL. - -cdrom-test/as-last-option: Defines the maximum number of boot devices (8) -where only the final entry in the boot order is valid. Ensures that a valid -device will be selected even after multiple failed IPL attempts from both -virtio-blk and virtio-scsi device types. - -Signed-off-by: Jared Rossi -Reviewed-by: Thomas Huth -Message-ID: <20241020012953.1380075-20-jrossi@linux.ibm.com> -Signed-off-by: Thomas Huth -(cherry picked from commit f5aa2d9d4c6480fa73b89c935050afe57e5d8bd9) ---- - tests/qtest/cdrom-test.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - -diff --git a/tests/qtest/cdrom-test.c b/tests/qtest/cdrom-test.c -index 5d89e62515..ecba648144 100644 ---- a/tests/qtest/cdrom-test.c -+++ b/tests/qtest/cdrom-test.c -@@ -206,6 +206,30 @@ static void add_s390x_tests(void) - "-drive driver=null-co,read-zeroes=on,if=none,id=d1 " - "-device virtio-blk,drive=d2,bootindex=1 " - "-drive if=none,id=d2,media=cdrom,file=", test_cdboot); -+ qtest_add_data_func("cdrom/boot/as-fallback-device", -+ "-device virtio-serial -device virtio-scsi " -+ "-device virtio-blk,drive=d1,bootindex=1 " -+ "-drive driver=null-co,read-zeroes=on,if=none,id=d1 " -+ "-device virtio-blk,drive=d2,bootindex=2 " -+ "-drive if=none,id=d2,media=cdrom,file=", test_cdboot); -+ qtest_add_data_func("cdrom/boot/as-last-option", -+ "-device virtio-serial -device virtio-scsi " -+ "-device virtio-blk,drive=d1,bootindex=1 " -+ "-drive driver=null-co,read-zeroes=on,if=none,id=d1 " -+ "-device virtio-blk,drive=d2,bootindex=2 " -+ "-drive driver=null-co,read-zeroes=on,if=none,id=d2 " -+ "-device virtio-blk,drive=d3,bootindex=3 " -+ "-drive driver=null-co,read-zeroes=on,if=none,id=d3 " -+ "-device scsi-hd,drive=d4,bootindex=4 " -+ "-drive driver=null-co,read-zeroes=on,if=none,id=d4 " -+ "-device scsi-hd,drive=d5,bootindex=5 " -+ "-drive driver=null-co,read-zeroes=on,if=none,id=d5 " -+ "-device virtio-blk,drive=d6,bootindex=6 " -+ "-drive driver=null-co,read-zeroes=on,if=none,id=d6 " -+ "-device scsi-hd,drive=d7,bootindex=7 " -+ "-drive driver=null-co,read-zeroes=on,if=none,id=d7 " -+ "-device scsi-cd,drive=d8,bootindex=8 " -+ "-drive if=none,id=d8,media=cdrom,file=", test_cdboot); - if (qtest_has_device("x-terminal3270")) { - qtest_add_data_func("cdrom/boot/without-bootindex", - "-device virtio-scsi -device virtio-serial " --- -2.39.3 - diff --git a/kvm-tests-qtest-migration-add-postcopy-tests-with-multif.patch b/kvm-tests-qtest-migration-add-postcopy-tests-with-multif.patch new file mode 100644 index 0000000..ae3fb34 --- /dev/null +++ b/kvm-tests-qtest-migration-add-postcopy-tests-with-multif.patch @@ -0,0 +1,270 @@ +From 73a8cce94ae861259b3769fe05d5cb79f5a20abb Mon Sep 17 00:00:00 2001 +From: Prasad Pandit +Date: Mon, 12 May 2025 18:21:24 +0530 +Subject: [PATCH 11/33] tests/qtest/migration: add postcopy tests with multifd + +RH-Author: Prasad Pandit +RH-MergeRequest: 390: migration: allow to enable multifd+postcopy features together, but use multifd during precopy only +RH-Jira: RHEL-59697 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Miroslav Rezanina +RH-Commit: [11/11] 35d1ea7a8473725d876d02ebbc29ab6063823742 (pjp/cs-qemu-kvm) + +Add new qtests to run postcopy migration with multifd +channels enabled. + +Jira: https://issues.redhat.com/browse/RHEL-59697 +Signed-off-by: Prasad Pandit +Link: https://lore.kernel.org/r/20250512125124.147064-4-ppandit@redhat.com +[peterx: rename all new tests to be under /migration/multifd+postcopy/] +Signed-off-by: Peter Xu +(cherry picked from commit 766bbabac8f00bc5cf23ba90a8326678636280ed) +Signed-off-by: Prasad Pandit +--- + tests/qtest/migration/compression-tests.c | 18 ++++++++ + tests/qtest/migration/postcopy-tests.c | 27 ++++++++++++ + tests/qtest/migration/precopy-tests.c | 28 ++++++++++++- + tests/qtest/migration/tls-tests.c | 51 +++++++++++++++++++++++ + 4 files changed, 122 insertions(+), 2 deletions(-) + +diff --git a/tests/qtest/migration/compression-tests.c b/tests/qtest/migration/compression-tests.c +index 41e79f031b..b827665b8e 100644 +--- a/tests/qtest/migration/compression-tests.c ++++ b/tests/qtest/migration/compression-tests.c +@@ -42,6 +42,20 @@ static void test_multifd_tcp_zstd(void) + }; + test_precopy_common(&args); + } ++ ++static void test_multifd_postcopy_tcp_zstd(void) ++{ ++ MigrateCommon args = { ++ .listen_uri = "defer", ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ .caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] = true, ++ }, ++ .start_hook = migrate_hook_start_precopy_tcp_multifd_zstd, ++ }; ++ ++ test_precopy_common(&args); ++} + #endif /* CONFIG_ZSTD */ + + #ifdef CONFIG_QATZIP +@@ -184,6 +198,10 @@ void migration_test_add_compression(MigrationTestEnv *env) + #ifdef CONFIG_ZSTD + migration_test_add("/migration/multifd/tcp/plain/zstd", + test_multifd_tcp_zstd); ++ if (env->has_uffd) { ++ migration_test_add("/migration/multifd+postcopy/tcp/plain/zstd", ++ test_multifd_postcopy_tcp_zstd); ++ } + #endif + + #ifdef CONFIG_QATZIP +diff --git a/tests/qtest/migration/postcopy-tests.c b/tests/qtest/migration/postcopy-tests.c +index 483e3ff99f..3773525843 100644 +--- a/tests/qtest/migration/postcopy-tests.c ++++ b/tests/qtest/migration/postcopy-tests.c +@@ -94,6 +94,29 @@ static void migration_test_add_postcopy_smoke(MigrationTestEnv *env) + } + } + ++static void test_multifd_postcopy(void) ++{ ++ MigrateCommon args = { ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, ++ }; ++ ++ test_postcopy_common(&args); ++} ++ ++static void test_multifd_postcopy_preempt(void) ++{ ++ MigrateCommon args = { ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true, ++ }, ++ }; ++ ++ test_postcopy_common(&args); ++} ++ + void migration_test_add_postcopy(MigrationTestEnv *env) + { + migration_test_add_postcopy_smoke(env); +@@ -114,6 +137,10 @@ void migration_test_add_postcopy(MigrationTestEnv *env) + "/migration/postcopy/recovery/double-failures/reconnect", + test_postcopy_recovery_fail_reconnect); + ++ migration_test_add("/migration/multifd+postcopy/plain", ++ test_multifd_postcopy); ++ migration_test_add("/migration/multifd+postcopy/preempt/plain", ++ test_multifd_postcopy_preempt); + if (env->is_x86) { + migration_test_add("/migration/postcopy/suspend", + test_postcopy_suspend); +diff --git a/tests/qtest/migration/precopy-tests.c b/tests/qtest/migration/precopy-tests.c +index a62d3c5378..bb38292550 100644 +--- a/tests/qtest/migration/precopy-tests.c ++++ b/tests/qtest/migration/precopy-tests.c +@@ -569,7 +569,7 @@ static void test_multifd_tcp_channels_none(void) + * + * And see that it works + */ +-static void test_multifd_tcp_cancel(void) ++static void test_multifd_tcp_cancel(bool postcopy_ram) + { + MigrateStart args = { + .hide_stderr = true, +@@ -583,6 +583,11 @@ static void test_multifd_tcp_cancel(void) + migrate_ensure_non_converge(from); + migrate_prepare_for_dirty_mem(from); + ++ if (postcopy_ram) { ++ migrate_set_capability(from, "postcopy-ram", true); ++ migrate_set_capability(to, "postcopy-ram", true); ++ } ++ + migrate_set_parameter_int(from, "multifd-channels", 16); + migrate_set_parameter_int(to, "multifd-channels", 16); + +@@ -624,6 +629,10 @@ static void test_multifd_tcp_cancel(void) + return; + } + ++ if (postcopy_ram) { ++ migrate_set_capability(to2, "postcopy-ram", true); ++ } ++ + migrate_set_parameter_int(to2, "multifd-channels", 16); + + migrate_set_capability(to2, "multifd", true); +@@ -647,6 +656,16 @@ static void test_multifd_tcp_cancel(void) + migrate_end(from, to2, true); + } + ++static void test_multifd_precopy_tcp_cancel(void) ++{ ++ test_multifd_tcp_cancel(false); ++} ++ ++static void test_multifd_postcopy_tcp_cancel(void) ++{ ++ test_multifd_tcp_cancel(true); ++} ++ + static void test_cancel_src_after_failed(QTestState *from, QTestState *to, + const char *uri, const char *phase) + { +@@ -1233,7 +1252,12 @@ static void migration_test_add_precopy_smoke(MigrationTestEnv *env) + migration_test_add("/migration/multifd/tcp/uri/plain/none", + test_multifd_tcp_uri_none); + migration_test_add("/migration/multifd/tcp/plain/cancel", +- test_multifd_tcp_cancel); ++ test_multifd_precopy_tcp_cancel); ++ if (env->has_uffd) { ++ migration_test_add("/migration/multifd+postcopy/tcp/plain/cancel", ++ test_multifd_postcopy_tcp_cancel); ++ } ++ + #ifdef CONFIG_RDMA + migration_test_add("/migration/precopy/rdma/plain", + test_precopy_rdma_plain); +diff --git a/tests/qtest/migration/tls-tests.c b/tests/qtest/migration/tls-tests.c +index 72f44defbb..21e9fec87d 100644 +--- a/tests/qtest/migration/tls-tests.c ++++ b/tests/qtest/migration/tls-tests.c +@@ -395,6 +395,19 @@ static void test_postcopy_recovery_tls_psk(void) + test_postcopy_recovery_common(&args); + } + ++static void test_multifd_postcopy_recovery_tls_psk(void) ++{ ++ MigrateCommon args = { ++ .start_hook = migrate_hook_start_tls_psk_match, ++ .end_hook = migrate_hook_end_tls_psk, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, ++ }; ++ ++ test_postcopy_recovery_common(&args); ++} ++ + /* This contains preempt+recovery+tls test altogether */ + static void test_postcopy_preempt_all(void) + { +@@ -409,6 +422,20 @@ static void test_postcopy_preempt_all(void) + test_postcopy_recovery_common(&args); + } + ++static void test_multifd_postcopy_preempt_recovery_tls_psk(void) ++{ ++ MigrateCommon args = { ++ .start_hook = migrate_hook_start_tls_psk_match, ++ .end_hook = migrate_hook_end_tls_psk, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true, ++ }, ++ }; ++ ++ test_postcopy_recovery_common(&args); ++} ++ + static void test_precopy_unix_tls_psk(void) + { + g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs); +@@ -657,6 +684,21 @@ static void test_multifd_tcp_tls_psk_mismatch(void) + test_precopy_common(&args); + } + ++static void test_multifd_postcopy_tcp_tls_psk_match(void) ++{ ++ MigrateCommon args = { ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ .caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] = true, ++ }, ++ .listen_uri = "defer", ++ .start_hook = migrate_hook_start_multifd_tcp_tls_psk_match, ++ .end_hook = migrate_hook_end_tls_psk, ++ }; ++ ++ test_precopy_common(&args); ++} ++ + #ifdef CONFIG_TASN1 + static void test_multifd_tcp_tls_x509_default_host(void) + { +@@ -774,6 +816,11 @@ void migration_test_add_tls(MigrationTestEnv *env) + test_postcopy_preempt_tls_psk); + migration_test_add("/migration/postcopy/preempt/recovery/tls/psk", + test_postcopy_preempt_all); ++ migration_test_add("/migration/multifd+postcopy/recovery/tls/psk", ++ test_multifd_postcopy_recovery_tls_psk); ++ migration_test_add( ++ "/migration/multifd+postcopy/preempt/recovery/tls/psk", ++ test_multifd_postcopy_preempt_recovery_tls_psk); + } + #ifdef CONFIG_TASN1 + migration_test_add("/migration/precopy/unix/tls/x509/default-host", +@@ -805,6 +852,10 @@ void migration_test_add_tls(MigrationTestEnv *env) + test_multifd_tcp_tls_psk_match); + migration_test_add("/migration/multifd/tcp/tls/psk/mismatch", + test_multifd_tcp_tls_psk_mismatch); ++ if (env->has_uffd) { ++ migration_test_add("/migration/multifd+postcopy/tcp/tls/psk/match", ++ test_multifd_postcopy_tcp_tls_psk_match); ++ } + #ifdef CONFIG_TASN1 + migration_test_add("/migration/multifd/tcp/tls/x509/default-host", + test_multifd_tcp_tls_x509_default_host); +-- +2.39.3 + diff --git a/kvm-tests-qtest-migration-consolidate-set-capabilities.patch b/kvm-tests-qtest-migration-consolidate-set-capabilities.patch new file mode 100644 index 0000000..d216826 --- /dev/null +++ b/kvm-tests-qtest-migration-consolidate-set-capabilities.patch @@ -0,0 +1,659 @@ +From 450029655e9fe0b958d05ae3ba1469a2e322b59a Mon Sep 17 00:00:00 2001 +From: Prasad Pandit +Date: Fri, 11 Apr 2025 17:15:33 +0530 +Subject: [PATCH 05/33] tests/qtest/migration: consolidate set capabilities + +RH-Author: Prasad Pandit +RH-MergeRequest: 390: migration: allow to enable multifd+postcopy features together, but use multifd during precopy only +RH-Jira: RHEL-59697 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Miroslav Rezanina +RH-Commit: [5/11] 9cfa760da90b57cb554a9766ad79635436fca4b9 (pjp/cs-qemu-kvm) + +Migration capabilities are set in multiple '.start_hook' +functions for various tests. Instead, consolidate setting +capabilities in 'migrate_start_set_capabilities()' function +which is called from the 'migrate_start()' function. +While simplifying the capabilities setting, it helps +to declutter the qtest sources. + +Jira: https://issues.redhat.com/browse/RHEL-59697 +Suggested-by: Fabiano Rosas +Signed-off-by: Prasad Pandit +Reviewed-by: Fabiano Rosas +Message-ID: <20250411114534.3370816-7-ppandit@redhat.com> +[fix open brace] +Signed-off-by: Fabiano Rosas +(cherry picked from commit 115cec9d663c1a2f5a73df4a5ca02b3a676e8a2a) +Signed-off-by: Prasad Pandit +--- + tests/qtest/migration/compression-tests.c | 22 +++++-- + tests/qtest/migration/cpr-tests.c | 6 +- + tests/qtest/migration/file-tests.c | 58 ++++++++---------- + tests/qtest/migration/framework.c | 75 +++++++++++++++-------- + tests/qtest/migration/framework.h | 9 ++- + tests/qtest/migration/misc-tests.c | 4 +- + tests/qtest/migration/postcopy-tests.c | 8 ++- + tests/qtest/migration/precopy-tests.c | 29 +++++---- + tests/qtest/migration/tls-tests.c | 23 ++++++- + 9 files changed, 150 insertions(+), 84 deletions(-) + +diff --git a/tests/qtest/migration/compression-tests.c b/tests/qtest/migration/compression-tests.c +index 8b58401b84..41e79f031b 100644 +--- a/tests/qtest/migration/compression-tests.c ++++ b/tests/qtest/migration/compression-tests.c +@@ -35,6 +35,9 @@ static void test_multifd_tcp_zstd(void) + { + MigrateCommon args = { + .listen_uri = "defer", ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + .start_hook = migrate_hook_start_precopy_tcp_multifd_zstd, + }; + test_precopy_common(&args); +@@ -56,6 +59,9 @@ static void test_multifd_tcp_qatzip(void) + { + MigrateCommon args = { + .listen_uri = "defer", ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + .start_hook = migrate_hook_start_precopy_tcp_multifd_qatzip, + }; + test_precopy_common(&args); +@@ -74,6 +80,9 @@ static void test_multifd_tcp_qpl(void) + { + MigrateCommon args = { + .listen_uri = "defer", ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + .start_hook = migrate_hook_start_precopy_tcp_multifd_qpl, + }; + test_precopy_common(&args); +@@ -92,6 +101,9 @@ static void test_multifd_tcp_uadk(void) + { + MigrateCommon args = { + .listen_uri = "defer", ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + .start_hook = migrate_hook_start_precopy_tcp_multifd_uadk, + }; + test_precopy_common(&args); +@@ -103,10 +115,6 @@ migrate_hook_start_xbzrle(QTestState *from, + QTestState *to) + { + migrate_set_parameter_int(from, "xbzrle-cache-size", 33554432); +- +- migrate_set_capability(from, "xbzrle", true); +- migrate_set_capability(to, "xbzrle", true); +- + return NULL; + } + +@@ -118,6 +126,9 @@ static void test_precopy_unix_xbzrle(void) + .listen_uri = uri, + .start_hook = migrate_hook_start_xbzrle, + .iterations = 2, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_XBZRLE] = true, ++ }, + /* + * XBZRLE needs pages to be modified when doing the 2nd+ round + * iteration to have real data pushed to the stream. +@@ -146,6 +157,9 @@ static void test_multifd_tcp_zlib(void) + { + MigrateCommon args = { + .listen_uri = "defer", ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + .start_hook = migrate_hook_start_precopy_tcp_multifd_zlib, + }; + test_precopy_common(&args); +diff --git a/tests/qtest/migration/cpr-tests.c b/tests/qtest/migration/cpr-tests.c +index 4758841824..5536e14610 100644 +--- a/tests/qtest/migration/cpr-tests.c ++++ b/tests/qtest/migration/cpr-tests.c +@@ -24,9 +24,6 @@ static void *migrate_hook_start_mode_reboot(QTestState *from, QTestState *to) + migrate_set_parameter_str(from, "mode", "cpr-reboot"); + migrate_set_parameter_str(to, "mode", "cpr-reboot"); + +- migrate_set_capability(from, "x-ignore-shared", true); +- migrate_set_capability(to, "x-ignore-shared", true); +- + return NULL; + } + +@@ -39,6 +36,9 @@ static void test_mode_reboot(void) + .connect_uri = uri, + .listen_uri = "defer", + .start_hook = migrate_hook_start_mode_reboot, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED] = true, ++ }, + }; + + test_file_common(&args, true); +diff --git a/tests/qtest/migration/file-tests.c b/tests/qtest/migration/file-tests.c +index f260e2871d..4d78ce0855 100644 +--- a/tests/qtest/migration/file-tests.c ++++ b/tests/qtest/migration/file-tests.c +@@ -107,15 +107,6 @@ static void test_precopy_file_offset_bad(void) + test_file_common(&args, false); + } + +-static void *migrate_hook_start_mapped_ram(QTestState *from, +- QTestState *to) +-{ +- migrate_set_capability(from, "mapped-ram", true); +- migrate_set_capability(to, "mapped-ram", true); +- +- return NULL; +-} +- + static void test_precopy_file_mapped_ram_live(void) + { + g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs, +@@ -123,7 +114,9 @@ static void test_precopy_file_mapped_ram_live(void) + MigrateCommon args = { + .connect_uri = uri, + .listen_uri = "defer", +- .start_hook = migrate_hook_start_mapped_ram, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true, ++ }, + }; + + test_file_common(&args, false); +@@ -136,26 +129,14 @@ static void test_precopy_file_mapped_ram(void) + MigrateCommon args = { + .connect_uri = uri, + .listen_uri = "defer", +- .start_hook = migrate_hook_start_mapped_ram, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true, ++ }, + }; + + test_file_common(&args, true); + } + +-static void *migrate_hook_start_multifd_mapped_ram(QTestState *from, +- QTestState *to) +-{ +- migrate_hook_start_mapped_ram(from, to); +- +- migrate_set_parameter_int(from, "multifd-channels", 4); +- migrate_set_parameter_int(to, "multifd-channels", 4); +- +- migrate_set_capability(from, "multifd", true); +- migrate_set_capability(to, "multifd", true); +- +- return NULL; +-} +- + static void test_multifd_file_mapped_ram_live(void) + { + g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs, +@@ -163,7 +144,10 @@ static void test_multifd_file_mapped_ram_live(void) + MigrateCommon args = { + .connect_uri = uri, + .listen_uri = "defer", +- .start_hook = migrate_hook_start_multifd_mapped_ram, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true, ++ }, + }; + + test_file_common(&args, false); +@@ -176,7 +160,10 @@ static void test_multifd_file_mapped_ram(void) + MigrateCommon args = { + .connect_uri = uri, + .listen_uri = "defer", +- .start_hook = migrate_hook_start_multifd_mapped_ram, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true, ++ }, + }; + + test_file_common(&args, true); +@@ -185,8 +172,6 @@ static void test_multifd_file_mapped_ram(void) + static void *migrate_hook_start_multifd_mapped_ram_dio(QTestState *from, + QTestState *to) + { +- migrate_hook_start_multifd_mapped_ram(from, to); +- + migrate_set_parameter_bool(from, "direct-io", true); + migrate_set_parameter_bool(to, "direct-io", true); + +@@ -201,6 +186,10 @@ static void test_multifd_file_mapped_ram_dio(void) + .connect_uri = uri, + .listen_uri = "defer", + .start_hook = migrate_hook_start_multifd_mapped_ram_dio, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true, ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + }; + + if (!probe_o_direct_support(tmpfs)) { +@@ -246,7 +235,6 @@ static void *migrate_hook_start_multifd_mapped_ram_fdset_dio(QTestState *from, + fdset_add_fds(from, file, O_WRONLY, 2, true); + fdset_add_fds(to, file, O_RDONLY, 2, true); + +- migrate_hook_start_multifd_mapped_ram(from, to); + migrate_set_parameter_bool(from, "direct-io", true); + migrate_set_parameter_bool(to, "direct-io", true); + +@@ -261,8 +249,6 @@ static void *migrate_hook_start_multifd_mapped_ram_fdset(QTestState *from, + fdset_add_fds(from, file, O_WRONLY, 2, false); + fdset_add_fds(to, file, O_RDONLY, 2, false); + +- migrate_hook_start_multifd_mapped_ram(from, to); +- + return NULL; + } + +@@ -275,6 +261,10 @@ static void test_multifd_file_mapped_ram_fdset(void) + .listen_uri = "defer", + .start_hook = migrate_hook_start_multifd_mapped_ram_fdset, + .end_hook = migrate_hook_end_multifd_mapped_ram_fdset, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true, ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + }; + + test_file_common(&args, true); +@@ -289,6 +279,10 @@ static void test_multifd_file_mapped_ram_fdset_dio(void) + .listen_uri = "defer", + .start_hook = migrate_hook_start_multifd_mapped_ram_fdset_dio, + .end_hook = migrate_hook_end_multifd_mapped_ram_fdset, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MAPPED_RAM] = true, ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + }; + + if (!probe_o_direct_support(tmpfs)) { +diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c +index 10e1d04b58..e48b80a127 100644 +--- a/tests/qtest/migration/framework.c ++++ b/tests/qtest/migration/framework.c +@@ -30,6 +30,7 @@ + #define QEMU_VM_FILE_MAGIC 0x5145564d + #define QEMU_ENV_SRC "QTEST_QEMU_BINARY_SRC" + #define QEMU_ENV_DST "QTEST_QEMU_BINARY_DST" ++#define MULTIFD_TEST_CHANNELS 4 + + unsigned start_address; + unsigned end_address; +@@ -207,6 +208,51 @@ static QList *migrate_start_get_qmp_capabilities(const MigrateStart *args) + return capabilities; + } + ++static void migrate_start_set_capabilities(QTestState *from, QTestState *to, ++ MigrateStart *args) ++{ ++ /* ++ * MigrationCapability_lookup and MIGRATION_CAPABILITY_ constants ++ * are from qapi-types-migration.h. ++ */ ++ for (uint8_t i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { ++ if (!args->caps[i]) { ++ continue; ++ } ++ if (from) { ++ migrate_set_capability(from, ++ MigrationCapability_lookup.array[i], true); ++ } ++ if (to) { ++ migrate_set_capability(to, ++ MigrationCapability_lookup.array[i], true); ++ } ++ } ++ ++ /* ++ * Always enable migration events. Libvirt always uses it, let's try ++ * to mimic as closer as that. ++ */ ++ migrate_set_capability(from, "events", true); ++ if (!args->defer_target_connect) { ++ migrate_set_capability(to, "events", true); ++ } ++ ++ /* ++ * Default number of channels should be fine for most ++ * tests. Individual tests can override by calling ++ * migrate_set_parameter() directly. ++ */ ++ if (args->caps[MIGRATION_CAPABILITY_MULTIFD]) { ++ migrate_set_parameter_int(from, "multifd-channels", ++ MULTIFD_TEST_CHANNELS); ++ migrate_set_parameter_int(to, "multifd-channels", ++ MULTIFD_TEST_CHANNELS); ++ } ++ ++ return; ++} ++ + int migrate_start(QTestState **from, QTestState **to, const char *uri, + MigrateStart *args) + { +@@ -379,14 +425,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri, + unlink(shmem_path); + } + +- /* +- * Always enable migration events. Libvirt always uses it, let's try +- * to mimic as closer as that. +- */ +- migrate_set_capability(*from, "events", true); +- if (!args->defer_target_connect) { +- migrate_set_capability(*to, "events", true); +- } ++ migrate_start_set_capabilities(*from, *to, args); + + return 0; + } +@@ -432,6 +471,10 @@ static int migrate_postcopy_prepare(QTestState **from_ptr, + { + QTestState *from, *to; + ++ /* set postcopy capabilities */ ++ args->start.caps[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME] = true; ++ args->start.caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] = true; ++ + if (migrate_start(&from, &to, "defer", &args->start)) { + return -1; + } +@@ -440,17 +483,7 @@ static int migrate_postcopy_prepare(QTestState **from_ptr, + args->postcopy_data = args->start_hook(from, to); + } + +- migrate_set_capability(from, "postcopy-ram", true); +- migrate_set_capability(to, "postcopy-ram", true); +- migrate_set_capability(to, "postcopy-blocktime", true); +- +- if (args->postcopy_preempt) { +- migrate_set_capability(from, "postcopy-preempt", true); +- migrate_set_capability(to, "postcopy-preempt", true); +- } +- + migrate_ensure_non_converge(from); +- + migrate_prepare_for_dirty_mem(from); + qtest_qmp_assert_success(to, "{ 'execute': 'migrate-incoming'," + " 'arguments': { " +@@ -948,15 +981,9 @@ void *migrate_hook_start_precopy_tcp_multifd_common(QTestState *from, + QTestState *to, + const char *method) + { +- migrate_set_parameter_int(from, "multifd-channels", 16); +- migrate_set_parameter_int(to, "multifd-channels", 16); +- + migrate_set_parameter_str(from, "multifd-compression", method); + migrate_set_parameter_str(to, "multifd-compression", method); + +- migrate_set_capability(from, "multifd", true); +- migrate_set_capability(to, "multifd", true); +- + /* Start incoming migration from the 1st socket */ + migrate_incoming_qmp(to, "tcp:127.0.0.1:0", NULL, "{}"); + +diff --git a/tests/qtest/migration/framework.h b/tests/qtest/migration/framework.h +index e4a11870f6..01e425e64e 100644 +--- a/tests/qtest/migration/framework.h ++++ b/tests/qtest/migration/framework.h +@@ -12,6 +12,7 @@ + #define TEST_FRAMEWORK_H + + #include "libqtest.h" ++#include + + #define FILE_TEST_FILENAME "migfile" + #define FILE_TEST_OFFSET 0x1000 +@@ -120,6 +121,13 @@ typedef struct { + + /* Do not connect to target monitor and qtest sockets in qtest_init */ + bool defer_target_connect; ++ ++ /* ++ * Migration capabilities to be set in both source and ++ * destination. For unilateral capabilities, use ++ * migration_set_capabilities(). ++ */ ++ bool caps[MIGRATION_CAPABILITY__MAX]; + } MigrateStart; + + typedef enum PostcopyRecoveryFailStage { +@@ -207,7 +215,6 @@ typedef struct { + + /* Postcopy specific fields */ + void *postcopy_data; +- bool postcopy_preempt; + PostcopyRecoveryFailStage postcopy_recovery_fail_stage; + } MigrateCommon; + +diff --git a/tests/qtest/migration/misc-tests.c b/tests/qtest/migration/misc-tests.c +index 2e612d9e38..54995256d8 100644 +--- a/tests/qtest/migration/misc-tests.c ++++ b/tests/qtest/migration/misc-tests.c +@@ -98,6 +98,7 @@ static void test_ignore_shared(void) + QTestState *from, *to; + MigrateStart args = { + .use_shmem = true, ++ .caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED] = true, + }; + + if (migrate_start(&from, &to, uri, &args)) { +@@ -107,9 +108,6 @@ static void test_ignore_shared(void) + migrate_ensure_non_converge(from); + migrate_prepare_for_dirty_mem(from); + +- migrate_set_capability(from, "x-ignore-shared", true); +- migrate_set_capability(to, "x-ignore-shared", true); +- + /* Wait for the first serial output from the source */ + wait_for_serial("src_serial"); + +diff --git a/tests/qtest/migration/postcopy-tests.c b/tests/qtest/migration/postcopy-tests.c +index 982457bed1..483e3ff99f 100644 +--- a/tests/qtest/migration/postcopy-tests.c ++++ b/tests/qtest/migration/postcopy-tests.c +@@ -39,7 +39,9 @@ static void test_postcopy_suspend(void) + static void test_postcopy_preempt(void) + { + MigrateCommon args = { +- .postcopy_preempt = true, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true, ++ }, + }; + + test_postcopy_common(&args); +@@ -73,7 +75,9 @@ static void test_postcopy_recovery_fail_reconnect(void) + static void test_postcopy_preempt_recovery(void) + { + MigrateCommon args = { +- .postcopy_preempt = true, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true, ++ }, + }; + + test_postcopy_recovery_common(&args); +diff --git a/tests/qtest/migration/precopy-tests.c b/tests/qtest/migration/precopy-tests.c +index ba273d10b9..f8404793b8 100644 +--- a/tests/qtest/migration/precopy-tests.c ++++ b/tests/qtest/migration/precopy-tests.c +@@ -108,23 +108,14 @@ static void test_precopy_tcp_plain(void) + test_precopy_common(&args); + } + +-static void *migrate_hook_start_switchover_ack(QTestState *from, QTestState *to) +-{ +- +- migrate_set_capability(from, "return-path", true); +- migrate_set_capability(to, "return-path", true); +- +- migrate_set_capability(from, "switchover-ack", true); +- migrate_set_capability(to, "switchover-ack", true); +- +- return NULL; +-} +- + static void test_precopy_tcp_switchover_ack(void) + { + MigrateCommon args = { + .listen_uri = "tcp:127.0.0.1:0", +- .start_hook = migrate_hook_start_switchover_ack, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_RETURN_PATH] = true, ++ .caps[MIGRATION_CAPABILITY_SWITCHOVER_ACK] = true, ++ }, + /* + * Source VM must be running in order to consider the switchover ACK + * when deciding to do switchover or not. +@@ -393,6 +384,9 @@ static void test_multifd_tcp_uri_none(void) + MigrateCommon args = { + .listen_uri = "defer", + .start_hook = migrate_hook_start_precopy_tcp_multifd, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + /* + * Multifd is more complicated than most of the features, it + * directly takes guest page buffers when sending, make sure +@@ -408,6 +402,9 @@ static void test_multifd_tcp_zero_page_legacy(void) + MigrateCommon args = { + .listen_uri = "defer", + .start_hook = migrate_hook_start_precopy_tcp_multifd_zero_page_legacy, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + /* + * Multifd is more complicated than most of the features, it + * directly takes guest page buffers when sending, make sure +@@ -423,6 +420,9 @@ static void test_multifd_tcp_no_zero_page(void) + MigrateCommon args = { + .listen_uri = "defer", + .start_hook = migrate_hook_start_precopy_tcp_multifd_no_zero_page, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + /* + * Multifd is more complicated than most of the features, it + * directly takes guest page buffers when sending, make sure +@@ -439,6 +439,9 @@ static void test_multifd_tcp_channels_none(void) + .listen_uri = "defer", + .start_hook = migrate_hook_start_precopy_tcp_multifd, + .live = true, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + .connect_channels = ("[ { 'channel-type': 'main'," + " 'addr': { 'transport': 'socket'," + " 'type': 'inet'," +diff --git a/tests/qtest/migration/tls-tests.c b/tests/qtest/migration/tls-tests.c +index 2cb4a44bcd..72f44defbb 100644 +--- a/tests/qtest/migration/tls-tests.c ++++ b/tests/qtest/migration/tls-tests.c +@@ -375,9 +375,11 @@ static void test_postcopy_tls_psk(void) + static void test_postcopy_preempt_tls_psk(void) + { + MigrateCommon args = { +- .postcopy_preempt = true, + .start_hook = migrate_hook_start_tls_psk_match, + .end_hook = migrate_hook_end_tls_psk, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true, ++ }, + }; + + test_postcopy_common(&args); +@@ -397,9 +399,11 @@ static void test_postcopy_recovery_tls_psk(void) + static void test_postcopy_preempt_all(void) + { + MigrateCommon args = { +- .postcopy_preempt = true, + .start_hook = migrate_hook_start_tls_psk_match, + .end_hook = migrate_hook_end_tls_psk, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true, ++ }, + }; + + test_postcopy_recovery_common(&args); +@@ -631,6 +635,9 @@ static void test_multifd_tcp_tls_psk_match(void) + .listen_uri = "defer", + .start_hook = migrate_hook_start_multifd_tcp_tls_psk_match, + .end_hook = migrate_hook_end_tls_psk, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + }; + test_precopy_common(&args); + } +@@ -640,6 +647,7 @@ static void test_multifd_tcp_tls_psk_mismatch(void) + MigrateCommon args = { + .start = { + .hide_stderr = true, ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, + }, + .listen_uri = "defer", + .start_hook = migrate_hook_start_multifd_tcp_tls_psk_mismatch, +@@ -656,6 +664,9 @@ static void test_multifd_tcp_tls_x509_default_host(void) + .listen_uri = "defer", + .start_hook = migrate_hook_start_multifd_tls_x509_default_host, + .end_hook = migrate_hook_end_tls_x509, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + }; + test_precopy_common(&args); + } +@@ -666,6 +677,9 @@ static void test_multifd_tcp_tls_x509_override_host(void) + .listen_uri = "defer", + .start_hook = migrate_hook_start_multifd_tls_x509_override_host, + .end_hook = migrate_hook_end_tls_x509, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + }; + test_precopy_common(&args); + } +@@ -688,6 +702,7 @@ static void test_multifd_tcp_tls_x509_mismatch_host(void) + MigrateCommon args = { + .start = { + .hide_stderr = true, ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, + }, + .listen_uri = "defer", + .start_hook = migrate_hook_start_multifd_tls_x509_mismatch_host, +@@ -703,6 +718,9 @@ static void test_multifd_tcp_tls_x509_allow_anon_client(void) + .listen_uri = "defer", + .start_hook = migrate_hook_start_multifd_tls_x509_allow_anon_client, + .end_hook = migrate_hook_end_tls_x509, ++ .start = { ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, ++ }, + }; + test_precopy_common(&args); + } +@@ -712,6 +730,7 @@ static void test_multifd_tcp_tls_x509_reject_anon_client(void) + MigrateCommon args = { + .start = { + .hide_stderr = true, ++ .caps[MIGRATION_CAPABILITY_MULTIFD] = true, + }, + .listen_uri = "defer", + .start_hook = migrate_hook_start_multifd_tls_x509_reject_anon_client, +-- +2.39.3 + diff --git a/kvm-tests-unit-test-util-sockets-fix-mem-leak-on-error-o.patch b/kvm-tests-unit-test-util-sockets-fix-mem-leak-on-error-o.patch new file mode 100644 index 0000000..74a0b67 --- /dev/null +++ b/kvm-tests-unit-test-util-sockets-fix-mem-leak-on-error-o.patch @@ -0,0 +1,53 @@ +From 450ca242645a6a2c68ea8aacbedfafec11c75fec Mon Sep 17 00:00:00 2001 +From: Matheus Tavares Bernardino +Date: Mon, 26 May 2025 10:20:55 -0700 +Subject: [PATCH 9/9] tests/unit/test-util-sockets: fix mem-leak on error + object + +RH-Author: Juraj Marcin +RH-MergeRequest: 368: util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive +RH-Jira: RHEL-67706 +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina +RH-Commit: [7/7] ed714ea8693fe69166e7f991904bebd20636804a (JurajMarcin/centos-src-qemu-kvm) + +The test fails with --enable-asan as the error struct is never freed. +In the case where the test expects a success but it fails, let's also +report the error for debugging (it will be freed internally). + +Fixes 316e8ee8d6 ("util/qemu-sockets: Refactor inet_parse() to use QemuOpts") + +Signed-off-by: Matheus Tavares Bernardino +Reviewed-by: Juraj Marcin +Message-ID: <518d94c7db20060b2a086cf55ee9bffab992a907.1748280011.git.matheus.bernardino@oss.qualcomm.com> +Signed-off-by: Thomas Huth + +(cherry picked from commit 5c54a367265ec19ed94a535cd15d178c16b8cae0) + +JIRA: https://issues.redhat.com/browse/RHEL-67706 + +Signed-off-by: Juraj Marcin +--- + tests/unit/test-util-sockets.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tests/unit/test-util-sockets.c b/tests/unit/test-util-sockets.c +index 8492f4d68f..ee66d727c3 100644 +--- a/tests/unit/test-util-sockets.c ++++ b/tests/unit/test-util-sockets.c +@@ -341,8 +341,12 @@ static void inet_parse_test_helper(const char *str, + int rc = inet_parse(&addr, str, &error); + + if (success) { ++ if (error) { ++ error_report_err(error); ++ } + g_assert_cmpint(rc, ==, 0); + } else { ++ error_free(error); + g_assert_cmpint(rc, <, 0); + } + if (exp_addr != NULL) { +-- +2.39.3 + diff --git a/kvm-ui-vnc-Update-display-update-interval-when-VM-state-.patch b/kvm-ui-vnc-Update-display-update-interval-when-VM-state-.patch index 3c13049..3f323f3 100644 --- a/kvm-ui-vnc-Update-display-update-interval-when-VM-state-.patch +++ b/kvm-ui-vnc-Update-display-update-interval-when-VM-state-.patch @@ -1,18 +1,18 @@ -From 108605d8be2edd1acbad7970cf45cb6941818d88 Mon Sep 17 00:00:00 2001 +From d2ae6b7855efeb865f6a93db057378142ca172ea Mon Sep 17 00:00:00 2001 From: Juraj Marcin Date: Wed, 21 May 2025 17:16:13 +0200 -Subject: [PATCH 01/31] ui/vnc: Update display update interval when VM state +Subject: [PATCH 43/43] ui/vnc: Update display update interval when VM state changes to RUNNING MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RH-Author: Juraj Marcin -RH-MergeRequest: 462: ui/vnc: Update display update interval when VM state changes to RUNNING -RH-Jira: RHEL-100765 +RH-MergeRequest: 384: ui/vnc: Update display update interval when VM state changes to RUNNING +RH-Jira: RHEL-83883 RH-Acked-by: Peter Xu RH-Acked-by: Marc-AndrĂ© Lureau -RH-Commit: [1/1] 40bb8d265979dccbe847c21ed8c08b6f5eecc7b5 +RH-Commit: [1/1] 1231bccaeb9ea0ca78dd6fd53ba4b523f3bc569f (JurajMarcin/centos-src-qemu-kvm) If a virtual machine is paused for an extended period time, for example, due to an incoming migration, there are also no changes on the screen. @@ -41,7 +41,7 @@ Signed-off-by: Peter Xu (cherry picked from commit 0310d594d98b39f9dde79b87fd8b0ad16e7c5459) -JIRA: https://issues.redhat.com/browse/RHEL-100765 +JIRA: https://issues.redhat.com/browse/RHEL-83883 Signed-off-by: Juraj Marcin --- @@ -50,7 +50,7 @@ Signed-off-by: Juraj Marcin 2 files changed, 14 insertions(+) diff --git a/ui/vnc.c b/ui/vnc.c -index 5057ec8680..4afc925a18 100644 +index 9241caaad9..75fb1e74f0 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3386,6 +3386,16 @@ static const DisplayChangeListenerOps dcl_ops = { @@ -80,10 +80,10 @@ index 5057ec8680..4afc925a18 100644 diff --git a/ui/vnc.h b/ui/vnc.h -index e5fa2efa3e..e9da707dbc 100644 +index acc53a2cc1..3bb23acd34 100644 --- a/ui/vnc.h +++ b/ui/vnc.h -@@ -186,6 +186,8 @@ struct VncDisplay +@@ -185,6 +185,8 @@ struct VncDisplay #endif AudioState *audio_state; diff --git a/kvm-update-Linux-headers-to-KVM-tree-master.patch b/kvm-update-Linux-headers-to-KVM-tree-master.patch new file mode 100644 index 0000000..b0355c8 --- /dev/null +++ b/kvm-update-Linux-headers-to-KVM-tree-master.patch @@ -0,0 +1,54 @@ +From 2f54dbc70c175f64313ca1f62a427f9a9cdfa7e8 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:45 +0200 +Subject: [PATCH 015/100] update Linux headers to KVM tree master + +To fetch the update of TDX + +Signed-off-by: Xiaoyao Li +Link: https://lore.kernel.org/r/20250703024021.3559286-3-xiaoyao.li@intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 25c98a135001559be905a0399669e5cdb3b0a613) +Signed-off-by: Paolo Bonzini +--- + linux-headers/asm-x86/kvm.h | 8 +++++++- + linux-headers/linux/kvm.h | 4 ++++ + 2 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h +index cd275ae76d..f0c1a730d9 100644 +--- a/linux-headers/asm-x86/kvm.h ++++ b/linux-headers/asm-x86/kvm.h +@@ -963,7 +963,13 @@ struct kvm_tdx_cmd { + struct kvm_tdx_capabilities { + __u64 supported_attrs; + __u64 supported_xfam; +- __u64 reserved[254]; ++ ++ __u64 kernel_tdvmcallinfo_1_r11; ++ __u64 user_tdvmcallinfo_1_r11; ++ __u64 kernel_tdvmcallinfo_1_r12; ++ __u64 user_tdvmcallinfo_1_r12; ++ ++ __u64 reserved[250]; + + /* Configurable CPUID bits for userspace */ + struct kvm_cpuid2 cpuid; +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 0690743944..32c5885a3c 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -459,6 +459,10 @@ struct kvm_run { + __u64 leaf; + __u64 r11, r12, r13, r14; + } get_tdvmcall_info; ++ struct { ++ __u64 ret; ++ __u64 vector; ++ } setup_event_notify; + }; + } tdx; + /* Fix the size of the union. */ +-- +2.47.3 + diff --git a/kvm-update-Linux-headers-to-v6.16-rc3.patch b/kvm-update-Linux-headers-to-v6.16-rc3.patch new file mode 100644 index 0000000..69120ae --- /dev/null +++ b/kvm-update-Linux-headers-to-v6.16-rc3.patch @@ -0,0 +1,489 @@ +From 3d50e2c0ac1a9732345f84a13e9df750235cd74f Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 18 Jul 2025 18:03:45 +0200 +Subject: [PATCH 014/100] update Linux headers to v6.16-rc3 + +Signed-off-by: Paolo Bonzini +(cherry picked from commit 688b0756ad2fdbe8effdb66f724a1129f62be7a2) +Signed-off-by: Paolo Bonzini +--- + include/standard-headers/asm-x86/setup_data.h | 13 +- + include/standard-headers/drm/drm_fourcc.h | 45 ++++++ + include/standard-headers/linux/ethtool.h | 134 +++++++++--------- + include/standard-headers/linux/fuse.h | 6 +- + .../linux/input-event-codes.h | 3 +- + include/standard-headers/linux/pci_regs.h | 12 +- + include/standard-headers/linux/virtio_gpu.h | 3 +- + include/standard-headers/linux/virtio_pci.h | 1 + + linux-headers/asm-arm64/kvm.h | 9 +- + linux-headers/asm-x86/kvm.h | 1 + + linux-headers/linux/bits.h | 4 +- + linux-headers/linux/kvm.h | 25 ++++ + linux-headers/linux/vhost.h | 4 +- + 13 files changed, 182 insertions(+), 78 deletions(-) + +diff --git a/include/standard-headers/asm-x86/setup_data.h b/include/standard-headers/asm-x86/setup_data.h +index a483d72f42..2e446c1d85 100644 +--- a/include/standard-headers/asm-x86/setup_data.h ++++ b/include/standard-headers/asm-x86/setup_data.h +@@ -13,7 +13,8 @@ + #define SETUP_CC_BLOB 7 + #define SETUP_IMA 8 + #define SETUP_RNG_SEED 9 +-#define SETUP_ENUM_MAX SETUP_RNG_SEED ++#define SETUP_KEXEC_KHO 10 ++#define SETUP_ENUM_MAX SETUP_KEXEC_KHO + + #define SETUP_INDIRECT (1<<31) + #define SETUP_TYPE_MAX (SETUP_ENUM_MAX | SETUP_INDIRECT) +@@ -78,6 +79,16 @@ struct ima_setup_data { + uint64_t size; + } QEMU_PACKED; + ++/* ++ * Locations of kexec handover metadata ++ */ ++struct kho_data { ++ uint64_t fdt_addr; ++ uint64_t fdt_size; ++ uint64_t scratch_addr; ++ uint64_t scratch_size; ++} QEMU_PACKED; ++ + #endif /* __ASSEMBLER__ */ + + #endif /* _ASM_X86_SETUP_DATA_H */ +diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h +index a8b759dcbc..c8309d378b 100644 +--- a/include/standard-headers/drm/drm_fourcc.h ++++ b/include/standard-headers/drm/drm_fourcc.h +@@ -421,6 +421,7 @@ extern "C" { + #define DRM_FORMAT_MOD_VENDOR_ALLWINNER 0x09 + #define DRM_FORMAT_MOD_VENDOR_AMLOGIC 0x0a + #define DRM_FORMAT_MOD_VENDOR_MTK 0x0b ++#define DRM_FORMAT_MOD_VENDOR_APPLE 0x0c + + /* add more to the end as needed */ + +@@ -1493,6 +1494,50 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) + /* alias for the most common tiling format */ + #define DRM_FORMAT_MOD_MTK_16L_32S_TILE DRM_FORMAT_MOD_MTK(MTK_FMT_MOD_TILE_16L32S) + ++/* ++ * Apple GPU-tiled layouts. ++ * ++ * Apple GPUs support nonlinear tilings with optional lossless compression. ++ * ++ * GPU-tiled images are divided into 16KiB tiles: ++ * ++ * Bytes per pixel Tile size ++ * --------------- --------- ++ * 1 128x128 ++ * 2 128x64 ++ * 4 64x64 ++ * 8 64x32 ++ * 16 32x32 ++ * ++ * Tiles are raster-order. Pixels within a tile are interleaved (Morton order). ++ * ++ * Compressed images pad the body to 128-bytes and are immediately followed by a ++ * metadata section. The metadata section rounds the image dimensions to ++ * powers-of-two and contains 8 bytes for each 16x16 compression subtile. ++ * Subtiles are interleaved (Morton order). ++ * ++ * All images are 128-byte aligned. ++ * ++ * These layouts fundamentally do not have meaningful strides. No matter how we ++ * specify strides for these layouts, userspace unaware of Apple image layouts ++ * will be unable to use correctly the specified stride for any purpose. ++ * Userspace aware of the image layouts do not use strides. The most "correct" ++ * convention would be setting the image stride to 0. Unfortunately, some ++ * software assumes the stride is at least (width * bytes per pixel). We ++ * therefore require that stride equals (width * bytes per pixel). Since the ++ * stride is arbitrary here, we pick the simplest convention. ++ * ++ * Although containing two sections, compressed image layouts are treated in ++ * software as a single plane. This is modelled after AFBC, a similar ++ * scheme. Attempting to separate the sections to be "explicit" in DRM would ++ * only generate more confusion, as software does not treat the image this way. ++ * ++ * For detailed information on the hardware image layouts, see ++ * https://docs.mesa3d.org/drivers/asahi.html#image-layouts ++ */ ++#define DRM_FORMAT_MOD_APPLE_GPU_TILED fourcc_mod_code(APPLE, 1) ++#define DRM_FORMAT_MOD_APPLE_GPU_TILED_COMPRESSED fourcc_mod_code(APPLE, 2) ++ + /* + * AMD modifiers + * +diff --git a/include/standard-headers/linux/ethtool.h b/include/standard-headers/linux/ethtool.h +index 5d1ad5fdea..cef0d207a6 100644 +--- a/include/standard-headers/linux/ethtool.h ++++ b/include/standard-headers/linux/ethtool.h +@@ -2295,71 +2295,75 @@ static inline int ethtool_validate_duplex(uint8_t duplex) + #define RXH_XFRM_SYM_OR_XOR (1 << 1) + #define RXH_XFRM_NO_CHANGE 0xff + +-/* L2-L4 network traffic flow types */ +-#define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */ +-#define UDP_V4_FLOW 0x02 /* hash or spec (udp_ip4_spec) */ +-#define SCTP_V4_FLOW 0x03 /* hash or spec (sctp_ip4_spec) */ +-#define AH_ESP_V4_FLOW 0x04 /* hash only */ +-#define TCP_V6_FLOW 0x05 /* hash or spec (tcp_ip6_spec; nfc only) */ +-#define UDP_V6_FLOW 0x06 /* hash or spec (udp_ip6_spec; nfc only) */ +-#define SCTP_V6_FLOW 0x07 /* hash or spec (sctp_ip6_spec; nfc only) */ +-#define AH_ESP_V6_FLOW 0x08 /* hash only */ +-#define AH_V4_FLOW 0x09 /* hash or spec (ah_ip4_spec) */ +-#define ESP_V4_FLOW 0x0a /* hash or spec (esp_ip4_spec) */ +-#define AH_V6_FLOW 0x0b /* hash or spec (ah_ip6_spec; nfc only) */ +-#define ESP_V6_FLOW 0x0c /* hash or spec (esp_ip6_spec; nfc only) */ +-#define IPV4_USER_FLOW 0x0d /* spec only (usr_ip4_spec) */ +-#define IP_USER_FLOW IPV4_USER_FLOW +-#define IPV6_USER_FLOW 0x0e /* spec only (usr_ip6_spec; nfc only) */ +-#define IPV4_FLOW 0x10 /* hash only */ +-#define IPV6_FLOW 0x11 /* hash only */ +-#define ETHER_FLOW 0x12 /* spec only (ether_spec) */ +- +-/* Used for GTP-U IPv4 and IPv6. +- * The format of GTP packets only includes +- * elements such as TEID and GTP version. +- * It is primarily intended for data communication of the UE. +- */ +-#define GTPU_V4_FLOW 0x13 /* hash only */ +-#define GTPU_V6_FLOW 0x14 /* hash only */ +- +-/* Use for GTP-C IPv4 and v6. +- * The format of these GTP packets does not include TEID. +- * Primarily expected to be used for communication +- * to create sessions for UE data communication, +- * commonly referred to as CSR (Create Session Request). +- */ +-#define GTPC_V4_FLOW 0x15 /* hash only */ +-#define GTPC_V6_FLOW 0x16 /* hash only */ +- +-/* Use for GTP-C IPv4 and v6. +- * Unlike GTPC_V4_FLOW, the format of these GTP packets includes TEID. +- * After session creation, it becomes this packet. +- * This is mainly used for requests to realize UE handover. +- */ +-#define GTPC_TEID_V4_FLOW 0x17 /* hash only */ +-#define GTPC_TEID_V6_FLOW 0x18 /* hash only */ +- +-/* Use for GTP-U and extended headers for the PSC (PDU Session Container). +- * The format of these GTP packets includes TEID and QFI. +- * In 5G communication using UPF (User Plane Function), +- * data communication with this extended header is performed. +- */ +-#define GTPU_EH_V4_FLOW 0x19 /* hash only */ +-#define GTPU_EH_V6_FLOW 0x1a /* hash only */ +- +-/* Use for GTP-U IPv4 and v6 PSC (PDU Session Container) extended headers. +- * This differs from GTPU_EH_V(4|6)_FLOW in that it is distinguished by +- * UL/DL included in the PSC. +- * There are differences in the data included based on Downlink/Uplink, +- * and can be used to distinguish packets. +- * The functions described so far are useful when you want to +- * handle communication from the mobile network in UPF, PGW, etc. +- */ +-#define GTPU_UL_V4_FLOW 0x1b /* hash only */ +-#define GTPU_UL_V6_FLOW 0x1c /* hash only */ +-#define GTPU_DL_V4_FLOW 0x1d /* hash only */ +-#define GTPU_DL_V6_FLOW 0x1e /* hash only */ ++enum { ++ /* L2-L4 network traffic flow types */ ++ TCP_V4_FLOW = 0x01, /* hash or spec (tcp_ip4_spec) */ ++ UDP_V4_FLOW = 0x02, /* hash or spec (udp_ip4_spec) */ ++ SCTP_V4_FLOW = 0x03, /* hash or spec (sctp_ip4_spec) */ ++ AH_ESP_V4_FLOW = 0x04, /* hash only */ ++ TCP_V6_FLOW = 0x05, /* hash or spec (tcp_ip6_spec; nfc only) */ ++ UDP_V6_FLOW = 0x06, /* hash or spec (udp_ip6_spec; nfc only) */ ++ SCTP_V6_FLOW = 0x07, /* hash or spec (sctp_ip6_spec; nfc only) */ ++ AH_ESP_V6_FLOW = 0x08, /* hash only */ ++ AH_V4_FLOW = 0x09, /* hash or spec (ah_ip4_spec) */ ++ ESP_V4_FLOW = 0x0a, /* hash or spec (esp_ip4_spec) */ ++ AH_V6_FLOW = 0x0b, /* hash or spec (ah_ip6_spec; nfc only) */ ++ ESP_V6_FLOW = 0x0c, /* hash or spec (esp_ip6_spec; nfc only) */ ++ IPV4_USER_FLOW = 0x0d, /* spec only (usr_ip4_spec) */ ++ IP_USER_FLOW = IPV4_USER_FLOW, ++ IPV6_USER_FLOW = 0x0e, /* spec only (usr_ip6_spec; nfc only) */ ++ IPV4_FLOW = 0x10, /* hash only */ ++ IPV6_FLOW = 0x11, /* hash only */ ++ ETHER_FLOW = 0x12, /* spec only (ether_spec) */ ++ ++ /* Used for GTP-U IPv4 and IPv6. ++ * The format of GTP packets only includes ++ * elements such as TEID and GTP version. ++ * It is primarily intended for data communication of the UE. ++ */ ++ GTPU_V4_FLOW = 0x13, /* hash only */ ++ GTPU_V6_FLOW = 0x14, /* hash only */ ++ ++ /* Use for GTP-C IPv4 and v6. ++ * The format of these GTP packets does not include TEID. ++ * Primarily expected to be used for communication ++ * to create sessions for UE data communication, ++ * commonly referred to as CSR (Create Session Request). ++ */ ++ GTPC_V4_FLOW = 0x15, /* hash only */ ++ GTPC_V6_FLOW = 0x16, /* hash only */ ++ ++ /* Use for GTP-C IPv4 and v6. ++ * Unlike GTPC_V4_FLOW, the format of these GTP packets includes TEID. ++ * After session creation, it becomes this packet. ++ * This is mainly used for requests to realize UE handover. ++ */ ++ GTPC_TEID_V4_FLOW = 0x17, /* hash only */ ++ GTPC_TEID_V6_FLOW = 0x18, /* hash only */ ++ ++ /* Use for GTP-U and extended headers for the PSC (PDU Session Container). ++ * The format of these GTP packets includes TEID and QFI. ++ * In 5G communication using UPF (User Plane Function), ++ * data communication with this extended header is performed. ++ */ ++ GTPU_EH_V4_FLOW = 0x19, /* hash only */ ++ GTPU_EH_V6_FLOW = 0x1a, /* hash only */ ++ ++ /* Use for GTP-U IPv4 and v6 PSC (PDU Session Container) extended headers. ++ * This differs from GTPU_EH_V(4|6)_FLOW in that it is distinguished by ++ * UL/DL included in the PSC. ++ * There are differences in the data included based on Downlink/Uplink, ++ * and can be used to distinguish packets. ++ * The functions described so far are useful when you want to ++ * handle communication from the mobile network in UPF, PGW, etc. ++ */ ++ GTPU_UL_V4_FLOW = 0x1b, /* hash only */ ++ GTPU_UL_V6_FLOW = 0x1c, /* hash only */ ++ GTPU_DL_V4_FLOW = 0x1d, /* hash only */ ++ GTPU_DL_V6_FLOW = 0x1e, /* hash only */ ++ ++ __FLOW_TYPE_COUNT, ++}; + + /* Flag to enable additional fields in struct ethtool_rx_flow_spec */ + #define FLOW_EXT 0x80000000 +diff --git a/include/standard-headers/linux/fuse.h b/include/standard-headers/linux/fuse.h +index a2b5815d89..d8b2fd67e1 100644 +--- a/include/standard-headers/linux/fuse.h ++++ b/include/standard-headers/linux/fuse.h +@@ -232,6 +232,9 @@ + * + * 7.43 + * - add FUSE_REQUEST_TIMEOUT ++ * ++ * 7.44 ++ * - add FUSE_NOTIFY_INC_EPOCH + */ + + #ifndef _LINUX_FUSE_H +@@ -263,7 +266,7 @@ + #define FUSE_KERNEL_VERSION 7 + + /** Minor version number of this interface */ +-#define FUSE_KERNEL_MINOR_VERSION 43 ++#define FUSE_KERNEL_MINOR_VERSION 44 + + /** The node ID of the root inode */ + #define FUSE_ROOT_ID 1 +@@ -667,6 +670,7 @@ enum fuse_notify_code { + FUSE_NOTIFY_RETRIEVE = 5, + FUSE_NOTIFY_DELETE = 6, + FUSE_NOTIFY_RESEND = 7, ++ FUSE_NOTIFY_INC_EPOCH = 8, + FUSE_NOTIFY_CODE_MAX, + }; + +diff --git a/include/standard-headers/linux/input-event-codes.h b/include/standard-headers/linux/input-event-codes.h +index 09ba0ad878..a82ff795e0 100644 +--- a/include/standard-headers/linux/input-event-codes.h ++++ b/include/standard-headers/linux/input-event-codes.h +@@ -925,7 +925,8 @@ + #define SW_MUTE_DEVICE 0x0e /* set = device disabled */ + #define SW_PEN_INSERTED 0x0f /* set = pen inserted */ + #define SW_MACHINE_COVER 0x10 /* set = cover closed */ +-#define SW_MAX_ 0x10 ++#define SW_USB_INSERT 0x11 /* set = USB audio device connected */ ++#define SW_MAX_ 0x11 + #define SW_CNT (SW_MAX_+1) + + /* +diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h +index ba326710f9..a3a3e942de 100644 +--- a/include/standard-headers/linux/pci_regs.h ++++ b/include/standard-headers/linux/pci_regs.h +@@ -750,7 +750,8 @@ + #define PCI_EXT_CAP_ID_NPEM 0x29 /* Native PCIe Enclosure Management */ + #define PCI_EXT_CAP_ID_PL_32GT 0x2A /* Physical Layer 32.0 GT/s */ + #define PCI_EXT_CAP_ID_DOE 0x2E /* Data Object Exchange */ +-#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_DOE ++#define PCI_EXT_CAP_ID_PL_64GT 0x31 /* Physical Layer 64.0 GT/s */ ++#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PL_64GT + + #define PCI_EXT_CAP_DSN_SIZEOF 12 + #define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40 +@@ -1144,12 +1145,21 @@ + #define PCI_DLF_CAP 0x04 /* Capabilities Register */ + #define PCI_DLF_EXCHANGE_ENABLE 0x80000000 /* Data Link Feature Exchange Enable */ + ++/* Secondary PCIe Capability 8.0 GT/s */ ++#define PCI_SECPCI_LE_CTRL 0x0c /* Lane Equalization Control Register */ ++ + /* Physical Layer 16.0 GT/s */ + #define PCI_PL_16GT_LE_CTRL 0x20 /* Lane Equalization Control Register */ + #define PCI_PL_16GT_LE_CTRL_DSP_TX_PRESET_MASK 0x0000000F + #define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_MASK 0x000000F0 + #define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_SHIFT 4 + ++/* Physical Layer 32.0 GT/s */ ++#define PCI_PL_32GT_LE_CTRL 0x20 /* Lane Equalization Control Register */ ++ ++/* Physical Layer 64.0 GT/s */ ++#define PCI_PL_64GT_LE_CTRL 0x20 /* Lane Equalization Control Register */ ++ + /* Native PCIe Enclosure Management */ + #define PCI_NPEM_CAP 0x04 /* NPEM capability register */ + #define PCI_NPEM_CAP_CAPABLE 0x00000001 /* NPEM Capable */ +diff --git a/include/standard-headers/linux/virtio_gpu.h b/include/standard-headers/linux/virtio_gpu.h +index 6459fdb9fb..00cd3f04af 100644 +--- a/include/standard-headers/linux/virtio_gpu.h ++++ b/include/standard-headers/linux/virtio_gpu.h +@@ -309,8 +309,9 @@ struct virtio_gpu_cmd_submit { + + #define VIRTIO_GPU_CAPSET_VIRGL 1 + #define VIRTIO_GPU_CAPSET_VIRGL2 2 +-/* 3 is reserved for gfxstream */ ++#define VIRTIO_GPU_CAPSET_GFXSTREAM_VULKAN 3 + #define VIRTIO_GPU_CAPSET_VENUS 4 ++#define VIRTIO_GPU_CAPSET_CROSS_DOMAIN 5 + #define VIRTIO_GPU_CAPSET_DRM 6 + + /* VIRTIO_GPU_CMD_GET_CAPSET_INFO */ +diff --git a/include/standard-headers/linux/virtio_pci.h b/include/standard-headers/linux/virtio_pci.h +index 91fec6f502..09e964e6ee 100644 +--- a/include/standard-headers/linux/virtio_pci.h ++++ b/include/standard-headers/linux/virtio_pci.h +@@ -246,6 +246,7 @@ struct virtio_pci_cfg_cap { + #define VIRTIO_ADMIN_CMD_LIST_USE 0x1 + + /* Admin command group type. */ ++#define VIRTIO_ADMIN_GROUP_TYPE_SELF 0x0 + #define VIRTIO_ADMIN_GROUP_TYPE_SRIOV 0x1 + + /* Transitional device admin command. */ +diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h +index 4e6aff08df..f4d9baafa1 100644 +--- a/linux-headers/asm-arm64/kvm.h ++++ b/linux-headers/asm-arm64/kvm.h +@@ -419,10 +419,11 @@ enum { + + /* Device Control API on vcpu fd */ + #define KVM_ARM_VCPU_PMU_V3_CTRL 0 +-#define KVM_ARM_VCPU_PMU_V3_IRQ 0 +-#define KVM_ARM_VCPU_PMU_V3_INIT 1 +-#define KVM_ARM_VCPU_PMU_V3_FILTER 2 +-#define KVM_ARM_VCPU_PMU_V3_SET_PMU 3 ++#define KVM_ARM_VCPU_PMU_V3_IRQ 0 ++#define KVM_ARM_VCPU_PMU_V3_INIT 1 ++#define KVM_ARM_VCPU_PMU_V3_FILTER 2 ++#define KVM_ARM_VCPU_PMU_V3_SET_PMU 3 ++#define KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS 4 + #define KVM_ARM_VCPU_TIMER_CTRL 1 + #define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0 + #define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1 +diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h +index 7fb57ccb2a..cd275ae76d 100644 +--- a/linux-headers/asm-x86/kvm.h ++++ b/linux-headers/asm-x86/kvm.h +@@ -843,6 +843,7 @@ struct kvm_sev_snp_launch_start { + }; + + /* Kept in sync with firmware values for simplicity. */ ++#define KVM_SEV_PAGE_TYPE_INVALID 0x0 + #define KVM_SEV_SNP_PAGE_TYPE_NORMAL 0x1 + #define KVM_SEV_SNP_PAGE_TYPE_ZERO 0x3 + #define KVM_SEV_SNP_PAGE_TYPE_UNMEASURED 0x4 +diff --git a/linux-headers/linux/bits.h b/linux-headers/linux/bits.h +index 58596d18f4..9243f38975 100644 +--- a/linux-headers/linux/bits.h ++++ b/linux-headers/linux/bits.h +@@ -4,9 +4,9 @@ + #ifndef _LINUX_BITS_H + #define _LINUX_BITS_H + +-#define __GENMASK(h, l) (((~_UL(0)) << (l)) & (~_UL(0) >> (BITS_PER_LONG - 1 - (h)))) ++#define __GENMASK(h, l) (((~_UL(0)) << (l)) & (~_UL(0) >> (__BITS_PER_LONG - 1 - (h)))) + +-#define __GENMASK_ULL(h, l) (((~_ULL(0)) << (l)) & (~_ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h)))) ++#define __GENMASK_ULL(h, l) (((~_ULL(0)) << (l)) & (~_ULL(0) >> (__BITS_PER_LONG_LONG - 1 - (h)))) + + #define __GENMASK_U128(h, l) \ + ((_BIT128((h)) << 1) - (_BIT128(l))) +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 99cc82a275..0690743944 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -178,6 +178,7 @@ struct kvm_xen_exit { + #define KVM_EXIT_NOTIFY 37 + #define KVM_EXIT_LOONGARCH_IOCSR 38 + #define KVM_EXIT_MEMORY_FAULT 39 ++#define KVM_EXIT_TDX 40 + + /* For KVM_EXIT_INTERNAL_ERROR */ + /* Emulate instruction failed. */ +@@ -439,6 +440,27 @@ struct kvm_run { + __u64 gpa; + __u64 size; + } memory_fault; ++ /* KVM_EXIT_TDX */ ++ struct { ++ __u64 flags; ++ __u64 nr; ++ union { ++ struct { ++ __u64 ret; ++ __u64 data[5]; ++ } unknown; ++ struct { ++ __u64 ret; ++ __u64 gpa; ++ __u64 size; ++ } get_quote; ++ struct { ++ __u64 ret; ++ __u64 leaf; ++ __u64 r11, r12, r13, r14; ++ } get_tdvmcall_info; ++ }; ++ } tdx; + /* Fix the size of the union. */ + char padding[256]; + }; +@@ -923,6 +945,9 @@ struct kvm_enable_cap { + #define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237 + #define KVM_CAP_X86_GUEST_MODE 238 + #define KVM_CAP_ARM_WRITABLE_IMP_ID_REGS 239 ++#define KVM_CAP_ARM_EL2 240 ++#define KVM_CAP_ARM_EL2_E2H0 241 ++#define KVM_CAP_RISCV_MP_STATE_RESET 242 + + struct kvm_irq_routing_irqchip { + __u32 irqchip; +diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h +index b95dd84eef..d4b3e2ae13 100644 +--- a/linux-headers/linux/vhost.h ++++ b/linux-headers/linux/vhost.h +@@ -28,10 +28,10 @@ + + /* Set current process as the (exclusive) owner of this file descriptor. This + * must be called before any other vhost command. Further calls to +- * VHOST_OWNER_SET fail until VHOST_OWNER_RESET is called. */ ++ * VHOST_SET_OWNER fail until VHOST_RESET_OWNER is called. */ + #define VHOST_SET_OWNER _IO(VHOST_VIRTIO, 0x01) + /* Give up ownership, and reset the device to default values. +- * Allows subsequent call to VHOST_OWNER_SET to succeed. */ ++ * Allows subsequent call to VHOST_SET_OWNER to succeed. */ + #define VHOST_RESET_OWNER _IO(VHOST_VIRTIO, 0x02) + + /* Set up/modify memory layout */ +-- +2.47.3 + diff --git a/kvm-util-qemu-sockets-Add-support-for-keep-alive-flag-to.patch b/kvm-util-qemu-sockets-Add-support-for-keep-alive-flag-to.patch new file mode 100644 index 0000000..32d7358 --- /dev/null +++ b/kvm-util-qemu-sockets-Add-support-for-keep-alive-flag-to.patch @@ -0,0 +1,86 @@ +From df0a8441d5352faaa1e2a3a27a48cafd6fa737e4 Mon Sep 17 00:00:00 2001 +From: Juraj Marcin +Date: Wed, 21 May 2025 15:52:33 +0200 +Subject: [PATCH 6/9] util/qemu-sockets: Add support for keep-alive flag to + passive sockets +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Juraj Marcin +RH-MergeRequest: 368: util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive +RH-Jira: RHEL-67706 +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina +RH-Commit: [4/7] af13774c325fc152814885c858813bdc2f1d62e7 (JurajMarcin/centos-src-qemu-kvm) + +Commit aec21d3175 (qapi: Add InetSocketAddress member keep-alive) +introduces the keep-alive flag, which enables the SO_KEEPALIVE socket +option, but only on client-side sockets. However, this option is also +useful for server-side sockets, so they can check if a client is still +reachable or drop the connection otherwise. + +This patch enables the SO_KEEPALIVE socket option on passive server-side +sockets if the keep-alive flag is enabled. This socket option is then +inherited by active server-side sockets communicating with connected +clients. + +Signed-off-by: Juraj Marcin +Reviewed-by: Daniel P. BerrangĂ© +Signed-off-by: Daniel P. BerrangĂ© + +(cherry picked from commit 00064705ed1f3943d3634be25da434466c87e7d5) + +JIRA: https://issues.redhat.com/browse/RHEL-67706 + +Signed-off-by: Juraj Marcin +--- + qapi/sockets.json | 4 ++-- + util/qemu-sockets.c | 9 +++------ + 2 files changed, 5 insertions(+), 8 deletions(-) + +diff --git a/qapi/sockets.json b/qapi/sockets.json +index 6a95023315..62797cd027 100644 +--- a/qapi/sockets.json ++++ b/qapi/sockets.json +@@ -56,8 +56,8 @@ + # @ipv6: whether to accept IPv6 addresses, default try both IPv4 and + # IPv6 + # +-# @keep-alive: enable keep-alive when connecting to this socket. Not +-# supported for passive sockets. (Since 4.2) ++# @keep-alive: enable keep-alive when connecting to/listening on this socket. ++# (Since 4.2, not supported for listening sockets until 10.1) + # + # @mptcp: enable multi-path TCP. (Since 6.1) + # +diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c +index 329fdbfd97..4fbf1ed5bf 100644 +--- a/util/qemu-sockets.c ++++ b/util/qemu-sockets.c +@@ -236,12 +236,6 @@ static int inet_listen_saddr(InetSocketAddress *saddr, + int saved_errno = 0; + bool socket_created = false; + +- if (saddr->keep_alive) { +- error_setg(errp, "keep-alive option is not supported for passive " +- "sockets"); +- return -1; +- } +- + memset(&ai,0, sizeof(ai)); + ai.ai_flags = AI_PASSIVE; + if (saddr->has_numeric && saddr->numeric) { +@@ -349,6 +343,9 @@ static int inet_listen_saddr(InetSocketAddress *saddr, + goto fail; + } + /* We have a listening socket */ ++ if (inet_set_sockopts(slisten, saddr, errp) < 0) { ++ goto fail; ++ } + freeaddrinfo(res); + return slisten; + } +-- +2.39.3 + diff --git a/kvm-util-qemu-sockets-Introduce-inet-socket-options-cont.patch b/kvm-util-qemu-sockets-Introduce-inet-socket-options-cont.patch new file mode 100644 index 0000000..a4b1629 --- /dev/null +++ b/kvm-util-qemu-sockets-Introduce-inet-socket-options-cont.patch @@ -0,0 +1,314 @@ +From 51becf11d7727e6f6e224ca2a1d56e26fd3d0fb2 Mon Sep 17 00:00:00 2001 +From: Juraj Marcin +Date: Wed, 21 May 2025 15:52:35 +0200 +Subject: [PATCH 8/9] util/qemu-sockets: Introduce inet socket options + controlling TCP keep-alive +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Juraj Marcin +RH-MergeRequest: 368: util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive +RH-Jira: RHEL-67706 +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina +RH-Commit: [6/7] 4c8bac67f739c923fa1590e1cc34cd84c08653c1 (JurajMarcin/centos-src-qemu-kvm) + +With the default TCP stack configuration, it could be even 2 hours +before the connection times out due to the other side not being +reachable. However, in some cases, the application needs to be aware of +a connection issue much sooner. + +This is the case, for example, for postcopy live migration. If there is +no traffic from the migration destination guest (server-side) to the +migration source guest (client-side), the destination keeps waiting for +pages indefinitely and does not switch to the postcopy-paused state. +This can happen, for example, if the destination QEMU instance is +started with the '-S' command line option and the machine is not started +yet, or if the machine is idle and produces no new page faults for +not-yet-migrated pages. + +This patch introduces new inet socket parameters that control count, +idle period, and interval of TCP keep-alive packets before the +connection is considered broken. These parameters are available on +systems where the respective TCP socket options are defined, that +includes Linux, Windows, macOS, but not OpenBSD. Additionally, macOS +defines TCP_KEEPIDLE as TCP_KEEPALIVE instead, so the patch supplies its +own definition. + +The default value for all is 0, which means the system configuration is +used. + +Signed-off-by: Juraj Marcin +Reviewed-by: Daniel P. BerrangĂ© +Signed-off-by: Daniel P. BerrangĂ© + +(cherry picked from commit 1bd4237cb1095d71c16afad3ce93b4a1e453173e) + +JIRA: https://issues.redhat.com/browse/RHEL-67706 + +Signed-off-by: Juraj Marcin +--- + meson.build | 30 +++++++++++++ + qapi/sockets.json | 19 ++++++++ + tests/unit/test-util-sockets.c | 39 +++++++++++++++++ + util/qemu-sockets.c | 80 ++++++++++++++++++++++++++++++++++ + 4 files changed, 168 insertions(+) + +diff --git a/meson.build b/meson.build +index dadd47d362..23b56175d5 100644 +--- a/meson.build ++++ b/meson.build +@@ -2745,6 +2745,36 @@ if linux_io_uring.found() + config_host_data.set('HAVE_IO_URING_PREP_WRITEV2', + cc.has_header_symbol('liburing.h', 'io_uring_prep_writev2')) + endif ++config_host_data.set('HAVE_TCP_KEEPCNT', ++ cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPCNT') or ++ cc.compiles(''' ++ #include ++ #ifndef TCP_KEEPCNT ++ #error ++ #endif ++ int main(void) { return 0; }''', ++ name: 'Win32 TCP_KEEPCNT')) ++# On Darwin TCP_KEEPIDLE is available under different name, TCP_KEEPALIVE. ++# https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/bsd/man/man4/tcp.4#L172 ++config_host_data.set('HAVE_TCP_KEEPIDLE', ++ cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPIDLE') or ++ cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPALIVE') or ++ cc.compiles(''' ++ #include ++ #ifndef TCP_KEEPIDLE ++ #error ++ #endif ++ int main(void) { return 0; }''', ++ name: 'Win32 TCP_KEEPIDLE')) ++config_host_data.set('HAVE_TCP_KEEPINTVL', ++ cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPINTVL') or ++ cc.compiles(''' ++ #include ++ #ifndef TCP_KEEPINTVL ++ #error ++ #endif ++ int main(void) { return 0; }''', ++ name: 'Win32 TCP_KEEPINTVL')) + + # has_member + config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID', +diff --git a/qapi/sockets.json b/qapi/sockets.json +index 62797cd027..f9f559daba 100644 +--- a/qapi/sockets.json ++++ b/qapi/sockets.json +@@ -59,6 +59,22 @@ + # @keep-alive: enable keep-alive when connecting to/listening on this socket. + # (Since 4.2, not supported for listening sockets until 10.1) + # ++# @keep-alive-count: number of keep-alive packets sent before the connection is ++# closed. Only supported for TCP sockets on systems where TCP_KEEPCNT ++# socket option is defined (this includes Linux, Windows, macOS, FreeBSD, ++# but not OpenBSD). When set to 0, system setting is used. (Since 10.1) ++# ++# @keep-alive-idle: time in seconds the connection needs to be idle before ++# sending a keepalive packet. Only supported for TCP sockets on systems ++# where TCP_KEEPIDLE socket option is defined (this includes Linux, ++# Windows, macOS, FreeBSD, but not OpenBSD). When set to 0, system setting ++# is used. (Since 10.1) ++# ++# @keep-alive-interval: time in seconds between keep-alive packets. Only ++# supported for TCP sockets on systems where TCP_KEEPINTVL is defined (this ++# includes Linux, Windows, macOS, FreeBSD, but not OpenBSD). When set to ++# 0, system setting is used. (Since 10.1) ++# + # @mptcp: enable multi-path TCP. (Since 6.1) + # + # Since: 1.3 +@@ -71,6 +87,9 @@ + '*ipv4': 'bool', + '*ipv6': 'bool', + '*keep-alive': 'bool', ++ '*keep-alive-count': { 'type': 'uint32', 'if': 'HAVE_TCP_KEEPCNT' }, ++ '*keep-alive-idle': { 'type': 'uint32', 'if': 'HAVE_TCP_KEEPIDLE' }, ++ '*keep-alive-interval': { 'type': 'uint32', 'if': 'HAVE_TCP_KEEPINTVL' }, + '*mptcp': { 'type': 'bool', 'if': 'HAVE_IPPROTO_MPTCP' } } } + + ## +diff --git a/tests/unit/test-util-sockets.c b/tests/unit/test-util-sockets.c +index 9e39b92e7c..8492f4d68f 100644 +--- a/tests/unit/test-util-sockets.c ++++ b/tests/unit/test-util-sockets.c +@@ -359,6 +359,24 @@ static void inet_parse_test_helper(const char *str, + g_assert_cmpint(addr.ipv6, ==, exp_addr->ipv6); + g_assert_cmpint(addr.has_keep_alive, ==, exp_addr->has_keep_alive); + g_assert_cmpint(addr.keep_alive, ==, exp_addr->keep_alive); ++#ifdef HAVE_TCP_KEEPCNT ++ g_assert_cmpint(addr.has_keep_alive_count, ==, ++ exp_addr->has_keep_alive_count); ++ g_assert_cmpint(addr.keep_alive_count, ==, ++ exp_addr->keep_alive_count); ++#endif ++#ifdef HAVE_TCP_KEEPIDLE ++ g_assert_cmpint(addr.has_keep_alive_idle, ==, ++ exp_addr->has_keep_alive_idle); ++ g_assert_cmpint(addr.keep_alive_idle, ==, ++ exp_addr->keep_alive_idle); ++#endif ++#ifdef HAVE_TCP_KEEPINTVL ++ g_assert_cmpint(addr.has_keep_alive_interval, ==, ++ exp_addr->has_keep_alive_interval); ++ g_assert_cmpint(addr.keep_alive_interval, ==, ++ exp_addr->keep_alive_interval); ++#endif + #ifdef HAVE_IPPROTO_MPTCP + g_assert_cmpint(addr.has_mptcp, ==, exp_addr->has_mptcp); + g_assert_cmpint(addr.mptcp, ==, exp_addr->mptcp); +@@ -460,6 +478,18 @@ static void test_inet_parse_all_options_good(void) + .ipv6 = true, + .has_keep_alive = true, + .keep_alive = true, ++#ifdef HAVE_TCP_KEEPCNT ++ .has_keep_alive_count = true, ++ .keep_alive_count = 10, ++#endif ++#ifdef HAVE_TCP_KEEPIDLE ++ .has_keep_alive_idle = true, ++ .keep_alive_idle = 60, ++#endif ++#ifdef HAVE_TCP_KEEPINTVL ++ .has_keep_alive_interval = true, ++ .keep_alive_interval = 30, ++#endif + #ifdef HAVE_IPPROTO_MPTCP + .has_mptcp = true, + .mptcp = false, +@@ -467,6 +497,15 @@ static void test_inet_parse_all_options_good(void) + }; + inet_parse_test_helper( + "[::1]:5000,numeric=on,to=5006,ipv4=off,ipv6=on,keep-alive=on" ++#ifdef HAVE_TCP_KEEPCNT ++ ",keep-alive-count=10" ++#endif ++#ifdef HAVE_TCP_KEEPIDLE ++ ",keep-alive-idle=60" ++#endif ++#ifdef HAVE_TCP_KEEPINTVL ++ ",keep-alive-interval=30" ++#endif + #ifdef HAVE_IPPROTO_MPTCP + ",mptcp=off" + #endif +diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c +index 403dc26b36..4773755fd5 100644 +--- a/util/qemu-sockets.c ++++ b/util/qemu-sockets.c +@@ -45,6 +45,14 @@ + # define AI_NUMERICSERV 0 + #endif + ++/* ++ * On macOS TCP_KEEPIDLE is available under a different name, TCP_KEEPALIVE. ++ * https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/bsd/man/man4/tcp.4#L172 ++ */ ++#if defined(TCP_KEEPALIVE) && !defined(TCP_KEEPIDLE) ++# define TCP_KEEPIDLE TCP_KEEPALIVE ++#endif ++ + + static int inet_getport(struct addrinfo *e) + { +@@ -218,6 +226,42 @@ static int inet_set_sockopts(int sock, InetSocketAddress *saddr, Error **errp) + "Unable to set keep-alive option on socket"); + return -1; + } ++#ifdef HAVE_TCP_KEEPCNT ++ if (saddr->has_keep_alive_count && saddr->keep_alive_count) { ++ int keep_count = saddr->keep_alive_count; ++ ret = setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, &keep_count, ++ sizeof(keep_count)); ++ if (ret < 0) { ++ error_setg_errno(errp, errno, ++ "Unable to set TCP keep-alive count option on socket"); ++ return -1; ++ } ++ } ++#endif ++#ifdef HAVE_TCP_KEEPIDLE ++ if (saddr->has_keep_alive_idle && saddr->keep_alive_idle) { ++ int keep_idle = saddr->keep_alive_idle; ++ ret = setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, &keep_idle, ++ sizeof(keep_idle)); ++ if (ret < 0) { ++ error_setg_errno(errp, errno, ++ "Unable to set TCP keep-alive idle option on socket"); ++ return -1; ++ } ++ } ++#endif ++#ifdef HAVE_TCP_KEEPINTVL ++ if (saddr->has_keep_alive_interval && saddr->keep_alive_interval) { ++ int keep_interval = saddr->keep_alive_interval; ++ ret = setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, &keep_interval, ++ sizeof(keep_interval)); ++ if (ret < 0) { ++ error_setg_errno(errp, errno, ++ "Unable to set TCP keep-alive interval option on socket"); ++ return -1; ++ } ++ } ++#endif + } + return 0; + } +@@ -630,6 +674,24 @@ static QemuOptsList inet_opts = { + .name = "keep-alive", + .type = QEMU_OPT_BOOL, + }, ++#ifdef HAVE_TCP_KEEPCNT ++ { ++ .name = "keep-alive-count", ++ .type = QEMU_OPT_NUMBER, ++ }, ++#endif ++#ifdef HAVE_TCP_KEEPIDLE ++ { ++ .name = "keep-alive-idle", ++ .type = QEMU_OPT_NUMBER, ++ }, ++#endif ++#ifdef HAVE_TCP_KEEPINTVL ++ { ++ .name = "keep-alive-interval", ++ .type = QEMU_OPT_NUMBER, ++ }, ++#endif + #ifdef HAVE_IPPROTO_MPTCP + { + .name = "mptcp", +@@ -695,6 +757,24 @@ int inet_parse(InetSocketAddress *addr, const char *str, Error **errp) + addr->has_keep_alive = true; + addr->keep_alive = qemu_opt_get_bool(opts, "keep-alive", false); + } ++#ifdef HAVE_TCP_KEEPCNT ++ if (qemu_opt_find(opts, "keep-alive-count")) { ++ addr->has_keep_alive_count = true; ++ addr->keep_alive_count = qemu_opt_get_number(opts, "keep-alive-count", 0); ++ } ++#endif ++#ifdef HAVE_TCP_KEEPIDLE ++ if (qemu_opt_find(opts, "keep-alive-idle")) { ++ addr->has_keep_alive_idle = true; ++ addr->keep_alive_idle = qemu_opt_get_number(opts, "keep-alive-idle", 0); ++ } ++#endif ++#ifdef HAVE_TCP_KEEPINTVL ++ if (qemu_opt_find(opts, "keep-alive-interval")) { ++ addr->has_keep_alive_interval = true; ++ addr->keep_alive_interval = qemu_opt_get_number(opts, "keep-alive-interval", 0); ++ } ++#endif + #ifdef HAVE_IPPROTO_MPTCP + if (qemu_opt_find(opts, "mptcp")) { + addr->has_mptcp = true; +-- +2.39.3 + diff --git a/kvm-util-qemu-sockets-Refactor-inet_parse-to-use-QemuOpt.patch b/kvm-util-qemu-sockets-Refactor-inet_parse-to-use-QemuOpt.patch new file mode 100644 index 0000000..036c406 --- /dev/null +++ b/kvm-util-qemu-sockets-Refactor-inet_parse-to-use-QemuOpt.patch @@ -0,0 +1,460 @@ +From 56ed06502da893f9fd756cbe683917c64f4af0a6 Mon Sep 17 00:00:00 2001 +From: Juraj Marcin +Date: Wed, 21 May 2025 15:52:34 +0200 +Subject: [PATCH 7/9] util/qemu-sockets: Refactor inet_parse() to use QemuOpts +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Juraj Marcin +RH-MergeRequest: 368: util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive +RH-Jira: RHEL-67706 +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina +RH-Commit: [5/7] 49ea5df8850a7518eb546c27878551cdb1aaa9ff (JurajMarcin/centos-src-qemu-kvm) + +Currently, the inet address parser cannot handle multiple options where +one is prefixed with the name of the other. For example, with the +'keep-alive-idle' option added, the current parser cannot parse +'127.0.0.1:5000,keep-alive-idle=60,keep-alive' correctly. Instead, it +fails with "error parsing 'keep-alive' flag '-idle=60,keep-alive'". + +To resolve these issues, this patch rewrites the inet address parsing +using the QemuOpts parser, which the inet_parse_flag() function tries to +mimic. This new parser supports all previously supported options and on +top of that the 'numeric' flag is now also supported. The only +difference is, the new parser produces an error if an unknown option is +passed, instead of silently ignoring it. + +Signed-off-by: Juraj Marcin +Reviewed-by: Daniel P. BerrangĂ© +Signed-off-by: Daniel P. BerrangĂ© + +(cherry picked from commit 316e8ee8d614f049bfae697570a5e62af450491c) + +JIRA: https://issues.redhat.com/browse/RHEL-67706 + +Signed-off-by: Juraj Marcin +--- + tests/unit/test-util-sockets.c | 196 +++++++++++++++++++++++++++++++++ + util/qemu-sockets.c | 158 +++++++++++++------------- + 2 files changed, 270 insertions(+), 84 deletions(-) + +diff --git a/tests/unit/test-util-sockets.c b/tests/unit/test-util-sockets.c +index 4c9dd0b271..9e39b92e7c 100644 +--- a/tests/unit/test-util-sockets.c ++++ b/tests/unit/test-util-sockets.c +@@ -332,6 +332,177 @@ static void test_socket_unix_abstract(void) + + #endif /* CONFIG_LINUX */ + ++static void inet_parse_test_helper(const char *str, ++ InetSocketAddress *exp_addr, bool success) ++{ ++ InetSocketAddress addr; ++ Error *error = NULL; ++ ++ int rc = inet_parse(&addr, str, &error); ++ ++ if (success) { ++ g_assert_cmpint(rc, ==, 0); ++ } else { ++ g_assert_cmpint(rc, <, 0); ++ } ++ if (exp_addr != NULL) { ++ g_assert_cmpstr(addr.host, ==, exp_addr->host); ++ g_assert_cmpstr(addr.port, ==, exp_addr->port); ++ /* Own members: */ ++ g_assert_cmpint(addr.has_numeric, ==, exp_addr->has_numeric); ++ g_assert_cmpint(addr.numeric, ==, exp_addr->numeric); ++ g_assert_cmpint(addr.has_to, ==, exp_addr->has_to); ++ g_assert_cmpint(addr.to, ==, exp_addr->to); ++ g_assert_cmpint(addr.has_ipv4, ==, exp_addr->has_ipv4); ++ g_assert_cmpint(addr.ipv4, ==, exp_addr->ipv4); ++ g_assert_cmpint(addr.has_ipv6, ==, exp_addr->has_ipv6); ++ g_assert_cmpint(addr.ipv6, ==, exp_addr->ipv6); ++ g_assert_cmpint(addr.has_keep_alive, ==, exp_addr->has_keep_alive); ++ g_assert_cmpint(addr.keep_alive, ==, exp_addr->keep_alive); ++#ifdef HAVE_IPPROTO_MPTCP ++ g_assert_cmpint(addr.has_mptcp, ==, exp_addr->has_mptcp); ++ g_assert_cmpint(addr.mptcp, ==, exp_addr->mptcp); ++#endif ++ } ++ ++ g_free(addr.host); ++ g_free(addr.port); ++} ++ ++static void test_inet_parse_nohost_good(void) ++{ ++ char host[] = ""; ++ char port[] = "5000"; ++ InetSocketAddress exp_addr = { ++ .host = host, ++ .port = port, ++ }; ++ inet_parse_test_helper(":5000", &exp_addr, true); ++} ++ ++static void test_inet_parse_empty_bad(void) ++{ ++ inet_parse_test_helper("", NULL, false); ++} ++ ++static void test_inet_parse_only_colon_bad(void) ++{ ++ inet_parse_test_helper(":", NULL, false); ++} ++ ++static void test_inet_parse_ipv4_good(void) ++{ ++ char host[] = "127.0.0.1"; ++ char port[] = "5000"; ++ InetSocketAddress exp_addr = { ++ .host = host, ++ .port = port, ++ }; ++ inet_parse_test_helper("127.0.0.1:5000", &exp_addr, true); ++} ++ ++static void test_inet_parse_ipv4_noport_bad(void) ++{ ++ inet_parse_test_helper("127.0.0.1", NULL, false); ++} ++ ++static void test_inet_parse_ipv6_good(void) ++{ ++ char host[] = "::1"; ++ char port[] = "5000"; ++ InetSocketAddress exp_addr = { ++ .host = host, ++ .port = port, ++ }; ++ inet_parse_test_helper("[::1]:5000", &exp_addr, true); ++} ++ ++static void test_inet_parse_ipv6_noend_bad(void) ++{ ++ inet_parse_test_helper("[::1", NULL, false); ++} ++ ++static void test_inet_parse_ipv6_noport_bad(void) ++{ ++ inet_parse_test_helper("[::1]:", NULL, false); ++} ++ ++static void test_inet_parse_ipv6_empty_bad(void) ++{ ++ inet_parse_test_helper("[]:5000", NULL, false); ++} ++ ++static void test_inet_parse_hostname_good(void) ++{ ++ char host[] = "localhost"; ++ char port[] = "5000"; ++ InetSocketAddress exp_addr = { ++ .host = host, ++ .port = port, ++ }; ++ inet_parse_test_helper("localhost:5000", &exp_addr, true); ++} ++ ++static void test_inet_parse_all_options_good(void) ++{ ++ char host[] = "::1"; ++ char port[] = "5000"; ++ InetSocketAddress exp_addr = { ++ .host = host, ++ .port = port, ++ .has_numeric = true, ++ .numeric = true, ++ .has_to = true, ++ .to = 5006, ++ .has_ipv4 = true, ++ .ipv4 = false, ++ .has_ipv6 = true, ++ .ipv6 = true, ++ .has_keep_alive = true, ++ .keep_alive = true, ++#ifdef HAVE_IPPROTO_MPTCP ++ .has_mptcp = true, ++ .mptcp = false, ++#endif ++ }; ++ inet_parse_test_helper( ++ "[::1]:5000,numeric=on,to=5006,ipv4=off,ipv6=on,keep-alive=on" ++#ifdef HAVE_IPPROTO_MPTCP ++ ",mptcp=off" ++#endif ++ , &exp_addr, true); ++} ++ ++static void test_inet_parse_all_implicit_bool_good(void) ++{ ++ char host[] = "::1"; ++ char port[] = "5000"; ++ InetSocketAddress exp_addr = { ++ .host = host, ++ .port = port, ++ .has_numeric = true, ++ .numeric = true, ++ .has_to = true, ++ .to = 5006, ++ .has_ipv4 = true, ++ .ipv4 = true, ++ .has_ipv6 = true, ++ .ipv6 = true, ++ .has_keep_alive = true, ++ .keep_alive = true, ++#ifdef HAVE_IPPROTO_MPTCP ++ .has_mptcp = true, ++ .mptcp = true, ++#endif ++ }; ++ inet_parse_test_helper( ++ "[::1]:5000,numeric,to=5006,ipv4,ipv6,keep-alive" ++#ifdef HAVE_IPPROTO_MPTCP ++ ",mptcp" ++#endif ++ , &exp_addr, true); ++} ++ + int main(int argc, char **argv) + { + bool has_ipv4, has_ipv6; +@@ -377,6 +548,31 @@ int main(int argc, char **argv) + test_socket_unix_abstract); + #endif + ++ g_test_add_func("/util/socket/inet-parse/nohost-good", ++ test_inet_parse_nohost_good); ++ g_test_add_func("/util/socket/inet-parse/empty-bad", ++ test_inet_parse_empty_bad); ++ g_test_add_func("/util/socket/inet-parse/only-colon-bad", ++ test_inet_parse_only_colon_bad); ++ g_test_add_func("/util/socket/inet-parse/ipv4-good", ++ test_inet_parse_ipv4_good); ++ g_test_add_func("/util/socket/inet-parse/ipv4-noport-bad", ++ test_inet_parse_ipv4_noport_bad); ++ g_test_add_func("/util/socket/inet-parse/ipv6-good", ++ test_inet_parse_ipv6_good); ++ g_test_add_func("/util/socket/inet-parse/ipv6-noend-bad", ++ test_inet_parse_ipv6_noend_bad); ++ g_test_add_func("/util/socket/inet-parse/ipv6-noport-bad", ++ test_inet_parse_ipv6_noport_bad); ++ g_test_add_func("/util/socket/inet-parse/ipv6-empty-bad", ++ test_inet_parse_ipv6_empty_bad); ++ g_test_add_func("/util/socket/inet-parse/hostname-good", ++ test_inet_parse_hostname_good); ++ g_test_add_func("/util/socket/inet-parse/all-options-good", ++ test_inet_parse_all_options_good); ++ g_test_add_func("/util/socket/inet-parse/all-bare-bool-good", ++ test_inet_parse_all_implicit_bool_good); ++ + end: + return g_test_run(); + } +diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c +index 4fbf1ed5bf..403dc26b36 100644 +--- a/util/qemu-sockets.c ++++ b/util/qemu-sockets.c +@@ -30,6 +30,7 @@ + #include "qapi/qobject-input-visitor.h" + #include "qapi/qobject-output-visitor.h" + #include "qemu/cutils.h" ++#include "qemu/option.h" + #include "trace.h" + + #ifndef AI_ADDRCONFIG +@@ -600,115 +601,104 @@ err: + return -1; + } + +-/* compatibility wrapper */ +-static int inet_parse_flag(const char *flagname, const char *optstr, bool *val, +- Error **errp) +-{ +- char *end; +- size_t len; +- +- end = strstr(optstr, ","); +- if (end) { +- if (end[1] == ',') { /* Reject 'ipv6=on,,foo' */ +- error_setg(errp, "error parsing '%s' flag '%s'", flagname, optstr); +- return -1; +- } +- len = end - optstr; +- } else { +- len = strlen(optstr); +- } +- if (len == 0 || (len == 3 && strncmp(optstr, "=on", len) == 0)) { +- *val = true; +- } else if (len == 4 && strncmp(optstr, "=off", len) == 0) { +- *val = false; +- } else { +- error_setg(errp, "error parsing '%s' flag '%s'", flagname, optstr); +- return -1; +- } +- return 0; +-} ++static QemuOptsList inet_opts = { ++ .name = "InetSocketAddress", ++ .head = QTAILQ_HEAD_INITIALIZER(inet_opts.head), ++ .implied_opt_name = "addr", ++ .desc = { ++ { ++ .name = "addr", ++ .type = QEMU_OPT_STRING, ++ }, ++ { ++ .name = "numeric", ++ .type = QEMU_OPT_BOOL, ++ }, ++ { ++ .name = "to", ++ .type = QEMU_OPT_NUMBER, ++ }, ++ { ++ .name = "ipv4", ++ .type = QEMU_OPT_BOOL, ++ }, ++ { ++ .name = "ipv6", ++ .type = QEMU_OPT_BOOL, ++ }, ++ { ++ .name = "keep-alive", ++ .type = QEMU_OPT_BOOL, ++ }, ++#ifdef HAVE_IPPROTO_MPTCP ++ { ++ .name = "mptcp", ++ .type = QEMU_OPT_BOOL, ++ }, ++#endif ++ { /* end of list */ } ++ }, ++}; + + int inet_parse(InetSocketAddress *addr, const char *str, Error **errp) + { +- const char *optstr, *h; +- char host[65]; +- char port[33]; +- int to; +- int pos; +- char *begin; +- ++ QemuOpts *opts = qemu_opts_parse(&inet_opts, str, true, errp); ++ if (!opts) { ++ return -1; ++ } + memset(addr, 0, sizeof(*addr)); + + /* parse address */ +- if (str[0] == ':') { +- /* no host given */ +- host[0] = '\0'; +- if (sscanf(str, ":%32[^,]%n", port, &pos) != 1) { +- error_setg(errp, "error parsing port in address '%s'", str); +- return -1; +- } +- } else if (str[0] == '[') { ++ const char *addr_str = qemu_opt_get(opts, "addr"); ++ if (!addr_str) { ++ error_setg(errp, "error parsing address ''"); ++ return -1; ++ } ++ if (str[0] == '[') { + /* IPv6 addr */ +- if (sscanf(str, "[%64[^]]]:%32[^,]%n", host, port, &pos) != 2) { +- error_setg(errp, "error parsing IPv6 address '%s'", str); ++ const char *ip_end = strstr(addr_str, "]:"); ++ if (!ip_end || ip_end - addr_str < 2 || strlen(ip_end) < 3) { ++ error_setg(errp, "error parsing IPv6 address '%s'", addr_str); + return -1; + } ++ addr->host = g_strndup(addr_str + 1, ip_end - addr_str - 1); ++ addr->port = g_strdup(ip_end + 2); + } else { +- /* hostname or IPv4 addr */ +- if (sscanf(str, "%64[^:]:%32[^,]%n", host, port, &pos) != 2) { +- error_setg(errp, "error parsing address '%s'", str); ++ /* no host, hostname or IPv4 addr */ ++ const char *port = strchr(addr_str, ':'); ++ if (!port || strlen(port) < 2) { ++ error_setg(errp, "error parsing address '%s'", addr_str); + return -1; + } ++ addr->host = g_strndup(addr_str, port - addr_str); ++ addr->port = g_strdup(port + 1); + } + +- addr->host = g_strdup(host); +- addr->port = g_strdup(port); +- + /* parse options */ +- optstr = str + pos; +- h = strstr(optstr, ",to="); +- if (h) { +- h += 4; +- if (sscanf(h, "%d%n", &to, &pos) != 1 || +- (h[pos] != '\0' && h[pos] != ',')) { +- error_setg(errp, "error parsing to= argument"); +- return -1; +- } ++ if (qemu_opt_find(opts, "numeric")) { ++ addr->has_numeric = true, ++ addr->numeric = qemu_opt_get_bool(opts, "numeric", false); ++ } ++ if (qemu_opt_find(opts, "to")) { + addr->has_to = true; +- addr->to = to; ++ addr->to = qemu_opt_get_number(opts, "to", 0); + } +- begin = strstr(optstr, ",ipv4"); +- if (begin) { +- if (inet_parse_flag("ipv4", begin + 5, &addr->ipv4, errp) < 0) { +- return -1; +- } ++ if (qemu_opt_find(opts, "ipv4")) { + addr->has_ipv4 = true; ++ addr->ipv4 = qemu_opt_get_bool(opts, "ipv4", false); + } +- begin = strstr(optstr, ",ipv6"); +- if (begin) { +- if (inet_parse_flag("ipv6", begin + 5, &addr->ipv6, errp) < 0) { +- return -1; +- } ++ if (qemu_opt_find(opts, "ipv6")) { + addr->has_ipv6 = true; ++ addr->ipv6 = qemu_opt_get_bool(opts, "ipv6", false); + } +- begin = strstr(optstr, ",keep-alive"); +- if (begin) { +- if (inet_parse_flag("keep-alive", begin + strlen(",keep-alive"), +- &addr->keep_alive, errp) < 0) +- { +- return -1; +- } ++ if (qemu_opt_find(opts, "keep-alive")) { + addr->has_keep_alive = true; ++ addr->keep_alive = qemu_opt_get_bool(opts, "keep-alive", false); + } + #ifdef HAVE_IPPROTO_MPTCP +- begin = strstr(optstr, ",mptcp"); +- if (begin) { +- if (inet_parse_flag("mptcp", begin + strlen(",mptcp"), +- &addr->mptcp, errp) < 0) +- { +- return -1; +- } ++ if (qemu_opt_find(opts, "mptcp")) { + addr->has_mptcp = true; ++ addr->mptcp = qemu_opt_get_bool(opts, "mptcp", 0); + } + #endif + return 0; +-- +2.39.3 + diff --git a/kvm-util-qemu-sockets-Refactor-setting-client-sockopts-i.patch b/kvm-util-qemu-sockets-Refactor-setting-client-sockopts-i.patch new file mode 100644 index 0000000..b9329d6 --- /dev/null +++ b/kvm-util-qemu-sockets-Refactor-setting-client-sockopts-i.patch @@ -0,0 +1,83 @@ +From e6348c4dd343f1a367a30f08c01a0f25c764a93c Mon Sep 17 00:00:00 2001 +From: Juraj Marcin +Date: Wed, 21 May 2025 15:52:31 +0200 +Subject: [PATCH 4/9] util/qemu-sockets: Refactor setting client sockopts into + a separate function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Juraj Marcin +RH-MergeRequest: 368: util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive +RH-Jira: RHEL-67706 +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina +RH-Commit: [2/7] c06976f96dbdf70b15079aa81dd1ac87abb0f1ab (JurajMarcin/centos-src-qemu-kvm) + +This is done in preparation for enabling the SO_KEEPALIVE support for +server sockets and adding settings for more TCP keep-alive socket +options. + +Signed-off-by: Juraj Marcin +Reviewed-by: Daniel P. BerrangĂ© +Signed-off-by: Daniel P. BerrangĂ© + +(cherry picked from commit b8b5278aca78be4a1c2e7cbb11c6be176f63706d) + +JIRA: https://issues.redhat.com/browse/RHEL-67706 + +Signed-off-by: Juraj Marcin +--- + util/qemu-sockets.c | 29 +++++++++++++++++++---------- + 1 file changed, 19 insertions(+), 10 deletions(-) + +diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c +index 77477c1cd5..4a878e0527 100644 +--- a/util/qemu-sockets.c ++++ b/util/qemu-sockets.c +@@ -205,6 +205,22 @@ static int try_bind(int socket, InetSocketAddress *saddr, struct addrinfo *e) + #endif + } + ++static int inet_set_sockopts(int sock, InetSocketAddress *saddr, Error **errp) ++{ ++ if (saddr->keep_alive) { ++ int keep_alive = 1; ++ int ret = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, ++ &keep_alive, sizeof(keep_alive)); ++ ++ if (ret < 0) { ++ error_setg_errno(errp, errno, ++ "Unable to set keep-alive option on socket"); ++ return -1; ++ } ++ } ++ return 0; ++} ++ + static int inet_listen_saddr(InetSocketAddress *saddr, + int port_offset, + int num, +@@ -475,16 +491,9 @@ int inet_connect_saddr(InetSocketAddress *saddr, Error **errp) + return sock; + } + +- if (saddr->keep_alive) { +- int val = 1; +- int ret = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, +- &val, sizeof(val)); +- +- if (ret < 0) { +- error_setg_errno(errp, errno, "Unable to set KEEPALIVE"); +- close(sock); +- return -1; +- } ++ if (inet_set_sockopts(sock, saddr, errp) < 0) { ++ close(sock); ++ return -1; + } + + return sock; +-- +2.39.3 + diff --git a/kvm-util-qemu-sockets-Refactor-success-and-failure-paths.patch b/kvm-util-qemu-sockets-Refactor-success-and-failure-paths.patch new file mode 100644 index 0000000..ff7ecb4 --- /dev/null +++ b/kvm-util-qemu-sockets-Refactor-success-and-failure-paths.patch @@ -0,0 +1,141 @@ +From 5001e77f9a8b91bee86e5c8ecbc417d0d2551855 Mon Sep 17 00:00:00 2001 +From: Juraj Marcin +Date: Wed, 21 May 2025 15:52:32 +0200 +Subject: [PATCH 5/9] util/qemu-sockets: Refactor success and failure paths in + inet_listen_saddr() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Juraj Marcin +RH-MergeRequest: 368: util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive +RH-Jira: RHEL-67706 +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina +RH-Commit: [3/7] 2e18c6f6eeadf99d6a526a089009bb89cd2fd6a8 (JurajMarcin/centos-src-qemu-kvm) + +To get a listening socket, we need to first create a socket, try binding +it to a certain port, and lastly starting listening to it. Each of these +operations can fail due to various reasons, one of them being that the +requested address/port is already in use. In such case, the function +tries the same process with a new port number. + +This patch refactors the port number loop, so the success path is no +longer buried inside the 'if' statements in the middle of the loop. Now, +the success path is not nested and ends at the end of the iteration +after successful socket creation, binding, and listening. In case any of +the operations fails, it either continues to the next iteration (and the +next port) or jumps out of the loop to handle the error and exits the +function. + +Signed-off-by: Juraj Marcin +Reviewed-by: Daniel P. BerrangĂ© +Signed-off-by: Daniel P. BerrangĂ© + +(cherry picked from commit 911e0f2c6e2d00c985affa75ec188c8edcf480f2) + +JIRA: https://issues.redhat.com/browse/RHEL-67706 + +Signed-off-by: Juraj Marcin +--- + util/qemu-sockets.c | 51 ++++++++++++++++++++++++--------------------- + 1 file changed, 27 insertions(+), 24 deletions(-) + +diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c +index 4a878e0527..329fdbfd97 100644 +--- a/util/qemu-sockets.c ++++ b/util/qemu-sockets.c +@@ -303,11 +303,20 @@ static int inet_listen_saddr(InetSocketAddress *saddr, + port_min = inet_getport(e); + port_max = saddr->has_to ? saddr->to + port_offset : port_min; + for (p = port_min; p <= port_max; p++) { ++ if (slisten >= 0) { ++ /* ++ * We have a socket we tried with the previous port. It cannot ++ * be rebound, we need to close it and create a new one. ++ */ ++ close(slisten); ++ slisten = -1; ++ } + inet_setport(e, p); + + slisten = create_fast_reuse_socket(e); + if (slisten < 0) { +- /* First time we expect we might fail to create the socket ++ /* ++ * First time we expect we might fail to create the socket + * eg if 'e' has AF_INET6 but ipv6 kmod is not loaded. + * Later iterations should always succeed if first iteration + * worked though, so treat that as fatal. +@@ -317,40 +326,38 @@ static int inet_listen_saddr(InetSocketAddress *saddr, + } else { + error_setg_errno(errp, errno, + "Failed to recreate failed listening socket"); +- goto listen_failed; ++ goto fail; + } + } + socket_created = true; + + rc = try_bind(slisten, saddr, e); + if (rc < 0) { +- if (errno != EADDRINUSE) { +- error_setg_errno(errp, errno, "Failed to bind socket"); +- goto listen_failed; +- } +- } else { +- if (!listen(slisten, num)) { +- goto listen_ok; ++ if (errno == EADDRINUSE) { ++ /* This port is already used, try the next one */ ++ continue; + } +- if (errno != EADDRINUSE) { +- error_setg_errno(errp, errno, "Failed to listen on socket"); +- goto listen_failed; ++ error_setg_errno(errp, errno, "Failed to bind socket"); ++ goto fail; ++ } ++ if (listen(slisten, num)) { ++ if (errno == EADDRINUSE) { ++ /* This port is already used, try the next one */ ++ continue; + } ++ error_setg_errno(errp, errno, "Failed to listen on socket"); ++ goto fail; + } +- /* Someone else managed to bind to the same port and beat us +- * to listen on it! Socket semantics does not allow us to +- * recover from this situation, so we need to recreate the +- * socket to allow bind attempts for subsequent ports: +- */ +- close(slisten); +- slisten = -1; ++ /* We have a listening socket */ ++ freeaddrinfo(res); ++ return slisten; + } + } + error_setg_errno(errp, errno, + socket_created ? + "Failed to find an available port" : + "Failed to create a socket"); +-listen_failed: ++fail: + saved_errno = errno; + if (slisten >= 0) { + close(slisten); +@@ -358,10 +365,6 @@ listen_failed: + freeaddrinfo(res); + errno = saved_errno; + return -1; +- +-listen_ok: +- freeaddrinfo(res); +- return slisten; + } + + #ifdef _WIN32 +-- +2.39.3 + diff --git a/kvm-vfio-container-Fix-container-object-destruction.patch b/kvm-vfio-container-Fix-container-object-destruction.patch deleted file mode 100644 index aa9bcb9..0000000 --- a/kvm-vfio-container-Fix-container-object-destruction.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 21236464550a1a4c844de937e48ff88619228ed7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Mon, 18 Nov 2024 16:34:40 +0100 -Subject: [PATCH 1/3] vfio/container: Fix container object destruction -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: CĂ©dric Le Goater -RH-MergeRequest: 294: vfio/container: Fix container object destruction -RH-Jira: RHEL-67936 -RH-Acked-by: Eric Auger -RH-Acked-by: Alex Williamson -RH-Commit: [1/1] 5ae46457515b16aee12f5e010d9ef3179525f57f (clegoate/qemu-kvm-centos) - -JIRA: https://issues.redhat.com/browse/RHEL-67936 - -commit ebbf7c60bbd1ceedf9faf962e428ceda2388c248 -Author: CĂ©dric Le Goater -Date: Fri Nov 15 09:34:40 2024 +0100 - - vfio/container: Fix container object destruction - - When commit 96b7af4388b3 intoduced a .instance_finalize() handler, - it did not take into account that the container was not necessarily - inserted into the container list of the address space. Hence, if - the container object is destroyed, by calling object_unref() for - example, before vfio_address_space_insert() is called, QEMU may - crash when removing the container from the list as done in - vfio_container_instance_finalize(). This was seen with an SEV-SNP - guest for which discarding of RAM fails. - - To resolve this issue, use the safe version of QLIST_REMOVE(). - - Cc: Zhenzhong Duan - Cc: Eric Auger - Fixes: 96b7af4388b3 ("vfio/container: Move vfio_container_destroy() to an instance_finalize() handler") - Reviewed-by: Zhenzhong Duan - Signed-off-by: CĂ©dric Le Goater - -Signed-off-by: CĂ©dric Le Goater ---- - hw/vfio/container-base.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c -index 809b157674..6f86c37d97 100644 ---- a/hw/vfio/container-base.c -+++ b/hw/vfio/container-base.c -@@ -103,7 +103,7 @@ static void vfio_container_instance_finalize(Object *obj) - VFIOContainerBase *bcontainer = VFIO_IOMMU(obj); - VFIOGuestIOMMU *giommu, *tmp; - -- QLIST_REMOVE(bcontainer, next); -+ QLIST_SAFE_REMOVE(bcontainer, next); - - QLIST_FOREACH_SAFE(giommu, &bcontainer->giommu_list, giommu_next, tmp) { - memory_region_unregister_iommu_notifier( --- -2.39.3 - diff --git a/kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch b/kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch deleted file mode 100644 index d0a5cdf..0000000 --- a/kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 85752ed0d3bdf707a9c84a12b8b717d932b882a6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Wed, 6 Nov 2024 17:31:16 +0100 -Subject: [PATCH 27/38] vfio/migration: Change trace formats from hex to - decimal -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: CĂ©dric Le Goater -RH-MergeRequest: 283: vfio/migration: Report only stop-copy size in vfio_state_pending_exact() -RH-Jira: RHEL-64308 -RH-Acked-by: Peter Xu -RH-Acked-by: Alex Williamson -RH-Commit: [2/2] c4f7485b3ad4f779a2f13b6f09c9bb5712a45401 (clegoate/qemu-kvm-c9s) - -JIRA: https://issues.redhat.com/browse/RHEL-64308 - -commit fa4e20defe239e42af0a1b5c030dec114f799f56 -Author: Avihai Horon -Date: Sun Oct 20 16:01:08 2024 +0300 - - vfio/migration: Change trace formats from hex to decimal - - Data sizes in VFIO migration trace events are printed in hex format - while in migration core trace events they are printed in decimal format. - - This inconsistency makes it less readable when using both trace event - types. Hence, change the data sizes print format to decimal in VFIO - migration trace events. - - Signed-off-by: Avihai Horon - Reviewed-by: CĂ©dric Le Goater - -Signed-off-by: CĂ©dric Le Goater ---- - hw/vfio/trace-events | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events -index 98bd4dccea..3756ff660e 100644 ---- a/hw/vfio/trace-events -+++ b/hw/vfio/trace-events -@@ -151,7 +151,7 @@ vfio_display_edid_write_error(void) "" - vfio_load_cleanup(const char *name) " (%s)" - vfio_load_device_config_state(const char *name) " (%s)" - vfio_load_state(const char *name, uint64_t data) " (%s) data 0x%"PRIx64 --vfio_load_state_device_data(const char *name, uint64_t data_size, int ret) " (%s) size 0x%"PRIx64" ret %d" -+vfio_load_state_device_data(const char *name, uint64_t data_size, int ret) " (%s) size %"PRIu64" ret %d" - vfio_migration_realize(const char *name) " (%s)" - vfio_migration_set_device_state(const char *name, const char *state) " (%s) state %s" - vfio_migration_set_state(const char *name, const char *new_state, const char *recover_state) " (%s) new state %s, recover state %s" -@@ -160,10 +160,10 @@ vfio_save_block(const char *name, int data_size) " (%s) data_size %d" - vfio_save_cleanup(const char *name) " (%s)" - vfio_save_complete_precopy(const char *name, int ret) " (%s) ret %d" - vfio_save_device_config_state(const char *name) " (%s)" --vfio_save_iterate(const char *name, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy initial size 0x%"PRIx64" precopy dirty size 0x%"PRIx64 --vfio_save_setup(const char *name, uint64_t data_buffer_size) " (%s) data buffer size 0x%"PRIx64 --vfio_state_pending_estimate(const char *name, uint64_t precopy, uint64_t postcopy, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy 0x%"PRIx64" postcopy 0x%"PRIx64" precopy initial size 0x%"PRIx64" precopy dirty size 0x%"PRIx64 --vfio_state_pending_exact(const char *name, uint64_t precopy, uint64_t postcopy, uint64_t stopcopy_size, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy 0x%"PRIx64" postcopy 0x%"PRIx64" stopcopy size 0x%"PRIx64" precopy initial size 0x%"PRIx64" precopy dirty size 0x%"PRIx64 -+vfio_save_iterate(const char *name, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy initial size %"PRIu64" precopy dirty size %"PRIu64 -+vfio_save_setup(const char *name, uint64_t data_buffer_size) " (%s) data buffer size %"PRIu64 -+vfio_state_pending_estimate(const char *name, uint64_t precopy, uint64_t postcopy, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy %"PRIu64" postcopy %"PRIu64" precopy initial size %"PRIu64" precopy dirty size %"PRIu64 -+vfio_state_pending_exact(const char *name, uint64_t precopy, uint64_t postcopy, uint64_t stopcopy_size, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy %"PRIu64" postcopy %"PRIu64" stopcopy size %"PRIu64" precopy initial size %"PRIu64" precopy dirty size %"PRIu64 - vfio_vmstate_change(const char *name, int running, const char *reason, const char *dev_state) " (%s) running %d reason %s device state %s" - vfio_vmstate_change_prepare(const char *name, int running, const char *reason, const char *dev_state) " (%s) running %d reason %s device state %s" - --- -2.39.3 - diff --git a/kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch b/kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch deleted file mode 100644 index bb62e86..0000000 --- a/kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch +++ /dev/null @@ -1,66 +0,0 @@ -From d32c2291e836f912a72aedaf2ace31d4e1679f95 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= -Date: Wed, 6 Nov 2024 17:31:16 +0100 -Subject: [PATCH 26/38] vfio/migration: Report only stop-copy size in - vfio_state_pending_exact() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: CĂ©dric Le Goater -RH-MergeRequest: 283: vfio/migration: Report only stop-copy size in vfio_state_pending_exact() -RH-Jira: RHEL-64308 -RH-Acked-by: Peter Xu -RH-Acked-by: Alex Williamson -RH-Commit: [1/2] 85956ae33c6aea99dba95500595e0ca7dc9dcdad (clegoate/qemu-kvm-c9s) - -JIRA: https://issues.redhat.com/browse/RHEL-64308 - -commit 3b5948f808e3b99aedfa0aff45cffbe8b7ec07ed -Author: Avihai Horon -Date: Sun Oct 20 16:01:06 2024 +0300 - - vfio/migration: Report only stop-copy size in vfio_state_pending_exact() - - vfio_state_pending_exact() is used to update migration core how much - device data is left for the device migration. Currently, the sum of - pre-copy and stop-copy sizes of the VFIO device are reported. - - The pre-copy size is obtained via the VFIO_MIG_GET_PRECOPY_INFO ioctl, - which returns the amount of device data available to be transferred - while the device is in the PRE_COPY states. - - The stop-copy size is obtained via the VFIO_DEVICE_FEATURE_MIG_DATA_SIZE - ioctl, which returns the total amount of device data left to be - transferred in order to complete the device migration. - - According to the above, current implementation is wrong -- it reports - extra overlapping data because pre-copy size is already contained in - stop-copy size. Fix it by reporting only stop-copy size. - - Fixes: eda7362af959 ("vfio/migration: Add VFIO migration pre-copy support") - Signed-off-by: Avihai Horon - Reviewed-by: CĂ©dric Le Goater - -Signed-off-by: CĂ©dric Le Goater ---- - hw/vfio/migration.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c -index 262d42a46e..dd717e8d6c 100644 ---- a/hw/vfio/migration.c -+++ b/hw/vfio/migration.c -@@ -576,9 +576,6 @@ static void vfio_state_pending_exact(void *opaque, uint64_t *must_precopy, - - if (vfio_device_state_is_precopy(vbasedev)) { - vfio_query_precopy_size(migration); -- -- *must_precopy += -- migration->precopy_init_size + migration->precopy_dirty_size; - } - - trace_vfio_state_pending_exact(vbasedev->name, *must_precopy, *can_postcopy, --- -2.39.3 - diff --git a/kvm-vhost-Add-stubs-for-the-migration-state-transfer-int.patch b/kvm-vhost-Add-stubs-for-the-migration-state-transfer-int.patch deleted file mode 100644 index 427e75e..0000000 --- a/kvm-vhost-Add-stubs-for-the-migration-state-transfer-int.patch +++ /dev/null @@ -1,87 +0,0 @@ -From dcf22c934f3c3672d4a4b58a74b1f99619da1d3d Mon Sep 17 00:00:00 2001 -From: Laurent Vivier -Date: Wed, 15 Jan 2025 14:50:43 +0100 -Subject: [PATCH 2/3] vhost: Add stubs for the migration state transfer - interface - -RH-Author: Laurent Vivier -RH-MergeRequest: 336: virtio-net: vhost-user: Implement internal migration -RH-Jira: RHEL-78370 -RH-Acked-by: Hanna Czenczek -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/2] 4afc9b5f73e5ef2941bcf36e31c4771d2b3ab3ba (lvivier/qemu-kvm-centos) - -JIRA: https://issues.redhat.com/browse/RHEL-78370 - -Migration state transfer interface is only used by vhost-user-fs, -so the interface needs to be defined only when vhost is built. - -But I need to use this interface with virtio-net and vhost is not always -enabled, and to avoid undefined reference error during build, define stub -functions for vhost_supports_device_state(), vhost_save_backend_state() and -vhost_load_backend_state(). - -Cc: Hanna Czenczek -Signed-off-by: Laurent Vivier -Message-Id: <20250115135044.799698-2-lvivier@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry picked from commit 3f65357313e0f928e0bd3ff868b705855d0405bc) -Signed-off-by: Laurent Vivier ---- - include/hw/virtio/vhost.h | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h -index d75faf46e9..1d524f85b9 100644 ---- a/include/hw/virtio/vhost.h -+++ b/include/hw/virtio/vhost.h -@@ -363,7 +363,14 @@ static inline int vhost_reset_device(struct vhost_dev *hdev) - * Returns true if the device supports these commands, and false if it - * does not. - */ -+#ifdef CONFIG_VHOST - bool vhost_supports_device_state(struct vhost_dev *dev); -+#else -+static inline bool vhost_supports_device_state(struct vhost_dev *dev) -+{ -+ return false; -+} -+#endif - - /** - * vhost_set_device_state_fd(): Begin transfer of internal state from/to -@@ -446,7 +453,15 @@ int vhost_check_device_state(struct vhost_dev *dev, Error **errp); - * - * Returns 0 on success, and -errno otherwise. - */ -+#ifdef CONFIG_VHOST - int vhost_save_backend_state(struct vhost_dev *dev, QEMUFile *f, Error **errp); -+#else -+static inline int vhost_save_backend_state(struct vhost_dev *dev, QEMUFile *f, -+ Error **errp) -+{ -+ return -ENOSYS; -+} -+#endif - - /** - * vhost_load_backend_state(): High-level function to load a vhost -@@ -463,6 +478,14 @@ int vhost_save_backend_state(struct vhost_dev *dev, QEMUFile *f, Error **errp); - * - * Returns 0 on success, and -errno otherwise. - */ -+#ifdef CONFIG_VHOST - int vhost_load_backend_state(struct vhost_dev *dev, QEMUFile *f, Error **errp); -+#else -+static inline int vhost_load_backend_state(struct vhost_dev *dev, QEMUFile *f, -+ Error **errp) -+{ -+ return -ENOSYS; -+} -+#endif - - #endif --- -2.39.3 - diff --git a/kvm-vhost-fail-device-start-if-iotlb-update-fails.patch b/kvm-vhost-fail-device-start-if-iotlb-update-fails.patch deleted file mode 100644 index 854bb04..0000000 --- a/kvm-vhost-fail-device-start-if-iotlb-update-fails.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 2b12ea393b9a5d8392cb510406626f4c99c9f4c5 Mon Sep 17 00:00:00 2001 -From: Prasad Pandit -Date: Thu, 7 Nov 2024 17:02:47 +0530 -Subject: [PATCH 6/7] vhost: fail device start if iotlb update fails - -RH-Author: Prasad Pandit -RH-MergeRequest: 318: vhost: fail device start if iotlb update fails -RH-Jira: RHEL-73005 -RH-Acked-by: Stefano Garzarella -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/1] f185f02378ebbf36a38aef0ea608b70c637a4816 (pjp/cs-qemu-kvm) - -While starting a vhost device, updating iotlb entries -via 'vhost_device_iotlb_miss' may return an error. - - qemu-kvm: vhost_device_iotlb_miss: - 700871,700871: Fail to update device iotlb - -Fail device start when such an error occurs. - -Jira: https://issues.redhat.com/browse/RHEL-73005 -Signed-off-by: Prasad Pandit -Message-Id: <20241107113247.46532-1-ppandit@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Reviewed-by: Stefano Garzarella -(cherry picked from commit 571bdc97b83646dfd3746ec56fb2f70bca55b9a2) -Signed-off-by: Prasad Pandit ---- - hw/virtio/vhost.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 06fc71746e..e25fdce3dd 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -2151,11 +2151,22 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) - * vhost-kernel code requires for this.*/ - for (i = 0; i < hdev->nvqs; ++i) { - struct vhost_virtqueue *vq = hdev->vqs + i; -- vhost_device_iotlb_miss(hdev, vq->used_phys, true); -+ r = vhost_device_iotlb_miss(hdev, vq->used_phys, true); -+ if (r) { -+ goto fail_iotlb; -+ } - } - } - vhost_start_config_intr(hdev); - return 0; -+fail_iotlb: -+ if (vhost_dev_has_iommu(hdev) && -+ hdev->vhost_ops->vhost_set_iotlb_callback) { -+ hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false); -+ } -+ if (hdev->vhost_ops->vhost_dev_start) { -+ hdev->vhost_ops->vhost_dev_start(hdev, false); -+ } - fail_start: - if (vrings) { - vhost_dev_set_vring_enable(hdev, false); --- -2.39.3 - diff --git a/kvm-virtio-net-Add-queues-before-loading-them.patch b/kvm-virtio-net-Add-queues-before-loading-them.patch deleted file mode 100644 index 9ff0150..0000000 --- a/kvm-virtio-net-Add-queues-before-loading-them.patch +++ /dev/null @@ -1,94 +0,0 @@ -From cff01d88d59e4227c6801f9f4605f6d1333e0c37 Mon Sep 17 00:00:00 2001 -From: Akihiko Odaki -Date: Tue, 22 Oct 2024 15:49:01 +0900 -Subject: [PATCH 1/9] virtio-net: Add queues before loading them -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: 小田喜陽彦 -RH-MergeRequest: 274: virtio-net: Add queues before loading them -RH-Jira: RHEL-58316 -RH-Acked-by: Laurent Vivier -RH-Acked-by: Jason Wang -RH-Commit: [1/1] 0cdfea34b1466538abad0d9d216ea6bcfd21ac67 (akihiko.odaki/qemu-kvm) - -Call virtio_net_set_multiqueue() to add queues before loading their -states. Otherwise the loaded queues will not have handlers and elements -in them will not be processed. - -Cc: qemu-stable@nongnu.org -Fixes: 8c49756825da ("virtio-net: Add only one queue pair when realizing") -Reported-by: Laurent Vivier -Signed-off-by: Akihiko Odaki -Acked-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -(cherry picked from commit 9379ea9db3c0064fa2787db0794a23a30f7b2d2d) ---- - hw/net/virtio-net.c | 10 ++++++++++ - hw/virtio/virtio.c | 7 +++++++ - include/hw/virtio/virtio.h | 2 ++ - 3 files changed, 19 insertions(+) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index ed33a32877..90d05f94d4 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -3032,6 +3032,15 @@ static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue) - virtio_net_set_queue_pairs(n); - } - -+static int virtio_net_pre_load_queues(VirtIODevice *vdev) -+{ -+ virtio_net_set_multiqueue(VIRTIO_NET(vdev), -+ virtio_has_feature(vdev->guest_features, VIRTIO_NET_F_RSS) || -+ virtio_has_feature(vdev->guest_features, VIRTIO_NET_F_MQ)); -+ -+ return 0; -+} -+ - static int virtio_net_post_load_device(void *opaque, int version_id) - { - VirtIONet *n = opaque; -@@ -4010,6 +4019,7 @@ static void virtio_net_class_init(ObjectClass *klass, void *data) - vdc->guest_notifier_mask = virtio_net_guest_notifier_mask; - vdc->guest_notifier_pending = virtio_net_guest_notifier_pending; - vdc->legacy_features |= (0x1 << VIRTIO_NET_F_GSO); -+ vdc->pre_load_queues = virtio_net_pre_load_queues; - vdc->post_load = virtio_net_post_load_virtio; - vdc->vmsd = &vmstate_virtio_net_device; - vdc->primary_unplug_pending = primary_unplug_pending; -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index 9e10cbc058..10f24a58dd 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -3251,6 +3251,13 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id) - config_len--; - } - -+ if (vdc->pre_load_queues) { -+ ret = vdc->pre_load_queues(vdev); -+ if (ret) { -+ return ret; -+ } -+ } -+ - num = qemu_get_be32(f); - - if (num > VIRTIO_QUEUE_MAX) { -diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h -index 0fcbc5c0c6..953dfca27c 100644 ---- a/include/hw/virtio/virtio.h -+++ b/include/hw/virtio/virtio.h -@@ -210,6 +210,8 @@ struct VirtioDeviceClass { - void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask); - int (*start_ioeventfd)(VirtIODevice *vdev); - void (*stop_ioeventfd)(VirtIODevice *vdev); -+ /* Called before loading queues. Useful to add queues before loading. */ -+ int (*pre_load_queues)(VirtIODevice *vdev); - /* Saving and loading of a device; trying to deprecate save/load - * use vmsd for new devices. - */ --- -2.39.3 - diff --git a/kvm-virtio-net-disable-USO-for-RHEL9.patch b/kvm-virtio-net-disable-USO-for-RHEL9.patch deleted file mode 100644 index 6b32588..0000000 --- a/kvm-virtio-net-disable-USO-for-RHEL9.patch +++ /dev/null @@ -1,49 +0,0 @@ -From cd94a5c750554f21ddbff37f53ff629128200259 Mon Sep 17 00:00:00 2001 -From: "Michael S. Tsirkin" -Date: Wed, 6 Nov 2024 17:29:35 -0500 -Subject: [PATCH 2/3] virtio-net: disable USO for RHEL9 - -RH-Author: MST -RH-MergeRequest: 289: Disable USO for virtio-net to fix RHEL10 to RHEL9 migration -RH-Jira: RHEL-40950 -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/1] 9fc588b66c5bad72df1e9b644f48a2a7aa82bfa3 (mstredhat/qemu-kvm-centos) - -Theoretically, QEMU from RHEL9.3 and on supports USO, -but practically we clear the support because RHEL9 -kernels do not support that. - -Now that RHEL10 beta does we suddenly get a migration compatibility -issue. We should not have enabled the feature in RHEL9 userspace, -but luckily, it's not too late to fix that. - -Note: if we ever change RHEL9 kernel to enable USO, we will need to -mask this in RHEL9 QEMU, too. - -Upstream status: n/a: upstream has no guarantee if kernel features change -Tested: lightly on developer's machine. -JIRA: https://issues.redhat.com/browse/RHEL-40950 -Signed-off-by: Michael S. Tsirkin ---- - hw/core/machine.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/hw/core/machine.c b/hw/core/machine.c -index d95f246f66..04d180eac4 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -337,6 +337,11 @@ GlobalProperty hw_compat_rhel_9_5[] = { - { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" }, - /* hw_compat_rhel_9_5 from hw_compat_8_2 */ - { "virtio-gpu-device", "x-scanout-vmstate-version", "1" }, -+ /* supported by userspace, but RHEL 9 *kernels* do not support USO. */ -+ /* TODO: if we ever add 9.6 compat, this has to be there, too */ -+ { 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_5_len = G_N_ELEMENTS(hw_compat_rhel_9_5); - --- -2.39.3 - diff --git a/kvm-virtio-net-disable-USO-for-all-RHEL9.patch b/kvm-virtio-net-disable-USO-for-all-RHEL9.patch deleted file mode 100644 index 07fb75e..0000000 --- a/kvm-virtio-net-disable-USO-for-all-RHEL9.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 76376a85ff5cbe555db6a6d729fcb83f56988f25 Mon Sep 17 00:00:00 2001 -From: "Michael S. Tsirkin" -Date: Wed, 6 Nov 2024 17:29:35 -0500 -Subject: [PATCH 7/7] virtio-net: disable USO for all RHEL9 - -RH-Author: MST -RH-MergeRequest: 319: virtio-net migration: ensure compatibility of rhel9* -RH-Jira: RHEL-69500 -RH-Acked-by: Peter Xu -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/1] c7518d8293e1cfdd928f0ce454249ecb7bd7117a (mstredhat/qemu-kvm-centos) - -With commit 298dae99b77f ("virtio-net: disable USO for RHEL9") -we fixed migration for 9.6 but we forgot to apply the fix -for 9.6 when it was created. - -To help us not forget in 9.7 and beyond, create a generic RHEL9 compat -and apply it. - -Upstream status: n/a: upstream has no guarantee if kernel features change -Tested: lightly on developer's machine. -JIRA: https://issues.redhat.com/browse/RHEL-69500 -Signed-off-by: Michael S. Tsirkin - -Patch-name: kvm-virtio-net-disable-USO-for-RHEL9.patch -Patch-id: 83 -Patch-present-in-specfile: True ---- - hw/arm/virt.c | 3 +++ - hw/core/machine.c | 13 ++++++++----- - hw/i386/pc_q35.c | 3 +++ - hw/s390x/s390-virtio-ccw.c | 3 +++ - include/hw/boards.h | 3 +++ - 5 files changed, 20 insertions(+), 5 deletions(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 078098ec3a..6d55bba241 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -3595,6 +3595,9 @@ 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); -+ -+ /* 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) - -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 04d180eac4..1ee0e1dee8 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -327,6 +327,14 @@ GlobalProperty hw_compat_rhel_10_0[] = { - }; - 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 */ -@@ -337,11 +345,6 @@ GlobalProperty hw_compat_rhel_9_5[] = { - { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" }, - /* hw_compat_rhel_9_5 from hw_compat_8_2 */ - { "virtio-gpu-device", "x-scanout-vmstate-version", "1" }, -- /* supported by userspace, but RHEL 9 *kernels* do not support USO. */ -- /* TODO: if we ever add 9.6 compat, this has to be there, too */ -- { 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_5_len = G_N_ELEMENTS(hw_compat_rhel_9_5); - -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 506f9dc0c0..b2b8124225 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -690,6 +690,9 @@ static void pc_q35_rhel_machine_9_6_0_options(MachineClass *m) - m->alias = NULL; - 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_BUGFIX(9, 6, 0); -diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c -index 0347dc69ca..2e276ad72b 100644 ---- a/hw/s390x/s390-virtio-ccw.c -+++ b/hw/s390x/s390-virtio-ccw.c -@@ -1305,6 +1305,9 @@ static void ccw_rhel_machine_9_6_0_instance_options(MachineState *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); - -diff --git a/include/hw/boards.h b/include/hw/boards.h -index ac917b87fb..83d11de42f 100644 ---- a/include/hw/boards.h -+++ b/include/hw/boards.h -@@ -805,6 +805,9 @@ 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[]; -+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; - --- -2.39.3 - diff --git a/kvm-virtio-net-vhost-user-Implement-internal-migration.patch b/kvm-virtio-net-vhost-user-Implement-internal-migration.patch deleted file mode 100644 index 8f70917..0000000 --- a/kvm-virtio-net-vhost-user-Implement-internal-migration.patch +++ /dev/null @@ -1,161 +0,0 @@ -From bb1d7e0dd85a37912540c173f573e40dd1425e72 Mon Sep 17 00:00:00 2001 -From: Laurent Vivier -Date: Wed, 15 Jan 2025 14:50:44 +0100 -Subject: [PATCH 3/3] virtio-net: vhost-user: Implement internal migration - -RH-Author: Laurent Vivier -RH-MergeRequest: 336: virtio-net: vhost-user: Implement internal migration -RH-Jira: RHEL-78370 -RH-Acked-by: Hanna Czenczek -RH-Acked-by: Miroslav Rezanina -RH-Commit: [2/2] b7a9c887c47cea1a38ae8aee8901b74c84a6cd0d (lvivier/qemu-kvm-centos) - -JIRA: https://issues.redhat.com/browse/RHEL-78370 - -Add support of VHOST_USER_PROTOCOL_F_DEVICE_STATE in virtio-net -with vhost-user backend. - -Cc: Hanna Czenczek -Signed-off-by: Laurent Vivier -Message-Id: <20250115135044.799698-3-lvivier@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry picked from commit 60f543ad917fad731e39ff8ce2ca83b9a9cc9d90) -Signed-off-by: Laurent Vivier ---- - hw/net/virtio-net.c | 105 ++++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 97 insertions(+), 8 deletions(-) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 90d05f94d4..3d2b2460ad 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -3305,6 +3305,102 @@ static const VMStateDescription vmstate_virtio_net_rss = { - }, - }; - -+static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) -+{ -+ VirtIONet *n = VIRTIO_NET(vdev); -+ NetClientState *nc = qemu_get_queue(n->nic); -+ struct vhost_net *net = get_vhost_net(nc->peer); -+ return &net->dev; -+} -+ -+static int vhost_user_net_save_state(QEMUFile *f, void *pv, size_t size, -+ const VMStateField *field, -+ JSONWriter *vmdesc) -+{ -+ VirtIONet *n = pv; -+ VirtIODevice *vdev = VIRTIO_DEVICE(n); -+ struct vhost_dev *vhdev; -+ Error *local_error = NULL; -+ int ret; -+ -+ vhdev = virtio_net_get_vhost(vdev); -+ if (vhdev == NULL) { -+ error_reportf_err(local_error, -+ "Error getting vhost back-end of %s device %s: ", -+ vdev->name, vdev->parent_obj.canonical_path); -+ return -1; -+ } -+ -+ ret = vhost_save_backend_state(vhdev, f, &local_error); -+ if (ret < 0) { -+ error_reportf_err(local_error, -+ "Error saving back-end state of %s device %s: ", -+ vdev->name, vdev->parent_obj.canonical_path); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int vhost_user_net_load_state(QEMUFile *f, void *pv, size_t size, -+ const VMStateField *field) -+{ -+ VirtIONet *n = pv; -+ VirtIODevice *vdev = VIRTIO_DEVICE(n); -+ struct vhost_dev *vhdev; -+ Error *local_error = NULL; -+ int ret; -+ -+ vhdev = virtio_net_get_vhost(vdev); -+ if (vhdev == NULL) { -+ error_reportf_err(local_error, -+ "Error getting vhost back-end of %s device %s: ", -+ vdev->name, vdev->parent_obj.canonical_path); -+ return -1; -+ } -+ -+ ret = vhost_load_backend_state(vhdev, f, &local_error); -+ if (ret < 0) { -+ error_reportf_err(local_error, -+ "Error loading back-end state of %s device %s: ", -+ vdev->name, vdev->parent_obj.canonical_path); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static bool vhost_user_net_is_internal_migration(void *opaque) -+{ -+ VirtIONet *n = opaque; -+ VirtIODevice *vdev = VIRTIO_DEVICE(n); -+ struct vhost_dev *vhdev; -+ -+ vhdev = virtio_net_get_vhost(vdev); -+ if (vhdev == NULL) { -+ return false; -+ } -+ -+ return vhost_supports_device_state(vhdev); -+} -+ -+static const VMStateDescription vhost_user_net_backend_state = { -+ .name = "virtio-net-device/backend", -+ .version_id = 0, -+ .needed = vhost_user_net_is_internal_migration, -+ .fields = (const VMStateField[]) { -+ { -+ .name = "backend", -+ .info = &(const VMStateInfo) { -+ .name = "virtio-net vhost-user backend state", -+ .get = vhost_user_net_load_state, -+ .put = vhost_user_net_save_state, -+ }, -+ }, -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ - static const VMStateDescription vmstate_virtio_net_device = { - .name = "virtio-net-device", - .version_id = VIRTIO_NET_VM_VERSION, -@@ -3357,6 +3453,7 @@ static const VMStateDescription vmstate_virtio_net_device = { - }, - .subsections = (const VMStateDescription * const []) { - &vmstate_virtio_net_rss, -+ &vhost_user_net_backend_state, - NULL - } - }; -@@ -3902,14 +3999,6 @@ static bool dev_unplug_pending(void *opaque) - return vdc->primary_unplug_pending(dev); - } - --static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) --{ -- VirtIONet *n = VIRTIO_NET(vdev); -- NetClientState *nc = qemu_get_queue(n->nic); -- struct vhost_net *net = get_vhost_net(nc->peer); -- return &net->dev; --} -- - static const VMStateDescription vmstate_virtio_net = { - .name = "virtio-net", - .minimum_version_id = VIRTIO_NET_VM_VERSION, --- -2.39.3 - diff --git a/kvm-vl-use-qmp_device_add-in-qemu_create_cli_devices.patch b/kvm-vl-use-qmp_device_add-in-qemu_create_cli_devices.patch deleted file mode 100644 index 987eed8..0000000 --- a/kvm-vl-use-qmp_device_add-in-qemu_create_cli_devices.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 59fe7329e9f1660a3b26e5147de2df348b1bbaed Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 27 Aug 2024 15:27:51 -0400 -Subject: [PATCH 4/7] vl: use qmp_device_add() in qemu_create_cli_devices() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 312: qdev-monitor: avoid QemuOpts in QMP device_add -RH-Jira: RHEL-43412 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Hanna Czenczek -RH-Commit: [4/4] b581207df4723f8a278452c92cb1b71a207aabe8 (stefanha/centos-stream-qemu-kvm) - -qemu_create_cli_devices() should use qmp_device_add() to match the -behavior of the QMP monitor. A comment explained that libvirt changes -implementing strict CLI syntax were needed. - -Peter Krempa has confirmed that modern libvirt uses -the same JSON for -device (CLI) and device_add (QMP). Go ahead and use -qmp_device_add(). - -Cc: Peter Krempa -Reviewed-by: Markus Armbruster -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240827192751.948633-3-stefanha@redhat.com> -Reviewed-by: Daniel P. BerrangĂ© -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit 11bf1d6aa06138e93b274e942d6992af63ffc510) -Signed-off-by: Stefan Hajnoczi ---- - system/vl.c | 14 ++++---------- - 1 file changed, 4 insertions(+), 10 deletions(-) - -diff --git a/system/vl.c b/system/vl.c -index 5359231bf5..900d471f5e 100644 ---- a/system/vl.c -+++ b/system/vl.c -@@ -2661,17 +2661,11 @@ static void qemu_create_cli_devices(void) - qemu_opts_foreach(qemu_find_opts("device"), - device_init_func, NULL, &error_fatal); - QTAILQ_FOREACH(opt, &device_opts, next) { -- DeviceState *dev; -+ QObject *ret_data = NULL; -+ - loc_push_restore(&opt->loc); -- /* -- * TODO Eventually we should call qmp_device_add() here to make sure it -- * behaves the same, but QMP still has to accept incorrectly typed -- * options until libvirt is fixed and we want to be strict on the CLI -- * from the start, so call qdev_device_add_from_qdict() directly for -- * now. -- */ -- dev = qdev_device_add_from_qdict(opt->opts, true, &error_fatal); -- object_unref(OBJECT(dev)); -+ qmp_device_add(opt->opts, &ret_data, &error_fatal); -+ assert(ret_data == NULL); /* error_fatal aborts */ - loc_pop(&opt->loc); - } - rom_reset_order_override(); --- -2.39.3 - diff --git a/kvm-vnc-fix-crash-when-no-console-attached.patch b/kvm-vnc-fix-crash-when-no-console-attached.patch deleted file mode 100644 index 0e9d1cc..0000000 --- a/kvm-vnc-fix-crash-when-no-console-attached.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 9e58f195620d723a2a0b609aa1c59d4938551835 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Tue, 20 Aug 2024 17:11:12 +0400 -Subject: [PATCH 25/38] vnc: fix crash when no console attached -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Marc-AndrĂ© Lureau -RH-MergeRequest: 279: vnc: fix crash when no console attached -RH-Jira: RHEL-50529 -RH-Acked-by: Paolo Bonzini -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/1] 0ea2135d95786752fe50c00271be997144adb4bc (marcandre.lureau-rh/qemu-kvm-centos) - -JIRA: https://issues.redhat.com/browse/RHEL-50529 - -Since commit e99441a3793b5 ("ui/curses: Do not use console_select()") -qemu_text_console_put_keysym() no longer checks for NULL console -argument, which leads to a later crash: - -Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault. -0x00005555559ee186 in qemu_text_console_handle_keysym (s=0x0, keysym=31) at ../ui/console-vc.c:332 -332 } else if (s->echo && (keysym == '\r' || keysym == '\n')) { -(gdb) bt - #0 0x00005555559ee186 in qemu_text_console_handle_keysym (s=0x0, keysym=31) at ../ui/console-vc.c:332 - #1 0x00005555559e18e5 in qemu_text_console_put_keysym (s=, keysym=) at ../ui/console.c:303 - #2 0x00005555559f2e88 in do_key_event (vs=vs@entry=0x5555579045c0, down=down@entry=1, keycode=keycode@entry=60, sym=sym@entry=65471) at ../ui/vnc.c:2034 - #3 0x00005555559f845c in ext_key_event (vs=0x5555579045c0, down=1, sym=65471, keycode=) at ../ui/vnc.c:2070 - #4 protocol_client_msg (vs=0x5555579045c0, data=, len=) at ../ui/vnc.c:2514 - #5 0x00005555559f515c in vnc_client_read (vs=0x5555579045c0) at ../ui/vnc.c:1607 - -Fixes: e99441a3793b5 ("ui/curses: Do not use console_select()") -Fixes: https://issues.redhat.com/browse/RHEL-50529 -Cc: qemu-stable@nongnu.org -Signed-off-by: Marc-AndrĂ© Lureau -Reviewed-by: Akihiko Odaki -Reviewed-by: Michael Tokarev -Signed-off-by: Michael Tokarev - -(cherry picked from commit 0e60fc80938d9ce84274a36ddfaaa640bdef2be8) -Signed-off-by: Marc-AndrĂ© Lureau ---- - ui/vnc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ui/vnc.c b/ui/vnc.c -index dae5d51210..5057ec8680 100644 ---- a/ui/vnc.c -+++ b/ui/vnc.c -@@ -1935,7 +1935,7 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym) - } - - qkbd_state_key_event(vs->vd->kbd, qcode, down); -- if (!qemu_console_is_graphic(vs->vd->dcl.con)) { -+ if (QEMU_IS_TEXT_CONSOLE(vs->vd->dcl.con)) { - QemuTextConsole *con = QEMU_TEXT_CONSOLE(vs->vd->dcl.con); - bool numlock = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK); - bool control = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL); --- -2.39.3 - diff --git a/kvm-x86-create-new-pc-q35-machine-type-for-rhel-9.6.patch b/kvm-x86-create-new-pc-q35-machine-type-for-rhel-9.6.patch deleted file mode 100644 index 55f3618..0000000 --- a/kvm-x86-create-new-pc-q35-machine-type-for-rhel-9.6.patch +++ /dev/null @@ -1,50 +0,0 @@ -From a498476ecdb2b81b7feae6bf496f0b8caa68d2e7 Mon Sep 17 00:00:00 2001 -From: Sebastian Ott -Date: Thu, 5 Sep 2024 13:58:44 +0200 -Subject: [PATCH 1/9] x86: create new pc-q35 machine type for rhel 9.6 - -RH-Author: Sebastian Ott -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 -RH-Acked-by: Cornelia Huck -RH-Acked-by: Eric Auger -RH-Commit: [1/7] 3c735a074e629eee589d5acf8fdace6517c57c54 (seott1/cos-qemu-kvm) - -Signed-off-by: Sebastian Ott ---- - hw/i386/pc_q35.c | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index a05df61cfc..6ee032e91e 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -672,11 +672,23 @@ DEFINE_Q35_MACHINE(2, 4); - - /* Red Hat Enterprise Linux machine types */ - --static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m) -+static void pc_q35_rhel_machine_9_6_0_options(MachineClass *m) - { - PCMachineClass *pcmc = PC_MACHINE_CLASS(m); - pc_q35_machine_options(m); -+ m->desc = "RHEL-9.6.0 PC (Q35 + ICH9, 2009)"; -+ pcmc->smbios_stream_product = "RHEL"; -+ pcmc->smbios_stream_version = "9.6.0"; -+} -+ -+DEFINE_Q35_MACHINE_BUGFIX(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); - m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)"; -+ m->alias = NULL; - pcmc->smbios_stream_product = "RHEL"; - pcmc->smbios_stream_version = "9.4.0"; - --- -2.39.3 - diff --git a/kvm-x86-create-pc-i440fx-machine-type-for-rhel10.patch b/kvm-x86-create-pc-i440fx-machine-type-for-rhel10.patch deleted file mode 100644 index 41f065d..0000000 --- a/kvm-x86-create-pc-i440fx-machine-type-for-rhel10.patch +++ /dev/null @@ -1,79 +0,0 @@ -From e31809f655d2298a4e21e317c8c6cb453a63939b Mon Sep 17 00:00:00 2001 -From: Sebastian Ott -Date: Tue, 28 May 2024 14:04:07 +0200 -Subject: [PATCH 3/9] x86: create pc-i440fx machine type for rhel10 - -RH-Author: Sebastian Ott -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 -RH-Acked-by: Cornelia Huck -RH-Acked-by: Eric Auger -RH-Commit: [3/7] e5aab53bc07dac21097497ce0d9798c6414dce57 (seott1/cos-qemu-kvm) - -Create a new machine type pc-i440fx-rhel10.0.0, -set it as default and alias to pc. - -Signed-off-by: Sebastian Ott ---- - hw/i386/pc_piix.c | 37 +++++++++++++++++++++++++++++++++++-- - 1 file changed, 35 insertions(+), 2 deletions(-) - -diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index 447f98b438..663f67aa3a 100644 ---- a/hw/i386/pc_piix.c -+++ b/hw/i386/pc_piix.c -@@ -830,6 +830,41 @@ DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init, - - /* Red Hat Enterprise Linux machine types */ - -+static void pc_machine_rhel10_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ ObjectClass *oc = OBJECT_CLASS(m); -+ 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, -+ pc_get_south_bridge, -+ pc_set_south_bridge); -+ object_class_property_set_description(oc, "x-south-bridge", -+ "Use a different south bridge than PIIX3"); -+} -+ -+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; -+ m->alias = "pc"; -+ m->is_default = 1; -+} -+DEFINE_I440FX_MACHINE(10, 0, 0); -+ - /* Options for the latest rhel7 machine type */ - static void pc_machine_rhel7_options(MachineClass *m) - { -@@ -844,8 +879,6 @@ static void pc_machine_rhel7_options(MachineClass *m) - 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; - } - --- -2.39.3 - diff --git a/kvm-x86-create-pc-q35-machine-type-for-rhel10.patch b/kvm-x86-create-pc-q35-machine-type-for-rhel10.patch deleted file mode 100644 index 47a7be3..0000000 --- a/kvm-x86-create-pc-q35-machine-type-for-rhel10.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 16bd67e1b3706f2e20bda52a5f8ad42742a51f55 Mon Sep 17 00:00:00 2001 -From: Sebastian Ott -Date: Thu, 22 Aug 2024 17:21:52 +0200 -Subject: [PATCH 4/9] x86: create pc-q35 machine type for rhel10 - -RH-Author: Sebastian Ott -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 -RH-Acked-by: Cornelia Huck -RH-Acked-by: Eric Auger -RH-Commit: [4/7] 86639ee63c884fb97e1f6bc7e24b2773ac2b4a7a (seott1/cos-qemu-kvm) - -Create a new machine type pc-q35-rhel10.0.0 with alias q35. - -Signed-off-by: Sebastian Ott ---- - hw/i386/pc_q35.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 6ee032e91e..4ad4ad79a4 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -672,11 +672,22 @@ DEFINE_Q35_MACHINE(2, 4); - - /* Red Hat Enterprise Linux machine types */ - --static void pc_q35_rhel_machine_9_6_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"; -+} -+DEFINE_Q35_MACHINE_BUGFIX(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)"; -+ m->alias = NULL; - pcmc->smbios_stream_product = "RHEL"; - pcmc->smbios_stream_version = "9.6.0"; - } -@@ -688,7 +699,6 @@ 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); - m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)"; -- m->alias = NULL; - pcmc->smbios_stream_product = "RHEL"; - pcmc->smbios_stream_version = "9.4.0"; - --- -2.39.3 - diff --git a/kvm-x86-remove-deprecated-rhel-machine-types.patch b/kvm-x86-remove-deprecated-rhel-machine-types.patch deleted file mode 100644 index 98acd71..0000000 --- a/kvm-x86-remove-deprecated-rhel-machine-types.patch +++ /dev/null @@ -1,274 +0,0 @@ -From e0fdae22db8d3a333d5c01e64d0c063b3d47c553 Mon Sep 17 00:00:00 2001 -From: Sebastian Ott -Date: Thu, 22 Aug 2024 16:30:08 +0200 -Subject: [PATCH 6/9] x86: remove deprecated rhel machine types - -RH-Author: Sebastian Ott -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 -RH-Acked-by: Cornelia Huck -RH-Acked-by: Eric Auger -RH-Commit: [6/7] 928c59980a5c5f613e90e4ccfcfcfc08488da519 (seott1/cos-qemu-kvm) - -Remove the following deprecated x86 rhel specific machine types: - -pc RHEL 7.6.0 PC (i440FX + PIIX, 1996) (alias of pc-i440fx-rhel7.6.0) -pc-i440fx-rhel7.6.0 RHEL 7.6.0 PC (i440FX + PIIX, 1996) (default) (deprecated) -pc-q35-rhel8.6.0 RHEL-8.6.0 PC (Q35 + ICH9, 2009) (deprecated) -pc-q35-rhel8.5.0 RHEL-8.5.0 PC (Q35 + ICH9, 2009) (deprecated) -pc-q35-rhel8.4.0 RHEL-8.4.0 PC (Q35 + ICH9, 2009) (deprecated) -pc-q35-rhel8.3.0 RHEL-8.3.0 PC (Q35 + ICH9, 2009) (deprecated) -pc-q35-rhel8.2.0 RHEL-8.2.0 PC (Q35 + ICH9, 2009) (deprecated) -pc-q35-rhel8.1.0 RHEL-8.1.0 PC (Q35 + ICH9, 2009) (deprecated) -pc-q35-rhel8.0.0 RHEL-8.0.0 PC (Q35 + ICH9, 2009) (deprecated) -pc-q35-rhel7.6.0 RHEL-7.6.0 PC (Q35 + ICH9, 2009) (deprecated) - -Signed-off-by: Sebastian Ott ---- - hw/i386/pc_piix.c | 95 ---------------------------------- - hw/i386/pc_q35.c | 128 ---------------------------------------------- - 2 files changed, 223 deletions(-) - -diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index 663f67aa3a..96f5997051 100644 ---- a/hw/i386/pc_piix.c -+++ b/hw/i386/pc_piix.c -@@ -864,98 +864,3 @@ static void pc_i440fx_rhel_machine_10_0_0_options(MachineClass *m) - m->is_default = 1; - } - DEFINE_I440FX_MACHINE(10, 0, 0); -- --/* 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->smp_props.prefer_sockets = true; --} -- --static void pc_i440fx_rhel_machine_7_6_0_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; -- -- object_class_property_add_enum(oc, "x-south-bridge", "PCSouthBridgeOption", -- &PCSouthBridgeOption_lookup, -- pc_get_south_bridge, -- 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_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, -- 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); -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 4ad4ad79a4..37f54062c8 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -760,131 +760,3 @@ static void pc_q35_rhel_machine_9_0_0_options(MachineClass *m) - } - - 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); -- --- -2.39.3 - diff --git a/qemu-ga.sysconfig b/qemu-ga.sysconfig index 6f6e98b..b574514 100644 --- a/qemu-ga.sysconfig +++ b/qemu-ga.sysconfig @@ -13,7 +13,7 @@ # # You can get the list of RPC commands using "qemu-ga --allow-rpcs='?'". # There should be no spaces between commas and commands in the allow list. -FILTER_RPC_ARGS="--allow-rpcs=guest-sync-delimited,guest-sync,guest-ping,guest-get-time,guest-set-time,guest-info,guest-shutdown,guest-fsfreeze-status,guest-fsfreeze-freeze,guest-fsfreeze-freeze-list,guest-fsfreeze-thaw,guest-fstrim,guest-suspend-disk,guest-suspend-ram,guest-suspend-hybrid,guest-network-get-interfaces,guest-get-vcpus,guest-set-vcpus,guest-get-disks,guest-get-fsinfo,guest-set-user-password,guest-get-memory-blocks,guest-set-memory-blocks,guest-get-memory-block-info,guest-get-host-name,guest-get-users,guest-get-timezone,guest-get-osinfo,guest-get-devices,guest-ssh-get-authorized-keys,guest-ssh-add-authorized-keys,guest-ssh-remove-authorized-keys,guest-get-diskstats,guest-get-cpustats,guest-network-get-route" +FILTER_RPC_ARGS="--allow-rpcs=guest-sync-delimited,guest-sync,guest-ping,guest-get-time,guest-set-time,guest-info,guest-shutdown,guest-fsfreeze-status,guest-fsfreeze-freeze,guest-fsfreeze-freeze-list,guest-fsfreeze-thaw,guest-fstrim,guest-suspend-disk,guest-suspend-ram,guest-suspend-hybrid,guest-network-get-interfaces,guest-get-vcpus,guest-set-vcpus,guest-get-disks,guest-get-fsinfo,guest-set-user-password,guest-get-memory-blocks,guest-set-memory-blocks,guest-get-memory-block-info,guest-get-host-name,guest-get-users,guest-get-timezone,guest-get-osinfo,guest-get-devices,guest-ssh-get-authorized-keys,guest-ssh-add-authorized-keys,guest-ssh-remove-authorized-keys,guest-get-diskstats,guest-get-cpustats,guest-network-get-route,guest-get-load" # Fsfreeze hook script specification. # diff --git a/qemu-kvm.spec b/qemu-kvm.spec index c21da52..ed8da32 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -67,7 +67,7 @@ %endif %endif -%ifnarch %{ix86} x86_64 aarch64 +%ifnarch x86_64 aarch64 %global have_usbredir 0 %endif @@ -76,13 +76,10 @@ %ifarch s390x %global modprobe_kvm_conf %{_sourcedir}/kvm-s390x.conf %endif -%ifarch %{ix86} x86_64 +%ifarch x86_64 %global modprobe_kvm_conf %{_sourcedir}/kvm-x86.conf %endif -%ifarch %{ix86} - %global kvm_target i386 -%endif %ifarch x86_64 %global kvm_target x86_64 %else @@ -96,12 +93,13 @@ %global kvm_target s390x %global have_modules_load 1 %endif -%ifarch ppc - %global kvm_target ppc -%endif %ifarch aarch64 %global kvm_target aarch64 %endif +%ifarch riscv64 + %global kvm_target riscv64 +%endif + %global target_list %{kvm_target}-softmmu %global block_drivers_rw_list qcow2,raw,file,host_device,nbd,iscsi,rbd,blkdebug,luks,null-co,nvme,copy-on-read,throttle,compress,virtio-blk-vhost-vdpa,virtio-blk-vfio-pci,virtio-blk-vhost-user,io_uring,nvme-io_uring @@ -133,7 +131,9 @@ Requires: %{name}-device-usb-host = %{epoch}:%{version}-%{release} \ Requires: %{name}-device-usb-redirect = %{epoch}:%{version}-%{release} \ %endif \ Requires: %{name}-block-blkio = %{epoch}:%{version}-%{release} \ +%if %{have_block_rbd} \ Requires: %{name}-block-rbd = %{epoch}:%{version}-%{release} \ +%endif \ Requires: %{name}-audio-pa = %{epoch}:%{version}-%{release} # Since SPICE is removed from RHEL-9, the following Obsoletes: @@ -157,15 +157,15 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \ Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm -Version: 9.1.0 -Release: 15%{?rcrel}%{?dist}%{?cc_suffix}.4.alma.1 +Version: 10.0.0 +Release: 14%{?rcrel}%{?dist}%{?cc_suffix}.alma.1 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped # Epoch 15 used for RHEL 8 # Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5) Epoch: 18 License: GPL-2.0-only AND GPL-2.0-or-later AND CC-BY-3.0 URL: http://www.qemu.org/ -ExclusiveArch: x86_64 %{power64} aarch64 s390x +ExclusiveArch: x86_64 %{power64} aarch64 s390x riscv64 Source0: http://wiki.qemu.org/download/qemu-%{version}%{?rcstr}.tar.xz @@ -199,372 +199,348 @@ Patch0016: 0016-vfio-cap-number-of-devices-that-can-be-assigned.patch Patch0017: 0017-Add-support-statement-to-help-output.patch Patch0018: 0018-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch Patch0019: 0019-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch -Patch0021: 0021-Add-upstream-compatibility-bits.patch -Patch0022: 0022-redhat-Add-QEMU-9.1-compat-handling-to-the-s390x-mac.patch -Patch0023: 0023-redhat-Add-rhel9.6.0-and-rhel10.0.0-machine-types.patch -Patch0024: 0024-x86-ensure-compatibility-of-pc-q35-rhel9.patch -Patch0025: 0025-arm-ensure-compatibility-of-virt-rhel9.patch -# For RHEL-29002 - Remove the existing deprecated machine types in RHEL-10 -# For RHEL-29003 - Deprecate RHEL-9 machine types in RHEL-10 -# For RHEL-35587 - Create a pc-i440fx-rhel10.0 machine type -# For RHEL-38411 - [Fujitsu 10.0 FEAT]: qemu-kvm: Continue to support i440fx for RHEL10 -# For RHEL-45141 - Introduce virt-rhel10.0 arm-virt machine type [aarch64] -Patch26: kvm-x86-create-new-pc-q35-machine-type-for-rhel-9.6.patch -# For RHEL-29002 - Remove the existing deprecated machine types in RHEL-10 -# For RHEL-29003 - Deprecate RHEL-9 machine types in RHEL-10 -# For RHEL-35587 - Create a pc-i440fx-rhel10.0 machine type -# For RHEL-38411 - [Fujitsu 10.0 FEAT]: qemu-kvm: Continue to support i440fx for RHEL10 -# For RHEL-45141 - Introduce virt-rhel10.0 arm-virt machine type [aarch64] -Patch27: kvm-arm-create-new-virt-machine-type-for-rhel-9.6.patch -# For RHEL-29002 - Remove the existing deprecated machine types in RHEL-10 -# For RHEL-29003 - Deprecate RHEL-9 machine types in RHEL-10 -# For RHEL-35587 - Create a pc-i440fx-rhel10.0 machine type -# For RHEL-38411 - [Fujitsu 10.0 FEAT]: qemu-kvm: Continue to support i440fx for RHEL10 -# For RHEL-45141 - Introduce virt-rhel10.0 arm-virt machine type [aarch64] -Patch28: kvm-x86-create-pc-i440fx-machine-type-for-rhel10.patch -# For RHEL-29002 - Remove the existing deprecated machine types in RHEL-10 -# For RHEL-29003 - Deprecate RHEL-9 machine types in RHEL-10 -# For RHEL-35587 - Create a pc-i440fx-rhel10.0 machine type -# For RHEL-38411 - [Fujitsu 10.0 FEAT]: qemu-kvm: Continue to support i440fx for RHEL10 -# For RHEL-45141 - Introduce virt-rhel10.0 arm-virt machine type [aarch64] -Patch29: kvm-x86-create-pc-q35-machine-type-for-rhel10.patch -# For RHEL-29002 - Remove the existing deprecated machine types in RHEL-10 -# For RHEL-29003 - Deprecate RHEL-9 machine types in RHEL-10 -# For RHEL-35587 - Create a pc-i440fx-rhel10.0 machine type -# For RHEL-38411 - [Fujitsu 10.0 FEAT]: qemu-kvm: Continue to support i440fx for RHEL10 -# For RHEL-45141 - Introduce virt-rhel10.0 arm-virt machine type [aarch64] -Patch30: kvm-arm-create-virt-machine-type-for-rhel10.patch -# For RHEL-29002 - Remove the existing deprecated machine types in RHEL-10 -# For RHEL-29003 - Deprecate RHEL-9 machine types in RHEL-10 -# For RHEL-35587 - Create a pc-i440fx-rhel10.0 machine type -# For RHEL-38411 - [Fujitsu 10.0 FEAT]: qemu-kvm: Continue to support i440fx for RHEL10 -# For RHEL-45141 - Introduce virt-rhel10.0 arm-virt machine type [aarch64] -Patch31: kvm-x86-remove-deprecated-rhel-machine-types.patch -# For RHEL-29002 - Remove the existing deprecated machine types in RHEL-10 -# For RHEL-29003 - Deprecate RHEL-9 machine types in RHEL-10 -# For RHEL-35587 - Create a pc-i440fx-rhel10.0 machine type -# For RHEL-38411 - [Fujitsu 10.0 FEAT]: qemu-kvm: Continue to support i440fx for RHEL10 -# For RHEL-45141 - Introduce virt-rhel10.0 arm-virt machine type [aarch64] -Patch32: kvm-remove-stale-compat-definitions.patch -# For RHEL-38374 - aarch64 SMBIOS 'Manufacturer' and 'Product Name' differ from x86 ones [rhel-10] -Patch33: kvm-RH-Author-Shaoqin-Huang-shahuang-redhat.com.patch -# For RHEL-57028 - fsfreeze hooks break on the systems first restorecon [rhel-10] -Patch34: kvm-qemu-guest-agent-Update-the-logfile-path-of-qga-fsfr.patch -# For RHEL-58936 - [RHEL-10.0] QEMU core dump on applying merge property to memory backend -Patch35: kvm-hostmem-Apply-merge-property-after-the-memory-region.patch -# For RHEL-58928 - Boot SNP guests failed with qemu-kvm: kvm_set_user_memory_region -Patch36: kvm-accel-kvm-check-for-KVM_CAP_READONLY_MEM-on-VM.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch37: kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch38: kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch39: kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch41: kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch42: kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch43: kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch44: kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch45: kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch46: kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch47: kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch48: kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch49: kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch50: kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch51: kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch52: kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch53: kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch54: kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch55: kvm-docs-system-Update-documentation-for-s390x-IPL.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch56: kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch57: kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch58: kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch -# For RHEL-58153 - [IBM 10.0 FEAT] KVM: Full boot order support - qemu part -Patch59: kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch -# For RHEL-50529 - Qemu-kvm crashed if no display device setting and switching display by remote-viewer -Patch60: kvm-vnc-fix-crash-when-no-console-attached.patch -# For RHEL-64308 - High threshold value observed in vGPU live migration -Patch61: kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch -# For RHEL-64308 - High threshold value observed in vGPU live migration -Patch62: kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch -# For RHEL-20574 - Fail migration properly when put cpu register fails -Patch63: kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch -# For RHEL-20574 - Fail migration properly when put cpu register fails -Patch64: kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch -# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support -# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 -Patch65: kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch -# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support -# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 -Patch66: kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch -# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support -# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 -Patch67: kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch -# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support -# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 -Patch68: kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch -# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support -# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 -Patch69: kvm-target-i386-add-CPUID.24-features-for-AVX10.patch -# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support -# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 -Patch70: kvm-target-i386-Add-feature-dependencies-for-AVX10.patch -# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support -# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 -Patch71: kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch -# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support -# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 -Patch72: kvm-target-i386-Introduce-GraniteRapids-v2-model.patch -# For RHEL-30315 - [Intel 10.0 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support -# For RHEL-45110 - [Intel 10.0 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 -Patch73: kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch -# For RHEL-63051 - qemu crashed after killed virtiofsd during migration -Patch74: kvm-migration-Ensure-vmstate_save-sets-errp.patch -# For RHEL-57685 - Bad migration performance when performing vGPU VM live migration -Patch75: kvm-kvm-replace-fprintf-with-error_report-printf-in-kvm_.patch -# For RHEL-57685 - Bad migration performance when performing vGPU VM live migration -Patch76: kvm-kvm-refactor-core-virtual-machine-creation-into-its-.patch -# For RHEL-57685 - Bad migration performance when performing vGPU VM live migration -Patch77: kvm-accel-kvm-refactor-dirty-ring-setup.patch -# For RHEL-57685 - Bad migration performance when performing vGPU VM live migration -Patch78: kvm-KVM-Dynamic-sized-kvm-memslots-array.patch -# For RHEL-57685 - Bad migration performance when performing vGPU VM live migration -Patch79: kvm-KVM-Define-KVM_MEMSLOTS_NUM_MAX_DEFAULT.patch -# For RHEL-57685 - Bad migration performance when performing vGPU VM live migration -Patch80: kvm-KVM-Rename-KVMMemoryListener.nr_used_slots-to-nr_slo.patch -# For RHEL-57685 - Bad migration performance when performing vGPU VM live migration -Patch81: kvm-KVM-Rename-KVMState-nr_slots-to-nr_slots_max.patch -# For RHEL-67936 - QEMU should fail gracefully with passthrough devices in SEV-SNP guests -Patch82: kvm-vfio-container-Fix-container-object-destruction.patch -# For RHEL-40950 - [Stable_Guest_ABI][USO]From 10-beta to RHEL.9.5.0 the guest with 9.4 machine type only, the guest crashed with - qemu-kvm: Features 0x1c0010130afffa7 unsupported. Allowed features: 0x10179bfffe7 -Patch83: kvm-virtio-net-disable-USO-for-RHEL9.patch -# For RHEL-58316 - qemu crashed when migrate vm with multiqueue from rhel9.4 to rhel10.0 -Patch84: kvm-virtio-net-Add-queues-before-loading-them.patch -# For RHEL-68444 - The new "boot order" feature is sometimes not working as expected [RHEL 10] -Patch85: kvm-docs-system-s390x-bootdevices-Update-loadparm-docume.patch -# For RHEL-68444 - The new "boot order" feature is sometimes not working as expected [RHEL 10] -Patch86: kvm-docs-system-bootindex-Make-it-clear-that-s390x-can-a.patch -# For RHEL-68444 - The new "boot order" feature is sometimes not working as expected [RHEL 10] -Patch87: kvm-hw-s390x-Restrict-loadparm-property-to-devices-that-.patch -# For RHEL-68444 - The new "boot order" feature is sometimes not working as expected [RHEL 10] -Patch88: kvm-hw-Add-loadparm-property-to-scsi-disk-devices-for-bo.patch -# For RHEL-68444 - The new "boot order" feature is sometimes not working as expected [RHEL 10] -Patch89: kvm-scsi-fix-allocation-for-s390x-loadparm.patch -# For RHEL-68444 - The new "boot order" feature is sometimes not working as expected [RHEL 10] -Patch90: kvm-pc-bios-s390x-Initialize-cdrom-type-to-false-for-eac.patch -# For RHEL-68444 - The new "boot order" feature is sometimes not working as expected [RHEL 10] -Patch91: kvm-pc-bios-s390x-Initialize-machine-loadparm-before-pro.patch -# For RHEL-68444 - The new "boot order" feature is sometimes not working as expected [RHEL 10] -Patch92: kvm-pc-bios-s390-ccw-Re-initialize-receive-queue-index-b.patch -# For RHEL-69047 - warning: fd: migration to a file is deprecated when create or revert a snapshot -Patch93: kvm-migration-Allow-pipes-to-keep-working-for-fd-migrati.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch94: kvm-linux-headers-Update-to-Linux-v6.12-rc5.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch95: kvm-s390x-cpumodel-add-msa10-subfunctions.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch96: kvm-s390x-cpumodel-add-msa11-subfunctions.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch97: kvm-s390x-cpumodel-add-msa12-changes.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch98: kvm-s390x-cpumodel-add-msa13-subfunctions.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch99: kvm-s390x-cpumodel-Add-ptff-Query-Time-Stamp-Event-QTSE-.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch100: kvm-linux-headers-Update-to-Linux-6.13-rc1.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch101: kvm-s390x-cpumodel-add-Concurrent-functions-facility-sup.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch102: kvm-s390x-cpumodel-add-Vector-Enhancements-facility-3.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch103: kvm-s390x-cpumodel-add-Miscellaneous-Instruction-Extensi.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch104: kvm-s390x-cpumodel-add-Vector-Packed-Decimal-Enhancement.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch105: kvm-s390x-cpumodel-add-Ineffective-nonconstrained-transa.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch106: kvm-s390x-cpumodel-Add-Sequential-Instruction-Fetching-f.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch107: kvm-s390x-cpumodel-correct-PLO-feature-wording.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch108: kvm-s390x-cpumodel-Add-PLO-extension-facility.patch -# For RHEL-32665 - [IBM 10.0 FEAT] KVM: CPU model for new IBM Z HW - qemu-kvm part -Patch109: kvm-s390x-cpumodel-gen17-model.patch -# For RHEL-71939 - qemu-ga cannot freeze filesystems with sentinelone -Patch110: kvm-qga-skip-bind-mounts-in-fs-list.patch -# For RHEL-67108 - [aarch64] [rhel-10.0] Backport some important post 9.1 qemu fixes -Patch111: kvm-hw-char-pl011-Use-correct-masks-for-IBRD-and-FBRD.patch -# For RHEL-43412 - qom-get iothread-vq-mapping is empty on new hotplug disk [rhel-10.0-beta] -Patch112: kvm-qdev-Fix-set_pci_devfn-to-visit-option-only-once.patch -# For RHEL-43412 - qom-get iothread-vq-mapping is empty on new hotplug disk [rhel-10.0-beta] -Patch113: kvm-tests-avocado-hotplug_blk-Fix-addr-in-device_add-com.patch -# For RHEL-43412 - qom-get iothread-vq-mapping is empty on new hotplug disk [rhel-10.0-beta] -Patch114: kvm-qdev-monitor-avoid-QemuOpts-in-QMP-device_add.patch -# For RHEL-43412 - qom-get iothread-vq-mapping is empty on new hotplug disk [rhel-10.0-beta] -Patch115: kvm-vl-use-qmp_device_add-in-qemu_create_cli_devices.patch -# For RHEL-57668 - [RFE] [HPEMC] [RHEL-10.0] qemu-kvm: support up to 4096 VCPUs -Patch116: kvm-pc-q35-Bump-max_cpus-to-4096-vcpus.patch -# For RHEL-73005 - qemu-kvm: vhost: reports error while updating IOTLB entries -Patch117: kvm-vhost-fail-device-start-if-iotlb-update-fails.patch -# For RHEL-69500 - [Stable_Guest_ABI][USO][9.6.0-machine-type]From 10.0 to RHEL.9.6.0 the guest with 9.6 machine type only, the guest crashed with - qemu-kvm: Features 0x1c0010130afffa7 unsupported. Allowed features: 0x10179bfffe7 -Patch118: kvm-virtio-net-disable-USO-for-all-RHEL9.patch -# For RHEL-73002 - kvm-unti kvm-hyperv_synic test is stuck on AMD with COS9 [rhel-10] -Patch119: kvm-target-i386-Make-sure-SynIC-state-is-really-updated-.patch -# For RHEL-73835 - VM crashes when requesting domstats [rhel-10] -Patch120: kvm-hw-virtio-fix-crash-in-processing-balloon-stats.patch -# For RHEL-74361 - qemu-ga logs only "guest-fsfreeze called" (but not "guest-fsthaw called") -Patch121: kvm-qga-Add-log-to-guest-fsfreeze-thaw-command.patch -# For RHEL-74461 - fsfreeze hooks doesn't log error on system logs when running hook fails [rhel-10] -Patch122: kvm-qemu-ga-Optimize-freeze-hook-script-logic-of-logging.patch -# For RHEL-65618 - [RHEL10] Failed to hot add PCIe device behind xio3130 downstream -Patch123: kvm-pci-ensure-valid-link-status-bits-for-downstream-por.patch -# For RHEL-72717 - Boot fall back to cdrom from network not always working -Patch124: kvm-pc-bios-s390-ccw-Abort-IPL-on-invalid-loadparm.patch -# For RHEL-72717 - Boot fall back to cdrom from network not always working -Patch125: kvm-pc-bios-s390-ccw-virtio-Add-a-function-to-reset-a-vi.patch -# For RHEL-72717 - Boot fall back to cdrom from network not always working -Patch126: kvm-pc-bios-s390-ccw-Fix-boot-problem-with-virtio-net-de.patch -# For RHEL-72717 - Boot fall back to cdrom from network not always working -Patch127: kvm-pc-bios-s390-ccw-netmain-Fix-error-messages-with-reg.patch -# For RHEL-71761 - [Nvidia "Grace"] Lack of "PAuth" CPU feature results in live migration failure from RHEL 9.6 to 10 -Patch128: kvm-arm-disable-pauth-for-virt-rhel9-in-RHEL10.patch -# For RHEL-76908 - Ensure qemu as NBD server does not flood logs [rhel-10] -Patch129: kvm-nbd-server-Silence-server-warnings-on-port-probes.patch -# For RHEL-73894 - No RARP packets on the destination after migration [rhel-10] -Patch130: kvm-net-Fix-announce_self.patch -# For RHEL-78370 - Add vhost-user internal migration for passt -Patch131: kvm-vhost-Add-stubs-for-the-migration-state-transfer-int.patch -# For RHEL-78370 - Add vhost-user internal migration for passt -Patch132: kvm-virtio-net-vhost-user-Implement-internal-migration.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch133: kvm-migration-Add-helper-to-get-target-runstate.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch134: kvm-qmp-cont-Only-activate-disks-if-migration-completed.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch135: kvm-migration-block-Make-late-block-active-the-default.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch136: kvm-migration-block-Apply-late-block-active-behavior-to-.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch137: kvm-migration-block-Fix-possible-race-with-block_inactiv.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch138: kvm-migration-block-Rewrite-disk-activation.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch139: kvm-block-Add-active-field-to-BlockDeviceInfo.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch140: kvm-block-Allow-inactivating-already-inactive-nodes.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch141: kvm-block-Inactivate-external-snapshot-overlays-when-nec.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch142: kvm-migration-block-active-Remove-global-active-flag.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch143: kvm-block-Don-t-attach-inactive-child-to-active-node.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch144: kvm-block-Fix-crash-on-block_resize-on-inactive-node.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch145: kvm-block-Add-option-to-create-inactive-nodes.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch146: kvm-block-Add-blockdev-set-active-QMP-command.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch147: kvm-block-Support-inactive-nodes-in-blk_insert_bs.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch148: kvm-block-export-Don-t-ignore-image-activation-error-in-.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch149: kvm-block-Drain-nodes-before-inactivating-them.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch150: kvm-block-export-Add-option-to-allow-export-of-inactive-.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch151: kvm-nbd-server-Support-inactive-nodes.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch152: kvm-iotests-Add-filter_qtest.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch153: kvm-iotests-Add-qsd-migrate-case.patch -# For RHEL-54670 - Provide QMP command for block device reactivation after migration [rhel-10.0] -Patch154: kvm-iotests-Add-NBD-based-tests-for-inactive-nodes.patch -# For RHEL-80522 - Allow libvirt to restart passt/vhost-user when the process is killed -Patch155: kvm-net-vhost-user-add-QAPI-events-to-report-connection-.patch -# For RHEL-92430 - Fix x86 M-type compats [rhel-10.0.z] -Patch156: kvm-hw-i386-Fix-machine-type-compatibility.patch -# For RHEL-100765 - Video stuck after switchover phase when play one video during migration [rhel-10.0.z] -Patch157: kvm-ui-vnc-Update-display-update-interval-when-VM-state-.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch158: kvm-include-qemu-compiler-add-QEMU_UNINITIALIZED-attribu.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch159: kvm-hw-virtio-virtio-avoid-cost-of-ftrivial-auto-var-ini.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch160: kvm-block-skip-automatic-zero-init-of-large-array-in-ioq.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch161: kvm-chardev-char-fd-skip-automatic-zero-init-of-large-ar.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch162: kvm-chardev-char-pty-skip-automatic-zero-init-of-large-a.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch163: kvm-chardev-char-socket-skip-automatic-zero-init-of-larg.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch164: kvm-hw-audio-ac97-skip-automatic-zero-init-of-large-arra.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch165: kvm-hw-audio-cs4231a-skip-automatic-zero-init-of-large-a.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch166: kvm-hw-audio-es1370-skip-automatic-zero-init-of-large-ar.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch167: kvm-hw-audio-gus-skip-automatic-zero-init-of-large-array.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch168: kvm-hw-audio-marvell_88w8618-skip-automatic-zero-init-of.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch169: kvm-hw-audio-sb16-skip-automatic-zero-init-of-large-arra.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch170: kvm-hw-audio-via-ac97-skip-automatic-zero-init-of-large-.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch171: kvm-hw-char-sclpconsole-lm-skip-automatic-zero-init-of-l.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch172: kvm-hw-dma-xlnx_csu_dma-skip-automatic-zero-init-of-larg.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch173: kvm-hw-display-vmware_vga-skip-automatic-zero-init-of-la.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch174: kvm-hw-hyperv-syndbg-skip-automatic-zero-init-of-large-a.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch175: kvm-hw-misc-aspeed_hace-skip-automatic-zero-init-of-larg.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch176: kvm-hw-net-rtl8139-skip-automatic-zero-init-of-large-arr.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch177: kvm-hw-net-tulip-skip-automatic-zero-init-of-large-array.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch178: kvm-hw-net-virtio-net-skip-automatic-zero-init-of-large-.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch179: kvm-hw-net-xgamc-skip-automatic-zero-init-of-large-array.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch180: kvm-hw-nvme-ctrl-skip-automatic-zero-init-of-large-array.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch181: kvm-hw-ppc-spapr_tpm_proxy-skip-automatic-zero-init-of-l.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch182: kvm-hw-usb-hcd-ohci-skip-automatic-zero-init-of-large-ar.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch183: kvm-hw-scsi-lsi53c895a-skip-automatic-zero-init-of-large.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch184: kvm-hw-scsi-megasas-skip-automatic-zero-init-of-large-ar.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch185: kvm-hw-ufs-lu-skip-automatic-zero-init-of-large-array.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch186: kvm-net-socket-skip-automatic-zero-init-of-large-array.patch -# For RHEL-99889 - -ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z] -Patch187: kvm-net-stream-skip-automatic-zero-init-of-large-array.patch -# For RHEL-108727 - Openstack guest becomes inaccessible via network when storage network on the hypervisor is disabled/lost [rhel-10.0.z] -Patch188: kvm-rbd-Fix-.bdrv_get_specific_info-implementation.patch +# For RHEL-87642 - QEMU sends unaligned discards on 4K devices[RHEL-10] +Patch20: kvm-file-posix-probe-discard-alignment-on-Linux-block-de.patch +# For RHEL-87642 - QEMU sends unaligned discards on 4K devices[RHEL-10] +Patch21: kvm-block-io-skip-head-tail-requests-on-EINVAL.patch +# For RHEL-87642 - QEMU sends unaligned discards on 4K devices[RHEL-10] +Patch22: kvm-file-posix-Fix-crash-on-discard_granularity-0.patch +# For RHEL-86056 - Enable 'vhost-user-gpu-pci' in qemu-kvm for RHIVOS +Patch23: kvm-Enable-vhost-user-gpu-pci-for-RHIVOS.patch +# For RHEL-85635 - Video stuck about 1 min after switchover phase when play one video during postcopy-preempt migration +Patch24: kvm-migration-postcopy-Spatial-locality-page-hint-for-pr.patch +# For RHEL-88457 - qemu inadvertantly built with valgrind coroutine stack debugging on x86_64 +Patch25: kvm-meson-configure-add-valgrind-option-en-dis-able-valg.patch +# Fixing s390x build issues +Patch26: kvm-docs-Don-t-define-duplicate-label-in-qemu-block-driv.patch +# For RHEL-88435 - --migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-10.1] +# For RHEL-88437 - Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-10.1] +Patch27: kvm-block-Expand-block-status-mode-from-bool-to-flags.patch +# For RHEL-88435 - --migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-10.1] +# For RHEL-88437 - Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-10.1] +Patch28: kvm-file-posix-gluster-Handle-zero-block-status-hint-bet.patch +# For RHEL-88435 - --migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-10.1] +# For RHEL-88437 - Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-10.1] +Patch29: kvm-block-Let-bdrv_co_is_zero_fast-consolidate-adjacent-.patch +# For RHEL-88435 - --migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-10.1] +# For RHEL-88437 - Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-10.1] +Patch30: kvm-block-Add-new-bdrv_co_is_all_zeroes-function.patch +# For RHEL-88435 - --migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-10.1] +# For RHEL-88437 - Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-10.1] +Patch31: kvm-iotests-Improve-iotest-194-to-mirror-data.patch +# For RHEL-88435 - --migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-10.1] +# For RHEL-88437 - Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-10.1] +Patch32: kvm-mirror-Minor-refactoring.patch +# For RHEL-88435 - --migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-10.1] +# For RHEL-88437 - Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-10.1] +Patch33: kvm-mirror-Pass-full-sync-mode-rather-than-bool-to-inter.patch +# For RHEL-88435 - --migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-10.1] +# For RHEL-88437 - Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-10.1] +Patch34: kvm-mirror-Allow-QMP-override-to-declare-target-already-.patch +# For RHEL-88435 - --migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-10.1] +# For RHEL-88437 - Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-10.1] +Patch35: kvm-mirror-Drop-redundant-zero_target-parameter.patch +# For RHEL-88435 - --migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-10.1] +# For RHEL-88437 - Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-10.1] +Patch36: kvm-mirror-Skip-pre-zeroing-destination-if-it-is-already.patch +# For RHEL-88435 - --migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-10.1] +# For RHEL-88437 - Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-10.1] +Patch37: kvm-mirror-Skip-writing-zeroes-when-target-is-already-ze.patch +# For RHEL-88435 - --migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-10.1] +# For RHEL-88437 - Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-10.1] +Patch38: kvm-iotests-common.rc-add-disk_usage-function.patch +# For RHEL-88435 - --migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-10.1] +# For RHEL-88437 - Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-10.1] +Patch39: kvm-tests-Add-iotest-mirror-sparse-for-recent-patches.patch +# For RHEL-88435 - --migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-10.1] +# For RHEL-88437 - Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-10.1] +Patch40: kvm-mirror-Reduce-I-O-when-destination-is-detect-zeroes-.patch +# For RHEL-65852 - Support multipath failover with scsi-block +Patch41: kvm-file-posix-Define-DM_MPATH_PROBE_PATHS.patch +# For RHEL-65852 - Support multipath failover with scsi-block +Patch42: kvm-file-posix-Probe-paths-and-retry-SG_IO-on-potential-.patch +# For RHEL-67706 - postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S' +Patch43: kvm-io-Fix-partial-struct-copy-in-qio_dns_resolver_looku.patch +# For RHEL-67706 - postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S' +Patch44: kvm-util-qemu-sockets-Refactor-setting-client-sockopts-i.patch +# For RHEL-67706 - postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S' +Patch45: kvm-util-qemu-sockets-Refactor-success-and-failure-paths.patch +# For RHEL-67706 - postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S' +Patch46: kvm-util-qemu-sockets-Add-support-for-keep-alive-flag-to.patch +# For RHEL-67706 - postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S' +Patch47: kvm-util-qemu-sockets-Refactor-inet_parse-to-use-QemuOpt.patch +# For RHEL-67706 - postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S' +Patch48: kvm-util-qemu-sockets-Introduce-inet-socket-options-cont.patch +# For RHEL-67706 - postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S' +Patch49: kvm-tests-unit-test-util-sockets-fix-mem-leak-on-error-o.patch +# For RHEL-71962 - [RFE] Implement FUA support in scsi-disk +Patch50: kvm-scsi-disk-Add-native-FUA-write-support.patch +# For RHEL-96057 - qemu-kvm: Various small issues in the spec file +Patch51: kvm-Disable-virtio-net-pci-romfile-loading-on-riscv64.patch +# For RHEL-98555 - [s390x][RHEL10.1][ccw-device] there would be memory leak with virtio_blk disks +Patch52: kvm-s390x-Fix-leak-in-machine_set_loadparm.patch +# For RHEL-98555 - [s390x][RHEL10.1][ccw-device] there would be memory leak with virtio_blk disks +Patch53: kvm-hw-s390x-ccw-device-Fix-memory-leak-in-loadparm-sett.patch +# For RHEL-52650 - [AMDSERVER 10.1 Feature] Turin: Qemu EPYC-Turin Model +Patch54: kvm-target-i386-Update-EPYC-CPU-model-for-Cache-property.patch +# For RHEL-52650 - [AMDSERVER 10.1 Feature] Turin: Qemu EPYC-Turin Model +Patch55: kvm-target-i386-Update-EPYC-Rome-CPU-model-for-Cache-pro.patch +# For RHEL-52650 - [AMDSERVER 10.1 Feature] Turin: Qemu EPYC-Turin Model +Patch56: kvm-target-i386-Update-EPYC-Milan-CPU-model-for-Cache-pr.patch +# For RHEL-52650 - [AMDSERVER 10.1 Feature] Turin: Qemu EPYC-Turin Model +Patch57: kvm-target-i386-Add-couple-of-feature-bits-in-CPUID_Fn80.patch +# For RHEL-52650 - [AMDSERVER 10.1 Feature] Turin: Qemu EPYC-Turin Model +Patch58: kvm-target-i386-Update-EPYC-Genoa-for-Cache-property-per.patch +# For RHEL-52650 - [AMDSERVER 10.1 Feature] Turin: Qemu EPYC-Turin Model +Patch59: kvm-target-i386-Add-support-for-EPYC-Turin-model.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch60: kvm-include-qemu-compiler-add-QEMU_UNINITIALIZED-attribu.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch61: kvm-hw-virtio-virtio-avoid-cost-of-ftrivial-auto-var-ini.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch62: kvm-block-skip-automatic-zero-init-of-large-array-in-ioq.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch63: kvm-chardev-char-fd-skip-automatic-zero-init-of-large-ar.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch64: kvm-chardev-char-pty-skip-automatic-zero-init-of-large-a.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch65: kvm-chardev-char-socket-skip-automatic-zero-init-of-larg.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch66: kvm-hw-audio-ac97-skip-automatic-zero-init-of-large-arra.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch67: kvm-hw-audio-cs4231a-skip-automatic-zero-init-of-large-a.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch68: kvm-hw-audio-es1370-skip-automatic-zero-init-of-large-ar.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch69: kvm-hw-audio-gus-skip-automatic-zero-init-of-large-array.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch70: kvm-hw-audio-marvell_88w8618-skip-automatic-zero-init-of.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch71: kvm-hw-audio-sb16-skip-automatic-zero-init-of-large-arra.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch72: kvm-hw-audio-via-ac97-skip-automatic-zero-init-of-large-.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch73: kvm-hw-char-sclpconsole-lm-skip-automatic-zero-init-of-l.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch74: kvm-hw-dma-xlnx_csu_dma-skip-automatic-zero-init-of-larg.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch75: kvm-hw-display-vmware_vga-skip-automatic-zero-init-of-la.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch76: kvm-hw-hyperv-syndbg-skip-automatic-zero-init-of-large-a.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch77: kvm-hw-misc-aspeed_hace-skip-automatic-zero-init-of-larg.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch78: kvm-hw-net-rtl8139-skip-automatic-zero-init-of-large-arr.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch79: kvm-hw-net-tulip-skip-automatic-zero-init-of-large-array.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch80: kvm-hw-net-virtio-net-skip-automatic-zero-init-of-large-.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch81: kvm-hw-net-xgamc-skip-automatic-zero-init-of-large-array.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch82: kvm-hw-nvme-ctrl-skip-automatic-zero-init-of-large-array.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch83: kvm-hw-ppc-pnv_occ-skip-automatic-zero-init-of-large-str.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch84: kvm-hw-ppc-spapr_tpm_proxy-skip-automatic-zero-init-of-l.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch85: kvm-hw-usb-hcd-ohci-skip-automatic-zero-init-of-large-ar.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch86: kvm-hw-scsi-lsi53c895a-skip-automatic-zero-init-of-large.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch87: kvm-hw-scsi-megasas-skip-automatic-zero-init-of-large-ar.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch88: kvm-hw-ufs-lu-skip-automatic-zero-init-of-large-array.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch89: kvm-net-socket-skip-automatic-zero-init-of-large-array.patch +# For RHEL-95479 - -ftrivial-auto-var-init=zero reduced performance +Patch90: kvm-net-stream-skip-automatic-zero-init-of-large-array.patch +# For RHEL-85649 - [RHEL 10]Qemu/amd-iommu: Add ability to manually specify the AMDVI-PCI device +Patch91: kvm-hw-i386-amd_iommu-Isolate-AMDVI-PCI-from-amd-iommu-d.patch +# For RHEL-85649 - [RHEL 10]Qemu/amd-iommu: Add ability to manually specify the AMDVI-PCI device +Patch92: kvm-hw-i386-amd_iommu-Allow-migration-when-explicitly-cr.patch +# For RHEL-85649 - [RHEL 10]Qemu/amd-iommu: Add ability to manually specify the AMDVI-PCI device +Patch93: kvm-Enable-amd-iommu-device.patch +# For RHEL-83883 - Video stuck after switchover phase when play one video during migration +Patch94: kvm-ui-vnc-Update-display-update-interval-when-VM-state-.patch +# For RHEL-59697 - Allow multifd+postcopy features being enabled together, but only use multifd during precopy +Patch95: kvm-migration-multifd-move-macros-to-multifd-header.patch +# For RHEL-59697 - Allow multifd+postcopy features being enabled together, but only use multifd during precopy +Patch96: kvm-migration-refactor-channel-discovery-mechanism.patch +# For RHEL-59697 - Allow multifd+postcopy features being enabled together, but only use multifd during precopy +Patch97: kvm-migration-Add-save_postcopy_prepare-savevm-handler.patch +# For RHEL-59697 - Allow multifd+postcopy features being enabled together, but only use multifd during precopy +Patch98: kvm-migration-ram-Implement-save_postcopy_prepare.patch +# For RHEL-59697 - Allow multifd+postcopy features being enabled together, but only use multifd during precopy +Patch99: kvm-tests-qtest-migration-consolidate-set-capabilities.patch +# For RHEL-59697 - Allow multifd+postcopy features being enabled together, but only use multifd during precopy +Patch100: kvm-migration-write-zero-pages-when-postcopy-enabled.patch +# For RHEL-59697 - Allow multifd+postcopy features being enabled together, but only use multifd during precopy +Patch101: kvm-migration-enable-multifd-and-postcopy-together.patch +# For RHEL-59697 - Allow multifd+postcopy features being enabled together, but only use multifd during precopy +Patch102: kvm-migration-Add-qtest-for-migration-over-RDMA.patch +# For RHEL-59697 - Allow multifd+postcopy features being enabled together, but only use multifd during precopy +Patch103: kvm-qtest-migration-rdma-Enforce-RLIMIT_MEMLOCK-128MB-re.patch +# For RHEL-59697 - Allow multifd+postcopy features being enabled together, but only use multifd during precopy +Patch104: kvm-qtest-migration-rdma-Add-test-for-rdma-migration-wit.patch +# For RHEL-59697 - Allow multifd+postcopy features being enabled together, but only use multifd during precopy +Patch105: kvm-tests-qtest-migration-add-postcopy-tests-with-multif.patch +# For RHEL-96854 - Performance Degradation(aio=threads) between Upstream Commit b75c5f9 and 984a32f +Patch106: kvm-file-posix-Fix-aio-threads-performance-regression-af.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch107: kvm-block-remove-outdated-comments-about-AioContext-lock.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch108: kvm-block-move-drain-outside-of-read-locked-bdrv_reopen_.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch109: kvm-block-snapshot-move-drain-outside-of-read-locked-bdr.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch110: kvm-block-move-drain-outside-of-read-locked-bdrv_inactiv.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch111: kvm-block-mark-bdrv_parent_change_aio_context-GRAPH_RDLO.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch112: kvm-block-mark-change_aio_ctx-callback-and-instances-as-.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch113: kvm-block-mark-bdrv_child_change_aio_context-GRAPH_RDLOC.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch114: kvm-block-move-drain-outside-of-bdrv_change_aio_context-.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch115: kvm-block-move-drain-outside-of-bdrv_try_change_aio_cont.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch116: kvm-block-move-drain-outside-of-bdrv_attach_child_common.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch117: kvm-block-move-drain-outside-of-bdrv_set_backing_hd_drai.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch118: kvm-block-move-drain-outside-of-bdrv_root_attach_child.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch119: kvm-block-move-drain-outside-of-bdrv_attach_child.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch120: kvm-block-move-drain-outside-of-quorum_add_child.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch121: kvm-block-move-drain-outside-of-bdrv_root_unref_child.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch122: kvm-block-move-drain-outside-of-quorum_del_child.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch123: kvm-blockdev-drain-while-unlocked-in-internal_snapshot_a.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch124: kvm-blockdev-drain-while-unlocked-in-external_snapshot_a.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch125: kvm-block-mark-bdrv_drained_begin-and-friends-as-GRAPH_U.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch126: kvm-iotests-graph-changes-while-io-remove-image-file-aft.patch +# For RHEL-88561 - qemu graph deadlock during job-dismiss +Patch127: kvm-iotests-graph-changes-while-io-add-test-case-with-re.patch +# For RHEL-45624 - Deprecate rtl8139 NIC in QEMU +Patch128: kvm-Declare-rtl8139-as-deprecated.patch +# For RHEL-102325 - [qemu] enable variable service for edk2 +Patch129: kvm-Enable-uefi-variable-service-for-edk2.patch +# For RHEL-105440 - Openstack guest becomes inaccessible via network when storage network on the hypervisor is disabled/lost [rhel-10.1] +Patch130: kvm-rbd-Fix-.bdrv_get_specific_info-implementation.patch +Patch131: kvm-i386-Remove-unused-parameter-uint32_t-bit-in-feature.patch +Patch132: kvm-target-i386-Print-CPUID-subleaf-info-for-unsupported.patch +Patch133: kvm-qom-reverse-order-of-instance_post_init-calls.patch +Patch134: kvm-target-i386-Remove-AccelCPUClass-cpu_class_init-need.patch +Patch135: kvm-i386-cpu-Consolidate-the-helper-to-get-Host-s-vendor.patch +Patch136: kvm-rocker-do-not-pollute-the-namespace.patch +Patch137: kvm-include-system-Move-exec-memory.h-to-system-memory.h.patch +Patch138: kvm-include-system-Move-exec-address-spaces.h-to-system-.patch +Patch139: kvm-include-system-Move-exec-ioport.h-to-system-ioport.h.patch +Patch140: kvm-include-system-Move-exec-ram_addr.h-to-system-ram_ad.patch +Patch141: kvm-include-system-Move-exec-ramblock.h-to-system-ramblo.patch +Patch142: kvm-linux-headers-Update-to-Linux-v6.15-rc3.patch +Patch143: kvm-linux-headers-update-from-6.15-kvm-next.patch +Patch144: kvm-update-Linux-headers-to-v6.16-rc3.patch +Patch145: kvm-update-Linux-headers-to-KVM-tree-master.patch +Patch146: kvm-i386-Introduce-tdx-guest-object.patch +Patch147: kvm-i386-tdx-Implement-tdx_kvm_type-for-TDX.patch +Patch148: kvm-i386-tdx-Implement-tdx_kvm_init-to-initialize-TDX-VM.patch +Patch149: kvm-i386-tdx-Get-tdx_capabilities-via-KVM_TDX_CAPABILITI.patch +Patch150: kvm-i386-tdx-Introduce-is_tdx_vm-helper-and-cache-tdx_gu.patch +Patch151: kvm-kvm-Introduce-kvm_arch_pre_create_vcpu.patch +Patch152: kvm-i386-tdx-Initialize-TDX-before-creating-TD-vcpus.patch +Patch153: kvm-i386-tdx-Add-property-sept-ve-disable-for-tdx-guest-.patch +Patch154: kvm-i386-tdx-Make-sept_ve_disable-set-by-default.patch +Patch155: kvm-i386-tdx-Wire-CPU-features-up-with-attributes-of-TD-.patch +Patch156: kvm-i386-tdx-Validate-TD-attributes.patch +Patch157: kvm-i386-tdx-Support-user-configurable-mrconfigid-mrowne.patch +Patch158: kvm-i386-tdx-Set-APIC-bus-rate-to-match-with-what-TDX-mo.patch +Patch159: kvm-i386-tdx-Implement-user-specified-tsc-frequency.patch +Patch160: kvm-i386-tdx-load-TDVF-for-TD-guest.patch +Patch161: kvm-i386-tdvf-Introduce-function-to-parse-TDVF-metadata.patch +Patch162: kvm-i386-tdx-Parse-TDVF-metadata-for-TDX-VM.patch +Patch163: kvm-i386-tdx-Don-t-initialize-pc.rom-for-TDX-VMs.patch +Patch164: kvm-i386-tdx-Track-mem_ptr-for-each-firmware-entry-of-TD.patch +Patch165: kvm-i386-tdx-Track-RAM-entries-for-TDX-VM.patch +Patch166: kvm-headers-Add-definitions-from-UEFI-spec-for-volumes-r.patch +Patch167: kvm-i386-tdx-Setup-the-TD-HOB-list.patch +Patch168: kvm-i386-tdx-Add-TDVF-memory-via-KVM_TDX_INIT_MEM_REGION.patch +Patch169: kvm-i386-tdx-Call-KVM_TDX_INIT_VCPU-to-initialize-TDX-vc.patch +Patch170: kvm-i386-tdx-Finalize-TDX-VM.patch +Patch171: kvm-i386-tdx-Enable-user-exit-on-KVM_HC_MAP_GPA_RANGE.patch +Patch172: kvm-i386-tdx-Handle-KVM_SYSTEM_EVENT_TDX_FATAL.patch +Patch173: kvm-i386-tdx-Wire-TDX_REPORT_FATAL_ERROR-with-GuestPanic.patch +Patch174: kvm-kvm-Check-KVM_CAP_MAX_VCPUS-at-vm-level.patch +Patch175: kvm-i386-cpu-introduce-x86_confidential_guest_cpu_instan.patch +Patch176: kvm-i386-tdx-implement-tdx_cpu_instance_init.patch +Patch177: kvm-i386-cpu-Introduce-enable_cpuid_0x1f-to-force-exposi.patch +Patch178: kvm-i386-tdx-Force-exposing-CPUID-0x1f.patch +Patch179: kvm-i386-tdx-Set-kvm_readonly_mem_enabled-to-false-for-T.patch +Patch180: kvm-i386-tdx-Disable-SMM-for-TDX-VMs.patch +Patch181: kvm-i386-tdx-Disable-PIC-for-TDX-VMs.patch +Patch182: kvm-i386-tdx-Set-and-check-kernel_irqchip-mode-for-TDX.patch +Patch183: kvm-i386-tdx-Don-t-synchronize-guest-tsc-for-TDs.patch +Patch184: kvm-i386-tdx-Only-configure-MSR_IA32_UCODE_REV-in-kvm_in.patch +Patch185: kvm-i386-apic-Skip-kvm_apic_put-for-TDX.patch +Patch186: kvm-cpu-Don-t-set-vcpu_dirty-when-guest_state_protected.patch +Patch187: kvm-i386-cgs-Rename-mask_cpuid_features-to-adjust_cpuid_.patch +Patch188: kvm-i386-tdx-Implement-adjust_cpuid_features-for-TDX.patch +Patch189: kvm-i386-tdx-Add-TDX-fixed1-bits-to-supported-CPUIDs.patch +Patch190: kvm-i386-tdx-Add-supported-CPUID-bits-related-to-TD-Attr.patch +Patch191: kvm-i386-tdx-Add-supported-CPUID-bits-relates-to-XFAM.patch +Patch192: kvm-i386-tdx-Add-XFD-to-supported-bit-of-TDX.patch +Patch193: kvm-i386-tdx-Define-supported-KVM-features-for-TDX.patch +Patch194: kvm-i386-cgs-Introduce-x86_confidential_guest_check_feat.patch +Patch195: kvm-i386-tdx-Fetch-and-validate-CPUID-of-TD-guest.patch +Patch196: kvm-i386-tdx-Don-t-treat-SYSCALL-as-unavailable.patch +Patch197: kvm-i386-tdx-Make-invtsc-default-on.patch +Patch198: kvm-i386-tdx-Validate-phys_bits-against-host-value.patch +Patch199: kvm-docs-Add-TDX-documentation.patch +Patch200: kvm-i386-tdx-Fix-build-on-32-bit-host.patch +Patch201: kvm-i386-tdvf-Fix-build-on-32-bit-host.patch +Patch202: kvm-i386-cpu-Move-adjustment-of-CPUID_EXT_PDCM-before-fe.patch +Patch203: kvm-i386-tdx-Error-and-exit-when-named-cpu-model-is-requ.patch +Patch204: kvm-i386-cpu-Rename-enable_cpuid_0x1f-to-force_cpuid_0x1.patch +Patch205: kvm-i386-tdx-Fix-the-typo-of-the-comment-of-struct-TdxGu.patch +Patch206: kvm-i386-tdx-Clarify-the-error-message-of-mrconfigid-mro.patch +Patch207: kvm-i386-tdx-handle-TDG.VP.VMCALL-GetTdVmCallInfo.patch +Patch208: kvm-i386-tdx-handle-TDG.VP.VMCALL-GetQuote.patch +Patch209: kvm-target-i386-move-max_features-to-class.patch +Patch210: kvm-target-i386-nvmm-whpx-add-accel-CPU-class-that-sets-.patch +Patch211: kvm-target-i386-allow-reordering-max_x86_cpu_initfn-vs-a.patch +Patch212: kvm-target-i386-move-accel_cpu_instance_init-to-.instanc.patch +Patch213: kvm-target-i386-merge-host_cpu_instance_init-and-host_cp.patch +Patch214: kvm-i386-tdx-Remove-enumeration-of-GetQuote-in-tdx_handl.patch +Patch215: kvm-i386-tdx-Set-value-of-GetTdVmCallInfo-based-on-capab.patch +Patch216: kvm-i386-tdx-handle-TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUP.patch +Patch217: kvm-i386-tdx-Fix-the-report-of-gpa-in-QAPI.patch +Patch218: kvm-i386-tdx-Remove-task-watch-only-when-it-s-valid.patch +Patch219: kvm-i386-tdx-Don-t-mask-off-CPUID_EXT_PDCM.patch +Patch220: kvm-i386-cpu-Move-x86_ext_save_areas-initialization-to-..patch +Patch221: kvm-target-i386-tdx-fix-locking-for-interrupt-injection.patch +Patch222: kvm-i386-cpu-Cleanup-host_cpu_max_instance_init.patch +Patch223: kvm-i386-tdx-Remove-the-redundant-qemu_mutex_init-tdx-lo.patch +Patch224: kvm-redhat-enable-CONFIG_TDX.patch +Patch225: kvm-redhat-allow-5-level-paging-for-TDX-VMs.patch +Patch226: kvm-memory-Export-a-helper-to-get-intersection-of-a-Memo.patch +Patch227: kvm-memory-Change-memory_region_set_ram_discard_manager-.patch +Patch228: kvm-memory-Unify-the-definiton-of-ReplayRamPopulate-and-.patch +Patch229: kvm-ram-block-attributes-Introduce-RamBlockAttributes-to.patch +Patch230: kvm-physmem-Support-coordinated-discarding-of-RAM-with-g.patch +# For RHEL-108614 - CVE-2025-8860 qemu-kvm: uefi-vars: information disclosure vulnerability in uefi_vars_write callback [rhel-10.1] +Patch231: kvm-hw-uefi-clear-uefi-vars-buffer-in-uefi_vars_write-ca.patch +# For RHEL-108614 - CVE-2025-8860 qemu-kvm: uefi-vars: information disclosure vulnerability in uefi_vars_write callback [rhel-10.1] +Patch232: kvm-hw-uefi-return-success-for-notifications.patch +# For RHEL-108614 - CVE-2025-8860 qemu-kvm: uefi-vars: information disclosure vulnerability in uefi_vars_write callback [rhel-10.1] +Patch233: kvm-hw-uefi-check-access-for-first-variable.patch # AlmaLinux Patch Patch2001: 2001-Add-ppc64-support.patch @@ -651,6 +627,9 @@ BuildRequires: spice-server-devel BuildRequires: libcacard-devel BuildRequires: nss-devel %endif +%ifarch %{valgrind_arches} +BuildRequires: valgrind-devel +%endif # Requires for qemu-kvm package Requires: %{name}-core = %{epoch}:%{version}-%{release} @@ -672,12 +651,15 @@ Summary: %{name} core components %{obsoletes_some_modules} Requires: %{name}-common = %{epoch}:%{version}-%{release} Requires: qemu-img = %{epoch}:%{version}-%{release} -%ifarch %{ix86} x86_64 +%ifarch x86_64 Requires: edk2-ovmf %endif %ifarch aarch64 Requires: edk2-aarch64 %endif +%ifarch riscv64 +Requires: edk2-riscv64 +%endif Requires: libseccomp >= %{libseccomp_version} Requires: libusbx >= %{libusbx_version} @@ -709,10 +691,10 @@ Requires(post): /usr/sbin/useradd Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units -%ifarch %{ix86} x86_64 +%ifarch x86_64 Requires: seabios-bin >= 1.10.2-1 %endif -%ifnarch aarch64 s390x +%ifarch x86_64 %{power64} Requires: seavgabios-bin >= 1.12.0-3 Requires: ipxe-roms-qemu >= %{ipxe_version} %endif @@ -730,6 +712,8 @@ This package provides documentation and auxiliary programs used with %{name}. %package tools Summary: %{name} support tools +Recommends: systemtap-client +Recommends: systemtap-devel %description tools %{name}-tools provides various tools related to %{name} usage. @@ -930,6 +914,7 @@ ulimit -n 10240 %define disable_everything \\\ --audio-drv-list= \\\ --disable-alsa \\\ + --disable-asan \\\ --disable-attr \\\ --disable-auth-pam \\\ --disable-avx2 \\\ @@ -1007,6 +992,7 @@ ulimit -n 10240 --disable-parallels \\\ --disable-pie \\\ --disable-plugins \\\ + --disable-pvg \\\ --disable-qcow1 \\\ --disable-qed \\\ --disable-qga-vss \\\ @@ -1016,7 +1002,6 @@ ulimit -n 10240 --disable-replication \\\ --disable-rng-none \\\ --disable-safe-stack \\\ - --disable-sanitizers \\\ --disable-sdl \\\ --disable-sdl-image \\\ --disable-seccomp \\\ @@ -1035,8 +1020,10 @@ ulimit -n 10240 --disable-tools \\\ --disable-tpm \\\ --disable-u2f \\\ + --disable-ubsan \\\ --disable-usb-redir \\\ --disable-user \\\ + --disable-valgrind \\\ --disable-vde \\\ --disable-vdi \\\ --disable-vduse-blk-export \\\ @@ -1084,7 +1071,7 @@ run_configure() { --with-coroutine=ucontext \ --tls-priority=@QEMU,SYSTEM \ %{disable_everything} \ -%ifarch aarch64 s390x x86_64 +%ifarch aarch64 s390x x86_64 riscv64 --with-devices-%{kvm_target}=%{kvm_target}-rh-devices \ %endif %ifarch %{power64} @@ -1170,6 +1157,9 @@ run_configure \ --enable-tpm \ %if %{have_usbredir} --enable-usb-redir \ +%endif +%ifarch %{valgrind_arches} + --enable-valgrind \ %endif --enable-vdi \ --enable-vhost-kernel \ @@ -1229,6 +1219,7 @@ cp -a qemu-system-%{kvm_target} qemu-kvm cp pc-bios/s390-ccw/s390-ccw.img pc-bios/ %endif + popd # endif !tools_only %endif @@ -1365,6 +1356,7 @@ rm -rf %{buildroot}%{_datadir}/%{name}/u-boot.e500 rm -rf %{buildroot}%{_datadir}/%{name}/qemu_vga.ndrv rm -rf %{buildroot}%{_datadir}/%{name}/skiboot.lid rm -rf %{buildroot}%{_datadir}/%{name}/qboot.rom +rm -rf %{buildroot}%{_datadir}/%{name}/pnv-pnor.bin rm -rf %{buildroot}%{_datadir}/%{name}/s390-ccw.img rm -rf %{buildroot}%{_datadir}/%{name}/hppa-firmware.img @@ -1386,6 +1378,7 @@ rm -rf %{buildroot}%{_datadir}/%{name}/qemu-nsis.bmp rm -rf %{buildroot}%{_datadir}/%{name}/npcm7xx_bootrom.bin rm -rf %{buildroot}%{_libdir}/%{name}/ui-spice-app.so +rm -rf %{buildroot}%{_datadir}/%{name}/npcm8xx_bootrom.bin # Remove virtfs-proxy-helper files rm -rf %{buildroot}%{_libexecdir}/virtfs-proxy-helper @@ -1394,6 +1387,8 @@ rm -rf %{buildroot}%{_mandir}/man1/virtfs-proxy-helper* %ifarch s390x # Use the s390-ccw.img that we've just built, not the pre-built one install -m 0644 %{qemu_kvm_build}/pc-bios/s390-ccw/s390-ccw.img %{buildroot}%{_datadir}/%{name}/ + # Remove uefi vars + rm -rf %{buildroot}%{_libdir}/%{name}/hw-uefi-vars.so %else rm -rf %{buildroot}%{_libdir}/%{name}/hw-s390x-virtio-gpu-ccw.so %endif @@ -1583,6 +1578,8 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %ifarch s390x %{_datadir}/%{name}/s390-ccw.img +%else + %{_libdir}/%{name}/hw-uefi-vars.so %endif %{_datadir}/icons/* %{_datadir}/%{name}/linuxboot_dma.bin @@ -1594,6 +1591,9 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %files core +%ifarch ppc64le + %{_datadir}/%{name}/slof.bin +%endif %{_libexecdir}/qemu-kvm %{_datadir}/systemtap/tapset/qemu-kvm.stp %{_datadir}/systemtap/tapset/qemu-kvm-log.stp @@ -1605,14 +1605,6 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %{_datadir}/systemtap/tapset/qemu-nbd*.stp %{_datadir}/systemtap/tapset/qemu-storage-daemon*.stp -%ifarch x86_64 - %{_libdir}/%{name}/accel-tcg-%{kvm_target}.so -%endif - -%ifarch ppc64le - %{_datadir}/%{name}/slof.bin -%endif - %files device-display-virtio-gpu %{_libdir}/%{name}/hw-display-virtio-gpu.so @@ -1681,63 +1673,230 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog -* Wed Nov 05 2025 Eduard Abdullin - 18:9.1.0-15.4.alma.1 +* Thu Dec 04 2025 Eduard Abdullin - 18:10.0.0-14.alma.1 - Enable QXL device build - Enable building for ppc64le - Re-added Spice support - Don't remove slof.bin for ppc64le -* Mon Aug 18 2025 Miroslav Rezanina - 9.1.0-15.el10_0.4 -- kvm-rbd-Fix-.bdrv_get_specific_info-implementation.patch [RHEL-108727] -- Resolves: RHEL-108727 - (Openstack guest becomes inaccessible via network when storage network on the hypervisor is disabled/lost [rhel-10.0.z]) +* Wed Sep 17 2025 Miroslav Rezanina - 10.0.0-14 +- kvm-hw-uefi-clear-uefi-vars-buffer-in-uefi_vars_write-ca.patch [RHEL-108614] +- kvm-hw-uefi-return-success-for-notifications.patch [RHEL-108614] +- kvm-hw-uefi-check-access-for-first-variable.patch [RHEL-108614] +- Resolves: RHEL-108614 + (CVE-2025-8860 qemu-kvm: uefi-vars: information disclosure vulnerability in uefi_vars_write callback [rhel-10.1]) -* Tue Jul 01 2025 Miroslav Rezanina - 9.1.0-15.el10_0.3 -- kvm-ui-vnc-Update-display-update-interval-when-VM-state-.patch [RHEL-100765] -- kvm-include-qemu-compiler-add-QEMU_UNINITIALIZED-attribu.patch [RHEL-99889] -- kvm-hw-virtio-virtio-avoid-cost-of-ftrivial-auto-var-ini.patch [RHEL-99889] -- kvm-block-skip-automatic-zero-init-of-large-array-in-ioq.patch [RHEL-99889] -- kvm-chardev-char-fd-skip-automatic-zero-init-of-large-ar.patch [RHEL-99889] -- kvm-chardev-char-pty-skip-automatic-zero-init-of-large-a.patch [RHEL-99889] -- kvm-chardev-char-socket-skip-automatic-zero-init-of-larg.patch [RHEL-99889] -- kvm-hw-audio-ac97-skip-automatic-zero-init-of-large-arra.patch [RHEL-99889] -- kvm-hw-audio-cs4231a-skip-automatic-zero-init-of-large-a.patch [RHEL-99889] -- kvm-hw-audio-es1370-skip-automatic-zero-init-of-large-ar.patch [RHEL-99889] -- kvm-hw-audio-gus-skip-automatic-zero-init-of-large-array.patch [RHEL-99889] -- kvm-hw-audio-marvell_88w8618-skip-automatic-zero-init-of.patch [RHEL-99889] -- kvm-hw-audio-sb16-skip-automatic-zero-init-of-large-arra.patch [RHEL-99889] -- kvm-hw-audio-via-ac97-skip-automatic-zero-init-of-large-.patch [RHEL-99889] -- kvm-hw-char-sclpconsole-lm-skip-automatic-zero-init-of-l.patch [RHEL-99889] -- kvm-hw-dma-xlnx_csu_dma-skip-automatic-zero-init-of-larg.patch [RHEL-99889] -- kvm-hw-display-vmware_vga-skip-automatic-zero-init-of-la.patch [RHEL-99889] -- kvm-hw-hyperv-syndbg-skip-automatic-zero-init-of-large-a.patch [RHEL-99889] -- kvm-hw-misc-aspeed_hace-skip-automatic-zero-init-of-larg.patch [RHEL-99889] -- kvm-hw-net-rtl8139-skip-automatic-zero-init-of-large-arr.patch [RHEL-99889] -- kvm-hw-net-tulip-skip-automatic-zero-init-of-large-array.patch [RHEL-99889] -- kvm-hw-net-virtio-net-skip-automatic-zero-init-of-large-.patch [RHEL-99889] -- kvm-hw-net-xgamc-skip-automatic-zero-init-of-large-array.patch [RHEL-99889] -- kvm-hw-nvme-ctrl-skip-automatic-zero-init-of-large-array.patch [RHEL-99889] -- kvm-hw-ppc-spapr_tpm_proxy-skip-automatic-zero-init-of-l.patch [RHEL-99889] -- kvm-hw-usb-hcd-ohci-skip-automatic-zero-init-of-large-ar.patch [RHEL-99889] -- kvm-hw-scsi-lsi53c895a-skip-automatic-zero-init-of-large.patch [RHEL-99889] -- kvm-hw-scsi-megasas-skip-automatic-zero-init-of-large-ar.patch [RHEL-99889] -- kvm-hw-ufs-lu-skip-automatic-zero-init-of-large-array.patch [RHEL-99889] -- kvm-net-socket-skip-automatic-zero-init-of-large-array.patch [RHEL-99889] -- kvm-net-stream-skip-automatic-zero-init-of-large-array.patch [RHEL-99889] -- Resolves: RHEL-100765 - (Video stuck after switchover phase when play one video during migration [rhel-10.0.z]) -- Resolves: RHEL-99889 - (-ftrivial-auto-var-init=zero reduced performance [rhel-10.0.z]) +* Wed Sep 10 2025 Miroslav Rezanina - 10.0.0-13 +- Added TDX support +- Resolves: RHEL-20797 + ([Intel 10.0 FEAT] TDX: host: Virt-QEMU: Add safe device pass-through for TD) +- Resolves: RHEL-49727 + ([Intel 10.0 FEAT] [SPR][EMR] Virt-QEMU: TDX: Allow to configure apic bus clock) +- Resolves: RHEL-50307 + ([Intel 10.0 FEAT] [SPR] TDX: Virt-QEMU: QEMU Support) -* Mon May 26 2025 Miroslav Rezanina - 9.1.0-15.el10_0.2 -- kvm-hw-i386-Fix-machine-type-compatibility.patch [RHEL-92430] -- Resolves: RHEL-92430 - (Fix x86 M-type compats [rhel-10.0.z]) +* Thu Aug 21 2025 Miroslav Rezanina - 10.0.0-12 +- kvm-RHEL-Pack-uefi-vars-module.patch [RHEL-102325] +- Resolves: RHEL-102325 + ([qemu] enable variable service for edk2) -* Tue Mar 18 2025 Miroslav Rezanina - 9.1.0-15.el10_0.1 -- kvm-net-vhost-user-add-QAPI-events-to-report-connection-.patch [RHEL-80522] -- Resolves: RHEL-80522 - (Allow libvirt to restart passt/vhost-user when the process is killed) +* Mon Aug 18 2025 Miroslav Rezanina - 10.0.0-11 +- kvm-rbd-Fix-.bdrv_get_specific_info-implementation.patch [RHEL-105440] +- Resolves: RHEL-105440 + (Openstack guest becomes inaccessible via network when storage network on the hypervisor is disabled/lost [rhel-10.1]) + +* Tue Aug 12 2025 Miroslav Rezanina - 10.0.0-10 +- kvm-Enable-uefi-variable-service-for-edk2.patch [RHEL-102325] +- Resolves: RHEL-102325 + ([qemu] enable variable service for edk2) + +* Mon Aug 04 2025 Miroslav Rezanina - 10.0.0-9 +- kvm-Declare-rtl8139-as-deprecated.patch [RHEL-45624] +- Resolves: RHEL-45624 + (Deprecate rtl8139 NIC in QEMU) + +* Mon Jul 28 2025 Miroslav Rezanina - 10.0.0-8 +- kvm-migration-multifd-move-macros-to-multifd-header.patch [RHEL-59697] +- kvm-migration-refactor-channel-discovery-mechanism.patch [RHEL-59697] +- kvm-migration-Add-save_postcopy_prepare-savevm-handler.patch [RHEL-59697] +- kvm-migration-ram-Implement-save_postcopy_prepare.patch [RHEL-59697] +- kvm-tests-qtest-migration-consolidate-set-capabilities.patch [RHEL-59697] +- kvm-migration-write-zero-pages-when-postcopy-enabled.patch [RHEL-59697] +- kvm-migration-enable-multifd-and-postcopy-together.patch [RHEL-59697] +- kvm-migration-Add-qtest-for-migration-over-RDMA.patch [RHEL-59697] +- kvm-qtest-migration-rdma-Enforce-RLIMIT_MEMLOCK-128MB-re.patch [RHEL-59697] +- kvm-qtest-migration-rdma-Add-test-for-rdma-migration-wit.patch [RHEL-59697] +- kvm-tests-qtest-migration-add-postcopy-tests-with-multif.patch [RHEL-59697] +- kvm-file-posix-Fix-aio-threads-performance-regression-af.patch [RHEL-96854] +- kvm-block-remove-outdated-comments-about-AioContext-lock.patch [RHEL-88561] +- kvm-block-move-drain-outside-of-read-locked-bdrv_reopen_.patch [RHEL-88561] +- kvm-block-snapshot-move-drain-outside-of-read-locked-bdr.patch [RHEL-88561] +- kvm-block-move-drain-outside-of-read-locked-bdrv_inactiv.patch [RHEL-88561] +- kvm-block-mark-bdrv_parent_change_aio_context-GRAPH_RDLO.patch [RHEL-88561] +- kvm-block-mark-change_aio_ctx-callback-and-instances-as-.patch [RHEL-88561] +- kvm-block-mark-bdrv_child_change_aio_context-GRAPH_RDLOC.patch [RHEL-88561] +- kvm-block-move-drain-outside-of-bdrv_change_aio_context-.patch [RHEL-88561] +- kvm-block-move-drain-outside-of-bdrv_try_change_aio_cont.patch [RHEL-88561] +- kvm-block-move-drain-outside-of-bdrv_attach_child_common.patch [RHEL-88561] +- kvm-block-move-drain-outside-of-bdrv_set_backing_hd_drai.patch [RHEL-88561] +- kvm-block-move-drain-outside-of-bdrv_root_attach_child.patch [RHEL-88561] +- kvm-block-move-drain-outside-of-bdrv_attach_child.patch [RHEL-88561] +- kvm-block-move-drain-outside-of-quorum_add_child.patch [RHEL-88561] +- kvm-block-move-drain-outside-of-bdrv_root_unref_child.patch [RHEL-88561] +- kvm-block-move-drain-outside-of-quorum_del_child.patch [RHEL-88561] +- kvm-blockdev-drain-while-unlocked-in-internal_snapshot_a.patch [RHEL-88561] +- kvm-blockdev-drain-while-unlocked-in-external_snapshot_a.patch [RHEL-88561] +- kvm-block-mark-bdrv_drained_begin-and-friends-as-GRAPH_U.patch [RHEL-88561] +- kvm-iotests-graph-changes-while-io-remove-image-file-aft.patch [RHEL-88561] +- kvm-iotests-graph-changes-while-io-add-test-case-with-re.patch [RHEL-88561] +- Resolves: RHEL-59697 + (Allow multifd+postcopy features being enabled together, but only use multifd during precopy ) +- Resolves: RHEL-96854 + (Performance Degradation(aio=threads) between Upstream Commit b75c5f9 and 984a32f) +- Resolves: RHEL-88561 + (qemu graph deadlock during job-dismiss) + +* Mon Jul 07 2025 Miroslav Rezanina - 10.0.0-7 +- kvm-s390x-Fix-leak-in-machine_set_loadparm.patch [RHEL-98555] +- kvm-hw-s390x-ccw-device-Fix-memory-leak-in-loadparm-sett.patch [RHEL-98555] +- kvm-target-i386-Update-EPYC-CPU-model-for-Cache-property.patch [RHEL-52650] +- kvm-target-i386-Update-EPYC-Rome-CPU-model-for-Cache-pro.patch [RHEL-52650] +- kvm-target-i386-Update-EPYC-Milan-CPU-model-for-Cache-pr.patch [RHEL-52650] +- kvm-target-i386-Add-couple-of-feature-bits-in-CPUID_Fn80.patch [RHEL-52650] +- kvm-target-i386-Update-EPYC-Genoa-for-Cache-property-per.patch [RHEL-52650] +- kvm-target-i386-Add-support-for-EPYC-Turin-model.patch [RHEL-52650] +- kvm-include-qemu-compiler-add-QEMU_UNINITIALIZED-attribu.patch [RHEL-95479] +- kvm-hw-virtio-virtio-avoid-cost-of-ftrivial-auto-var-ini.patch [RHEL-95479] +- kvm-block-skip-automatic-zero-init-of-large-array-in-ioq.patch [RHEL-95479] +- kvm-chardev-char-fd-skip-automatic-zero-init-of-large-ar.patch [RHEL-95479] +- kvm-chardev-char-pty-skip-automatic-zero-init-of-large-a.patch [RHEL-95479] +- kvm-chardev-char-socket-skip-automatic-zero-init-of-larg.patch [RHEL-95479] +- kvm-hw-audio-ac97-skip-automatic-zero-init-of-large-arra.patch [RHEL-95479] +- kvm-hw-audio-cs4231a-skip-automatic-zero-init-of-large-a.patch [RHEL-95479] +- kvm-hw-audio-es1370-skip-automatic-zero-init-of-large-ar.patch [RHEL-95479] +- kvm-hw-audio-gus-skip-automatic-zero-init-of-large-array.patch [RHEL-95479] +- kvm-hw-audio-marvell_88w8618-skip-automatic-zero-init-of.patch [RHEL-95479] +- kvm-hw-audio-sb16-skip-automatic-zero-init-of-large-arra.patch [RHEL-95479] +- kvm-hw-audio-via-ac97-skip-automatic-zero-init-of-large-.patch [RHEL-95479] +- kvm-hw-char-sclpconsole-lm-skip-automatic-zero-init-of-l.patch [RHEL-95479] +- kvm-hw-dma-xlnx_csu_dma-skip-automatic-zero-init-of-larg.patch [RHEL-95479] +- kvm-hw-display-vmware_vga-skip-automatic-zero-init-of-la.patch [RHEL-95479] +- kvm-hw-hyperv-syndbg-skip-automatic-zero-init-of-large-a.patch [RHEL-95479] +- kvm-hw-misc-aspeed_hace-skip-automatic-zero-init-of-larg.patch [RHEL-95479] +- kvm-hw-net-rtl8139-skip-automatic-zero-init-of-large-arr.patch [RHEL-95479] +- kvm-hw-net-tulip-skip-automatic-zero-init-of-large-array.patch [RHEL-95479] +- kvm-hw-net-virtio-net-skip-automatic-zero-init-of-large-.patch [RHEL-95479] +- kvm-hw-net-xgamc-skip-automatic-zero-init-of-large-array.patch [RHEL-95479] +- kvm-hw-nvme-ctrl-skip-automatic-zero-init-of-large-array.patch [RHEL-95479] +- kvm-hw-ppc-pnv_occ-skip-automatic-zero-init-of-large-str.patch [RHEL-95479] +- kvm-hw-ppc-spapr_tpm_proxy-skip-automatic-zero-init-of-l.patch [RHEL-95479] +- kvm-hw-usb-hcd-ohci-skip-automatic-zero-init-of-large-ar.patch [RHEL-95479] +- kvm-hw-scsi-lsi53c895a-skip-automatic-zero-init-of-large.patch [RHEL-95479] +- kvm-hw-scsi-megasas-skip-automatic-zero-init-of-large-ar.patch [RHEL-95479] +- kvm-hw-ufs-lu-skip-automatic-zero-init-of-large-array.patch [RHEL-95479] +- kvm-net-socket-skip-automatic-zero-init-of-large-array.patch [RHEL-95479] +- kvm-net-stream-skip-automatic-zero-init-of-large-array.patch [RHEL-95479] +- kvm-hw-i386-amd_iommu-Isolate-AMDVI-PCI-from-amd-iommu-d.patch [RHEL-85649] +- kvm-hw-i386-amd_iommu-Allow-migration-when-explicitly-cr.patch [RHEL-85649] +- kvm-Enable-amd-iommu-device.patch [RHEL-85649] +- kvm-ui-vnc-Update-display-update-interval-when-VM-state-.patch [RHEL-83883] +- Resolves: RHEL-98555 + ([s390x][RHEL10.1][ccw-device] there would be memory leak with virtio_blk disks) +- Resolves: RHEL-52650 + ([AMDSERVER 10.1 Feature] Turin: Qemu EPYC-Turin Model) +- Resolves: RHEL-95479 + (-ftrivial-auto-var-init=zero reduced performance) +- Resolves: RHEL-85649 + ([RHEL 10]Qemu/amd-iommu: Add ability to manually specify the AMDVI-PCI device) +- Resolves: RHEL-83883 + (Video stuck after switchover phase when play one video during migration) + +* Fri Jun 20 2025 Miroslav Rezanina - 10.0.0-6 +- kvm-scsi-disk-Add-native-FUA-write-support.patch [RHEL-71962] +- kvm-Fix-handling-of-have_block_rbd.patch [RHEL-96057] +- kvm-Delete-obsolete-references-to-architectures.patch [RHEL-96057] +- kvm-Fix-arch-list-for-vgabios-and-ipxe-roms.patch [RHEL-96057] +- kvm-Disable-virtio-net-pci-romfile-loading-on-riscv64.patch [RHEL-96057] +- Resolves: RHEL-71962 + ([RFE] Implement FUA support in scsi-disk) +- Resolves: RHEL-96057 + (qemu-kvm: Various small issues in the spec file) + +* Mon Jun 09 2025 Miroslav Rezanina - 10.0.0-5 +- kvm-file-posix-Define-DM_MPATH_PROBE_PATHS.patch [RHEL-65852] +- kvm-file-posix-Probe-paths-and-retry-SG_IO-on-potential-.patch [RHEL-65852] +- kvm-io-Fix-partial-struct-copy-in-qio_dns_resolver_looku.patch [RHEL-67706] +- kvm-util-qemu-sockets-Refactor-setting-client-sockopts-i.patch [RHEL-67706] +- kvm-util-qemu-sockets-Refactor-success-and-failure-paths.patch [RHEL-67706] +- kvm-util-qemu-sockets-Add-support-for-keep-alive-flag-to.patch [RHEL-67706] +- kvm-util-qemu-sockets-Refactor-inet_parse-to-use-QemuOpt.patch [RHEL-67706] +- kvm-util-qemu-sockets-Introduce-inet-socket-options-cont.patch [RHEL-67706] +- kvm-tests-unit-test-util-sockets-fix-mem-leak-on-error-o.patch [RHEL-67706] +- Resolves: RHEL-65852 + (Support multipath failover with scsi-block) +- Resolves: RHEL-67706 + (postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S') + +* Mon May 26 2025 Miroslav Rezanina - 10.0.0-4 +- kvm-block-Expand-block-status-mode-from-bool-to-flags.patch [RHEL-88435 RHEL-88437] +- kvm-file-posix-gluster-Handle-zero-block-status-hint-bet.patch [RHEL-88435 RHEL-88437] +- kvm-block-Let-bdrv_co_is_zero_fast-consolidate-adjacent-.patch [RHEL-88435 RHEL-88437] +- kvm-block-Add-new-bdrv_co_is_all_zeroes-function.patch [RHEL-88435 RHEL-88437] +- kvm-iotests-Improve-iotest-194-to-mirror-data.patch [RHEL-88435 RHEL-88437] +- kvm-mirror-Minor-refactoring.patch [RHEL-88435 RHEL-88437] +- kvm-mirror-Pass-full-sync-mode-rather-than-bool-to-inter.patch [RHEL-88435 RHEL-88437] +- kvm-mirror-Allow-QMP-override-to-declare-target-already-.patch [RHEL-88435 RHEL-88437] +- kvm-mirror-Drop-redundant-zero_target-parameter.patch [RHEL-88435 RHEL-88437] +- kvm-mirror-Skip-pre-zeroing-destination-if-it-is-already.patch [RHEL-88435 RHEL-88437] +- kvm-mirror-Skip-writing-zeroes-when-target-is-already-ze.patch [RHEL-88435 RHEL-88437] +- kvm-iotests-common.rc-add-disk_usage-function.patch [RHEL-88435 RHEL-88437] +- kvm-tests-Add-iotest-mirror-sparse-for-recent-patches.patch [RHEL-88435 RHEL-88437] +- kvm-mirror-Reduce-I-O-when-destination-is-detect-zeroes-.patch [RHEL-88435 RHEL-88437] +- Resolves: RHEL-88435 + (--migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-10.1]) +- Resolves: RHEL-88437 + (Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-10.1]) + +* Mon May 19 2025 Miroslav Rezanina - 10.0.0-3 +- kvm-migration-postcopy-Spatial-locality-page-hint-for-pr.patch [RHEL-85635] +- kvm-meson-configure-add-valgrind-option-en-dis-able-valg.patch [RHEL-88457] +- kvm-distro-add-an-explicit-valgrind-devel-build-dep.patch [RHEL-88457] +- kvm-Allow-guest-get-load-QGA-command.patch [RHEL-91219] +- Resolves: RHEL-85635 + (Video stuck about 1 min after switchover phase when play one video during postcopy-preempt migration) +- Resolves: RHEL-88457 + (qemu inadvertantly built with valgrind coroutine stack debugging on x86_64) +- Resolves: RHEL-91219 + ([qemu-guest-agent] Enable 'guest-get-load' by default [RHEL-10]) + +* Mon May 12 2025 Miroslav Rezanina - 10.0.0-2 +- kvm-file-posix-probe-discard-alignment-on-Linux-block-de.patch [RHEL-87642] +- kvm-block-io-skip-head-tail-requests-on-EINVAL.patch [RHEL-87642] +- kvm-file-posix-Fix-crash-on-discard_granularity-0.patch [RHEL-87642] +- kvm-Enable-vhost-user-gpu-pci-for-RHIVOS.patch [RHEL-86056] +- Resolves: RHEL-87642 + (QEMU sends unaligned discards on 4K devices[RHEL-10]) +- Resolves: RHEL-86056 + (Enable 'vhost-user-gpu-pci' in qemu-kvm for RHIVOS) + +* Wed Apr 23 2025 Miroslav Rezanina - 10.0.0-1 +- Rebase to QEMU 10.0.0 [RHEL-74473] +- Resolves: RHEL-74473 + (Rebase qemu-kvm to QEMU 10.0.0) + +* Mon Apr 07 2025 Miroslav Rezanina - 9.1.0-17 +- kvm-Also-recommend-systemtap-devel-from-qemu-tools.patch [RHEL-83535] +- Resolves: RHEL-83535 + ([Qemu RHEL-10] qemu-trace-stap should handle lack of stap more gracefully) + +* Tue Mar 25 2025 Miroslav Rezanina - 9.1.0-16 +- kvm-migration-Fix-UAF-for-incoming-migration-on-Migratio.patch [RHEL-69776] +- kvm-scripts-improve-error-from-qemu-trace-stap-on-missin.patch [RHEL-83535] +- kvm-Recommend-systemtap-client-from-qemu-tools.patch [RHEL-83535] +- Resolves: RHEL-69776 + ([rhel10]Guest crashed on the target host when the migration was canceled) +- Resolves: RHEL-83535 + ([Qemu RHEL-10] qemu-trace-stap should handle lack of stap more gracefully) * Mon Feb 17 2025 Miroslav Rezanina - 9.1.0-15 - kvm-migration-Add-helper-to-get-target-runstate.patch [RHEL-54670] diff --git a/sources b/sources index 5f32cdc..b2a8ce2 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (qemu-9.1.0.tar.xz) = bf61d65e37945fa8ee8640712c719ace05164d86e6df700b98bdc5f79e0a8d5e8f85bd48e726edb62b2419db20673f63ec8b63a60393a914b09cb365621b35e2 +SHA512 (qemu-10.0.0.tar.xz) = 2215458ed8be3ab0b0032fe2a96e79183f5fc2da323d927018412ea3d980b022a07ba87d4f446229eaaa7d1b19a577d438dbcaa3af3bd537c7720b56734a2d8b