Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
vfio: Move iommu specific data to a union
This should help in adding support for other archs.  Create a
structure, add it to the union, populate it with map and unmap
function pointers, each of which take a pointer to your structure
as an argument, register that structure with something that will
call it when there's mappings to change.  If you need to free or
unregister, set the release function.  Map and unmap functions can
use container_of to get to the container and thefore the fd to use
to get to the iommu.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
  • Loading branch information
awilliam committed Jul 16, 2012
1 parent f98265e commit 96e6f84
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 7 deletions.
21 changes: 15 additions & 6 deletions hw/vfio_pci.c
Expand Up @@ -1064,7 +1064,8 @@ static bool vfio_listener_skipped_section(MemoryRegionSection *section)
static void vfio_listener_region_add(MemoryListener *listener,
MemoryRegionSection *section)
{
VFIOContainer *container = container_of(listener, VFIOContainer, listener);
VFIOContainer *container = container_of(listener, VFIOContainer,
iommu_data.listener);
target_phys_addr_t iova = section->offset_within_address_space;
ram_addr_t size = section->size;
void *vaddr;
Expand Down Expand Up @@ -1092,7 +1093,8 @@ static void vfio_listener_region_add(MemoryListener *listener,
static void vfio_listener_region_del(MemoryListener *listener,
MemoryRegionSection *section)
{
VFIOContainer *container = container_of(listener, VFIOContainer, listener);
VFIOContainer *container = container_of(listener, VFIOContainer,
iommu_data.listener);
target_phys_addr_t iova = section->offset_within_address_space;
ram_addr_t size = section->size;
int ret;
Expand All @@ -1112,6 +1114,11 @@ static void vfio_listener_region_del(MemoryListener *listener,
}
}

static void vfio_listener_release(VFIOContainer *container)
{
memory_listener_unregister(&container->iommu_data.listener);
}

/*
* Interrupt setup
*/
Expand Down Expand Up @@ -1603,7 +1610,7 @@ static int vfio_connect_container(VFIOGroup *group)
return -1;
}

container->listener = (MemoryListener) {
container->iommu_data.listener = (MemoryListener) {
.begin = vfio_listener_dummy1,
.commit = vfio_listener_dummy1,
.region_add = vfio_listener_region_add,
Expand All @@ -1617,8 +1624,10 @@ static int vfio_connect_container(VFIOGroup *group)
.eventfd_add = vfio_listener_dummy3,
.eventfd_del = vfio_listener_dummy3,
};
container->iommu_data.release = vfio_listener_release;

memory_listener_register(&container->listener, get_system_memory());
memory_listener_register(&container->iommu_data.listener,
get_system_memory());

} else {
error_report("vfio: No available IOMMU models\n");
Expand Down Expand Up @@ -1649,8 +1658,8 @@ static void vfio_disconnect_container(VFIOGroup *group)
group->container = NULL;

if (QLIST_EMPTY(&container->group_list)) {
if (container->listener.begin) {
memory_listener_unregister(&container->listener);
if (container->iommu_data.release) {
container->iommu_data.release(container);
}
QLIST_REMOVE(container, next);
DPRINTF("vfio_disconnect_container: close container->fd\n");
Expand Down
7 changes: 6 additions & 1 deletion hw/vfio_pci.h
Expand Up @@ -56,7 +56,12 @@ struct VFIOGroup;

typedef struct VFIOContainer {
int fd;
MemoryListener listener;
struct {
union {
MemoryListener listener;
};
void (*release)(struct VFIOContainer *);
} iommu_data;
QLIST_HEAD(, VFIOGroup) group_list;
QLIST_ENTRY(VFIOContainer) next;
} VFIOContainer;
Expand Down

0 comments on commit 96e6f84

Please sign in to comment.