From 44810968cfe22d47a5a6637caf1a23851cdc482c Mon Sep 17 00:00:00 2001 From: yangwencheng Date: Thu, 13 Nov 2025 12:56:54 +0000 Subject: [PATCH] [Hygon] vfio: Fix CSV3 mapping device mmio issue Hygon-SIG: commit none hygon csv: vfio: Fix CSV3 mapping device mmio issue To resolve double memory on CSV3 platform, patch "vfio: Only map shared region for CSV virtual machine" only setup mapping for shared pages, but device's mmio region is not mapped on iommu page table, thus device P2P is inavalable. The patch fixes the issue, the memory region for mmio has ram_device set to true, so we can filter out the mmio region, then setup mapping for the mmio region. Signed-off-by: yangwencheng Signed-off-by: Zhiguang Ni Cc: hygon-arch@list.openanolis.cn --- hw/vfio/common.c | 68 ++++++++++++++++++++++++++++++++++- include/hw/vfio/vfio-common.h | 2 ++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 7cc03a7ef9..15c553e196 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -1220,6 +1220,66 @@ static void vfio_listener_region_del(MemoryListener *listener, } } +static void csv3_vfio_ram_listener_region_add(MemoryListener *listener, + MemoryRegionSection *section) +{ + VFIOContainer *container; + + if (!csv_enabled()) + return; + + container = container_of(listener, VFIOContainer, csv3_ram_listener); + vfio_listener_region_add(&container->listener, section); +} + +static void csv3_vfio_ram_listener_region_del(MemoryListener *listener, + MemoryRegionSection *section) +{ + VFIOContainer *container; + + if (!csv_enabled()) + return; + + container = container_of(listener, VFIOContainer, csv3_ram_listener); + vfio_listener_region_del(&container->listener, section); +} + +static void csv3_vfio_mmio_listener_region_add(MemoryListener *listener, + MemoryRegionSection *section) +{ + VFIOContainer *container; + + if (!csv_enabled() || !memory_region_is_ram_device(section->mr)) + return; + + container = container_of(listener, VFIOContainer, csv3_mmio_listener); + vfio_listener_region_add(&container->listener, section); +} + +static void csv3_vfio_mmio_listener_region_del(MemoryListener *listener, + MemoryRegionSection *section) +{ + VFIOContainer *container; + + if (!csv_enabled() || !memory_region_is_ram_device(section->mr)) + return; + + container = container_of(listener, VFIOContainer, csv3_mmio_listener); + vfio_listener_region_del(&container->listener, section); +} + +const MemoryListener csv3_vfio_ram_listener = { + .name = "csv3-vfio-ram", + .region_add = csv3_vfio_ram_listener_region_add, + .region_del = csv3_vfio_ram_listener_region_del, +}; + +const MemoryListener csv3_vfio_mmio_listener = { + .name = "csv3-vfio-mmio", + .region_add = csv3_vfio_mmio_listener_region_add, + .region_del = csv3_vfio_mmio_listener_region_del, +}; + static void vfio_set_dirty_page_tracking(VFIOContainer *container, bool start) { int ret; @@ -1482,6 +1542,7 @@ static void vfio_listener_release(VFIOContainer *container) { if (csv_enabled()) { shared_memory_listener_unregister(); + memory_listener_unregister(&container->csv3_mmio_listener); } else { memory_listener_unregister(&container->listener); } @@ -2216,7 +2277,12 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, container->listener = vfio_memory_listener; if (csv_enabled()) { - shared_memory_listener_register(&container->listener, container->space->as); + container->csv3_ram_listener = csv3_vfio_ram_listener; + container->csv3_mmio_listener = csv3_vfio_mmio_listener; + shared_memory_listener_register(&container->csv3_ram_listener, + container->space->as); + memory_listener_register(&container->csv3_mmio_listener, + container->space->as); } else { memory_listener_register(&container->listener, container->space->as); } diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index 8af11b0a76..35107f8cea 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -80,6 +80,8 @@ typedef struct VFIOContainer { VFIOAddressSpace *space; int fd; /* /dev/vfio/vfio, empowered by the attached groups */ MemoryListener listener; + MemoryListener csv3_ram_listener; + MemoryListener csv3_mmio_listener; MemoryListener prereg_listener; unsigned iommu_type; Error *error; -- Gitee