@samitouri / QOSamiQemu / commits / ff77a51511

system/memory: Make ram device region directly accessible

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>

Gavin Shan committed Jul 28, 2026 at 13:17 UTC ff77a515113f052cc5fc571b6a328142fdfcf220
3 files changed +3 -51
include/system/memory.h
+2 -9
@@ -2718,15 +2718,8 @@ static inline bool memory_region_supports_direct_access(const MemoryRegion *mr)
2718 if (memory_region_is_romd(mr)) {
2719 return true;
2720 }
2721 - if (!memory_region_is_ram(mr)) {
2722 - return false;
2723 - }
2724 - /*
2725 - * RAM DEVICE regions can be accessed directly using memcpy, but it might
2726 - * be MMIO and access using mempy can be wrong (e.g., using instructions not
2727 - * intended for MMIO access). So we treat this as IO.
2728 - */
2729 - return !memory_region_is_ram_device(mr);
2721 +
2722 + return memory_region_is_ram(mr);
2723 }
2724
2725 static inline bool memory_access_is_direct(const MemoryRegion *mr,
system/memory.c
+1 -40
@@ -1364,43 +1364,6 @@ const MemoryRegionOps unassigned_mem_ops = {
1364 .endianness = DEVICE_NATIVE_ENDIAN,
1365 };
1366
1367 -static uint64_t memory_region_ram_device_read(void *opaque,
1368 - hwaddr addr, unsigned size)
1369 -{
1370 - MemoryRegion *mr = opaque;
1371 - uint64_t data = ldn_he_p(mr->ram_block->host + addr, size);
1372 -
1373 - trace_memory_region_ram_device_read(get_cpu_index(), mr, addr, data, size);
1374 -
1375 - return data;
1376 -}
1377 -
1378 -static void memory_region_ram_device_write(void *opaque, hwaddr addr,
1379 - uint64_t data, unsigned size)
1380 -{
1381 - MemoryRegion *mr = opaque;
1382 -
1383 - trace_memory_region_ram_device_write(get_cpu_index(), mr, addr, data, size);
1384 -
1385 - stn_he_p(mr->ram_block->host + addr, size, data);
1386 -}
1387 -
1388 -static const MemoryRegionOps ram_device_mem_ops = {
1389 - .read = memory_region_ram_device_read,
1390 - .write = memory_region_ram_device_write,
1391 - .endianness = HOST_BIG_ENDIAN ? DEVICE_BIG_ENDIAN : DEVICE_LITTLE_ENDIAN,
1392 - .valid = {
1393 - .min_access_size = 1,
1394 - .max_access_size = 8,
1395 - .unaligned = true,
1396 - },
1397 - .impl = {
1398 - .min_access_size = 1,
1399 - .max_access_size = 8,
1400 - .unaligned = true,
1401 - },
1402 -};
1403 -
1367 bool memory_region_access_valid(MemoryRegion *mr,
1368 hwaddr addr,
1369 unsigned size,
@@ -1692,10 +1655,8 @@ void memory_region_init_ram_device_ptr(MemoryRegion *mr, Object *owner,
1655 const char *name, uint64_t size,
1656 void *ptr)
1657 {
1695 - memory_region_init_io(mr, owner, &ram_device_mem_ops, mr, name, size);
1696 - mr->ram = true;
1658 + memory_region_init_ram_ptr(mr, owner, name, size, ptr);
1659 mr->ram_device = true;
1698 - memory_region_set_ram_ptr(mr, size, ptr);
1660 }
1661
1662 void memory_region_init_alias(MemoryRegion *mr, Object *owner,
system/trace-events
-2
@@ -20,8 +20,6 @@ memory_region_ops_read(int cpu_index, void *mr, uint64_t addr, uint64_t value, u
20 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'"
21 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"
22 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"
23 -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"
24 -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"
23 memory_region_sync_dirty(const char *mr, const char *listener, int global) "mr '%s' listener '%s' synced (global=%d)"
24 flatview_new(void *view, void *root) "%p (root %p)"
25 flatview_destroy(void *view, void *root) "%p (root %p)"