* Tue Aug 11 2026 Miroslav Rezanina <mrezanin@redhat.com> - 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)
This commit is contained in:
Miroslav Rezanina 2026-08-11 16:48:19 +02:00
parent 2d2c3aeaac
commit e0cf08c577
5 changed files with 579 additions and 1 deletions

View File

@ -0,0 +1,82 @@
From 22dbe118100e71df437677c58e74b3df6bcf5b6b Mon Sep 17 00:00:00 2001
From: Gavin Shan <gshan@redhat.com>
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 <gshan@redhat.com>
RH-MergeRequest: 512: memory: Make ram device region directly accessible
RH-Jira: VOYAGER-1010
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
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 <gshan@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/r/20260728031731.286666-2-gshan@redhat.com
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit 1efb05224dc2544f27687ad2970082e2a8c0a37d)
Signed-off-by: Gavin Shan <gshan@redhat.com>
---
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

View File

@ -0,0 +1,270 @@
From 8d21a40d17e2fcd9156cc18adb9706a8e694a265 Mon Sep 17 00:00:00 2001
From: Gavin Shan <gshan@redhat.com>
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 <gshan@redhat.com>
RH-MergeRequest: 512: memory: Make ram device region directly accessible
RH-Jira: VOYAGER-1010
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
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
<no more output afterwards, guest becomes frozen here>
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 <jugraham@redhat.com>
Reported-by: Liu Gang <liugang24219@sangfor.com.cn>
Reported-by: Ding Hui <dinghui@sangfor.com.cn>
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
Suggested-by: Peter Xu <peterx@redhat.com>
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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 <peterx@redhat.com>
(cherry picked from commit 9f32b8e9624459856f9b93c04dd56d4f5c66f58a)
Signed-off-by: Gavin Shan <gshan@redhat.com>
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

View File

@ -0,0 +1,143 @@
From 3381c6df9468e50b96233a86e375116f95a91629 Mon Sep 17 00:00:00 2001
From: Gavin Shan <gshan@redhat.com>
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 <gshan@redhat.com>
RH-MergeRequest: 512: memory: Make ram device region directly accessible
RH-Jira: VOYAGER-1010
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
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 <jugraham@redhat.com>
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
Suggested-by: Peter Xu <peterx@redhat.com>
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Link: https://lore.kernel.org/r/20260728031731.286666-4-gshan@redhat.com
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit 4fa94987b760f8a137e8911decf72d363ae1306e)
Signed-off-by: Gavin Shan <gshan@redhat.com>
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

View File

@ -0,0 +1,71 @@
From aac829caec814bb2a65372bd54f15a559ccf3b58 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
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 <None>
RH-MergeRequest: 514: vfio/region: Clarify dma-buf failure messages
RH-Jira: RHEL-224652
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
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 <nicolinc@nvidia.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
(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

View File

@ -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 <mrezanin@redhat.com> - 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 <mrezanin@redhat.com> - 10.1.0-26
- kvm-vfio-region-Clarify-dma-buf-failure-messages.patch [RHEL-224652]
* Thu Aug 06 2026 Miroslav Rezanina <mrezanin@redhat.com> - 10.1.0-25.el10nv.1
- Enable EGM for Voyager-2603 [VOYAGER-1105 VOYAGER-1106]
- Resolves: VOYAGER-1105