From dfaf2fe816a15f354e7ff797116c065eb5ab4812 Mon Sep 17 00:00:00 2001 From: yangwencheng Date: Thu, 13 Nov 2025 12:56:54 +0000 Subject: [PATCH] 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 | 60 +++++++++++++++++++++++++++ hw/vfio/container.c | 9 +++- include/hw/vfio/vfio-common.h | 2 + include/hw/vfio/vfio-container-base.h | 2 + 4 files changed, 71 insertions(+), 2 deletions(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index c0bc61fdeef..8b86229cde0 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -914,6 +914,66 @@ static void vfio_listener_region_del(MemoryListener *listener, vfio_container_del_section_window(bcontainer, section); } +static void csv3_vfio_ram_listener_region_add(MemoryListener *listener, + MemoryRegionSection *section) +{ + VFIOContainerBase *bcontainer; + + if (!kvm_csv3_enabled()) + return; + + bcontainer = container_of(listener, VFIOContainerBase, csv3_ram_listener); + vfio_listener_region_add(&bcontainer->listener, section); +} + +static void csv3_vfio_ram_listener_region_del(MemoryListener *listener, + MemoryRegionSection *section) +{ + VFIOContainerBase *bcontainer; + + if (!kvm_csv3_enabled()) + return; + + bcontainer = container_of(listener, VFIOContainerBase, csv3_ram_listener); + vfio_listener_region_del(&bcontainer->listener, section); +} + +static void csv3_vfio_mmio_listener_region_add(MemoryListener *listener, + MemoryRegionSection *section) +{ + VFIOContainerBase *bcontainer; + + if (!kvm_csv3_enabled() || !memory_region_is_ram_device(section->mr)) + return; + + bcontainer = container_of(listener, VFIOContainerBase, csv3_mmio_listener); + vfio_listener_region_add(&bcontainer->listener, section); +} + +static void csv3_vfio_mmio_listener_region_del(MemoryListener *listener, + MemoryRegionSection *section) +{ + VFIOContainerBase *bcontainer; + + if (!kvm_csv3_enabled() || !memory_region_is_ram_device(section->mr)) + return; + + bcontainer = container_of(listener, VFIOContainerBase, csv3_mmio_listener); + vfio_listener_region_del(&bcontainer->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, +}; + typedef struct VFIODirtyRanges { hwaddr min32; hwaddr max32; diff --git a/hw/vfio/container.c b/hw/vfio/container.c index 56c55d00f19..edc0daff33d 100644 --- a/hw/vfio/container.c +++ b/hw/vfio/container.c @@ -738,8 +738,12 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, bcontainer->listener = vfio_memory_listener; if (kvm_csv3_enabled()) { - shared_memory_listener_register(&bcontainer->listener, - bcontainer->space->as); + bcontainer->csv3_ram_listener = csv3_vfio_ram_listener; + bcontainer->csv3_mmio_listener = csv3_vfio_mmio_listener; + shared_memory_listener_register(&bcontainer->csv3_ram_listener, + bcontainer->space->as); + memory_listener_register(&bcontainer->csv3_mmio_listener, + bcontainer->space->as); } else { memory_listener_register(&bcontainer->listener, bcontainer->space->as); } @@ -760,6 +764,7 @@ listener_release_exit: vfio_kvm_device_del_group(group); if (kvm_csv3_enabled()) { shared_memory_listener_unregister(); + memory_listener_unregister(&bcontainer->csv3_mmio_listener); } else { memory_listener_unregister(&bcontainer->listener); } diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index a1bf609071a..001a90aeaf6 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -248,6 +248,8 @@ typedef QLIST_HEAD(VFIODeviceList, VFIODevice) VFIODeviceList; extern VFIOGroupList vfio_group_list; extern VFIODeviceList vfio_device_list; extern const MemoryListener vfio_memory_listener; +extern const MemoryListener csv3_vfio_ram_listener; +extern const MemoryListener csv3_vfio_mmio_listener; extern int vfio_kvm_device_fd; bool vfio_mig_active(void); diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h index faed33bf92b..3187f51fcad 100644 --- a/include/hw/vfio/vfio-container-base.h +++ b/include/hw/vfio/vfio-container-base.h @@ -37,6 +37,8 @@ typedef struct VFIOContainerBase { const VFIOIOMMUClass *ops; VFIOAddressSpace *space; MemoryListener listener; + MemoryListener csv3_ram_listener; + MemoryListener csv3_mmio_listener; Error *error; bool initialized; uint64_t dirty_pgsizes; -- Gitee