From bd7b93c113546a1a79f848a9200cdb5cf04bb26a Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Tue, 8 Jul 2025 02:53:14 -0400 Subject: [PATCH] * Tue Jul 08 2025 Miroslav Rezanina - 9.1.0-25 - kvm-s390x-Fix-leak-in-machine_set_loadparm.patch [RHEL-98554] - kvm-hw-s390x-ccw-device-Fix-memory-leak-in-loadparm-sett.patch [RHEL-98554] - kvm-amd_iommu-Rename-variable-mmio-to-mr_mmio.patch [RHEL-66202] - kvm-amd_iommu-Add-support-for-pass-though-mode.patch [RHEL-66202] - kvm-amd_iommu-Use-shared-memory-region-for-Interrupt-Rem.patch [RHEL-66202] - kvm-amd_iommu-Send-notification-when-invalidate-interrup.patch [RHEL-66202] - kvm-amd_iommu-Check-APIC-ID-255-for-XTSup.patch [RHEL-66202] - kvm-io-Fix-partial-struct-copy-in-qio_dns_resolver_looku.patch [RHEL-67104] - kvm-util-qemu-sockets-Refactor-setting-client-sockopts-i.patch [RHEL-67104] - kvm-util-qemu-sockets-Refactor-success-and-failure-paths.patch [RHEL-67104] - kvm-util-qemu-sockets-Add-support-for-keep-alive-flag-to.patch [RHEL-67104] - kvm-util-qemu-sockets-Refactor-inet_parse-to-use-QemuOpt.patch [RHEL-67104] - kvm-util-qemu-sockets-Introduce-inet-socket-options-cont.patch [RHEL-67104] - kvm-tests-unit-test-util-sockets-fix-mem-leak-on-error-o.patch [RHEL-67104] - kvm-target-i386-Expose-bits-related-to-SRSO-vulnerabilit.patch [RHEL-52649] - kvm-target-i386-Add-PerfMonV2-feature-bit.patch [RHEL-52649] - kvm-target-i386-Update-EPYC-CPU-model-for-Cache-property.patch [RHEL-52649] - kvm-target-i386-Update-EPYC-Rome-CPU-model-for-Cache-pro.patch [RHEL-52649] - kvm-target-i386-Update-EPYC-Milan-CPU-model-for-Cache-pr.patch [RHEL-52649] - kvm-target-i386-Add-couple-of-feature-bits-in-CPUID_Fn80.patch [RHEL-52649] - kvm-target-i386-Update-EPYC-Genoa-for-Cache-property-per.patch [RHEL-52649] - kvm-target-i386-Add-support-for-EPYC-Turin-model.patch [RHEL-52649] - kvm-hw-i386-amd_iommu-Assign-pci-id-0x1419-for-the-AMD-I.patch [RHEL-70926] - kvm-hw-i386-amd_iommu-Isolate-AMDVI-PCI-from-amd-iommu-d.patch [RHEL-70925] - kvm-hw-i386-amd_iommu-Allow-migration-when-explicitly-cr.patch [RHEL-70925] - kvm-Enable-amd-iommu-device.patch [RHEL-70925] - kvm-include-qemu-compiler-add-QEMU_UNINITIALIZED-attribu.patch [RHEL-99888] - kvm-hw-virtio-virtio-avoid-cost-of-ftrivial-auto-var-ini.patch [RHEL-99888] - kvm-block-skip-automatic-zero-init-of-large-array-in-ioq.patch [RHEL-99888] - kvm-chardev-char-fd-skip-automatic-zero-init-of-large-ar.patch [RHEL-99888] - kvm-chardev-char-pty-skip-automatic-zero-init-of-large-a.patch [RHEL-99888] - kvm-chardev-char-socket-skip-automatic-zero-init-of-larg.patch [RHEL-99888] - kvm-hw-audio-ac97-skip-automatic-zero-init-of-large-arra.patch [RHEL-99888] - kvm-hw-audio-cs4231a-skip-automatic-zero-init-of-large-a.patch [RHEL-99888] - kvm-hw-audio-es1370-skip-automatic-zero-init-of-large-ar.patch [RHEL-99888] - kvm-hw-audio-gus-skip-automatic-zero-init-of-large-array.patch [RHEL-99888] - kvm-hw-audio-marvell_88w8618-skip-automatic-zero-init-of.patch [RHEL-99888] - kvm-hw-audio-sb16-skip-automatic-zero-init-of-large-arra.patch [RHEL-99888] - kvm-hw-audio-via-ac97-skip-automatic-zero-init-of-large-.patch [RHEL-99888] - kvm-hw-char-sclpconsole-lm-skip-automatic-zero-init-of-l.patch [RHEL-99888] - kvm-hw-dma-xlnx_csu_dma-skip-automatic-zero-init-of-larg.patch [RHEL-99888] - kvm-hw-display-vmware_vga-skip-automatic-zero-init-of-la.patch [RHEL-99888] - kvm-hw-hyperv-syndbg-skip-automatic-zero-init-of-large-a.patch [RHEL-99888] - kvm-hw-misc-aspeed_hace-skip-automatic-zero-init-of-larg.patch [RHEL-99888] - kvm-hw-net-rtl8139-skip-automatic-zero-init-of-large-arr.patch [RHEL-99888] - kvm-hw-net-tulip-skip-automatic-zero-init-of-large-array.patch [RHEL-99888] - kvm-hw-net-virtio-net-skip-automatic-zero-init-of-large-.patch [RHEL-99888] - kvm-hw-net-xgamc-skip-automatic-zero-init-of-large-array.patch [RHEL-99888] - kvm-hw-nvme-ctrl-skip-automatic-zero-init-of-large-array.patch [RHEL-99888] - kvm-hw-ppc-spapr_tpm_proxy-skip-automatic-zero-init-of-l.patch [RHEL-99888] - kvm-hw-usb-hcd-ohci-skip-automatic-zero-init-of-large-ar.patch [RHEL-99888] - kvm-hw-scsi-lsi53c895a-skip-automatic-zero-init-of-large.patch [RHEL-99888] - kvm-hw-scsi-megasas-skip-automatic-zero-init-of-large-ar.patch [RHEL-99888] - kvm-hw-ufs-lu-skip-automatic-zero-init-of-large-array.patch [RHEL-99888] - kvm-net-socket-skip-automatic-zero-init-of-large-array.patch [RHEL-99888] - kvm-net-stream-skip-automatic-zero-init-of-large-array.patch [RHEL-99888] - kvm-ui-vnc-Update-display-update-interval-when-VM-state-.patch [RHEL-100741] - Resolves: RHEL-98554 ([s390x][RHEL9.7.0][virtio_block] there would be memory leak with virtio_blk disks) - Resolves: RHEL-66202 ([AMDSERVER 9.6 Feature] qemu: Interrupt Remap support for emulated amd viommu) - Resolves: RHEL-67104 (postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S') - Resolves: RHEL-52649 ([AMDSERVER 9.6 Feature] Turin: Qemu EPYC-Turin Model) - Resolves: RHEL-70926 (Qemu/amd-iommu: Advertise a suitable device id) - Resolves: RHEL-70925 (Qemu/amd-iommu: Add ability to manually specify the AMDVI-PCI device) - Resolves: RHEL-99888 (-ftrivial-auto-var-init=zero reduced performance [rhel-9]) - Resolves: RHEL-100741 (Video stuck after switchover phase when play one video during migration [rhel-9]) --- kvm-Enable-amd-iommu-device.patch | 38 ++ ...mmu-Add-support-for-pass-though-mode.patch | 141 ++++++ ...md_iommu-Check-APIC-ID-255-for-XTSup.patch | 66 +++ ...ommu-Rename-variable-mmio-to-mr_mmio.patch | 94 ++++ ...otification-when-invalidate-interrup.patch | 81 +++ ...ared-memory-region-for-Interrupt-Rem.patch | 105 ++++ ...atic-zero-init-of-large-array-in-ioq.patch | 48 ++ ...skip-automatic-zero-init-of-large-ar.patch | 49 ++ ...-skip-automatic-zero-init-of-large-a.patch | 49 ++ ...ket-skip-automatic-zero-init-of-larg.patch | 49 ++ ...ip-automatic-zero-init-of-large-arra.patch | 57 +++ ...-skip-automatic-zero-init-of-large-a.patch | 59 +++ ...skip-automatic-zero-init-of-large-ar.patch | 49 ++ ...p-automatic-zero-init-of-large-array.patch | 48 ++ ..._88w8618-skip-automatic-zero-init-of.patch | 50 ++ ...ip-automatic-zero-init-of-large-arra.patch | 48 ++ ...7-skip-automatic-zero-init-of-large-.patch | 49 ++ ...ole-lm-skip-automatic-zero-init-of-l.patch | 49 ++ ...e_vga-skip-automatic-zero-init-of-la.patch | 49 ++ ...dma-skip-automatic-zero-init-of-larg.patch | 47 ++ ...-skip-automatic-zero-init-of-large-a.patch | 56 +++ ...u-Allow-migration-when-explicitly-cr.patch | 117 +++++ ...u-Assign-pci-id-0x1419-for-the-AMD-I.patch | 57 +++ ...u-Isolate-AMDVI-PCI-from-amd-iommu-d.patch | 267 ++++++++++ ...ace-skip-automatic-zero-init-of-larg.patch | 57 +++ ...kip-automatic-zero-init-of-large-arr.patch | 48 ++ ...p-automatic-zero-init-of-large-array.patch | 47 ++ ...t-skip-automatic-zero-init-of-large-.patch | 54 ++ ...p-automatic-zero-init-of-large-array.patch | 47 ++ ...p-automatic-zero-init-of-large-array.patch | 72 +++ ..._proxy-skip-automatic-zero-init-of-l.patch | 52 ++ ...ice-Fix-memory-leak-in-loadparm-sett.patch | 47 ++ ...5a-skip-automatic-zero-init-of-large.patch | 49 ++ ...skip-automatic-zero-init-of-large-ar.patch | 73 +++ ...p-automatic-zero-init-of-large-array.patch | 50 ++ ...skip-automatic-zero-init-of-large-ar.patch | 50 ++ ...-avoid-cost-of-ftrivial-auto-var-ini.patch | 73 +++ ...piler-add-QEMU_UNINITIALIZED-attribu.patch | 80 +++ ...truct-copy-in-qio_dns_resolver_looku.patch | 73 +++ ...p-automatic-zero-init-of-large-array.patch | 49 ++ ...p-automatic-zero-init-of-large-array.patch | 49 ++ ...90x-Fix-leak-in-machine_set_loadparm.patch | 60 +++ ...arget-i386-Add-PerfMonV2-feature-bit.patch | 105 ++++ ...couple-of-feature-bits-in-CPUID_Fn80.patch | 83 ++++ ...386-Add-support-for-EPYC-Turin-model.patch | 200 ++++++++ ...se-bits-related-to-SRSO-vulnerabilit.patch | 84 ++++ ...te-EPYC-CPU-model-for-Cache-property.patch | 147 ++++++ ...te-EPYC-Genoa-for-Cache-property-per.patch | 167 +++++++ ...te-EPYC-Milan-CPU-model-for-Cache-pr.patch | 146 ++++++ ...te-EPYC-Rome-CPU-model-for-Cache-pro.patch | 147 ++++++ ...util-sockets-fix-mem-leak-on-error-o.patch | 53 ++ ...splay-update-interval-when-VM-state-.patch | 97 ++++ ...s-Add-support-for-keep-alive-flag-to.patch | 86 ++++ ...s-Introduce-inet-socket-options-cont.patch | 314 ++++++++++++ ...s-Refactor-inet_parse-to-use-QemuOpt.patch | 461 ++++++++++++++++++ ...s-Refactor-setting-client-sockopts-i.patch | 83 ++++ ...s-Refactor-success-and-failure-paths.patch | 141 ++++++ qemu-kvm.spec | 191 +++++++- 58 files changed, 5256 insertions(+), 1 deletion(-) create mode 100644 kvm-Enable-amd-iommu-device.patch create mode 100644 kvm-amd_iommu-Add-support-for-pass-though-mode.patch create mode 100644 kvm-amd_iommu-Check-APIC-ID-255-for-XTSup.patch create mode 100644 kvm-amd_iommu-Rename-variable-mmio-to-mr_mmio.patch create mode 100644 kvm-amd_iommu-Send-notification-when-invalidate-interrup.patch create mode 100644 kvm-amd_iommu-Use-shared-memory-region-for-Interrupt-Rem.patch create mode 100644 kvm-block-skip-automatic-zero-init-of-large-array-in-ioq.patch create mode 100644 kvm-chardev-char-fd-skip-automatic-zero-init-of-large-ar.patch create mode 100644 kvm-chardev-char-pty-skip-automatic-zero-init-of-large-a.patch create mode 100644 kvm-chardev-char-socket-skip-automatic-zero-init-of-larg.patch create mode 100644 kvm-hw-audio-ac97-skip-automatic-zero-init-of-large-arra.patch create mode 100644 kvm-hw-audio-cs4231a-skip-automatic-zero-init-of-large-a.patch create mode 100644 kvm-hw-audio-es1370-skip-automatic-zero-init-of-large-ar.patch create mode 100644 kvm-hw-audio-gus-skip-automatic-zero-init-of-large-array.patch create mode 100644 kvm-hw-audio-marvell_88w8618-skip-automatic-zero-init-of.patch create mode 100644 kvm-hw-audio-sb16-skip-automatic-zero-init-of-large-arra.patch create mode 100644 kvm-hw-audio-via-ac97-skip-automatic-zero-init-of-large-.patch create mode 100644 kvm-hw-char-sclpconsole-lm-skip-automatic-zero-init-of-l.patch create mode 100644 kvm-hw-display-vmware_vga-skip-automatic-zero-init-of-la.patch create mode 100644 kvm-hw-dma-xlnx_csu_dma-skip-automatic-zero-init-of-larg.patch create mode 100644 kvm-hw-hyperv-syndbg-skip-automatic-zero-init-of-large-a.patch create mode 100644 kvm-hw-i386-amd_iommu-Allow-migration-when-explicitly-cr.patch create mode 100644 kvm-hw-i386-amd_iommu-Assign-pci-id-0x1419-for-the-AMD-I.patch create mode 100644 kvm-hw-i386-amd_iommu-Isolate-AMDVI-PCI-from-amd-iommu-d.patch create mode 100644 kvm-hw-misc-aspeed_hace-skip-automatic-zero-init-of-larg.patch create mode 100644 kvm-hw-net-rtl8139-skip-automatic-zero-init-of-large-arr.patch create mode 100644 kvm-hw-net-tulip-skip-automatic-zero-init-of-large-array.patch create mode 100644 kvm-hw-net-virtio-net-skip-automatic-zero-init-of-large-.patch create mode 100644 kvm-hw-net-xgamc-skip-automatic-zero-init-of-large-array.patch create mode 100644 kvm-hw-nvme-ctrl-skip-automatic-zero-init-of-large-array.patch create mode 100644 kvm-hw-ppc-spapr_tpm_proxy-skip-automatic-zero-init-of-l.patch create mode 100644 kvm-hw-s390x-ccw-device-Fix-memory-leak-in-loadparm-sett.patch create mode 100644 kvm-hw-scsi-lsi53c895a-skip-automatic-zero-init-of-large.patch create mode 100644 kvm-hw-scsi-megasas-skip-automatic-zero-init-of-large-ar.patch create mode 100644 kvm-hw-ufs-lu-skip-automatic-zero-init-of-large-array.patch create mode 100644 kvm-hw-usb-hcd-ohci-skip-automatic-zero-init-of-large-ar.patch create mode 100644 kvm-hw-virtio-virtio-avoid-cost-of-ftrivial-auto-var-ini.patch create mode 100644 kvm-include-qemu-compiler-add-QEMU_UNINITIALIZED-attribu.patch create mode 100644 kvm-io-Fix-partial-struct-copy-in-qio_dns_resolver_looku.patch create mode 100644 kvm-net-socket-skip-automatic-zero-init-of-large-array.patch create mode 100644 kvm-net-stream-skip-automatic-zero-init-of-large-array.patch create mode 100644 kvm-s390x-Fix-leak-in-machine_set_loadparm.patch create mode 100644 kvm-target-i386-Add-PerfMonV2-feature-bit.patch create mode 100644 kvm-target-i386-Add-couple-of-feature-bits-in-CPUID_Fn80.patch create mode 100644 kvm-target-i386-Add-support-for-EPYC-Turin-model.patch create mode 100644 kvm-target-i386-Expose-bits-related-to-SRSO-vulnerabilit.patch create mode 100644 kvm-target-i386-Update-EPYC-CPU-model-for-Cache-property.patch create mode 100644 kvm-target-i386-Update-EPYC-Genoa-for-Cache-property-per.patch create mode 100644 kvm-target-i386-Update-EPYC-Milan-CPU-model-for-Cache-pr.patch create mode 100644 kvm-target-i386-Update-EPYC-Rome-CPU-model-for-Cache-pro.patch create mode 100644 kvm-tests-unit-test-util-sockets-fix-mem-leak-on-error-o.patch create mode 100644 kvm-ui-vnc-Update-display-update-interval-when-VM-state-.patch create mode 100644 kvm-util-qemu-sockets-Add-support-for-keep-alive-flag-to.patch create mode 100644 kvm-util-qemu-sockets-Introduce-inet-socket-options-cont.patch create mode 100644 kvm-util-qemu-sockets-Refactor-inet_parse-to-use-QemuOpt.patch create mode 100644 kvm-util-qemu-sockets-Refactor-setting-client-sockopts-i.patch create mode 100644 kvm-util-qemu-sockets-Refactor-success-and-failure-paths.patch diff --git a/kvm-Enable-amd-iommu-device.patch b/kvm-Enable-amd-iommu-device.patch new file mode 100644 index 0000000..44846a5 --- /dev/null +++ b/kvm-Enable-amd-iommu-device.patch @@ -0,0 +1,38 @@ +From 0608561efc441f234d9aaf45f1867ffb5c43cffe Mon Sep 17 00:00:00 2001 +From: John Allen +Date: Wed, 11 Jun 2025 15:41:14 -0500 +Subject: [PATCH 26/57] Enable amd-iommu device + +RH-Author: John Allen +RH-MergeRequest: 380: Add ability to manually specify the AMDVI-PCI device +RH-Jira: RHEL-70925 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [3/3] 852500a18275e14bcd94d598ccd0ee33b76578dc (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-70925 + +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 3e5f693b62..2b15fdc2db 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-amd_iommu-Add-support-for-pass-though-mode.patch b/kvm-amd_iommu-Add-support-for-pass-though-mode.patch new file mode 100644 index 0000000..b0038a7 --- /dev/null +++ b/kvm-amd_iommu-Add-support-for-pass-though-mode.patch @@ -0,0 +1,141 @@ +From 4114553452f7187283aefa001bc8342fc65b6b72 Mon Sep 17 00:00:00 2001 +From: John Allen +Date: Wed, 11 Dec 2024 15:06:48 -0600 +Subject: [PATCH 04/57] amd_iommu: Add support for pass though mode + +RH-Author: John Allen +RH-MergeRequest: 303: Interrupt Remap support for emulated amd viommu +RH-Jira: RHEL-66202 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [2/5] 0434fefd554baf27fb9d93026af513c621f8cdb0 (johnalle/qemu-kvm-fork) + +JIRA: https://issues.redhat.com/browse/RHEL-66202 + +commit c1f46999ef506d9854534560a94d02cf3cf9edd1 +Author: Suravee Suthikulpanit +Date: Fri Sep 27 12:29:10 2024 -0500 + + amd_iommu: Add support for pass though mode + + Introduce 'nodma' shared memory region to support PT mode + so that for each device, we only create an alias to shared memory + region when DMA-remapping is disabled. + + Reviewed-by: Alejandro Jimenez + Signed-off-by: Suravee Suthikulpanit + Signed-off-by: Santosh Shukla + Message-Id: <20240927172913.121477-3-santosh.shukla@amd.com> + Reviewed-by: Michael S. Tsirkin + Signed-off-by: Michael S. Tsirkin + +Signed-off-by: John Allen +--- + hw/i386/amd_iommu.c | 49 ++++++++++++++++++++++++++++++++++++--------- + hw/i386/amd_iommu.h | 2 ++ + 2 files changed, 42 insertions(+), 9 deletions(-) + +diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c +index 148b5ee51d..567cb8adc9 100644 +--- a/hw/i386/amd_iommu.c ++++ b/hw/i386/amd_iommu.c +@@ -60,8 +60,9 @@ struct AMDVIAddressSpace { + uint8_t bus_num; /* bus number */ + uint8_t devfn; /* device function */ + AMDVIState *iommu_state; /* AMDVI - one per machine */ +- MemoryRegion root; /* AMDVI Root memory map region */ ++ MemoryRegion root; /* AMDVI Root memory map region */ + IOMMUMemoryRegion iommu; /* Device's address translation region */ ++ MemoryRegion iommu_nodma; /* Alias of shared nodma memory region */ + MemoryRegion iommu_ir; /* Device's interrupt remapping region */ + AddressSpace as; /* device's corresponding address space */ + }; +@@ -1412,6 +1413,7 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) + AMDVIState *s = opaque; + AMDVIAddressSpace **iommu_as, *amdvi_dev_as; + int bus_num = pci_bus_num(bus); ++ X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s); + + iommu_as = s->address_spaces[bus_num]; + +@@ -1436,13 +1438,13 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) + * Memory region relationships looks like (Address range shows + * only lower 32 bits to make it short in length...): + * +- * |-----------------+-------------------+----------| +- * | Name | Address range | Priority | +- * |-----------------+-------------------+----------+ +- * | amdvi_root | 00000000-ffffffff | 0 | +- * | amdvi_iommu | 00000000-ffffffff | 1 | +- * | amdvi_iommu_ir | fee00000-feefffff | 64 | +- * |-----------------+-------------------+----------| ++ * |--------------------+-------------------+----------| ++ * | Name | Address range | Priority | ++ * |--------------------+-------------------+----------+ ++ * | amdvi-root | 00000000-ffffffff | 0 | ++ * | amdvi-iommu_nodma | 00000000-ffffffff | 0 | ++ * | amdvi-iommu_ir | fee00000-feefffff | 64 | ++ * |--------------------+-------------------+----------| + */ + memory_region_init_iommu(&amdvi_dev_as->iommu, + sizeof(amdvi_dev_as->iommu), +@@ -1461,7 +1463,25 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) + 64); + memory_region_add_subregion_overlap(&amdvi_dev_as->root, 0, + MEMORY_REGION(&amdvi_dev_as->iommu), +- 1); ++ 0); ++ ++ /* Build the DMA Disabled alias to shared memory */ ++ memory_region_init_alias(&amdvi_dev_as->iommu_nodma, OBJECT(s), ++ "amdvi-sys", &s->mr_sys, 0, ++ memory_region_size(&s->mr_sys)); ++ memory_region_add_subregion_overlap(&amdvi_dev_as->root, 0, ++ &amdvi_dev_as->iommu_nodma, ++ 0); ++ ++ if (!x86_iommu->pt_supported) { ++ memory_region_set_enabled(&amdvi_dev_as->iommu_nodma, false); ++ memory_region_set_enabled(MEMORY_REGION(&amdvi_dev_as->iommu), ++ true); ++ } else { ++ memory_region_set_enabled(MEMORY_REGION(&amdvi_dev_as->iommu), ++ false); ++ memory_region_set_enabled(&amdvi_dev_as->iommu_nodma, true); ++ } + } + return &iommu_as[devfn]->as; + } +@@ -1602,6 +1622,17 @@ static void amdvi_sysbus_realize(DeviceState *dev, Error **errp) + "amdvi-mmio", AMDVI_MMIO_SIZE); + memory_region_add_subregion(get_system_memory(), AMDVI_BASE_ADDR, + &s->mr_mmio); ++ ++ /* Create the share memory regions by all devices */ ++ memory_region_init(&s->mr_sys, OBJECT(s), "amdvi-sys", UINT64_MAX); ++ ++ /* set up the DMA disabled memory region */ ++ memory_region_init_alias(&s->mr_nodma, OBJECT(s), ++ "amdvi-nodma", get_system_memory(), 0, ++ memory_region_size(get_system_memory())); ++ memory_region_add_subregion_overlap(&s->mr_sys, 0, ++ &s->mr_nodma, 0); ++ + pci_setup_iommu(bus, &amdvi_iommu_ops, s); + amdvi_init(s); + } +diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h +index e5c2ae94f2..be417e51c4 100644 +--- a/hw/i386/amd_iommu.h ++++ b/hw/i386/amd_iommu.h +@@ -354,6 +354,8 @@ struct AMDVIState { + uint32_t pprlog_tail; /* ppr log tail */ + + MemoryRegion mr_mmio; /* MMIO region */ ++ MemoryRegion mr_sys; ++ MemoryRegion mr_nodma; + uint8_t mmior[AMDVI_MMIO_SIZE]; /* read/write MMIO */ + uint8_t w1cmask[AMDVI_MMIO_SIZE]; /* read/write 1 clear mask */ + uint8_t romask[AMDVI_MMIO_SIZE]; /* MMIO read/only mask */ +-- +2.39.3 + diff --git a/kvm-amd_iommu-Check-APIC-ID-255-for-XTSup.patch b/kvm-amd_iommu-Check-APIC-ID-255-for-XTSup.patch new file mode 100644 index 0000000..a230203 --- /dev/null +++ b/kvm-amd_iommu-Check-APIC-ID-255-for-XTSup.patch @@ -0,0 +1,66 @@ +From 0397ebacdba6539147d9986255c3f81cbfdabf1e Mon Sep 17 00:00:00 2001 +From: John Allen +Date: Wed, 11 Dec 2024 15:07:03 -0600 +Subject: [PATCH 07/57] amd_iommu: Check APIC ID > 255 for XTSup + +RH-Author: John Allen +RH-MergeRequest: 303: Interrupt Remap support for emulated amd viommu +RH-Jira: RHEL-66202 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [5/5] f39b3e3cdefc2b562f1ad2ef939a37bf404f355a (johnalle/qemu-kvm-fork) + +JIRA: https://issues.redhat.com/browse/RHEL-66202 + +commit b12cb3819baf6d9ee8140d4dd6d36fa829e2c6d9 +Author: Suravee Suthikulpanit +Date: Fri Sep 27 12:29:13 2024 -0500 + + amd_iommu: Check APIC ID > 255 for XTSup + + The XTSup mode enables x2APIC support for AMD IOMMU, which is needed + to support vcpu w/ APIC ID > 255. + + Reviewed-by: Alejandro Jimenez + Signed-off-by: Suravee Suthikulpanit + Signed-off-by: Santosh Shukla + Message-Id: <20240927172913.121477-6-santosh.shukla@amd.com> + Reviewed-by: Michael S. Tsirkin + Signed-off-by: Michael S. Tsirkin + +Signed-off-by: John Allen +--- + hw/i386/amd_iommu.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c +index 82d76dfca9..d804656ea8 100644 +--- a/hw/i386/amd_iommu.c ++++ b/hw/i386/amd_iommu.c +@@ -32,6 +32,7 @@ + #include "trace.h" + #include "hw/i386/apic-msidef.h" + #include "hw/qdev-properties.h" ++#include "kvm/kvm_i386.h" + + /* used AMD-Vi MMIO registers */ + const char *amdvi_mmio_low[] = { +@@ -1651,6 +1652,16 @@ static void amdvi_sysbus_realize(DeviceState *dev, Error **errp) + memory_region_add_subregion_overlap(&s->mr_sys, AMDVI_INT_ADDR_FIRST, + &s->mr_ir, 1); + ++ /* AMD IOMMU with x2APIC mode requires xtsup=on */ ++ if (x86ms->apic_id_limit > 255 && !s->xtsup) { ++ error_report("AMD IOMMU with x2APIC confguration requires xtsup=on"); ++ exit(EXIT_FAILURE); ++ } ++ if (s->xtsup && kvm_irqchip_is_split() && !kvm_enable_x2apic()) { ++ error_report("AMD IOMMU xtsup=on requires support on the KVM side"); ++ exit(EXIT_FAILURE); ++ } ++ + pci_setup_iommu(bus, &amdvi_iommu_ops, s); + amdvi_init(s); + } +-- +2.39.3 + diff --git a/kvm-amd_iommu-Rename-variable-mmio-to-mr_mmio.patch b/kvm-amd_iommu-Rename-variable-mmio-to-mr_mmio.patch new file mode 100644 index 0000000..76c9fd6 --- /dev/null +++ b/kvm-amd_iommu-Rename-variable-mmio-to-mr_mmio.patch @@ -0,0 +1,94 @@ +From f733325d3d91576ae9f6e341faabc301542fc6c8 Mon Sep 17 00:00:00 2001 +From: John Allen +Date: Wed, 11 Dec 2024 15:06:44 -0600 +Subject: [PATCH 03/57] amd_iommu: Rename variable mmio to mr_mmio + +RH-Author: John Allen +RH-MergeRequest: 303: Interrupt Remap support for emulated amd viommu +RH-Jira: RHEL-66202 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/5] 1996a48efb7210d4d1e0b929be2d115d672e1a02 (johnalle/qemu-kvm-fork) + +JIRA: https://issues.redhat.com/browse/RHEL-66202 + +commit 2e6f051cfc58e69dcb392cd245d8f01b0c2e963f +Author: Suravee Suthikulpanit +Date: Fri Sep 27 12:29:09 2024 -0500 + + amd_iommu: Rename variable mmio to mr_mmio + + Rename the MMIO memory region variable 'mmio' to 'mr_mmio' + so to correctly name align with struct AMDVIState::variable type. + + No functional change intended. + + Reviewed-by: Alejandro Jimenez + Signed-off-by: Suravee Suthikulpanit + Signed-off-by: Santosh Shukla + Message-Id: <20240927172913.121477-2-santosh.shukla@amd.com> + Reviewed-by: Michael S. Tsirkin + Signed-off-by: Michael S. Tsirkin + +Signed-off-by: John Allen +--- + hw/i386/acpi-build.c | 4 ++-- + hw/i386/amd_iommu.c | 6 +++--- + hw/i386/amd_iommu.h | 2 +- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c +index 5d4bd2b710..032fb1f904 100644 +--- a/hw/i386/acpi-build.c ++++ b/hw/i386/acpi-build.c +@@ -2397,7 +2397,7 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id, + /* Capability offset */ + build_append_int_noprefix(table_data, s->pci.capab_offset, 2); + /* IOMMU base address */ +- build_append_int_noprefix(table_data, s->mmio.addr, 8); ++ build_append_int_noprefix(table_data, s->mr_mmio.addr, 8); + /* PCI Segment Group */ + build_append_int_noprefix(table_data, 0, 2); + /* IOMMU info */ +@@ -2432,7 +2432,7 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id, + /* Capability offset */ + build_append_int_noprefix(table_data, s->pci.capab_offset, 2); + /* IOMMU base address */ +- build_append_int_noprefix(table_data, s->mmio.addr, 8); ++ build_append_int_noprefix(table_data, s->mr_mmio.addr, 8); + /* PCI Segment Group */ + build_append_int_noprefix(table_data, 0, 2); + /* IOMMU info */ +diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c +index 87643d2891..148b5ee51d 100644 +--- a/hw/i386/amd_iommu.c ++++ b/hw/i386/amd_iommu.c +@@ -1598,10 +1598,10 @@ static void amdvi_sysbus_realize(DeviceState *dev, Error **errp) + x86ms->ioapic_as = amdvi_host_dma_iommu(bus, s, AMDVI_IOAPIC_SB_DEVID); + + /* set up MMIO */ +- memory_region_init_io(&s->mmio, OBJECT(s), &mmio_mem_ops, s, "amdvi-mmio", +- AMDVI_MMIO_SIZE); ++ memory_region_init_io(&s->mr_mmio, OBJECT(s), &mmio_mem_ops, s, ++ "amdvi-mmio", AMDVI_MMIO_SIZE); + memory_region_add_subregion(get_system_memory(), AMDVI_BASE_ADDR, +- &s->mmio); ++ &s->mr_mmio); + pci_setup_iommu(bus, &amdvi_iommu_ops, s); + amdvi_init(s); + } +diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h +index 73619fe9ea..e5c2ae94f2 100644 +--- a/hw/i386/amd_iommu.h ++++ b/hw/i386/amd_iommu.h +@@ -353,7 +353,7 @@ struct AMDVIState { + uint32_t pprlog_head; /* ppr log head */ + uint32_t pprlog_tail; /* ppr log tail */ + +- MemoryRegion mmio; /* MMIO region */ ++ MemoryRegion mr_mmio; /* MMIO region */ + uint8_t mmior[AMDVI_MMIO_SIZE]; /* read/write MMIO */ + uint8_t w1cmask[AMDVI_MMIO_SIZE]; /* read/write 1 clear mask */ + uint8_t romask[AMDVI_MMIO_SIZE]; /* MMIO read/only mask */ +-- +2.39.3 + diff --git a/kvm-amd_iommu-Send-notification-when-invalidate-interrup.patch b/kvm-amd_iommu-Send-notification-when-invalidate-interrup.patch new file mode 100644 index 0000000..044f8d1 --- /dev/null +++ b/kvm-amd_iommu-Send-notification-when-invalidate-interrup.patch @@ -0,0 +1,81 @@ +From 17ce6ac0d8edb04ba79bb39d3f695cd0506a9dc2 Mon Sep 17 00:00:00 2001 +From: John Allen +Date: Wed, 11 Dec 2024 15:06:59 -0600 +Subject: [PATCH 06/57] amd_iommu: Send notification when invalidate interrupt + entry cache + +RH-Author: John Allen +RH-MergeRequest: 303: Interrupt Remap support for emulated amd viommu +RH-Jira: RHEL-66202 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [4/5] d57e8fb4e69f3c01d32673bf658aae5067d6b969 (johnalle/qemu-kvm-fork) + +JIRA: https://issues.redhat.com/browse/RHEL-66202 + +commit f84aad4d718b83d2a4d90485992e5421430032e1 +Author: Suravee Suthikulpanit +Date: Fri Sep 27 12:29:12 2024 -0500 + + amd_iommu: Send notification when invalidate interrupt entry cache + + In order to support AMD IOMMU interrupt remapping emulation with PCI + pass-through devices, QEMU needs to notify VFIO when guest IOMMU driver + updates and invalidate the guest interrupt remapping table (IRT), and + communicate information so that the host IOMMU driver can update + the shadowed interrupt remapping table in the host IOMMU. + + Therefore, send notification when guest IOMMU emulates the IRT + invalidation commands. + + Reviewed-by: Alejandro Jimenez + Signed-off-by: Suravee Suthikulpanit + Signed-off-by: Santosh Shukla + Message-Id: <20240927172913.121477-5-santosh.shukla@amd.com> + Reviewed-by: Michael S. Tsirkin + Signed-off-by: Michael S. Tsirkin + +Signed-off-by: John Allen +--- + hw/i386/amd_iommu.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c +index 8fcf5eacb4..82d76dfca9 100644 +--- a/hw/i386/amd_iommu.c ++++ b/hw/i386/amd_iommu.c +@@ -431,6 +431,12 @@ static void amdvi_complete_ppr(AMDVIState *s, uint64_t *cmd) + trace_amdvi_ppr_exec(); + } + ++static void amdvi_intremap_inval_notify_all(AMDVIState *s, bool global, ++ uint32_t index, uint32_t mask) ++{ ++ x86_iommu_iec_notify_all(X86_IOMMU_DEVICE(s), global, index, mask); ++} ++ + static void amdvi_inval_all(AMDVIState *s, uint64_t *cmd) + { + if (extract64(cmd[0], 0, 60) || cmd[1]) { +@@ -438,6 +444,9 @@ static void amdvi_inval_all(AMDVIState *s, uint64_t *cmd) + s->cmdbuf + s->cmdbuf_head); + } + ++ /* Notify global invalidation */ ++ amdvi_intremap_inval_notify_all(s, true, 0, 0); ++ + amdvi_iotlb_reset(s); + trace_amdvi_all_inval(); + } +@@ -486,6 +495,9 @@ static void amdvi_inval_inttable(AMDVIState *s, uint64_t *cmd) + return; + } + ++ /* Notify global invalidation */ ++ amdvi_intremap_inval_notify_all(s, true, 0, 0); ++ + trace_amdvi_intr_inval(); + } + +-- +2.39.3 + diff --git a/kvm-amd_iommu-Use-shared-memory-region-for-Interrupt-Rem.patch b/kvm-amd_iommu-Use-shared-memory-region-for-Interrupt-Rem.patch new file mode 100644 index 0000000..39ad4ef --- /dev/null +++ b/kvm-amd_iommu-Use-shared-memory-region-for-Interrupt-Rem.patch @@ -0,0 +1,105 @@ +From 4859d41adfaae8933e074dcefdc81edd3832c914 Mon Sep 17 00:00:00 2001 +From: John Allen +Date: Wed, 11 Dec 2024 15:06:55 -0600 +Subject: [PATCH 05/57] amd_iommu: Use shared memory region for Interrupt + Remapping + +RH-Author: John Allen +RH-MergeRequest: 303: Interrupt Remap support for emulated amd viommu +RH-Jira: RHEL-66202 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [3/5] 48c0513c80257bfbd12c2cf3bab2503bd95d0b1c (johnalle/qemu-kvm-fork) + +JIRA: https://issues.redhat.com/browse/RHEL-66202 + +commit 9fc9dbac61ddde7d8df37e84c8e02cec249d3222 +Author: Suravee Suthikulpanit +Date: Fri Sep 27 12:29:11 2024 -0500 + + amd_iommu: Use shared memory region for Interrupt Remapping + + Use shared memory region for interrupt remapping which can be + aliased by all devices. + + Reviewed-by: Alejandro Jimenez + Signed-off-by: Suravee Suthikulpanit + Signed-off-by: Santosh Shukla + Message-Id: <20240927172913.121477-4-santosh.shukla@amd.com> + Reviewed-by: Michael S. Tsirkin + Signed-off-by: Michael S. Tsirkin + +Signed-off-by: John Allen +--- + hw/i386/amd_iommu.c | 22 ++++++++++++++-------- + hw/i386/amd_iommu.h | 1 + + 2 files changed, 15 insertions(+), 8 deletions(-) + +diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c +index 567cb8adc9..8fcf5eacb4 100644 +--- a/hw/i386/amd_iommu.c ++++ b/hw/i386/amd_iommu.c +@@ -1443,7 +1443,7 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) + * |--------------------+-------------------+----------+ + * | amdvi-root | 00000000-ffffffff | 0 | + * | amdvi-iommu_nodma | 00000000-ffffffff | 0 | +- * | amdvi-iommu_ir | fee00000-feefffff | 64 | ++ * | amdvi-iommu_ir | fee00000-feefffff | 1 | + * |--------------------+-------------------+----------| + */ + memory_region_init_iommu(&amdvi_dev_as->iommu, +@@ -1454,13 +1454,6 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) + memory_region_init(&amdvi_dev_as->root, OBJECT(s), + "amdvi_root", UINT64_MAX); + address_space_init(&amdvi_dev_as->as, &amdvi_dev_as->root, name); +- memory_region_init_io(&amdvi_dev_as->iommu_ir, OBJECT(s), +- &amdvi_ir_ops, s, "amd_iommu_ir", +- AMDVI_INT_ADDR_SIZE); +- memory_region_add_subregion_overlap(&amdvi_dev_as->root, +- AMDVI_INT_ADDR_FIRST, +- &amdvi_dev_as->iommu_ir, +- 64); + memory_region_add_subregion_overlap(&amdvi_dev_as->root, 0, + MEMORY_REGION(&amdvi_dev_as->iommu), + 0); +@@ -1472,6 +1465,13 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) + memory_region_add_subregion_overlap(&amdvi_dev_as->root, 0, + &amdvi_dev_as->iommu_nodma, + 0); ++ /* Build the Interrupt Remapping alias to shared memory */ ++ memory_region_init_alias(&amdvi_dev_as->iommu_ir, OBJECT(s), ++ "amdvi-ir", &s->mr_ir, 0, ++ memory_region_size(&s->mr_ir)); ++ memory_region_add_subregion_overlap(MEMORY_REGION(&amdvi_dev_as->iommu), ++ AMDVI_INT_ADDR_FIRST, ++ &amdvi_dev_as->iommu_ir, 1); + + if (!x86_iommu->pt_supported) { + memory_region_set_enabled(&amdvi_dev_as->iommu_nodma, false); +@@ -1633,6 +1633,12 @@ static void amdvi_sysbus_realize(DeviceState *dev, Error **errp) + memory_region_add_subregion_overlap(&s->mr_sys, 0, + &s->mr_nodma, 0); + ++ /* set up the Interrupt Remapping memory region */ ++ memory_region_init_io(&s->mr_ir, OBJECT(s), &amdvi_ir_ops, ++ s, "amdvi-ir", AMDVI_INT_ADDR_SIZE); ++ memory_region_add_subregion_overlap(&s->mr_sys, AMDVI_INT_ADDR_FIRST, ++ &s->mr_ir, 1); ++ + pci_setup_iommu(bus, &amdvi_iommu_ops, s); + amdvi_init(s); + } +diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h +index be417e51c4..e0dac4d9a9 100644 +--- a/hw/i386/amd_iommu.h ++++ b/hw/i386/amd_iommu.h +@@ -356,6 +356,7 @@ struct AMDVIState { + MemoryRegion mr_mmio; /* MMIO region */ + MemoryRegion mr_sys; + MemoryRegion mr_nodma; ++ MemoryRegion mr_ir; + uint8_t mmior[AMDVI_MMIO_SIZE]; /* read/write MMIO */ + uint8_t w1cmask[AMDVI_MMIO_SIZE]; /* read/write 1 clear mask */ + uint8_t romask[AMDVI_MMIO_SIZE]; /* MMIO read/only mask */ +-- +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 new file mode 100644 index 0000000..72c7a02 --- /dev/null +++ b/kvm-block-skip-automatic-zero-init-of-large-array-in-ioq.patch @@ -0,0 +1,48 @@ +From d38bdce712f572e1920e3344132ff6600d657de2 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 29/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [3/30] 301a08b3acdcd95634dec5dab1d96fcfe3abf3be (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 +performance overhead in the I/O hot path. + +The 'iocbs' array will selectively initialized when processing +the I/O data. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-4-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 83750c1da807c973b0b11d977d61df7e41122d03) +Signed-off-by: Stefan Hajnoczi +--- + block/linux-aio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/block/linux-aio.c b/block/linux-aio.c +index e3b5ec9aba..26d9f086d2 100644 +--- a/block/linux-aio.c ++++ b/block/linux-aio.c +@@ -291,7 +291,7 @@ static void ioq_submit(LinuxAioState *s) + { + int ret, len; + struct qemu_laiocb *aiocb; +- struct iocb *iocbs[MAX_EVENTS]; ++ QEMU_UNINITIALIZED struct iocb *iocbs[MAX_EVENTS]; + QSIMPLEQ_HEAD(, qemu_laiocb) completed; + + do { +-- +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 new file mode 100644 index 0000000..4d56bf1 --- /dev/null +++ b/kvm-chardev-char-fd-skip-automatic-zero-init-of-large-ar.patch @@ -0,0 +1,49 @@ +From 1e8798a3adbbfc42167aaba0ee18175deac37193 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 30/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [4/30] b16fe5c9af4756e1856cd330df02a1a09d9f33ea (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 +of this array to eliminate the performance overhead in the I/O +hot path. + +The 'buf' array will be fully initialized when reading data off +the network socket. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-5-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit a503bdc22b91869e3bf45522e36b122889465306) +Signed-off-by: Stefan Hajnoczi +--- + chardev/char-fd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/chardev/char-fd.c b/chardev/char-fd.c +index d2c4923359..8dd662c066 100644 +--- a/chardev/char-fd.c ++++ b/chardev/char-fd.c +@@ -50,7 +50,7 @@ static gboolean fd_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) + Chardev *chr = CHARDEV(opaque); + FDChardev *s = FD_CHARDEV(opaque); + int len; +- uint8_t buf[CHR_READ_BUF_LEN]; ++ QEMU_UNINITIALIZED uint8_t buf[CHR_READ_BUF_LEN]; + ssize_t ret; + + len = sizeof(buf); +-- +2.39.3 + 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 new file mode 100644 index 0000000..7edacc8 --- /dev/null +++ b/kvm-chardev-char-pty-skip-automatic-zero-init-of-large-a.patch @@ -0,0 +1,49 @@ +From 74311b0ee8e211fccff211b975e4ae9236c063dc 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 31/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [5/30] a3b8458c30f485551093f292c00c20b0e118df77 (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 +of this array to eliminate the performance overhead in the I/O +hot path. + +The 'buf' array will be fully initialized when reading data off +the PTY. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-6-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 45bb7fb21c8d18294a9f92da99d01ab3c67c7df2) +Signed-off-by: Stefan Hajnoczi +--- + chardev/char-pty.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/chardev/char-pty.c b/chardev/char-pty.c +index cc2f7617fe..3319ad215d 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) + Chardev *chr = CHARDEV(opaque); + PtyChardev *s = PTY_CHARDEV(opaque); + gsize len; +- uint8_t buf[CHR_READ_BUF_LEN]; ++ QEMU_UNINITIALIZED uint8_t buf[CHR_READ_BUF_LEN]; + ssize_t ret; + + len = sizeof(buf); +-- +2.39.3 + 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 new file mode 100644 index 0000000..3b6889b --- /dev/null +++ b/kvm-chardev-char-socket-skip-automatic-zero-init-of-larg.patch @@ -0,0 +1,49 @@ +From d56a8ce56f0de70ab2de266a80e25cf309e72fda 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 32/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [6/30] 86a2ac03efa1838fb30931c38945ee77de9bbe06 (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 +of this array to eliminate the performance overhead in the I/O +hot path. + +The 'buf' array will be fully initialized when reading data off +the network socket. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-7-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 9a23075cef1ac6e73a95a489ac72f41c573ceb9b) +Signed-off-by: Stefan Hajnoczi +--- + chardev/char-socket.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/chardev/char-socket.c b/chardev/char-socket.c +index 1ca9441b1b..99d644e89f 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) + { + Chardev *chr = CHARDEV(opaque); + SocketChardev *s = SOCKET_CHARDEV(opaque); +- uint8_t buf[CHR_READ_BUF_LEN]; ++ QEMU_UNINITIALIZED uint8_t buf[CHR_READ_BUF_LEN]; + int len, size; + + if ((s->state != TCP_CHARDEV_STATE_CONNECTED) || +-- +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 new file mode 100644 index 0000000..ccaf1c4 --- /dev/null +++ b/kvm-hw-audio-ac97-skip-automatic-zero-init-of-large-arra.patch @@ -0,0 +1,57 @@ +From 2018f62f2242d8d4a970d83ebef9b3c2bccf6fda 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 33/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [7/30] 4a6b59a9b9122d9f89e99b3e44df19e6d92ed941 (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 +automatic zero-init of these arrays to eliminate the performance +overhead in the I/O hot path. + +The 'tmpbuf' array will be fully initialized when reading data from +the audio backend and/or device memory. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-8-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 2553d2d26a9d0f46386bf8c37d184567e5cede6c) +Signed-off-by: Stefan Hajnoczi +--- + hw/audio/ac97.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c +index 3f0053f94d..681b5752a1 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) + static int write_audio(AC97LinkState *s, AC97BusMasterRegs *r, + int max, int *stop) + { +- uint8_t tmpbuf[4096]; ++ QEMU_UNINITIALIZED uint8_t tmpbuf[4096]; + uint32_t addr = r->bd.addr; + uint32_t temp = r->picb << 1; + uint32_t written = 0; +@@ -959,7 +959,7 @@ static void write_bup(AC97LinkState *s, int elapsed) + static int read_audio(AC97LinkState *s, AC97BusMasterRegs *r, + int max, int *stop) + { +- uint8_t tmpbuf[4096]; ++ QEMU_UNINITIALIZED uint8_t tmpbuf[4096]; + uint32_t addr = r->bd.addr; + uint32_t temp = r->picb << 1; + uint32_t nread = 0; +-- +2.39.3 + 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 new file mode 100644 index 0000000..95f535f --- /dev/null +++ b/kvm-hw-audio-cs4231a-skip-automatic-zero-init-of-large-a.patch @@ -0,0 +1,59 @@ +From bd32bb22fb324a37b31ed9ac3387524f6f4ea5be 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 34/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [8/30] 6c454bcc2927e49896c62718287fb9e4b37b3bb9 (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 +automatic zero-init of these arrays to eliminate the performance +overhead in the I/O hot path. + +The 'tmpbuf' array will be fully initialized when reading a block of +data from the guest. The 'linbuf' array will be fully initialized +when converting the audio samples. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-9-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit ca2cc0385d97cea66cd54ee42553f385c403d4a6) +Signed-off-by: Stefan Hajnoczi +--- + hw/audio/cs4231a.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c +index 9ef57f042d..5c312642cc 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, + int dma_len, int len) + { + int temp, net; +- uint8_t tmpbuf[4096]; ++ QEMU_UNINITIALIZED uint8_t tmpbuf[4096]; + IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma); + + temp = len; +@@ -547,7 +547,7 @@ static int cs_write_audio (CSState *s, int nchan, int dma_pos, + copied = k->read_memory(s->isa_dma, nchan, tmpbuf, dma_pos, to_copy); + if (s->tab) { + int i; +- int16_t linbuf[4096]; ++ QEMU_UNINITIALIZED int16_t linbuf[4096]; + + for (i = 0; i < copied; ++i) + linbuf[i] = s->tab[tmpbuf[i]]; +-- +2.39.3 + 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 new file mode 100644 index 0000000..76a5d89 --- /dev/null +++ b/kvm-hw-audio-es1370-skip-automatic-zero-init-of-large-ar.patch @@ -0,0 +1,49 @@ +From cb12ddc6ed836091aa7724e2f77ab79cd9089cad 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 35/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [9/30] b992e4247d8d31dc09f9dc7671e7a532558174ec (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 +zero-init of this array to eliminate the performance overhead in +the I/O hot path. + +The 'tmpbuf' array will be fully initialized when reading data from +the audio backend and/or device memory. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-10-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 8236e206084b832d1d7ec947a4798b818f4cdf1f) +Signed-off-by: Stefan Hajnoczi +--- + hw/audio/es1370.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c +index 4ab61d3b9d..6aea934f54 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) + static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, + int max, bool *irq) + { +- uint8_t tmpbuf[4096]; ++ QEMU_UNINITIALIZED uint8_t tmpbuf[4096]; + size_t to_transfer; + uint32_t addr = d->frame_addr; + int sc = d->scount & 0xffff; +-- +2.39.3 + 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 new file mode 100644 index 0000000..2ce4fa8 --- /dev/null +++ b/kvm-hw-audio-gus-skip-automatic-zero-init-of-large-array.patch @@ -0,0 +1,48 @@ +From 9ad7091d82fd0577488f27ab54bb7851fe957020 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 36/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [10/30] 366953d0417ac31e3060fdc327fe8dade3375bf0 (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 +zero-init of this array to eliminate the performance overhead in +the I/O hot path. + +The 'tmpbuf' array will be fully initialized when reading data +from device memory. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-11-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 2e438da4929018c62609381e1156aac0b2fe3de3) +Signed-off-by: Stefan Hajnoczi +--- + hw/audio/gus.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/audio/gus.c b/hw/audio/gus.c +index 4beb3fd74e..e8b0b85d44 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) + { + GUSState *s = opaque; + IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma); +- char tmpbuf[4096]; ++ QEMU_UNINITIALIZED char tmpbuf[4096]; + int pos = dma_pos, mode, left = dma_len - dma_pos; + + ldebug ("read DMA %#x %d\n", dma_pos, dma_len); +-- +2.39.3 + 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 new file mode 100644 index 0000000..3608901 --- /dev/null +++ b/kvm-hw-audio-marvell_88w8618-skip-automatic-zero-init-of.patch @@ -0,0 +1,50 @@ +From 5cf61823cbe80b1ace2f5bdb9cc1971956425b98 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 37/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [11/30] e09cdb76430552081168873dadfef1b5c8f74327 (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 +zero-init of this array to eliminate the performance overhead in +the I/O hot path. + +The 'buf' array will be fully initialized when reading data from +device memory. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-12-berrange@redhat.com +[Fixed hw/audio/gus in commit message --Stefan] +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 5b6cd5c5df4229972d8a0fd9dd9a089a1644d6ba) +Signed-off-by: Stefan Hajnoczi +--- + hw/audio/marvell_88w8618.c | 2 +- + 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 +--- 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) + { + mv88w8618_audio_state *s = opaque; + int16_t *codec_buffer; +- int8_t buf[4096]; ++ QEMU_UNINITIALIZED int8_t buf[4096]; + int8_t *mem_buffer; + int pos, block_size; + +-- +2.39.3 + 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 new file mode 100644 index 0000000..7e531d6 --- /dev/null +++ b/kvm-hw-audio-sb16-skip-automatic-zero-init-of-large-arra.patch @@ -0,0 +1,48 @@ +From 0b4d59d75edd49ef99f0a82fbcbe360c5b48e4f8 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 38/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [12/30] 6475d67546bf04745636b317e965bcd89b6fb2d2 (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 +of this array to eliminate the performance overhead in the I/O hot +path. + +The 'tmpbuf' array will be fully initialized when reading data from +device memory. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-13-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 30c82f6657c1ee9fbb5473924b4d3273f214bd6f) +Signed-off-by: Stefan Hajnoczi +--- + hw/audio/sb16.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c +index fd76e78d18..04c818ed3d 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, + IsaDma *isa_dma = nchan == s->dma ? s->isa_dma : s->isa_hdma; + IsaDmaClass *k = ISADMA_GET_CLASS(isa_dma); + int temp, net; +- uint8_t tmpbuf[4096]; ++ QEMU_UNINITIALIZED uint8_t tmpbuf[4096]; + + temp = len; + net = 0; +-- +2.39.3 + 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 new file mode 100644 index 0000000..c52f0c1 --- /dev/null +++ b/kvm-hw-audio-via-ac97-skip-automatic-zero-init-of-large-.patch @@ -0,0 +1,49 @@ +From 35332282ef8bd06f59206266006eff222ffe6bec 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 39/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [13/30] 6391a04b29fcbb8bcdbce2c6b786758fc34f0d71 (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 +of this array to eliminate the performance overhead in the I/O hot +path. + +The 'tmpbuf' array will be fully initialized when reading data from +device memory. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-14-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit bb71d9fe1419f44529c91d1b09464718d157e647) +Signed-off-by: Stefan Hajnoczi +--- + hw/audio/via-ac97.c | 2 +- + 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 +--- a/hw/audio/via-ac97.c ++++ b/hw/audio/via-ac97.c +@@ -175,7 +175,7 @@ static void out_cb(void *opaque, int avail) + ViaAC97SGDChannel *c = &s->aur; + int temp, to_copy, copied; + bool stop = false; +- uint8_t tmpbuf[4096]; ++ QEMU_UNINITIALIZED uint8_t tmpbuf[4096]; + + if (c->stat & STAT_PAUSED) { + return; +-- +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 new file mode 100644 index 0000000..98d11f0 --- /dev/null +++ b/kvm-hw-char-sclpconsole-lm-skip-automatic-zero-init-of-l.patch @@ -0,0 +1,49 @@ +From b0c16a93460c2dfe834a9f439d25dc833dfb7427 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 40/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [14/30] 1491e0147a799ec523fa67fd49649722a07299e7 (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 +of this array to eliminate the performance overhead in the I/O hot +path. + +The 'buffer' array will be selectively initialized when data is converted +between EBCDIC and ASCII. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-15-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 8b1dac1ad57082611419b0e2f347acd96115d25f) +Signed-off-by: Stefan Hajnoczi +--- + hw/char/sclpconsole-lm.c | 2 +- + 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 +--- a/hw/char/sclpconsole-lm.c ++++ b/hw/char/sclpconsole-lm.c +@@ -214,7 +214,7 @@ static int process_mdb(SCLPEvent *event, MDBO *mdbo) + { + int rc; + int len; +- uint8_t buffer[SIZE_BUFFER]; ++ QEMU_UNINITIALIZED uint8_t buffer[SIZE_BUFFER]; + + len = be16_to_cpu(mdbo->length); + len -= sizeof(mdbo->length) + sizeof(mdbo->type) +-- +2.39.3 + 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 new file mode 100644 index 0000000..607fd50 --- /dev/null +++ b/kvm-hw-display-vmware_vga-skip-automatic-zero-init-of-la.patch @@ -0,0 +1,49 @@ +From 7b5624efccf55184278c6f4924efc2141df460f0 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 42/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [16/30] 4aaf459d4356bf28164be742889b9a78d3656703 (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 +automatic zero-init of this struct to eliminate the performance +overhead in the I/O hot path. + +The cursor variable will be fully initialized only when processing +a cursor definition message from the guest. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-17-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 7048e70f391df76d009eecca25f8027858f9f304) +Signed-off-by: Stefan Hajnoczi +--- + hw/display/vmware_vga.c | 2 +- + 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 +--- 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) + uint32_t cmd, colour; + int args, len, maxloop = 1024; + int x, y, dx, dy, width, height; +- struct vmsvga_cursor_definition_s cursor; ++ QEMU_UNINITIALIZED struct vmsvga_cursor_definition_s cursor; + uint32_t cmd_start; + + len = vmsvga_fifo_length(s); +-- +2.39.3 + 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 new file mode 100644 index 0000000..d38d141 --- /dev/null +++ b/kvm-hw-dma-xlnx_csu_dma-skip-automatic-zero-init-of-larg.patch @@ -0,0 +1,47 @@ +From cd3500c9e248dbefb36273046e6eee44ee0d5cbe 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 41/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [15/30] 063c88269c7d3bf07ae05aaf2d3d154e2016db81 (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 +eliminate the performance overhead in the I/O hot path. + +The 'buf' array will be fully initialized when data is copied. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-16-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit ce14f24611aa0469b464a9512e192b4fd51dca2b) +Signed-off-by: Stefan Hajnoczi +--- + hw/dma/xlnx_csu_dma.c | 2 +- + 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 +--- 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) + static void xlnx_csu_dma_src_notify(void *opaque) + { + XlnxCSUDMA *s = XLNX_CSU_DMA(opaque); +- unsigned char buf[4 * 1024]; ++ QEMU_UNINITIALIZED unsigned char buf[4 * 1024]; + size_t rlen = 0; + + ptimer_transaction_begin(s->src_timer); +-- +2.39.3 + 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 new file mode 100644 index 0000000..26d816e --- /dev/null +++ b/kvm-hw-hyperv-syndbg-skip-automatic-zero-init-of-large-a.patch @@ -0,0 +1,56 @@ +From a4673aab85958c60867b12c65cc3483d734bb6e0 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 43/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [17/30] 5f71779c431128601baf46115fe65178532a3836 (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 +zero-init of this array to eliminate the performance overhead in the +I/O hot path. + +The 'data_buf' array will be fully initialized when data is read +off the network socket. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-18-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 5a1f614d0cd0bcc8e84e0b7ab6af63d56bd348a2) +Signed-off-by: Stefan Hajnoczi + +Conflicts: + hw/hyperv/syndbg.c + + Context conflict due to missing commit 3efb9d226221 + ("hw/hyperv/syndbg: common compilation unit") downstream. There is no + need to backport the commit because it's not a bug fix. +--- + hw/hyperv/syndbg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/hyperv/syndbg.c b/hw/hyperv/syndbg.c +index 065e12fb1e..c7c43c8009 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, + uint64_t timeout, uint32_t *retrieved_count) + { + uint16_t ret; +- uint8_t data_buf[TARGET_PAGE_SIZE - UDP_PKT_HEADER_SIZE]; ++ QEMU_UNINITIALIZED uint8_t data_buf[TARGET_PAGE_SIZE - UDP_PKT_HEADER_SIZE]; + hwaddr out_len; + void *out_data; + ssize_t recv_byte_count; +-- +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..d68826a --- /dev/null +++ b/kvm-hw-i386-amd_iommu-Allow-migration-when-explicitly-cr.patch @@ -0,0 +1,117 @@ +From f1ff9d3b379697a2d4627e9529067195841d86a8 Mon Sep 17 00:00:00 2001 +From: Suravee Suthikulpanit +Date: Sun, 4 May 2025 17:04:05 +0000 +Subject: [PATCH 25/57] hw/i386/amd_iommu: Allow migration when explicitly + create the AMDVI-PCI device + +RH-Author: John Allen +RH-MergeRequest: 380: Add ability to manually specify the AMDVI-PCI device +RH-Jira: RHEL-70925 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [2/3] a42b88116e608a79b6fae13ebe3709874f2a853f (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-70925 + +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 6a5e76cfef..a34e0c5f59 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 ece71ff0b6..741dd9a910 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-Assign-pci-id-0x1419-for-the-AMD-I.patch b/kvm-hw-i386-amd_iommu-Assign-pci-id-0x1419-for-the-AMD-I.patch new file mode 100644 index 0000000..4542745 --- /dev/null +++ b/kvm-hw-i386-amd_iommu-Assign-pci-id-0x1419-for-the-AMD-I.patch @@ -0,0 +1,57 @@ +From e611119b8b4e0712ab103628051d69ea84538719 Mon Sep 17 00:00:00 2001 +From: Suravee Suthikulpanit +Date: Tue, 25 Mar 2025 02:11:40 +0000 +Subject: [PATCH 23/57] hw/i386/amd_iommu: Assign pci-id 0x1419 for the AMD + IOMMU device +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: John Allen +RH-MergeRequest: 379: hw/i386/amd_iommu: Assign pci-id 0x1419 for the AMD IOMMU device +RH-Jira: RHEL-70926 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/1] 69d847f64543caf328da3e7663e7d2ebe53cd448 (johnalle/qemu-kvm-fork) + +Currently, the QEMU-emulated AMD IOMMU device use PCI vendor id 0x1022 +(AMD) with device id zero (undefined). Eventhough this does not cause any +functional issue for AMD IOMMU driver since it normally uses information +in the ACPI IVRS table to probe and initialize the device per +recommendation in the AMD IOMMU specification, the device id zero causes +the Windows Device Manager utility to show the device as an unknown device. + +Since Windows only recognizes AMD IOMMU device with device id 0x1419 as +listed in the machine.inf file, modify the QEMU AMD IOMMU model to use +the id 0x1419 to avoid the issue. This advertise the IOMMU as the AMD +IOMMU device for Family 15h (Models 10h-1fh). + +Signed-off-by: Suravee Suthikulpanit +Message-Id: <20250325021140.5676-1-suravee.suthikulpanit@amd.com> +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Yan Vugenfirer +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 719255486df2fcbe1b8599786b37f4bb80272f1a) + +JIRA: https://issues.redhat.com/browse/RHEL-70926 + +Signed-off-by: John Allen +--- + hw/i386/amd_iommu.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c +index d804656ea8..59e1a01b7c 100644 +--- a/hw/i386/amd_iommu.c ++++ b/hw/i386/amd_iommu.c +@@ -1714,6 +1714,7 @@ static void amdvi_pci_class_init(ObjectClass *klass, void *data) + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->vendor_id = PCI_VENDOR_ID_AMD; ++ k->device_id = 0x1419; + k->class_id = 0x0806; + k->realize = amdvi_pci_realize; + +-- +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..6da1d5d --- /dev/null +++ b/kvm-hw-i386-amd_iommu-Isolate-AMDVI-PCI-from-amd-iommu-d.patch @@ -0,0 +1,267 @@ +From 5a697d0f66360acca8216f49c06dc9702231d470 Mon Sep 17 00:00:00 2001 +From: Suravee Suthikulpanit +Date: Sun, 4 May 2025 17:04:04 +0000 +Subject: [PATCH 24/57] 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: 380: Add ability to manually specify the AMDVI-PCI device +RH-Jira: RHEL-70925 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/3] 58254a72ba2d810b57c610462494f76691126521 (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-70925 + +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 032fb1f904..236261f8aa 100644 +--- a/hw/i386/acpi-build.c ++++ b/hw/i386/acpi-build.c +@@ -2392,10 +2392,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 */ +@@ -2427,10 +2427,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 59e1a01b7c..6a5e76cfef 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); + +@@ -1668,6 +1686,7 @@ static void amdvi_sysbus_realize(DeviceState *dev, Error **errp) + + static Property amdvi_properties[] = { + DEFINE_PROP_BOOL("xtsup", AMDVIState, xtsup, false), ++ DEFINE_PROP_STRING("pci-id", AMDVIState, pci_id), + DEFINE_PROP_END_OF_LIST(), + }; + +@@ -1676,13 +1695,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); +@@ -1704,7 +1716,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 e0dac4d9a9..ece71ff0b6 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 new file mode 100644 index 0000000..a1553f8 --- /dev/null +++ b/kvm-hw-misc-aspeed_hace-skip-automatic-zero-init-of-larg.patch @@ -0,0 +1,57 @@ +From 0bfbd2c49c01ee77d3b5a21bf9fe675916cbf0ed 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 44/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [18/30] ec8510be6b23b26b3eecd6767e1deb0c0c50dd58 (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 +zero-init of this array to eliminate the performance overhead in the +I/O hot path. + +The 'iovec' array will be selectively initialized based on data that +needs to be hashed. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-19-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 6992c886838282f36b20deee44b666bbfc573a8f) +Signed-off-by: Stefan Hajnoczi + +Conflicts: + hw/misc/aspeed_hace.c + + Context conflict due to missing commit b9ccbe212e24 + ("hw/misc/aspeed_hace: Extract accumulation-mode hash execution into + helper function") downstream. The commit is not a bug fix, so there is + no need to backport it. +--- + hw/misc/aspeed_hace.c | 2 +- + 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 +--- 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, + 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]; + 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 new file mode 100644 index 0000000..8161972 --- /dev/null +++ b/kvm-hw-net-rtl8139-skip-automatic-zero-init-of-large-arr.patch @@ -0,0 +1,48 @@ +From cc173deaaa4d9dc6ad9188e0b03f46b7e64f26b2 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 45/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [19/30] 344c720aef2feb35f84fd4b21f2b1b31e5572286 (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 +of this array to eliminate the performance overhead in the I/O +hot path. + +The 'txbuffer' will be fully initialized when reading PCI DMA +buffers. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-20-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 3ccc6489dd4925ddd1f3066bd3751389169cd7aa) +Signed-off-by: Stefan Hajnoczi +--- + hw/net/rtl8139.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index f2fe057535..a2732bf1c1 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -1818,7 +1818,7 @@ static int rtl8139_transmit_one(RTL8139State *s, int descriptor) + + PCIDevice *d = PCI_DEVICE(s); + int txsize = s->TxStatus[descriptor] & 0x1fff; +- uint8_t txbuffer[0x2000]; ++ QEMU_UNINITIALIZED uint8_t txbuffer[0x2000]; + + DPRINTF("+++ transmit reading %d bytes from host memory at 0x%08x\n", + txsize, s->TxAddr[descriptor]); +-- +2.39.3 + 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 new file mode 100644 index 0000000..06ea05e --- /dev/null +++ b/kvm-hw-net-tulip-skip-automatic-zero-init-of-large-array.patch @@ -0,0 +1,47 @@ +From 400b5c8ae7f06a450ef91230343d7ce489142a38 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 46/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [20/30] b3d29de8495c0ff40c26974673adefe4eb27a417 (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 +to eliminate the performance overhead in the I/O hot path. + +The 'buf' array will be fully initialized when reading data from the +device. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-21-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit e1afd5ee6eb2954f4baf3c97820e4aaf7de97d2a) +Signed-off-by: Stefan Hajnoczi +--- + hw/net/tulip.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/net/tulip.c b/hw/net/tulip.c +index 1f2ef20977..5cf2b96fbd 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) + static void tulip_setup_frame(TULIPState *s, + struct tulip_descriptor *desc) + { +- uint8_t buf[4096]; ++ QEMU_UNINITIALIZED uint8_t buf[4096]; + int len = (desc->control >> TDES1_BUF1_SIZE_SHIFT) & TDES1_BUF1_SIZE_MASK; + int i; + +-- +2.39.3 + 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 new file mode 100644 index 0000000..4fbe7a4 --- /dev/null +++ b/kvm-hw-net-virtio-net-skip-automatic-zero-init-of-large-.patch @@ -0,0 +1,54 @@ +From 0925796a4537e20e033a675ebc8899e4580235f3 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 47/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [21/30] 0450189a4c4c779b5a1850e9ea8278a5129c5f7f (stefanha/centos-stream-qemu-kvm) + +The 'virtio_net_receive_rcu' method has three arrays with +VIRTQUEUE_MAX_SIZE elements, which are apprixmately 32k in +size used for copying data between guest and host. Skip the +automatic zero-init of these arrays to eliminate the +performance overhead in the I/O hot path. + +The three arrays will be selectively initialized as required +when processing network buffers. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-22-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 21cf31c51a7aeff4270c9b30b37e019c536d54b2) +Signed-off-by: Stefan Hajnoczi +--- + hw/net/virtio-net.c | 6 +++--- + 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 +--- 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, + VirtIONet *n = qemu_get_nic_opaque(nc); + VirtIONetQueue *q = virtio_net_get_subqueue(nc); + VirtIODevice *vdev = VIRTIO_DEVICE(n); +- VirtQueueElement *elems[VIRTQUEUE_MAX_SIZE]; +- size_t lens[VIRTQUEUE_MAX_SIZE]; +- struct iovec mhdr_sg[VIRTQUEUE_MAX_SIZE]; ++ QEMU_UNINITIALIZED VirtQueueElement *elems[VIRTQUEUE_MAX_SIZE]; ++ QEMU_UNINITIALIZED size_t lens[VIRTQUEUE_MAX_SIZE]; ++ QEMU_UNINITIALIZED struct iovec mhdr_sg[VIRTQUEUE_MAX_SIZE]; + struct virtio_net_hdr_v1_hash extra_hdr; + unsigned mhdr_cnt = 0; + size_t offset, i, guest_offset, j; +-- +2.39.3 + 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 new file mode 100644 index 0000000..027ab99 --- /dev/null +++ b/kvm-hw-net-xgamc-skip-automatic-zero-init-of-large-array.patch @@ -0,0 +1,47 @@ +From 34116b3a243f005938a30e9b38c6f47a62752c3e 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 48/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [22/30] 63536d627705775c4bf72a511de3d68ec30ac7de (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 +array to eliminate the performance overhead in the I/O hot path. + +The 'frame' buffer will be fully initialized when reading guest +memory to fetch the data to send. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-23-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 8b723287b84a62bb5d1a7799ef0959ca8e6c293a) +Signed-off-by: Stefan Hajnoczi +--- + hw/net/xgmac.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c +index ffe3fc8dbe..eff8022aca 100644 +--- a/hw/net/xgmac.c ++++ b/hw/net/xgmac.c +@@ -207,7 +207,7 @@ static void xgmac_enet_send(XgmacState *s) + struct desc bd; + int frame_size; + int len; +- uint8_t frame[8192]; ++ QEMU_UNINITIALIZED uint8_t frame[8192]; + uint8_t *ptr; + + ptr = frame; +-- +2.39.3 + 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 new file mode 100644 index 0000000..6a84a1c --- /dev/null +++ b/kvm-hw-nvme-ctrl-skip-automatic-zero-init-of-large-array.patch @@ -0,0 +1,72 @@ +From 3e0134b45828bf9a623a26ac41d5fbb3a8d2917b 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 49/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [23/30] 57ce4361ffb307be4ea4d3edf9e0dac269d16908 (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 +to eliminate the performance overhead in the I/O hot path. + +The 'segment' array will be fully initialized when reading data from +the device. + +The 'nme_changed_nslist' method has a 4k byte array that is manually +initialized with memset(). The compiler ought to be intelligent +enough to turn the memset() into a static initialization operation, +and thus not duplicate the automatic zero-init. Replacing memset() +with '{}' makes it unambiguous that the array is statically initialized. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Klaus Jensen +Message-id: 20250610123709.835102-24-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 7eeb1d3acc175813ad3d5e824f26123e0992093a) +Signed-off-by: Stefan Hajnoczi +--- + hw/nvme/ctrl.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c +index d451ee0d00..75d7f20801 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, + */ + #define SEG_CHUNK_SIZE 256 + +- NvmeSglDescriptor segment[SEG_CHUNK_SIZE], *sgld, *last_sgld; ++ QEMU_UNINITIALIZED NvmeSglDescriptor segment[SEG_CHUNK_SIZE]; ++ NvmeSglDescriptor *sgld, *last_sgld; + 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, + static uint16_t nvme_changed_nslist(NvmeCtrl *n, uint8_t rae, uint32_t buf_len, + uint64_t off, NvmeRequest *req) + { +- uint32_t nslist[1024]; ++ uint32_t nslist[1024] = {}; + 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, + return NVME_INVALID_FIELD | NVME_DNR; + } + +- memset(nslist, 0x0, sizeof(nslist)); + trans_len = MIN(sizeof(nslist) - off, buf_len); + + while ((nsid = find_first_bit(n->changed_nsids, NVME_CHANGED_NSID_SIZE)) != +-- +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 new file mode 100644 index 0000000..4b12664 --- /dev/null +++ b/kvm-hw-ppc-spapr_tpm_proxy-skip-automatic-zero-init-of-l.patch @@ -0,0 +1,52 @@ +From 4c3fe6e7b88c58713c0c499d4bf0658a055ee52e 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 50/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [24/30] 8d963380c64a33a27adc99738b42b52864229111 (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 +arrays to eliminate the performance overhead in the I/O hot path. + +The two arrays will be fully initialized when reading data from +guest memory or reading data from the proxy FD. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Klaus Jensen +Reviewed-by: Harsh Prateek Bora +Message-id: 20250610123709.835102-26-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 5dd9087fff74b5672526cad254e76f790fb35c7a) +Signed-off-by: Stefan Hajnoczi +--- + hw/ppc/spapr_tpm_proxy.c | 4 ++-- + 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 +--- 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) + target_ulong data_in_size = args[2]; + uint64_t data_out = ppc64_phys_to_real(args[3]); + target_ulong data_out_size = args[4]; +- uint8_t buf_in[TPM_SPAPR_BUFSIZE]; +- uint8_t buf_out[TPM_SPAPR_BUFSIZE]; ++ QEMU_UNINITIALIZED uint8_t buf_in[TPM_SPAPR_BUFSIZE]; ++ QEMU_UNINITIALIZED uint8_t buf_out[TPM_SPAPR_BUFSIZE]; + ssize_t ret; + + trace_spapr_tpm_execute(data_in, data_in_size, data_out, data_out_size); +-- +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..5bf4b1a --- /dev/null +++ b/kvm-hw-s390x-ccw-device-Fix-memory-leak-in-loadparm-sett.patch @@ -0,0 +1,47 @@ +From b25bbfcad4a3df94555f6b5f238910314a5d17ea Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 25 Jun 2025 10:27:51 +0200 +Subject: [PATCH 02/57] 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: 387: s390x: Fix memory leaks related to loadparm [rhel-9] +RH-Jira: RHEL-98554 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Kevin Wolf +RH-Commit: [2/2] d85cf8b3c93ede47b51c4aa1336dc54f58b8cc3f (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 30f2fb486f..63e937401e 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-scsi-lsi53c895a-skip-automatic-zero-init-of-large.patch b/kvm-hw-scsi-lsi53c895a-skip-automatic-zero-init-of-large.patch new file mode 100644 index 0000000..77a1f92 --- /dev/null +++ b/kvm-hw-scsi-lsi53c895a-skip-automatic-zero-init-of-large.patch @@ -0,0 +1,49 @@ +From 45884bfad1f14585407a04eff9230a75bc5095fa 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 52/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [26/30] 235884d43fcb3e49b320e36faa631a3656d07de6 (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 +eliminate the performance overhead in the I/O hot path. + +The 'buf' array will be fully initialized when data is copied. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Klaus Jensen +Reviewed-by: Harsh Prateek Bora +Message-id: 20250610123709.835102-28-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 55243edf42ee87bce9f36ca251f3ab9cda1563e4) +Signed-off-by: Stefan Hajnoczi +--- + hw/scsi/lsi53c895a.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c +index f1935e5328..f165705f8a 100644 +--- a/hw/scsi/lsi53c895a.c ++++ b/hw/scsi/lsi53c895a.c +@@ -1112,7 +1112,7 @@ bad: + static void lsi_memcpy(LSIState *s, uint32_t dest, uint32_t src, int count) + { + int n; +- uint8_t buf[LSI_BUF_SIZE]; ++ QEMU_UNINITIALIZED uint8_t buf[LSI_BUF_SIZE]; + + trace_lsi_memcpy(dest, src, count); + while (count) { +-- +2.39.3 + 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 new file mode 100644 index 0000000..140160c --- /dev/null +++ b/kvm-hw-scsi-megasas-skip-automatic-zero-init-of-large-ar.patch @@ -0,0 +1,73 @@ +From 9f76103e90ce8406bc5bbda72a7314b82e56652e 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 53/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [27/30] b3a3f466fd03c64c665c52e26079b03def376f48 (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. +Skip the automatic zero-init of this array to eliminate the +performance overhead in the I/O hot path. + +The 'info' structs are manually initialized with memset(). The +compiler ought to be intelligent enough to turn the memset() +into a static initialization operation, and thus not duplicate +the automatic zero-init. Replacing memset() with '{}' makes it +unambiguous that the arrays are statically initialized. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Klaus Jensen +Reviewed-by: Harsh Prateek Bora +Message-id: 20250610123709.835102-29-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit ca0559e2350c618048f7caf80cb79c1259e7cfd2) +Signed-off-by: Stefan Hajnoczi +--- + hw/scsi/megasas.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c +index 2d0c607177..91b65accbc 100644 +--- a/hw/scsi/megasas.c ++++ b/hw/scsi/megasas.c +@@ -981,13 +981,11 @@ static int megasas_event_wait(MegasasState *s, MegasasCmd *cmd) + + static int megasas_dcmd_pd_get_list(MegasasState *s, MegasasCmd *cmd) + { +- struct mfi_pd_list info; +- size_t dcmd_size = sizeof(info); ++ struct mfi_pd_list info = {}; + BusChild *kid; + uint32_t offset, dcmd_limit, num_pd_disks = 0, max_pd_disks; + dma_addr_t residual; + +- memset(&info, 0, dcmd_size); + offset = 8; + dcmd_limit = offset + sizeof(struct mfi_pd_address); + if (cmd->iov_size < dcmd_limit) { +@@ -1429,11 +1427,10 @@ static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd) + + static int megasas_dcmd_get_properties(MegasasState *s, MegasasCmd *cmd) + { +- struct mfi_ctrl_props info; ++ struct mfi_ctrl_props info = {}; + size_t dcmd_size = sizeof(info); + dma_addr_t residual; + +- memset(&info, 0x0, dcmd_size); + if (cmd->iov_size < dcmd_size) { + trace_megasas_dcmd_invalid_xfer_len(cmd->index, cmd->iov_size, + dcmd_size); +-- +2.39.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 new file mode 100644 index 0000000..175b89b --- /dev/null +++ b/kvm-hw-ufs-lu-skip-automatic-zero-init-of-large-array.patch @@ -0,0 +1,50 @@ +From 3a0ae5a2f873fc7062262efc24a5403233988f5f 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 54/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [28/30] 62e7c83d15143387f6d6b366c8ec46b312d05577 (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 +this array to eliminate the performance overhead in the I/O hot +path. + +The 'outbuf' array will be fully initialized when data is copied +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-30-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 7708e298180550eac262c1fd742e6e80c711a5d8) +Signed-off-by: Stefan Hajnoczi +--- + hw/ufs/lu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/ufs/lu.c b/hw/ufs/lu.c +index 81bfff9b4e..caad82dcc4 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, + static UfsReqResult ufs_emulate_scsi_cmd(UfsLu *lu, UfsRequest *req) + { + uint8_t lun = lu->lun; +- uint8_t outbuf[4096]; ++ QEMU_UNINITIALIZED uint8_t outbuf[4096]; + uint8_t sense_buf[UFS_SENSE_SIZE]; + uint8_t scsi_status; + int len = 0; +-- +2.39.3 + 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 new file mode 100644 index 0000000..b5daa5b --- /dev/null +++ b/kvm-hw-usb-hcd-ohci-skip-automatic-zero-init-of-large-ar.patch @@ -0,0 +1,50 @@ +From 6d4761010ea4dc218a1623513f410fc2d1cfc832 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 51/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [25/30] 721dd97d384fb755c4a6a00cfc3d867e43f25b0b (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 +array to eliminate the performance overhead in the I/O hot path. + +The 'buf' array will be fully initialized when reading data from guest +memory. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Klaus Jensen +Reviewed-by: Harsh Prateek Bora +Message-id: 20250610123709.835102-27-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 14997d521d1cd0bb36c902ef1032f0d3f2a3c912) +Signed-off-by: Stefan Hajnoczi +--- + hw/usb/hcd-ohci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c +index 71b54914d3..72a9f9f474 100644 +--- a/hw/usb/hcd-ohci.c ++++ b/hw/usb/hcd-ohci.c +@@ -577,7 +577,7 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed) + USBDevice *dev; + USBEndpoint *ep; + USBPacket *pkt; +- uint8_t buf[8192]; ++ QEMU_UNINITIALIZED uint8_t buf[8192]; + bool int_req; + struct ohci_iso_td iso_td; + uint32_t addr; +-- +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 new file mode 100644 index 0000000..e006e88 --- /dev/null +++ b/kvm-hw-virtio-virtio-avoid-cost-of-ftrivial-auto-var-ini.patch @@ -0,0 +1,73 @@ +From 4727c044a09fb8c4fb6d667f26eb55bb6de7554d Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Tue, 10 Jun 2025 13:36:40 +0100 +Subject: [PATCH 28/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [2/30] 1c2cc6292deaaac068f4514439703c22c9ccb300 (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 +used to zero local variables. While this reduces security risks +associated with uninitialized stack data, it introduced a measurable +bottleneck in the virtqueue_split_pop() and virtqueue_packed_pop() +functions. + +These virtqueue functions are in the hot path. They are called for each +element (request) that is popped from a VIRTIO device's virtqueue. Using +__attribute__((uninitialized)) on large stack variables in these +functions improves fio randread bs=4k iodepth=64 performance from 304k +to 332k IOPS (+9%). + +This issue was found using perf-top(1). virtqueue_split_pop() was one of +the top CPU consumers and the "annotate" feature showed that the memory +zeroing instructions at the beginning of the functions were hot. + +Fixes: 7ff9ff039380 ("meson: mitigate against use of uninitialize stack for exploits") +Cc: Daniel P. Berrangé +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Stefan Hajnoczi +Message-id: 20250610123709.835102-3-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit ba2868ce091cd4abe4be6de4b7e44b3be303b352) +Signed-off-by: Stefan Hajnoczi +--- + hw/virtio/virtio.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index 10f24a58dd..7f7b178a50 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) + VirtIODevice *vdev = vq->vdev; + VirtQueueElement *elem = NULL; + unsigned out_num, in_num, elem_entries; +- hwaddr addr[VIRTQUEUE_MAX_SIZE]; +- struct iovec iov[VIRTQUEUE_MAX_SIZE]; ++ hwaddr QEMU_UNINITIALIZED addr[VIRTQUEUE_MAX_SIZE]; ++ struct iovec QEMU_UNINITIALIZED iov[VIRTQUEUE_MAX_SIZE]; + VRingDesc desc; + int rc; + +@@ -1826,8 +1826,8 @@ static void *virtqueue_packed_pop(VirtQueue *vq, size_t sz) + VirtIODevice *vdev = vq->vdev; + VirtQueueElement *elem = NULL; + unsigned out_num, in_num, elem_entries; +- hwaddr addr[VIRTQUEUE_MAX_SIZE]; +- struct iovec iov[VIRTQUEUE_MAX_SIZE]; ++ hwaddr QEMU_UNINITIALIZED addr[VIRTQUEUE_MAX_SIZE]; ++ struct iovec QEMU_UNINITIALIZED iov[VIRTQUEUE_MAX_SIZE]; + VRingPackedDesc desc; + uint16_t id; + int rc; +-- +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 new file mode 100644 index 0000000..a196764 --- /dev/null +++ b/kvm-include-qemu-compiler-add-QEMU_UNINITIALIZED-attribu.patch @@ -0,0 +1,80 @@ +From cf92fd8487195ac45bfbdad15168eaec70f3aaa9 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Tue, 10 Jun 2025 13:36:39 +0100 +Subject: [PATCH 27/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/30] 43c2412d318b6d8e0dcb0b37340640a9d90c3188 (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. + +Use this in cases where there a method in the device I/O path (or other +important hot paths), that has large variables on the stack. A rule of +thumb is that "large" means a method with 4kb data in the local stack +frame. Any variables which are KB in size, should be annotated with this +attribute, to pre-emptively eliminate any potential overhead from the +compiler zero'ing memory. + +Given that this turns off a security hardening feature, when using this +to flag variables, it is important that the code is double-checked to +ensure there is no possible use of uninitialized data in the method. + +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Daniel P. Berrangé +Message-id: 20250610123709.835102-2-berrange@redhat.com +[DB: split off patch & rewrite guidance on when to use the annotation] +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 +--- a/include/qemu/compiler.h ++++ b/include/qemu/compiler.h +@@ -212,6 +212,26 @@ + # define QEMU_USED + #endif + ++/* ++ * Disable -ftrivial-auto-var-init on a local variable. ++ * ++ * Use this in cases where there a method in the device I/O path (or other ++ * important hot paths), that has large variables on the stack. A rule of ++ * thumb is that "large" means a method with 4kb data in the local stack ++ * frame. Any variables which are KB in size, should be annotated with this ++ * attribute, to pre-emptively eliminate any potential overhead from the ++ * compiler's implicit zero'ing of memory. ++ * ++ * Given that this turns off a security hardening feature, when using this ++ * to flag variables, it is important that the code is double-checked to ++ * ensure there is no possible use of uninitialized data in the method. ++ */ ++#if __has_attribute(uninitialized) ++# define QEMU_UNINITIALIZED __attribute__((uninitialized)) ++#else ++# define QEMU_UNINITIALIZED ++#endif ++ + /* + * Ugly CPP trick that is like "defined FOO", but also works in C + * code. Useful to replace #ifdef with "if" statements; assumes +-- +2.39.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..23d927a --- /dev/null +++ b/kvm-io-Fix-partial-struct-copy-in-qio_dns_resolver_looku.patch @@ -0,0 +1,73 @@ +From 4545870823aea92b18a7e747b686b666d08006a4 Mon Sep 17 00:00:00 2001 +From: Juraj Marcin +Date: Wed, 21 May 2025 15:52:30 +0200 +Subject: [PATCH 08/57] 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: 369: util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive +RH-Jira: RHEL-67104 +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/7] 92c8b3e63c22a3ca6e5adc76cac1a9f812034912 (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-67104 + +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-net-socket-skip-automatic-zero-init-of-large-array.patch b/kvm-net-socket-skip-automatic-zero-init-of-large-array.patch new file mode 100644 index 0000000..f5361cf --- /dev/null +++ b/kvm-net-socket-skip-automatic-zero-init-of-large-array.patch @@ -0,0 +1,49 @@ +From 4b9a1a9154467fd65ac2a0a26959d3342d8fcd49 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 55/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [29/30] 645ad4d138d1222ea9bd1b2ac3b84d9ff83e2fa2 (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 +array to eliminate the performance overhead in the I/O hot path. + +The 'buf1' array will be fully initialized when reading data off +the network socket. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Klaus Jensen +Reviewed-by: Harsh Prateek Bora +Message-id: 20250610123709.835102-31-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 751b0e79f1e0e7f88fad2fe2f22595ad03d78859) +Signed-off-by: Stefan Hajnoczi +--- + net/socket.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/socket.c b/net/socket.c +index 8e3702e1f3..784dda686f 100644 +--- a/net/socket.c ++++ b/net/socket.c +@@ -157,7 +157,7 @@ static void net_socket_send(void *opaque) + NetSocketState *s = opaque; + int size; + int ret; +- uint8_t buf1[NET_BUFSIZE]; ++ QEMU_UNINITIALIZED uint8_t buf1[NET_BUFSIZE]; + const uint8_t *buf; + + size = recv(s->fd, buf1, sizeof(buf1), 0); +-- +2.39.3 + 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 new file mode 100644 index 0000000..e9abf3f --- /dev/null +++ b/kvm-net-stream-skip-automatic-zero-init-of-large-array.patch @@ -0,0 +1,49 @@ +From 94310a4168257297e52058d5d6aea4a2d06630c6 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 56/57] 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: 382: Solve -ftrivial-auto-var-init performance regression with QEMU_UNINITIALIZED +RH-Jira: RHEL-99888 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [30/30] 9dfec5c0e6358e3557bf58d66eee8e4ba6e93621 (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 +array to eliminate the performance overhead in the I/O hot path. + +The 'buf1' array will be fully initialized when reading data off +the network socket. + +Signed-off-by: Daniel P. Berrangé +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Klaus Jensen +Reviewed-by: Harsh Prateek Bora +Message-id: 20250610123709.835102-32-berrange@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit 837b87c4c5ba9ac7a255133c6642b8d578272a70) +Signed-off-by: Stefan Hajnoczi +--- + net/stream.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/stream.c b/net/stream.c +index 97e6ec6679..12384ffee5 100644 +--- a/net/stream.c ++++ b/net/stream.c +@@ -148,7 +148,7 @@ static gboolean net_stream_send(QIOChannel *ioc, + NetStreamState *s = data; + int size; + int ret; +- char buf1[NET_BUFSIZE]; ++ QEMU_UNINITIALIZED char buf1[NET_BUFSIZE]; + const char *buf; + + size = qio_channel_read(s->ioc, buf1, sizeof(buf1), NULL); +-- +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..8b2660d --- /dev/null +++ b/kvm-s390x-Fix-leak-in-machine_set_loadparm.patch @@ -0,0 +1,60 @@ +From 4f627e0ae8efb96380070b6a8d50e88c71f40477 Mon Sep 17 00:00:00 2001 +From: Fabiano Rosas +Date: Fri, 9 May 2025 14:49:38 -0300 +Subject: [PATCH 01/57] 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: 387: s390x: Fix memory leaks related to loadparm [rhel-9] +RH-Jira: RHEL-98554 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Kevin Wolf +RH-Commit: [1/2] dadf5b9e187a644e0a8a8c565b1b913ef7f4dcc8 (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 77a1bde71e..fc18ab575f 100644 +--- a/hw/s390x/s390-virtio-ccw.c ++++ b/hw/s390x/s390-virtio-ccw.c +@@ -782,6 +782,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-target-i386-Add-PerfMonV2-feature-bit.patch b/kvm-target-i386-Add-PerfMonV2-feature-bit.patch new file mode 100644 index 0000000..217987d --- /dev/null +++ b/kvm-target-i386-Add-PerfMonV2-feature-bit.patch @@ -0,0 +1,105 @@ +From 1587da0703e72cca8325a20b709280b8df85d066 Mon Sep 17 00:00:00 2001 +From: Sandipan Das +Date: Thu, 24 Oct 2024 17:18:21 -0500 +Subject: [PATCH 16/57] target/i386: Add PerfMonV2 feature bit + +RH-Author: John Allen +RH-MergeRequest: 378: Update EPYC Models and Feature Bits +RH-Jira: RHEL-52649 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [2/8] ec365cf4ac558c6c83f7a957e8df937cb6fbfa27 (johnalle/qemu-kvm-fork) + +CPUID leaf 0x80000022, i.e. ExtPerfMonAndDbg, advertises new performance +monitoring features for AMD processors. Bit 0 of EAX indicates support +for Performance Monitoring Version 2 (PerfMonV2) features. If found to +be set during PMU initialization, the EBX bits can be used to determine +the number of available counters for different PMUs. It also denotes the +availability of global control and status registers. + +Add the required CPUID feature word and feature bit to allow guests to +make use of the PerfMonV2 features. + +Signed-off-by: Sandipan Das +Signed-off-by: Babu Moger +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/a96f00ee2637674c63c61e9fc4dee343ea818053.1729807947.git.babu.moger@amd.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 209b0ac12074341d0093985eb9ad3e7edb252ce5) + +JIRA: https://issues.redhat.com/browse/RHEL-52649 + +Signed-off-by: John Allen +--- + target/i386/cpu.c | 26 ++++++++++++++++++++++++++ + target/i386/cpu.h | 4 ++++ + 2 files changed, 30 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 53069a460c..4546369836 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -1246,6 +1246,22 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + .tcg_features = 0, + .unmigratable_flags = 0, + }, ++ [FEAT_8000_0022_EAX] = { ++ .type = CPUID_FEATURE_WORD, ++ .feat_names = { ++ "perfmon-v2", NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, NULL, ++ }, ++ .cpuid = { .eax = 0x80000022, .reg = R_EAX, }, ++ .tcg_features = 0, ++ .unmigratable_flags = 0, ++ }, + [FEAT_XSAVE] = { + .type = CPUID_FEATURE_WORD, + .feat_names = { +@@ -7096,6 +7112,16 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, + *edx = 0; + } + break; ++ case 0x80000022: ++ *eax = *ebx = *ecx = *edx = 0; ++ /* AMD Extended Performance Monitoring and Debug */ ++ if (kvm_enabled() && cpu->enable_pmu && ++ (env->features[FEAT_8000_0022_EAX] & CPUID_8000_0022_EAX_PERFMON_V2)) { ++ *eax |= CPUID_8000_0022_EAX_PERFMON_V2; ++ *ebx |= kvm_arch_get_supported_cpuid(cs->kvm_state, index, count, ++ R_EBX) & 0xf; ++ } ++ break; + case 0xC0000000: + *eax = env->cpuid_xlevel2; + *ebx = 0; +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 9a16239b8e..cf92a4972c 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -638,6 +638,7 @@ typedef enum FeatureWord { + FEAT_8000_0007_EDX, /* CPUID[8000_0007].EDX */ + FEAT_8000_0008_EBX, /* CPUID[8000_0008].EBX */ + FEAT_8000_0021_EAX, /* CPUID[8000_0021].EAX */ ++ FEAT_8000_0022_EAX, /* CPUID[8000_0022].EAX */ + FEAT_C000_0001_EDX, /* CPUID[C000_0001].EDX */ + FEAT_KVM, /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */ + FEAT_KVM_HINTS, /* CPUID[4000_0001].EDX */ +@@ -1044,6 +1045,9 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); + /* Not vulnerable to SRSO at the user-kernel boundary */ + #define CPUID_8000_0021_EAX_SRSO_USER_KERNEL_NO (1U << 30) + ++/* Performance Monitoring Version 2 */ ++#define CPUID_8000_0022_EAX_PERFMON_V2 (1U << 0) ++ + #define CPUID_XSAVE_XSAVEOPT (1U << 0) + #define CPUID_XSAVE_XSAVEC (1U << 1) + #define CPUID_XSAVE_XGETBV1 (1U << 2) +-- +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..6214232 --- /dev/null +++ b/kvm-target-i386-Add-couple-of-feature-bits-in-CPUID_Fn80.patch @@ -0,0 +1,83 @@ +From 79ac76edecdbbe253ad42385730aac18cdc40bd7 Mon Sep 17 00:00:00 2001 +From: Babu Moger +Date: Fri, 20 Jun 2025 14:54:53 -0500 +Subject: [PATCH 20/57] target/i386: Add couple of feature bits in + CPUID_Fn80000021_EAX + +RH-Author: John Allen +RH-MergeRequest: 378: Update EPYC Models and Feature Bits +RH-Jira: RHEL-52649 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [6/8] c6507eb24fcef271fdd6a234d2c255ef38c4e691 (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 +cates +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 +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-52649 + +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 7d48c51767..2218071fca 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -1233,12 +1233,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, + NULL, NULL, NULL, NULL, + "ibpb-brtype", "srso-no", "srso-user-kernel-no", NULL, + }, +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index cf92a4972c..e513e5f62d 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -1030,12 +1030,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) + /* Selective Branch Predictor Barrier */ + #define CPUID_8000_0021_EAX_SBPB (1U << 27) + /* IBPB includes branch type prediction flushing */ +-- +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..6293b4c --- /dev/null +++ b/kvm-target-i386-Add-support-for-EPYC-Turin-model.patch @@ -0,0 +1,200 @@ +From e0b59a57883faac254cd75cc243fed784ad4975b Mon Sep 17 00:00:00 2001 +From: Babu Moger +Date: Thu, 8 May 2025 14:58:04 -0500 +Subject: [PATCH 22/57] target/i386: Add support for EPYC-Turin model + +RH-Author: John Allen +RH-MergeRequest: 378: Update EPYC Models and Feature Bits +RH-Jira: RHEL-52649 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [8/8] 42e90c7fc6bf858f98ae3a6be35d70b824a7d6bf (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-52649 + +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 2bc2d41259..fdfa183f4d 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -2651,6 +2651,61 @@ static const CPUCaches epyc_genoa_v2_cache_info = { + .share_level = CPU_TOPO_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_TOPO_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_TOPO_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_TOPO_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_TOPO_LEVEL_DIE, ++ }, ++}; ++ + /* The following VMX features are not supported by KVM and are left out in the + * CPU definitions: + * +@@ -5644,6 +5699,89 @@ static const X86CPUDefinition builtin_x86_defs[] = { + { /* end of list */ } + } + }, ++ { ++ .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-Expose-bits-related-to-SRSO-vulnerabilit.patch b/kvm-target-i386-Expose-bits-related-to-SRSO-vulnerabilit.patch new file mode 100644 index 0000000..7c666cf --- /dev/null +++ b/kvm-target-i386-Expose-bits-related-to-SRSO-vulnerabilit.patch @@ -0,0 +1,84 @@ +From 1d667a354613385b1552fdbae91799882776f908 Mon Sep 17 00:00:00 2001 +From: Babu Moger +Date: Thu, 24 Oct 2024 17:18:23 -0500 +Subject: [PATCH 15/57] target/i386: Expose bits related to SRSO vulnerability + +RH-Author: John Allen +RH-MergeRequest: 378: Update EPYC Models and Feature Bits +RH-Jira: RHEL-52649 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/8] 9a6f4126ab023269e8afb3537aaa94ae60228382 (johnalle/qemu-kvm-fork) + +Add following bits related Speculative Return Stack Overflow (SRSO). +Guests can make use of these bits if supported. + +These bits are reported via CPUID Fn8000_0021_EAX. +=================================================================== +Bit Feature Description +=================================================================== +27 SBPB Indicates support for the Selective Branch Predictor Barrier. +28 IBPB_BRTYPE MSR_PRED_CMD[IBPB] flushes all branch type predictions. +29 SRSO_NO Not vulnerable to SRSO. +30 SRSO_USER_KERNEL_NO Not vulnerable to SRSO at the user-kernel boundary. +=================================================================== + +Link: https://www.amd.com/content/dam/amd/en/documents/corporate/cr/speculative-return-stack-overflow-whitepaper.pdf +Link: https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/programmer-references/57238.zip +Signed-off-by: Babu Moger +Link: https://lore.kernel.org/r/dadbd70c38f4e165418d193918a3747bd715c5f4.1729807947.git.babu.moger@amd.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 2ec282b8eaaddf5c136f7566b5f61d80288a2065) + +JIRA: https://issues.redhat.com/browse/RHEL-52649 + +Signed-off-by: John Allen +--- + target/i386/cpu.c | 2 +- + target/i386/cpu.h | 14 +++++++++++--- + 2 files changed, 12 insertions(+), 4 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 0a955b1c45..53069a460c 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -1240,7 +1240,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +- NULL, NULL, NULL, NULL, ++ "ibpb-brtype", "srso-no", "srso-user-kernel-no", NULL, + }, + .cpuid = { .eax = 0x80000021, .reg = R_EAX, }, + .tcg_features = 0, +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 4da9ed5930..9a16239b8e 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -1028,13 +1028,21 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); + #define CPUID_8000_0008_EBX_AMD_PSFD (1U << 28) + + /* Processor ignores nested data breakpoints */ +-#define CPUID_8000_0021_EAX_No_NESTED_DATA_BP (1U << 0) ++#define CPUID_8000_0021_EAX_NO_NESTED_DATA_BP (1U << 0) + /* 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) ++#define CPUID_8000_0021_EAX_NULL_SEL_CLR_BASE (1U << 6) + /* Automatic IBRS */ +-#define CPUID_8000_0021_EAX_AUTO_IBRS (1U << 8) ++#define CPUID_8000_0021_EAX_AUTO_IBRS (1U << 8) ++/* Selective Branch Predictor Barrier */ ++#define CPUID_8000_0021_EAX_SBPB (1U << 27) ++/* IBPB includes branch type prediction flushing */ ++#define CPUID_8000_0021_EAX_IBPB_BRTYPE (1U << 28) ++/* Not vulnerable to Speculative Return Stack Overflow */ ++#define CPUID_8000_0021_EAX_SRSO_NO (1U << 29) ++/* Not vulnerable to SRSO at the user-kernel boundary */ ++#define CPUID_8000_0021_EAX_SRSO_USER_KERNEL_NO (1U << 30) + + #define CPUID_XSAVE_XSAVEOPT (1U << 0) + #define CPUID_XSAVE_XSAVEC (1U << 1) +-- +2.39.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..f5cfccc --- /dev/null +++ b/kvm-target-i386-Update-EPYC-CPU-model-for-Cache-property.patch @@ -0,0 +1,147 @@ +From 4091d13096918dfff5f3a292b43e613ea888ddc1 Mon Sep 17 00:00:00 2001 +From: Babu Moger +Date: Thu, 8 May 2025 14:57:59 -0500 +Subject: [PATCH 17/57] target/i386: Update EPYC CPU model for Cache property, + RAS, SVM feature bits + +RH-Author: John Allen +RH-MergeRequest: 378: Update EPYC Models and Feature Bits +RH-Jira: RHEL-52649 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [3/8] afc52d066ad5f66732b0bb04142e210c52896708 (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-52649 + +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 4546369836..32c575f63b 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -2166,6 +2166,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_TOPO_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_TOPO_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_TOPO_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_TOPO_LEVEL_DIE, ++ }, ++}; ++ + static const CPUCaches epyc_rome_cache_info = { + .l1d_cache = &(CPUCacheInfo) { + .type = DATA_CACHE, +@@ -5059,6 +5113,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..59260d8 --- /dev/null +++ b/kvm-target-i386-Update-EPYC-Genoa-for-Cache-property-per.patch @@ -0,0 +1,167 @@ +From 768e39f40b394eb4524a83857b86e8f7497f4414 Mon Sep 17 00:00:00 2001 +From: Babu Moger +Date: Thu, 8 May 2025 14:58:03 -0500 +Subject: [PATCH 21/57] target/i386: Update EPYC-Genoa for Cache property, + perfmon-v2, RAS and SVM feature bits + +RH-Author: John Allen +RH-MergeRequest: 378: Update EPYC Models and Feature Bits +RH-Jira: RHEL-52649 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [7/8] b144233a1115385a1f792c4454f4511173f753d8 (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-52649 + +Signed-off-by: John Allen +--- + target/i386/cpu.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 79 insertions(+), 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 2218071fca..2bc2d41259 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -2598,6 +2598,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_TOPO_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_TOPO_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_TOPO_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_TOPO_LEVEL_DIE, ++ }, ++}; + /* The following VMX features are not supported by KVM and are left out in the + * CPU definitions: + * +@@ -5530,7 +5583,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { + 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_NO_NESTED_DATA_BP | + CPUID_8000_0021_EAX_LFENCE_ALWAYS_SERIALIZING | + CPUID_8000_0021_EAX_NULL_SEL_CLR_BASE | + CPUID_8000_0021_EAX_AUTO_IBRS, +@@ -5565,6 +5618,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 */ } ++ } + }, + }; + +-- +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..ba143ba --- /dev/null +++ b/kvm-target-i386-Update-EPYC-Milan-CPU-model-for-Cache-pr.patch @@ -0,0 +1,146 @@ +From a2cd6a5aac0ba2bbb50d2ff22b83c8b9d7761028 Mon Sep 17 00:00:00 2001 +From: Babu Moger +Date: Thu, 8 May 2025 14:58:01 -0500 +Subject: [PATCH 19/57] target/i386: Update EPYC-Milan CPU model for Cache + property, RAS, SVM feature bits + +RH-Author: John Allen +RH-MergeRequest: 378: Update EPYC Models and Feature Bits +RH-Jira: RHEL-52649 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [5/8] e9e34ade25cb7be05d40745e1d074c0356d1923f (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-52649 + +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 a73b5bfca4..7d48c51767 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -2490,6 +2490,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_TOPO_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_TOPO_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_TOPO_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_TOPO_LEVEL_DIE, ++ }, ++}; ++ + static const CPUCaches epyc_genoa_cache_info = { + .l1d_cache = &(CPUCacheInfo) { + .type = DATA_CACHE, +@@ -5418,6 +5472,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..82c2cb4 --- /dev/null +++ b/kvm-target-i386-Update-EPYC-Rome-CPU-model-for-Cache-pro.patch @@ -0,0 +1,147 @@ +From dc86ee01fb27b174871ff8be9095ed1a20513772 Mon Sep 17 00:00:00 2001 +From: Babu Moger +Date: Thu, 8 May 2025 14:58:00 -0500 +Subject: [PATCH 18/57] target/i386: Update EPYC-Rome CPU model for Cache + property, RAS, SVM feature bits + +RH-Author: John Allen +RH-MergeRequest: 378: Update EPYC Models and Feature Bits +RH-Jira: RHEL-52649 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [4/8] f23618215eee3c54d9ba52c5b74f5d574c522649 (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-52649 + +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 32c575f63b..a73b5bfca4 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -2328,6 +2328,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_TOPO_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_TOPO_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_TOPO_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_TOPO_LEVEL_DIE, ++ }, ++}; ++ + static const CPUCaches epyc_milan_cache_info = { + .l1d_cache = &(CPUCacheInfo) { + .type = DATA_CACHE, +@@ -5270,6 +5324,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-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..d0787f4 --- /dev/null +++ b/kvm-tests-unit-test-util-sockets-fix-mem-leak-on-error-o.patch @@ -0,0 +1,53 @@ +From 83f09a8c65e1fef416e39d9b0a4ead14ed00601e Mon Sep 17 00:00:00 2001 +From: Matheus Tavares Bernardino +Date: Mon, 26 May 2025 10:20:55 -0700 +Subject: [PATCH 14/57] tests/unit/test-util-sockets: fix mem-leak on error + object + +RH-Author: Juraj Marcin +RH-MergeRequest: 369: util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive +RH-Jira: RHEL-67104 +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina +RH-Commit: [7/7] 31c74f784a26812e5c5898efacda9b4069874ed7 (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-67104 + +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 new file mode 100644 index 0000000..9d30908 --- /dev/null +++ b/kvm-ui-vnc-Update-display-update-interval-when-VM-state-.patch @@ -0,0 +1,97 @@ +From a69b8d66fb515cd55cef2fcaa626c350d761f1a9 Mon Sep 17 00:00:00 2001 +From: Juraj Marcin +Date: Wed, 21 May 2025 17:16:13 +0200 +Subject: [PATCH 57/57] 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: 385: ui/vnc: Update display update interval when VM state changes to RUNNING +RH-Jira: RHEL-100741 +RH-Acked-by: Peter Xu +RH-Acked-by: Marc-André Lureau +RH-Commit: [1/1] 30dd4790a607d646465c18d621073df997e8850b (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. +VNC in such case increases the display update interval by +VNC_REFRESH_INTERVAL_INC (50 ms). The update interval can then grow up +to VNC_REFRESH_INTERVAL_MAX (3000 ms). + +When the machine resumes, it can then take up to 3 seconds for the first +display update. Furthermore, the update interval is then halved with +each display update with changes on the screen. If there are moving +elements on the screen, such as a video, this can be perceived as +freezing and stuttering for few seconds before the movement is smooth +again. + +This patch resolves this issue, by adding a listener to VM state changes +and changing the update interval when the VM state changes to RUNNING. +The update_displaychangelistener() function updates the internal timer, +and the display is refreshed immediately if the timer is expired. + +Signed-off-by: Juraj Marcin +Reviewed-by: Marc-André Lureau +Reviewed-by: Peter Xu +Reviewed-by: Daniel P. Berrangé +Link: https://lore.kernel.org/r/20250521151616.3951178-1-jmarcin@redhat.com +Signed-off-by: Peter Xu + +(cherry picked from commit 0310d594d98b39f9dde79b87fd8b0ad16e7c5459) + +JIRA: https://issues.redhat.com/browse/RHEL-100741 + +Signed-off-by: Juraj Marcin +--- + ui/vnc.c | 12 ++++++++++++ + ui/vnc.h | 2 ++ + 2 files changed, 14 insertions(+) + +diff --git a/ui/vnc.c b/ui/vnc.c +index 5057ec8680..4afc925a18 100644 +--- a/ui/vnc.c ++++ b/ui/vnc.c +@@ -3386,6 +3386,16 @@ static const DisplayChangeListenerOps dcl_ops = { + .dpy_cursor_define = vnc_dpy_cursor_define, + }; + ++static void vmstate_change_handler(void *opaque, bool running, RunState state) ++{ ++ VncDisplay *vd = opaque; ++ ++ if (state != RUN_STATE_RUNNING) { ++ return; ++ } ++ update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE); ++} ++ + void vnc_display_init(const char *id, Error **errp) + { + VncDisplay *vd; +@@ -3422,6 +3432,8 @@ void vnc_display_init(const char *id, Error **errp) + vd->dcl.ops = &dcl_ops; + register_displaychangelistener(&vd->dcl); + vd->kbd = qkbd_state_init(vd->dcl.con); ++ vd->vmstate_handler_entry = qemu_add_vm_change_state_handler( ++ &vmstate_change_handler, vd); + } + + +diff --git a/ui/vnc.h b/ui/vnc.h +index e5fa2efa3e..e9da707dbc 100644 +--- a/ui/vnc.h ++++ b/ui/vnc.h +@@ -186,6 +186,8 @@ struct VncDisplay + #endif + + AudioState *audio_state; ++ ++ VMChangeStateEntry *vmstate_handler_entry; + }; + + typedef struct VncTight { +-- +2.39.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..9c53a87 --- /dev/null +++ b/kvm-util-qemu-sockets-Add-support-for-keep-alive-flag-to.patch @@ -0,0 +1,86 @@ +From 644b9e34d8c764598e663eb983e2d6eca4ed2510 Mon Sep 17 00:00:00 2001 +From: Juraj Marcin +Date: Wed, 21 May 2025 15:52:33 +0200 +Subject: [PATCH 11/57] 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: 369: util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive +RH-Jira: RHEL-67104 +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina +RH-Commit: [4/7] a8ec1996262b2bb657b8fe2e72c9045faee0a64c (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-67104 + +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 631d0c4023..8fc1f86145 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..8839085 --- /dev/null +++ b/kvm-util-qemu-sockets-Introduce-inet-socket-options-cont.patch @@ -0,0 +1,314 @@ +From 3e9458cd71f909474c1dd051f43fd3fbef8d53fd Mon Sep 17 00:00:00 2001 +From: Juraj Marcin +Date: Wed, 21 May 2025 15:52:35 +0200 +Subject: [PATCH 13/57] 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: 369: util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive +RH-Jira: RHEL-67104 +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina +RH-Commit: [6/7] 3861e7874d5952c53a5020c123b3b2e632149008 (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-67104 + +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 5bb2b757c3..c4539b66c5 100644 +--- a/meson.build ++++ b/meson.build +@@ -2581,6 +2581,36 @@ config_host_data.set('HAVE_OPTRESET', + cc.has_header_symbol('getopt.h', 'optreset')) + config_host_data.set('HAVE_IPPROTO_MPTCP', + cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP')) ++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 8017124c74..ef0a137bd2 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; + } +@@ -631,6 +675,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", +@@ -696,6 +758,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..e533fa2 --- /dev/null +++ b/kvm-util-qemu-sockets-Refactor-inet_parse-to-use-QemuOpt.patch @@ -0,0 +1,461 @@ +From d2155b6fe1f200a588dd5e95d7587e96109da989 Mon Sep 17 00:00:00 2001 +From: Juraj Marcin +Date: Wed, 21 May 2025 15:52:34 +0200 +Subject: [PATCH 12/57] 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: 369: util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive +RH-Jira: RHEL-67104 +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina +RH-Commit: [5/7] 7fd97ed112c6259928d94595c2ae23fe1208621e (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-67104 + +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 8fc1f86145..8017124c74 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 +@@ -601,115 +602,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..6b95ffb --- /dev/null +++ b/kvm-util-qemu-sockets-Refactor-setting-client-sockopts-i.patch @@ -0,0 +1,83 @@ +From cc7fbd3aabe3be1e2966472a151dc618be02ac4c Mon Sep 17 00:00:00 2001 +From: Juraj Marcin +Date: Wed, 21 May 2025 15:52:31 +0200 +Subject: [PATCH 09/57] 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: 369: util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive +RH-Jira: RHEL-67104 +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina +RH-Commit: [2/7] b9b258d9a21a31ead1dd4488f1f55f1728fa8b41 (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-67104 + +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 60c44b2b56..2c0e4883ce 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, +@@ -476,16 +492,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..de5c984 --- /dev/null +++ b/kvm-util-qemu-sockets-Refactor-success-and-failure-paths.patch @@ -0,0 +1,141 @@ +From 17af9176a1fff5af0d4c1bf1beb52228f7fc324d Mon Sep 17 00:00:00 2001 +From: Juraj Marcin +Date: Wed, 21 May 2025 15:52:32 +0200 +Subject: [PATCH 10/57] 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: 369: util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive +RH-Jira: RHEL-67104 +RH-Acked-by: Peter Xu +RH-Acked-by: Miroslav Rezanina +RH-Commit: [3/7] 5d5f0e704cdf3454a3c402ea7b130aa42705eb9f (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-67104 + +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 2c0e4883ce..631d0c4023 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/qemu-kvm.spec b/qemu-kvm.spec index bcdf074..6d65530 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -149,7 +149,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \ Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm Version: 9.1.0 -Release: 24%{?rcrel}%{?dist}%{?cc_suffix} +Release: 25%{?rcrel}%{?dist}%{?cc_suffix} # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped # Epoch 15 used for RHEL 8 # Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5) @@ -621,6 +621,120 @@ Patch218: kvm-tests-Add-iotest-mirror-sparse-for-recent-patches.patch # For RHEL-82906 - --migrate-disks-detect-zeroes doesn't take effect for disk migration [rhel-9.7] # For RHEL-83015 - Disk size of target raw image is full allocated when doing mirror with default discard value [rhel-9.7] Patch219: kvm-mirror-Reduce-I-O-when-destination-is-detect-zeroes-.patch +# For RHEL-98554 - [s390x][RHEL9.7.0][virtio_block] there would be memory leak with virtio_blk disks +Patch220: kvm-s390x-Fix-leak-in-machine_set_loadparm.patch +# For RHEL-98554 - [s390x][RHEL9.7.0][virtio_block] there would be memory leak with virtio_blk disks +Patch221: kvm-hw-s390x-ccw-device-Fix-memory-leak-in-loadparm-sett.patch +# For RHEL-66202 - [AMDSERVER 9.6 Feature] qemu: Interrupt Remap support for emulated amd viommu +Patch222: kvm-amd_iommu-Rename-variable-mmio-to-mr_mmio.patch +# For RHEL-66202 - [AMDSERVER 9.6 Feature] qemu: Interrupt Remap support for emulated amd viommu +Patch223: kvm-amd_iommu-Add-support-for-pass-though-mode.patch +# For RHEL-66202 - [AMDSERVER 9.6 Feature] qemu: Interrupt Remap support for emulated amd viommu +Patch224: kvm-amd_iommu-Use-shared-memory-region-for-Interrupt-Rem.patch +# For RHEL-66202 - [AMDSERVER 9.6 Feature] qemu: Interrupt Remap support for emulated amd viommu +Patch225: kvm-amd_iommu-Send-notification-when-invalidate-interrup.patch +# For RHEL-66202 - [AMDSERVER 9.6 Feature] qemu: Interrupt Remap support for emulated amd viommu +Patch226: kvm-amd_iommu-Check-APIC-ID-255-for-XTSup.patch +# For RHEL-67104 - postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S' +Patch227: kvm-io-Fix-partial-struct-copy-in-qio_dns_resolver_looku.patch +# For RHEL-67104 - postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S' +Patch228: kvm-util-qemu-sockets-Refactor-setting-client-sockopts-i.patch +# For RHEL-67104 - postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S' +Patch229: kvm-util-qemu-sockets-Refactor-success-and-failure-paths.patch +# For RHEL-67104 - postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S' +Patch230: kvm-util-qemu-sockets-Add-support-for-keep-alive-flag-to.patch +# For RHEL-67104 - postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S' +Patch231: kvm-util-qemu-sockets-Refactor-inet_parse-to-use-QemuOpt.patch +# For RHEL-67104 - postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S' +Patch232: kvm-util-qemu-sockets-Introduce-inet-socket-options-cont.patch +# For RHEL-67104 - postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S' +Patch233: kvm-tests-unit-test-util-sockets-fix-mem-leak-on-error-o.patch +# For RHEL-52649 - [AMDSERVER 9.6 Feature] Turin: Qemu EPYC-Turin Model +Patch234: kvm-target-i386-Expose-bits-related-to-SRSO-vulnerabilit.patch +# For RHEL-52649 - [AMDSERVER 9.6 Feature] Turin: Qemu EPYC-Turin Model +Patch235: kvm-target-i386-Add-PerfMonV2-feature-bit.patch +# For RHEL-52649 - [AMDSERVER 9.6 Feature] Turin: Qemu EPYC-Turin Model +Patch236: kvm-target-i386-Update-EPYC-CPU-model-for-Cache-property.patch +# For RHEL-52649 - [AMDSERVER 9.6 Feature] Turin: Qemu EPYC-Turin Model +Patch237: kvm-target-i386-Update-EPYC-Rome-CPU-model-for-Cache-pro.patch +# For RHEL-52649 - [AMDSERVER 9.6 Feature] Turin: Qemu EPYC-Turin Model +Patch238: kvm-target-i386-Update-EPYC-Milan-CPU-model-for-Cache-pr.patch +# For RHEL-52649 - [AMDSERVER 9.6 Feature] Turin: Qemu EPYC-Turin Model +Patch239: kvm-target-i386-Add-couple-of-feature-bits-in-CPUID_Fn80.patch +# For RHEL-52649 - [AMDSERVER 9.6 Feature] Turin: Qemu EPYC-Turin Model +Patch240: kvm-target-i386-Update-EPYC-Genoa-for-Cache-property-per.patch +# For RHEL-52649 - [AMDSERVER 9.6 Feature] Turin: Qemu EPYC-Turin Model +Patch241: kvm-target-i386-Add-support-for-EPYC-Turin-model.patch +# For RHEL-70926 - Qemu/amd-iommu: Advertise a suitable device id +Patch242: kvm-hw-i386-amd_iommu-Assign-pci-id-0x1419-for-the-AMD-I.patch +# For RHEL-70925 - Qemu/amd-iommu: Add ability to manually specify the AMDVI-PCI device +Patch243: kvm-hw-i386-amd_iommu-Isolate-AMDVI-PCI-from-amd-iommu-d.patch +# For RHEL-70925 - Qemu/amd-iommu: Add ability to manually specify the AMDVI-PCI device +Patch244: kvm-hw-i386-amd_iommu-Allow-migration-when-explicitly-cr.patch +# For RHEL-70925 - Qemu/amd-iommu: Add ability to manually specify the AMDVI-PCI device +Patch245: kvm-Enable-amd-iommu-device.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch246: kvm-include-qemu-compiler-add-QEMU_UNINITIALIZED-attribu.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch247: kvm-hw-virtio-virtio-avoid-cost-of-ftrivial-auto-var-ini.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch248: kvm-block-skip-automatic-zero-init-of-large-array-in-ioq.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch249: kvm-chardev-char-fd-skip-automatic-zero-init-of-large-ar.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch250: kvm-chardev-char-pty-skip-automatic-zero-init-of-large-a.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch251: kvm-chardev-char-socket-skip-automatic-zero-init-of-larg.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch252: kvm-hw-audio-ac97-skip-automatic-zero-init-of-large-arra.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch253: kvm-hw-audio-cs4231a-skip-automatic-zero-init-of-large-a.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch254: kvm-hw-audio-es1370-skip-automatic-zero-init-of-large-ar.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch255: kvm-hw-audio-gus-skip-automatic-zero-init-of-large-array.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch256: kvm-hw-audio-marvell_88w8618-skip-automatic-zero-init-of.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch257: kvm-hw-audio-sb16-skip-automatic-zero-init-of-large-arra.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch258: kvm-hw-audio-via-ac97-skip-automatic-zero-init-of-large-.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch259: kvm-hw-char-sclpconsole-lm-skip-automatic-zero-init-of-l.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch260: kvm-hw-dma-xlnx_csu_dma-skip-automatic-zero-init-of-larg.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch261: kvm-hw-display-vmware_vga-skip-automatic-zero-init-of-la.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch262: kvm-hw-hyperv-syndbg-skip-automatic-zero-init-of-large-a.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch263: kvm-hw-misc-aspeed_hace-skip-automatic-zero-init-of-larg.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch264: kvm-hw-net-rtl8139-skip-automatic-zero-init-of-large-arr.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch265: kvm-hw-net-tulip-skip-automatic-zero-init-of-large-array.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch266: kvm-hw-net-virtio-net-skip-automatic-zero-init-of-large-.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch267: kvm-hw-net-xgamc-skip-automatic-zero-init-of-large-array.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch268: kvm-hw-nvme-ctrl-skip-automatic-zero-init-of-large-array.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch269: kvm-hw-ppc-spapr_tpm_proxy-skip-automatic-zero-init-of-l.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch270: kvm-hw-usb-hcd-ohci-skip-automatic-zero-init-of-large-ar.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch271: kvm-hw-scsi-lsi53c895a-skip-automatic-zero-init-of-large.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch272: kvm-hw-scsi-megasas-skip-automatic-zero-init-of-large-ar.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch273: kvm-hw-ufs-lu-skip-automatic-zero-init-of-large-array.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch274: kvm-net-socket-skip-automatic-zero-init-of-large-array.patch +# For RHEL-99888 - -ftrivial-auto-var-init=zero reduced performance [rhel-9] +Patch275: kvm-net-stream-skip-automatic-zero-init-of-large-array.patch +# For RHEL-100741 - Video stuck after switchover phase when play one video during migration [rhel-9] +Patch276: kvm-ui-vnc-Update-display-update-interval-when-VM-state-.patch %if %{have_clang} BuildRequires: clang @@ -1696,6 +1810,81 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog +* Tue Jul 08 2025 Miroslav Rezanina - 9.1.0-25 +- kvm-s390x-Fix-leak-in-machine_set_loadparm.patch [RHEL-98554] +- kvm-hw-s390x-ccw-device-Fix-memory-leak-in-loadparm-sett.patch [RHEL-98554] +- kvm-amd_iommu-Rename-variable-mmio-to-mr_mmio.patch [RHEL-66202] +- kvm-amd_iommu-Add-support-for-pass-though-mode.patch [RHEL-66202] +- kvm-amd_iommu-Use-shared-memory-region-for-Interrupt-Rem.patch [RHEL-66202] +- kvm-amd_iommu-Send-notification-when-invalidate-interrup.patch [RHEL-66202] +- kvm-amd_iommu-Check-APIC-ID-255-for-XTSup.patch [RHEL-66202] +- kvm-io-Fix-partial-struct-copy-in-qio_dns_resolver_looku.patch [RHEL-67104] +- kvm-util-qemu-sockets-Refactor-setting-client-sockopts-i.patch [RHEL-67104] +- kvm-util-qemu-sockets-Refactor-success-and-failure-paths.patch [RHEL-67104] +- kvm-util-qemu-sockets-Add-support-for-keep-alive-flag-to.patch [RHEL-67104] +- kvm-util-qemu-sockets-Refactor-inet_parse-to-use-QemuOpt.patch [RHEL-67104] +- kvm-util-qemu-sockets-Introduce-inet-socket-options-cont.patch [RHEL-67104] +- kvm-tests-unit-test-util-sockets-fix-mem-leak-on-error-o.patch [RHEL-67104] +- kvm-target-i386-Expose-bits-related-to-SRSO-vulnerabilit.patch [RHEL-52649] +- kvm-target-i386-Add-PerfMonV2-feature-bit.patch [RHEL-52649] +- kvm-target-i386-Update-EPYC-CPU-model-for-Cache-property.patch [RHEL-52649] +- kvm-target-i386-Update-EPYC-Rome-CPU-model-for-Cache-pro.patch [RHEL-52649] +- kvm-target-i386-Update-EPYC-Milan-CPU-model-for-Cache-pr.patch [RHEL-52649] +- kvm-target-i386-Add-couple-of-feature-bits-in-CPUID_Fn80.patch [RHEL-52649] +- kvm-target-i386-Update-EPYC-Genoa-for-Cache-property-per.patch [RHEL-52649] +- kvm-target-i386-Add-support-for-EPYC-Turin-model.patch [RHEL-52649] +- kvm-hw-i386-amd_iommu-Assign-pci-id-0x1419-for-the-AMD-I.patch [RHEL-70926] +- kvm-hw-i386-amd_iommu-Isolate-AMDVI-PCI-from-amd-iommu-d.patch [RHEL-70925] +- kvm-hw-i386-amd_iommu-Allow-migration-when-explicitly-cr.patch [RHEL-70925] +- kvm-Enable-amd-iommu-device.patch [RHEL-70925] +- kvm-include-qemu-compiler-add-QEMU_UNINITIALIZED-attribu.patch [RHEL-99888] +- kvm-hw-virtio-virtio-avoid-cost-of-ftrivial-auto-var-ini.patch [RHEL-99888] +- kvm-block-skip-automatic-zero-init-of-large-array-in-ioq.patch [RHEL-99888] +- kvm-chardev-char-fd-skip-automatic-zero-init-of-large-ar.patch [RHEL-99888] +- kvm-chardev-char-pty-skip-automatic-zero-init-of-large-a.patch [RHEL-99888] +- kvm-chardev-char-socket-skip-automatic-zero-init-of-larg.patch [RHEL-99888] +- kvm-hw-audio-ac97-skip-automatic-zero-init-of-large-arra.patch [RHEL-99888] +- kvm-hw-audio-cs4231a-skip-automatic-zero-init-of-large-a.patch [RHEL-99888] +- kvm-hw-audio-es1370-skip-automatic-zero-init-of-large-ar.patch [RHEL-99888] +- kvm-hw-audio-gus-skip-automatic-zero-init-of-large-array.patch [RHEL-99888] +- kvm-hw-audio-marvell_88w8618-skip-automatic-zero-init-of.patch [RHEL-99888] +- kvm-hw-audio-sb16-skip-automatic-zero-init-of-large-arra.patch [RHEL-99888] +- kvm-hw-audio-via-ac97-skip-automatic-zero-init-of-large-.patch [RHEL-99888] +- kvm-hw-char-sclpconsole-lm-skip-automatic-zero-init-of-l.patch [RHEL-99888] +- kvm-hw-dma-xlnx_csu_dma-skip-automatic-zero-init-of-larg.patch [RHEL-99888] +- kvm-hw-display-vmware_vga-skip-automatic-zero-init-of-la.patch [RHEL-99888] +- kvm-hw-hyperv-syndbg-skip-automatic-zero-init-of-large-a.patch [RHEL-99888] +- kvm-hw-misc-aspeed_hace-skip-automatic-zero-init-of-larg.patch [RHEL-99888] +- kvm-hw-net-rtl8139-skip-automatic-zero-init-of-large-arr.patch [RHEL-99888] +- kvm-hw-net-tulip-skip-automatic-zero-init-of-large-array.patch [RHEL-99888] +- kvm-hw-net-virtio-net-skip-automatic-zero-init-of-large-.patch [RHEL-99888] +- kvm-hw-net-xgamc-skip-automatic-zero-init-of-large-array.patch [RHEL-99888] +- kvm-hw-nvme-ctrl-skip-automatic-zero-init-of-large-array.patch [RHEL-99888] +- kvm-hw-ppc-spapr_tpm_proxy-skip-automatic-zero-init-of-l.patch [RHEL-99888] +- kvm-hw-usb-hcd-ohci-skip-automatic-zero-init-of-large-ar.patch [RHEL-99888] +- kvm-hw-scsi-lsi53c895a-skip-automatic-zero-init-of-large.patch [RHEL-99888] +- kvm-hw-scsi-megasas-skip-automatic-zero-init-of-large-ar.patch [RHEL-99888] +- kvm-hw-ufs-lu-skip-automatic-zero-init-of-large-array.patch [RHEL-99888] +- kvm-net-socket-skip-automatic-zero-init-of-large-array.patch [RHEL-99888] +- kvm-net-stream-skip-automatic-zero-init-of-large-array.patch [RHEL-99888] +- kvm-ui-vnc-Update-display-update-interval-when-VM-state-.patch [RHEL-100741] +- Resolves: RHEL-98554 + ([s390x][RHEL9.7.0][virtio_block] there would be memory leak with virtio_blk disks) +- Resolves: RHEL-66202 + ([AMDSERVER 9.6 Feature] qemu: Interrupt Remap support for emulated amd viommu) +- Resolves: RHEL-67104 + (postcopy on the destination host can't switch into pause status under the network issue if boot VM with '-S') +- Resolves: RHEL-52649 + ([AMDSERVER 9.6 Feature] Turin: Qemu EPYC-Turin Model) +- Resolves: RHEL-70926 + (Qemu/amd-iommu: Advertise a suitable device id) +- Resolves: RHEL-70925 + (Qemu/amd-iommu: Add ability to manually specify the AMDVI-PCI device) +- Resolves: RHEL-99888 + (-ftrivial-auto-var-init=zero reduced performance [rhel-9]) +- Resolves: RHEL-100741 + (Video stuck after switchover phase when play one video during migration [rhel-9]) + * Mon Jun 16 2025 Jon Maloy - 9.1.0-24 - kvm-s390x-pci-add-support-for-guests-that-request-direct.patch [RHEL-11430] - kvm-s390x-pci-indicate-QEMU-supports-relaxed-translation.patch [RHEL-11430]