diff --git a/0484-system-memory-Use-memmove-for-directly-accessible-re.patch b/0484-system-memory-Use-memmove-for-directly-accessible-re.patch new file mode 100644 index 0000000..03edc12 --- /dev/null +++ b/0484-system-memory-Use-memmove-for-directly-accessible-re.patch @@ -0,0 +1,82 @@ +From 22dbe118100e71df437677c58e74b3df6bcf5b6b Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Wed, 29 Jul 2026 09:57:35 +1000 +Subject: [PATCH 1/4] system/memory: Use memmove() for directly accessible + regions + +RH-Author: Gavin Shan +RH-MergeRequest: 512: memory: Make ram device region directly accessible +RH-Jira: VOYAGER-1010 +RH-Acked-by: Eric Auger +RH-Commit: [1/3] c336d9555d (gwshan/qemu-centos10) + +JIRA: https://redhat.atlassian.net/browse/VOYAGER-1010 +UPSTREAM: no, https://gitlab.com/peterx/qemu.git (branch: next) 1efb05224dc2 + +Similar to what's done in commit 4a73aee88140 ("softmmu: Use memmove in +flatview_write_continue"), there are more sites where the overlapping +source and destination buffer are allowed for the directly accessible +regions. Use memmove() in those sites, listed as below. + + hw/remote/vfio-user-obj.c::vfu_object_mr_rw + include/system/memory.h::address_space_read + system/physmem.c::flatview_read_continue_step + +Signed-off-by: Gavin Shan +Reviewed-by: Peter Maydell +Reviewed-by: Peter Xu +Link: https://lore.kernel.org/r/20260728031731.286666-2-gshan@redhat.com +Signed-off-by: Peter Xu +(cherry picked from commit 1efb05224dc2544f27687ad2970082e2a8c0a37d) +Signed-off-by: Gavin Shan +--- + hw/remote/vfio-user-obj.c | 4 ++-- + include/system/memory.h | 2 +- + system/physmem.c | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c +index ea6165ebdc..494fea565c 100644 +--- a/hw/remote/vfio-user-obj.c ++++ b/hw/remote/vfio-user-obj.c +@@ -368,9 +368,9 @@ static int vfu_object_mr_rw(MemoryRegion *mr, uint8_t *buf, hwaddr offset, + ram_ptr = memory_region_get_ram_ptr(mr); + + if (is_write) { +- memcpy((ram_ptr + offset), buf, size); ++ memmove((ram_ptr + offset), buf, size); + } else { +- memcpy(buf, (ram_ptr + offset), size); ++ memmove(buf, (ram_ptr + offset), size); + } + + return 0; +diff --git a/include/system/memory.h b/include/system/memory.h +index 8e60f03d44..b39ec9a5d3 100644 +--- a/include/system/memory.h ++++ b/include/system/memory.h +@@ -3184,7 +3184,7 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr, + mr = flatview_translate(fv, addr, &addr1, &l, false, attrs); + if (len == l && memory_access_is_direct(mr, false, attrs)) { + ptr = qemu_map_ram_ptr(mr->ram_block, addr1); +- memcpy(buf, ptr, len); ++ memmove(buf, ptr, len); + } else { + result = flatview_read_continue(fv, addr, attrs, buf, len, + addr1, l, mr); +diff --git a/system/physmem.c b/system/physmem.c +index 4a1294f8a0..697e75dad7 100644 +--- a/system/physmem.c ++++ b/system/physmem.c +@@ -3074,7 +3074,7 @@ static MemTxResult flatview_read_continue_step(MemTxAttrs attrs, uint8_t *buf, + uint8_t *ram_ptr = qemu_ram_ptr_length(mr->ram_block, mr_addr, l, + false, false); + +- memcpy(buf, ram_ptr, *l); ++ memmove(buf, ram_ptr, *l); + + return MEMTX_OK; + } +-- +2.52.0 + diff --git a/0485-system-memory-Use-qemu_ram_move-for-directly-accessi.patch b/0485-system-memory-Use-qemu_ram_move-for-directly-accessi.patch new file mode 100644 index 0000000..a174f70 --- /dev/null +++ b/0485-system-memory-Use-qemu_ram_move-for-directly-accessi.patch @@ -0,0 +1,270 @@ +From 8d21a40d17e2fcd9156cc18adb9706a8e694a265 Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Wed, 29 Jul 2026 09:57:35 +1000 +Subject: [PATCH 2/4] system/memory: Use qemu_ram_move() for directly + accessible regions + +RH-Author: Gavin Shan +RH-MergeRequest: 512: memory: Make ram device region directly accessible +RH-Jira: VOYAGER-1010 +RH-Acked-by: Eric Auger +RH-Commit: [2/3] f53487900c (gwshan/qemu-centos10) + +JIRA: https://redhat.atlassian.net/browse/VOYAGER-1010 +UPSTREAM: no, https://gitlab.com/peterx/qemu.git (branch: next) 9f32b8e96244 + +All ram device regions were turned to be indirectly accessible by commit +4a2e242bbb ("memory: Don't use memcpy for ram_device regions"). This leads +to guest hang on attempt to build 'cuda-samples' as reported by Julia. The +guest is started by the following command lines, with GH100 GPU card passed +from the host. + + host$ lspci | grep GH100 + 0009:01:00.0 3D controller: NVIDIA Corporation GH100 [GH200 120GB / 480GB] (rev a1) + host$ /home/sandbox/gavin/qemu.main/build/qemu-system-aarch64 \ + -machine virt,gic-version=host,ras=on,highmem-mmio-size=4T \ + -accel kvm -cpu host -smp cpus=48 -m size=8G \ + -drive file=/home/gavin/sandbox/images/disk.qcow2,if=none,id=d0 \ + -device virtio-blk-pci,id=vb0,bus=pcie.0,drive=d0,num-queues=4 \ + -device vfio-pci-nohotplug,host=0009:01:00.0,bus=pcie.1.0 + : + guest$ cd cuda-samples/build + guest$ make -j 20 clean + guest$ make -j 20 + : + [ 54%] Linking CUDA executable graphMemoryNodes + [ 54%] Built target graphMemoryNodes + + + guest$ qemu-system-aarch64: virtio: bogus descriptor or out of resources + [ 555.814025] virtio_blk virtio0: [vda] new size: 268435456 512-byte logical blocks (137 GB/128 GiB) + +When the GPU's driver (NVidia open driver) is loaded on guest bootup, +the memory blocks residing in the PCI BAR#4 of the GH100 GPU card can +be presented to the guest through memory hot-add. The page cache can +then be allocated from the hot added memory blocks when cuda-samples +is being built. Afterwards, the page cache is sent to QEMU's virtio-blk +device as part of the DMA request, the bounce buffer has to be used to +accomodate the request as the corresponding memory region (MemoryRegion) +is an indirectly accessible ram device region in qemu. However, the max +bounce bufer size is only 4096 bytes by default and that is exhausted +quickly, leading to a reset on the virtio-blk device and frozen guest +eventually. + + QEMU + ==== + virtio_blk_handle_output + virtio_blk_handle_vq + virtio_blk_get_request + virtqueue_pop + virtqueue_split_pop + virtqueue_map_desc + address_space_map + memory_access_is_direct # Return false + memory_region_supports_direct_access + + (qemu) info mtree + memory-region: pci_bridge_pci + 0000000000000000-ffffffffffffffff (prio 0, container): pci_bridge_pci + 0000042000000000-0000043fffffffff (prio 1, i/o): 0009:01:00.0 base BAR 4 + 0000042000000000-0000043fffffffff (prio 0, i/o): 0009:01:00.0 BAR 4 + 0000042000000000-000004379fffffff (prio 0, ramd): 0009:01:00.0 BAR 4 mmaps[0] + +This adds qemu_ram_move() where the aligned and small-sized accesses are +handled by qatomics, and fall back to memmove() otherwise. The memove() +for the directly accessible regions is replaced by qemu_ram_move() so that +the issue covered by commit 4a2e242bbb (MMIO access instructions were +optimized to SSE instructions) is fixed. This makes 'ram_device_mem_ops' +redundant, paving the way to revert that commit to make the ram device +region directly accessible again in the next patch. + +Besides, this also fixes the issue of the unexpected frozen reception on +e1000 NIC in the scenario of DPDK due to the wrong Rx queue full indication +caused by the following memcpy(), which is turned to 3 consective 'strb' +instructions to the same location by glibc-2.24+ for aarch64. With this +applied, the syntax of one-byte store is strictly ensured by a one-byte +qatomic set. + + QEMU + ==== + e1000_receive_iov + pci_dma_write + pci_dma_rw + dma_memory_rw + dma_memory_rw_relaxed + address_space_rw + address_space_write + flatview_write + flatview_write_continue + flatview_write_continue_step + memcpy # 3 consective 'strb' instructions + +Reported-by: Julia Graham +Reported-by: Liu Gang +Reported-by: Ding Hui +Suggested-by: Michael S. Tsirkin +Suggested-by: Peter Xu +Suggested-by: Richard Henderson +Suggested-by: Peter Maydell +Signed-off-by: Gavin Shan +Reviewed-by: Peter Maydell +Link: https://lore.kernel.org/r/20260728031731.286666-3-gshan@redhat.com +[peterx: remove src==dst check, fix doc, enhance comments, per PeterM, add R-b] +Signed-off-by: Peter Xu +(cherry picked from commit 9f32b8e9624459856f9b93c04dd56d4f5c66f58a) +Signed-off-by: Gavin Shan +Conflicts: + include/system/memory.h + Contextual conflict due to missed upstream commit 47b23339a5bb + ("system/memory: Constify various AddressSpace arguments (access)") +--- + hw/remote/vfio-user-obj.c | 4 ++-- + include/system/memory.h | 35 +++++++++++++++++++++++++++- + system/physmem.c | 48 +++++++++++++++++++++++++++++++++++++-- + 3 files changed, 82 insertions(+), 5 deletions(-) + +diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c +index 494fea565c..c56ee70a0d 100644 +--- a/hw/remote/vfio-user-obj.c ++++ b/hw/remote/vfio-user-obj.c +@@ -368,9 +368,9 @@ static int vfu_object_mr_rw(MemoryRegion *mr, uint8_t *buf, hwaddr offset, + ram_ptr = memory_region_get_ram_ptr(mr); + + if (is_write) { +- memmove((ram_ptr + offset), buf, size); ++ qemu_ram_move((ram_ptr + offset), buf, size); + } else { +- memmove(buf, (ram_ptr + offset), size); ++ qemu_ram_move(buf, (ram_ptr + offset), size); + } + + return 0; +diff --git a/include/system/memory.h b/include/system/memory.h +index b39ec9a5d3..351cf1253c 100644 +--- a/include/system/memory.h ++++ b/include/system/memory.h +@@ -3103,6 +3103,39 @@ void address_space_register_map_client(AddressSpace *as, QEMUBH *bh); + void address_space_unregister_map_client(AddressSpace *as, QEMUBH *bh); + + /* Internal functions, part of the implementation of address_space_read. */ ++ ++/** ++ * qemu_ram_move: move data from or to ramblock ++ * ++ * @dst: destination where the data is moved to ++ * @src: source where the data is moved from ++ * @n: length of data to be moved ++ * ++ * Move @n bytes from @src to @dst, the memory areas may overlap. This ++ * provides the same semantics as memmove(), plus an additional stronger ++ * guarantee: if @n is 1, 2 or 4 or 8 bytes, and @src and @dst are both ++ * naturally aligned for that access size, then both the load and the store ++ * will be done as a single atomic access (with the semantics of ++ * qatomic_read() and qatomic_set()). ++ * ++ * This is the underlying function that we use to implement accesses by ++ * a guest vCPU or a device DMA operation to a ram block. The atomic ++ * guarantee is needed for two major cases: (A) When the ram block is ++ * backed by a PCI BAR passed through from a host device (and so it might ++ * be hardware registers that must be accessed exactly once at the right ++ * width); (B) When an emulated device updates a data structure shared in ++ * guest memory with guest software (e.g. a network device's set of tx and ++ * rx descriptor blocks), if a write to memory is accidentally performed ++ * multiple times then it can break the guest code when it busy polls the ++ * guest memory. ++ * ++ * We don't attempt to perform the exact access when it would be unaligned ++ * because this can't be done on all host architectures. Although this is ++ * strictly speaking not doing what would happen on real hardware, we don't ++ * think there are going to be situations where that matters in practice. ++ */ ++void qemu_ram_move(void *dst, const void *src, size_t n); ++ + MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr, + MemTxAttrs attrs, void *buf, hwaddr len); + MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr, +@@ -3184,7 +3217,7 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr, + mr = flatview_translate(fv, addr, &addr1, &l, false, attrs); + if (len == l && memory_access_is_direct(mr, false, attrs)) { + ptr = qemu_map_ram_ptr(mr->ram_block, addr1); +- memmove(buf, ptr, len); ++ qemu_ram_move(buf, ptr, len); + } else { + result = flatview_read_continue(fv, addr, attrs, buf, len, + addr1, l, mr); +diff --git a/system/physmem.c b/system/physmem.c +index 697e75dad7..d88349616e 100644 +--- a/system/physmem.c ++++ b/system/physmem.c +@@ -2869,6 +2869,50 @@ void memory_region_flush_rom_device(MemoryRegion *mr, hwaddr addr, hwaddr size) + invalidate_and_set_dirty(mr, addr, size); + } + ++void qemu_ram_move(void *dst, const void *src, size_t n) ++{ ++ uintptr_t test, len; ++ ++ if (n == 0) { ++ return; ++ } ++ ++ /* ++ * Calculate "the lowest set bit" over @src, @dst and @n, result put ++ * into @len (which guarantees a power-of-two). With that and the ++ * later check (len!=n), it makes sure that we will only do the atomic ++ * ops when: ++ * ++ * (1) @n is a power-of-two ++ * (2) @src and @dst addresses are both aligned to @n ++ */ ++ test = (uintptr_t)src | (uintptr_t)dst | n; ++ len = test & -test; ++ ++ /* Overlapping buffers, unaligned or oversized access */ ++ if (n > 8 || len != n) { ++ memmove(dst, src, n); ++ return; ++ } ++ ++ switch (len) { ++ case 1: ++ qatomic_set((uint8_t *)dst, qatomic_read((uint8_t *)src)); ++ break; ++ case 2: ++ qatomic_set((uint16_t *)dst, qatomic_read((uint16_t *)src)); ++ break; ++ case 4: ++ qatomic_set((uint32_t *)dst, qatomic_read((uint32_t *)src)); ++ break; ++ case 8: ++ qatomic_set((uint64_t *)dst, qatomic_read((uint64_t *)src)); ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++} ++ + int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr) + { + unsigned access_size_max = mr->ops->valid.max_access_size; +@@ -2981,7 +3025,7 @@ static MemTxResult flatview_write_continue_step(MemTxAttrs attrs, + uint8_t *ram_ptr = qemu_ram_ptr_length(mr->ram_block, mr_addr, l, + false, true); + +- memmove(ram_ptr, buf, *l); ++ qemu_ram_move(ram_ptr, buf, *l); + invalidate_and_set_dirty(mr, mr_addr, *l); + + return MEMTX_OK; +@@ -3074,7 +3118,7 @@ static MemTxResult flatview_read_continue_step(MemTxAttrs attrs, uint8_t *buf, + uint8_t *ram_ptr = qemu_ram_ptr_length(mr->ram_block, mr_addr, l, + false, false); + +- memmove(buf, ram_ptr, *l); ++ qemu_ram_move(buf, ram_ptr, *l); + + return MEMTX_OK; + } +-- +2.52.0 + diff --git a/0486-system-memory-Make-ram-device-region-directly-access.patch b/0486-system-memory-Make-ram-device-region-directly-access.patch new file mode 100644 index 0000000..3664745 --- /dev/null +++ b/0486-system-memory-Make-ram-device-region-directly-access.patch @@ -0,0 +1,143 @@ +From 3381c6df9468e50b96233a86e375116f95a91629 Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Wed, 29 Jul 2026 09:57:35 +1000 +Subject: [PATCH 3/4] system/memory: Make ram device region directly accessible + +RH-Author: Gavin Shan +RH-MergeRequest: 512: memory: Make ram device region directly accessible +RH-Jira: VOYAGER-1010 +RH-Acked-by: Eric Auger +RH-Commit: [3/3] 76101a2851 (gwshan/qemu-centos10) + +JIRA: https://redhat.atlassian.net/browse/VOYAGER-1010 +UPSTREAM: no, https://gitlab.com/peterx/qemu.git (branch: next) 4fa94987b760 + +This basically reverts 4a2e242bbb30 ("memory: Don't use memcpy for +ram_device regions") to make ram device region directly accessible +again. With this, the bounce buffer is bypassed in address_space_map() +when a ram device region is involved, potentially avoid to overrun +the (small) bounce buffer. + +Reported-by: Julia Graham +Suggested-by: Michael S. Tsirkin +Suggested-by: Peter Xu +Suggested-by: Richard Henderson +Suggested-by: Peter Maydell +Signed-off-by: Gavin Shan +Reviewed-by: Peter Maydell +Link: https://lore.kernel.org/r/20260728031731.286666-4-gshan@redhat.com +Signed-off-by: Peter Xu +(cherry picked from commit 4fa94987b760f8a137e8911decf72d363ae1306e) +Signed-off-by: Gavin Shan +Conflicts: + system/memory.c + Conflict due to missed upstream commit 5cb466d7ca56 ("memory: Add + internal memory_region_set_ops helper function") and 8fe668d0b492 + ("memory: Shorten memory_region_init_ram_device_ptr and + memory_region_init_rom_device") where MemoryRegion::{ops, opqaue} + of a ram device region are set by memory_region_set_ops() and + memory_region_init_io(). Drop MemoryRegion::{ops, opqaue} for a + ram device region in memory_region_init_ram_device_ptr(), which is + exactly what's done in commit 4a2e242bbb30 ("memory: Don't use memcpy + for ram_device regions"). +--- + include/system/memory.h | 11 ++--------- + system/memory.c | 39 --------------------------------------- + system/trace-events | 2 -- + 3 files changed, 2 insertions(+), 50 deletions(-) + +diff --git a/include/system/memory.h b/include/system/memory.h +index 351cf1253c..161d1944e0 100644 +--- a/include/system/memory.h ++++ b/include/system/memory.h +@@ -3161,15 +3161,8 @@ static inline bool memory_region_supports_direct_access(MemoryRegion *mr) + if (memory_region_is_romd(mr)) { + return true; + } +- if (!memory_region_is_ram(mr)) { +- return false; +- } +- /* +- * RAM DEVICE regions can be accessed directly using memcpy, but it might +- * be MMIO and access using mempy can be wrong (e.g., using instructions not +- * intended for MMIO access). So we treat this as IO. +- */ +- return !memory_region_is_ram_device(mr); ++ ++ return memory_region_is_ram(mr); + } + + static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write, +diff --git a/system/memory.c b/system/memory.c +index bdd53369a9..9bc5413f31 100644 +--- a/system/memory.c ++++ b/system/memory.c +@@ -1360,43 +1360,6 @@ const MemoryRegionOps unassigned_mem_ops = { + .endianness = DEVICE_NATIVE_ENDIAN, + }; + +-static uint64_t memory_region_ram_device_read(void *opaque, +- hwaddr addr, unsigned size) +-{ +- MemoryRegion *mr = opaque; +- uint64_t data = ldn_he_p(mr->ram_block->host + addr, size); +- +- trace_memory_region_ram_device_read(get_cpu_index(), mr, addr, data, size); +- +- return data; +-} +- +-static void memory_region_ram_device_write(void *opaque, hwaddr addr, +- uint64_t data, unsigned size) +-{ +- MemoryRegion *mr = opaque; +- +- trace_memory_region_ram_device_write(get_cpu_index(), mr, addr, data, size); +- +- stn_he_p(mr->ram_block->host + addr, size, data); +-} +- +-static const MemoryRegionOps ram_device_mem_ops = { +- .read = memory_region_ram_device_read, +- .write = memory_region_ram_device_write, +- .endianness = HOST_BIG_ENDIAN ? DEVICE_BIG_ENDIAN : DEVICE_LITTLE_ENDIAN, +- .valid = { +- .min_access_size = 1, +- .max_access_size = 8, +- .unaligned = true, +- }, +- .impl = { +- .min_access_size = 1, +- .max_access_size = 8, +- .unaligned = true, +- }, +-}; +- + bool memory_region_access_valid(MemoryRegion *mr, + hwaddr addr, + unsigned size, +@@ -1711,8 +1674,6 @@ void memory_region_init_ram_device_ptr(MemoryRegion *mr, + mr->ram = true; + mr->terminates = true; + mr->ram_device = true; +- mr->ops = &ram_device_mem_ops; +- mr->opaque = mr; + mr->destructor = memory_region_destructor_ram; + + /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL. */ +diff --git a/system/trace-events b/system/trace-events +index 82856e44f2..eb3e7681ab 100644 +--- a/system/trace-events ++++ b/system/trace-events +@@ -20,8 +20,6 @@ memory_region_ops_read(int cpu_index, void *mr, uint64_t addr, uint64_t value, u + memory_region_ops_write(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size, const char *name) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u name '%s'" + memory_region_subpage_read(int cpu_index, void *mr, uint64_t offset, uint64_t value, unsigned size) "cpu %d mr %p offset 0x%"PRIx64" value 0x%"PRIx64" size %u" + memory_region_subpage_write(int cpu_index, void *mr, uint64_t offset, uint64_t value, unsigned size) "cpu %d mr %p offset 0x%"PRIx64" value 0x%"PRIx64" size %u" +-memory_region_ram_device_read(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u" +-memory_region_ram_device_write(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u" + memory_region_sync_dirty(const char *mr, const char *listener, int global) "mr '%s' listener '%s' synced (global=%d)" + flatview_new(void *view, void *root) "%p (root %p)" + flatview_destroy(void *view, void *root) "%p (root %p)" +-- +2.52.0 + diff --git a/0487-vfio-region-Clarify-dma-buf-failure-messages.patch b/0487-vfio-region-Clarify-dma-buf-failure-messages.patch new file mode 100644 index 0000000..c155a42 --- /dev/null +++ b/0487-vfio-region-Clarify-dma-buf-failure-messages.patch @@ -0,0 +1,71 @@ +From aac829caec814bb2a65372bd54f15a559ccf3b58 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= +Date: Wed, 15 Jul 2026 10:00:00 +0200 +Subject: [PATCH 4/4] vfio/region: Clarify dma-buf failure messages +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Rodolfo Vick +RH-MergeRequest: 514: vfio/region: Clarify dma-buf failure messages +RH-Jira: RHEL-224652 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Eric Auger +RH-Commit: [1/1] 290b4b792bd444608b01bab64514a0e0725e9f89 (rovick1/qemu-kvm) + +The dma-buf failure messages in vfio_region_create_dma_buf() say "PCI +BAR IOMMU mappings may fail", which suggests the BAR is broken. In +practice, only P2P DMA is affected -- normal passthrough uses the mmap +fallback. + +Reword both messages to mention P2P DMA explicitly and clarify that +the mmap fallback is in use. Use warn_report_err_once() at the call +site so per-BAR repetition on mdev devices is suppressed. + +Fixes: dcf1b77e834d ("hw/vfio/region: Create dmabuf for PCI BAR per region") +Cc: Nicolin Chen +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Cédric Le Goater +(cherry picked from commit 4b2e6505d59b7b16c6e15a2494942d00648e8510) + +Patch-name: kvm-vfio-region-Clarify-dma-buf-failure-messages.patch +Patch-id: 480 +Patch-present-in-specfile: True +--- + hw/vfio/region.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/hw/vfio/region.c b/hw/vfio/region.c +index 1e9915fdd3..9258ab6847 100644 +--- a/hw/vfio/region.c ++++ b/hw/vfio/region.c +@@ -316,13 +316,12 @@ static bool vfio_region_create_dma_buf(VFIORegion *region, Error **errp) + ret = vfio_device_get_feature(vbasedev, feature); + if (ret < 0) { + if (ret == -ENOTTY) { +- warn_report_once("VFIO dma-buf not supported in kernel: " +- "PCI BAR IOMMU mappings may fail"); ++ warn_report_once("VFIO dma-buf not supported in kernel, " ++ "using mmap fallback, P2P DMA will not work"); + return true; + } +- /* P2P DMA or exposing device memory use cases are not supported. */ +- error_setg_errno(errp, -ret, "%s: failed to create dma-buf: " +- "PCI BAR IOMMU mappings may fail", ++ error_setg_errno(errp, -ret, "%s: dma-buf unavailable, " ++ "using mmap fallback, P2P DMA will not work", + memory_region_name(region->mem)); + return false; + } +@@ -443,7 +442,7 @@ int vfio_region_mmap(VFIORegion *region) + } + + if (!vfio_region_create_dma_buf(region, &local_err)) { +- error_report_err(local_err); ++ warn_report_err_once(local_err); + } + + return 0; +-- +2.52.0 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 2644889..f271bf6 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -143,7 +143,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \ Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm Version: 10.1.0 -Release: 25%{?rcrel}%{?dist}%{?cc_suffix}.1 +Release: 26%{?rcrel}%{?dist}%{?cc_suffix}.1 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped # Epoch 15 used for RHEL 8 # Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5) @@ -654,6 +654,10 @@ Patch480: 0480-s390x-kvm-clamp-stsi-3.2.2-size.patch Patch481: 0481-s390x-sclp-prevent-re-reading-the-sclp-header.patch Patch482: 0482-s390x-sclpcpi-check-event-length-field-before-readin.patch Patch483: 0483-s390x-css-firm-up-handling-of-chained-TIC-CCWs.patch +Patch484: 0484-system-memory-Use-memmove-for-directly-accessible-re.patch +Patch485: 0485-system-memory-Use-qemu_ram_move-for-directly-accessi.patch +Patch486: 0486-system-memory-Make-ram-device-region-directly-access.patch +Patch487: 0487-vfio-region-Clarify-dma-buf-failure-messages.patch %if %{have_clang} BuildRequires: clang @@ -1736,6 +1740,14 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog +* Tue Aug 11 2026 Miroslav Rezanina - 10.1.0-26el10nv.1 +- memory: Make ram device region directly accessible [VOYAGER-1010] +- Resolves: VOYAGER-1010 + (Guest hang due to exhausted bounce buffer on compiling cuda-samples) + +* Tue Aug 11 2026 Miroslav Rezanina - 10.1.0-26 +- kvm-vfio-region-Clarify-dma-buf-failure-messages.patch [RHEL-224652] + * Thu Aug 06 2026 Miroslav Rezanina - 10.1.0-25.el10nv.1 - Enable EGM for Voyager-2603 [VOYAGER-1105 VOYAGER-1106] - Resolves: VOYAGER-1105