>-----Original Message----- >From: Cédric Le Goater <c...@redhat.com> >Subject: Re: [PATCH for-10.1 13/32] vfio: Move VFIOAddressSpace helpers into >container-base.c > >+John > >On 3/20/25 10:36, Duan, Zhenzhong wrote: >> >> >>> -----Original Message----- >>> From: Cédric Le Goater <c...@redhat.com> >>> Subject: [PATCH for-10.1 13/32] vfio: Move VFIOAddressSpace helpers into >>> container-base.c >>> >>> VFIOAddressSpace is a common object used by VFIOContainerBase which is >>> declared in "hw/vfio/vfio-container-base.h". Move the VFIOAddressSpace >>> related services into "container-base.c". >>> >>> While at it, rename : >>> >>> vfio_get_address_space -> vfio_address_space_get >>> vfio_put_address_space -> vfio_address_space_put >>> >>> to better reflect the namespace these routines belong to. >>> >>> Signed-off-by: Cédric Le Goater <c...@redhat.com> >>> --- >>> include/hw/vfio/vfio-common.h | 6 --- >>> include/hw/vfio/vfio-container-base.h | 5 ++ >>> hw/ppc/spapr_pci_vfio.c | 5 +- >>> hw/vfio/common.c | 66 ------------------------- >>> hw/vfio/container-base.c | 69 +++++++++++++++++++++++++++ >>> hw/vfio/container.c | 6 +-- >>> hw/vfio/iommufd.c | 6 +-- >>> hw/vfio/trace-events | 4 +- >>> 8 files changed, 85 insertions(+), 82 deletions(-) >>> >>> diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h >>> index >>> >e23626856e6ff96939a4660f059833f166aa88e9..2ea7f9c6f6e7e752699954ac236 >>> cac0bbe834b39 100644 >>> --- a/include/hw/vfio/vfio-common.h >>> +++ b/include/hw/vfio/vfio-common.h >>> @@ -120,18 +120,12 @@ struct VFIODeviceOps { >>> #define TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO \ >>> TYPE_HOST_IOMMU_DEVICE_IOMMUFD "-vfio" >>> >>> -VFIOAddressSpace *vfio_get_address_space(AddressSpace *as); >>> -void vfio_put_address_space(VFIOAddressSpace *space); >>> -void vfio_address_space_insert(VFIOAddressSpace *space, >>> - VFIOContainerBase *bcontainer); >>> - >>> void vfio_disable_irqindex(VFIODevice *vbasedev, int index); >>> void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index); >>> void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index); >>> bool vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex, >>> int action, int fd, Error **errp); >>> >>> -void vfio_reset_handler(void *opaque); >>> struct vfio_device_info *vfio_get_device_info(int fd); >>> bool vfio_device_is_mdev(VFIODevice *vbasedev); >>> bool vfio_device_hiod_realize(VFIODevice *vbasedev, Error **errp); >>> diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio- >>> container-base.h >>> index >>> >4cff9943ab4861a25d07b5ebd1200509ebfab12d..27668879f5ca77e558a2bda954 >>> 8c8e60afefe794 100644 >>> --- a/include/hw/vfio/vfio-container-base.h >>> +++ b/include/hw/vfio/vfio-container-base.h >>> @@ -71,6 +71,11 @@ typedef struct VFIORamDiscardListener { >>> QLIST_ENTRY(VFIORamDiscardListener) next; >>> } VFIORamDiscardListener; >>> >>> +VFIOAddressSpace *vfio_address_space_get(AddressSpace *as); >>> +void vfio_address_space_put(VFIOAddressSpace *space); >>> +void vfio_address_space_insert(VFIOAddressSpace *space, >>> + VFIOContainerBase *bcontainer); >>> + >>> int vfio_container_dma_map(VFIOContainerBase *bcontainer, >>> hwaddr iova, ram_addr_t size, >>> void *vaddr, bool readonly); >>> diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c >>> index >>> >1722a5bfa3983d42baac558f22410e36eed375f5..e318d0d912f3e90d1289e4bc21 >>> 95bf68418e5206 100644 >>> --- a/hw/ppc/spapr_pci_vfio.c >>> +++ b/hw/ppc/spapr_pci_vfio.c >>> @@ -24,7 +24,6 @@ >>> #include "hw/pci-host/spapr.h" >>> #include "hw/pci/msix.h" >>> #include "hw/pci/pci_device.h" >>> -#include "hw/vfio/vfio-common.h" >>> #include "hw/vfio/vfio-container.h" >>> #include "qemu/error-report.h" >>> #include CONFIG_DEVICES /* CONFIG_VFIO_PCI */ >>> @@ -86,7 +85,7 @@ static int vfio_eeh_container_op(VFIOContainer >*container, >>> uint32_t op) >>> >>> static VFIOContainer *vfio_eeh_as_container(AddressSpace *as) >>> { >>> - VFIOAddressSpace *space = vfio_get_address_space(as); >>> + VFIOAddressSpace *space = vfio_address_space_get(as); >>> VFIOContainerBase *bcontainer = NULL; >>> >>> if (QLIST_EMPTY(&space->containers)) { >>> @@ -106,7 +105,7 @@ static VFIOContainer >>> *vfio_eeh_as_container(AddressSpace *as) >>> } >>> >>> out: >>> - vfio_put_address_space(space); >>> + vfio_address_space_put(space); >>> return container_of(bcontainer, VFIOContainer, bcontainer); >>> } >>> >>> diff --git a/hw/vfio/common.c b/hw/vfio/common.c >>> index >>> >0e3746eddd1c08e98bf57a59d542e158487d346e..08e2494d7c4a9858657724730 >>> b2829290fb3f197 100644 >>> --- a/hw/vfio/common.c >>> +++ b/hw/vfio/common.c >>> @@ -36,7 +36,6 @@ >>> #include "qemu/main-loop.h" >>> #include "qemu/range.h" >>> #include "system/kvm.h" >>> -#include "system/reset.h" >>> #include "system/runstate.h" >>> #include "trace.h" >>> #include "qapi/error.h" >>> @@ -48,8 +47,6 @@ >>> >>> VFIODeviceList vfio_device_list = >>> QLIST_HEAD_INITIALIZER(vfio_device_list); >>> -static QLIST_HEAD(, VFIOAddressSpace) vfio_address_spaces = >>> - QLIST_HEAD_INITIALIZER(vfio_address_spaces); >>> >>> #ifdef CONFIG_KVM >>> /* >>> @@ -1304,24 +1301,6 @@ const MemoryListener vfio_memory_listener = { >>> .log_sync = vfio_listener_log_sync, >>> }; >>> >>> -void vfio_reset_handler(void *opaque) >>> -{ >>> - VFIODevice *vbasedev; >>> - >>> - trace_vfio_reset_handler(); >>> - QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { >>> - if (vbasedev->dev->realized) { >>> - vbasedev->ops->vfio_compute_needs_reset(vbasedev); >>> - } >>> - } >>> - >>> - QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { >>> - if (vbasedev->dev->realized && vbasedev->needs_reset) { >>> - vbasedev->ops->vfio_hot_reset_multi(vbasedev); >>> - } >>> - } >>> -} >>> - >>> int vfio_kvm_device_add_fd(int fd, Error **errp) >>> { >>> #ifdef CONFIG_KVM >>> @@ -1380,51 +1359,6 @@ int vfio_kvm_device_del_fd(int fd, Error **errp) >>> return 0; >>> } >>> >>> -VFIOAddressSpace *vfio_get_address_space(AddressSpace *as) >>> -{ >>> - VFIOAddressSpace *space; >>> - >>> - QLIST_FOREACH(space, &vfio_address_spaces, list) { >>> - if (space->as == as) { >>> - return space; >>> - } >>> - } >>> - >>> - /* No suitable VFIOAddressSpace, create a new one */ >>> - space = g_malloc0(sizeof(*space)); >>> - space->as = as; >>> - QLIST_INIT(&space->containers); >>> - >>> - if (QLIST_EMPTY(&vfio_address_spaces)) { >>> - qemu_register_reset(vfio_reset_handler, NULL); >>> - } >>> - >>> - QLIST_INSERT_HEAD(&vfio_address_spaces, space, list); >>> - >>> - return space; >>> -} >>> - >>> -void vfio_put_address_space(VFIOAddressSpace *space) >>> -{ >>> - if (!QLIST_EMPTY(&space->containers)) { >>> - return; >>> - } >>> - >>> - QLIST_REMOVE(space, list); >>> - g_free(space); >>> - >>> - if (QLIST_EMPTY(&vfio_address_spaces)) { >>> - qemu_unregister_reset(vfio_reset_handler, NULL); >>> - } >>> -} >>> - >>> -void vfio_address_space_insert(VFIOAddressSpace *space, >>> - VFIOContainerBase *bcontainer) >>> -{ >>> - QLIST_INSERT_HEAD(&space->containers, bcontainer, next); >>> - bcontainer->space = space; >>> -} >>> - >>> struct vfio_device_info *vfio_get_device_info(int fd) >>> { >>> struct vfio_device_info *info; >>> diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c >>> index >>> >749a3fd29dd6fc9143f14edf7e4ac6238315fcce..83e83ab9e67de8b004dfaf0067e >>> 4c466a6c88451 100644 >>> --- a/hw/vfio/container-base.c >>> +++ b/hw/vfio/container-base.c >>> @@ -13,7 +13,76 @@ >>> #include "qemu/osdep.h" >>> #include "qapi/error.h" >>> #include "qemu/error-report.h" >>> +#include "system/reset.h" >>> #include "hw/vfio/vfio-container-base.h" >>> +#include "hw/vfio/vfio-common.h" /* for vfio_device_list */ >>> +#include "trace.h" >>> + >>> +static QLIST_HEAD(, VFIOAddressSpace) vfio_address_spaces = >>> + QLIST_HEAD_INITIALIZER(vfio_address_spaces); >>> + >>> +static void vfio_reset_handler(void *opaque) >>> +{ >>> + VFIODevice *vbasedev; >>> + >>> + trace_vfio_reset_handler(); >>> + QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { >>> + if (vbasedev->dev->realized) { >>> + vbasedev->ops->vfio_compute_needs_reset(vbasedev); >>> + } >>> + } >>> + >>> + QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { >>> + if (vbasedev->dev->realized && vbasedev->needs_reset) { >>> + vbasedev->ops->vfio_hot_reset_multi(vbasedev); >>> + } >>> + } >>> +} >> >> This is not an address space scoped function, > >yep. > >AIUI, pass-through devices of a VM are not necessarily in the same >group and we need to scan all groups/address_spaces when the machine >is reset.
Yes, before introducing vfio_device_list, we scan vfio_group_list. > >There use to be a long comment explaining the context but we lost it >along the way. I will add it back : > > /* > * We want to differentiate hot reset of mulitple in-use devices vs hot > reset > * of a single in-use device. VFIO_DEVICE_RESET will already handle the > case > * of doing hot resets when there is only a single device per bus. The > in-use > * here refers to how many VFIODevices are affected. A hot reset that > affects > * multiple devices, but only a single in-use device, means that we can call > * it from our bus ->reset() callback since the extent is effectively a > single > * device. This allows us to make use of it in the hotplug path. When > there > * are multiple in-use devices, we can only trigger the hot reset during a > * system reset and thus from our reset handler. We separate _one vs _multi > * here so that we don't overlap and do a double reset on the system reset > * path where both our reset handler and ->reset() callback are used. > Calling > * _one() will only do a hot reset for the one in-use devices case, calling > * _multi() will do nothing if a _one() would have been sufficient. > */ > >See commit f16f39c3fc97 ("Implement PCI hot reset"). > >> no sure if better to move to helper.c or common.c > >This is a machine scope "helper" calling VFIODevice handlers, may be in >device.c ? Sounds good. Thanks Zhenzhong