From: Alexey Kardashevskiy <aik@ozlabs.ru>
To: qemu-devel@nongnu.org
Cc: Peter Crosthwaite <peter.crosthwaite@xilinx.com>,
Alexey Kardashevskiy <aik@ozlabs.ru>,
Michael Roth <mdroth@linux.vnet.ibm.com>,
Alex Williamson <alex.williamson@redhat.com>,
qemu-ppc@nongnu.org, David Gibson <david@gibson.dropbear.id.au>
Subject: [Qemu-devel] [RFC PATCH qemu 2/4] vfio: Generalize IOMMU memory listener
Date: Mon, 20 Jul 2015 17:46:08 +1000 [thread overview]
Message-ID: <1437378370-6128-3-git-send-email-aik@ozlabs.ru> (raw)
In-Reply-To: <1437378370-6128-1-git-send-email-aik@ozlabs.ru>
At the moment VFIOContainer has an union for per IOMMU type data which
is now an IOMMU memory listener and setup flags. The listener listens
on PCI address space for both Type1 and sPAPR IOMMUs. The setup flags
(@initialized and @error) are only used by Type1 now but the next patch
will use it on sPAPR too.
This introduces VFIOMemoryListener which is wrapper for MemoryListener
and stores a pointer to the container. This allows having multiple
memory listeners for the same container. This replaces Type1 listener
with @iommu_listener.
This moves @initialized and @error out of @iommu_data as these will be
used soon for memory pre-registration.
As there is only release() left in @iommu_data, this moves it to
VFIOContainer and removes @iommu_data and VFIOType1.
This stores @iommu_type in VFIOContainer. The prereg patch will use it
to know whether or not to do proper cleanup.
This should cause no change in behavior.
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
Changes:
v4:
* used to be "vfio: Store IOMMU type in container"
* moved VFIOType1 content to container as it is not IOMMU type specific
---
hw/vfio/common.c | 74 +++++++++++++++++++++++++++----------------
include/hw/vfio/vfio-common.h | 25 +++++++--------
2 files changed, 59 insertions(+), 40 deletions(-)
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 85ee9b0..6eb85c7 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -312,11 +312,10 @@ out:
rcu_read_unlock();
}
-static void vfio_listener_region_add(MemoryListener *listener,
+static void vfio_listener_region_add(VFIOMemoryListener *vlistener,
MemoryRegionSection *section)
{
- VFIOContainer *container = container_of(listener, VFIOContainer,
- iommu_data.type1.listener);
+ VFIOContainer *container = vlistener->container;
hwaddr iova, end;
Int128 llend;
void *vaddr;
@@ -406,9 +405,9 @@ static void vfio_listener_region_add(MemoryListener *listener,
* can gracefully fail. Runtime, there's not much we can do other
* than throw a hardware error.
*/
- if (!container->iommu_data.type1.initialized) {
- if (!container->iommu_data.type1.error) {
- container->iommu_data.type1.error = ret;
+ if (!container->initialized) {
+ if (!container->error) {
+ container->error = ret;
}
} else {
hw_error("vfio: DMA mapping failed, unable to continue");
@@ -416,11 +415,10 @@ static void vfio_listener_region_add(MemoryListener *listener,
}
}
-static void vfio_listener_region_del(MemoryListener *listener,
+static void vfio_listener_region_del(VFIOMemoryListener *vlistener,
MemoryRegionSection *section)
{
- VFIOContainer *container = container_of(listener, VFIOContainer,
- iommu_data.type1.listener);
+ VFIOContainer *container = vlistener->container;
hwaddr iova, end;
int ret;
@@ -478,14 +476,33 @@ static void vfio_listener_region_del(MemoryListener *listener,
}
}
-static const MemoryListener vfio_memory_listener = {
- .region_add = vfio_listener_region_add,
- .region_del = vfio_listener_region_del,
+static void vfio_iommu_listener_region_add(MemoryListener *listener,
+ MemoryRegionSection *section)
+{
+ VFIOMemoryListener *vlistener = container_of(listener, VFIOMemoryListener,
+ listener);
+
+ vfio_listener_region_add(vlistener, section);
+}
+
+
+static void vfio_iommu_listener_region_del(MemoryListener *listener,
+ MemoryRegionSection *section)
+{
+ VFIOMemoryListener *vlistener = container_of(listener, VFIOMemoryListener,
+ listener);
+
+ vfio_listener_region_del(vlistener, section);
+}
+
+static const MemoryListener vfio_iommu_listener = {
+ .region_add = vfio_iommu_listener_region_add,
+ .region_del = vfio_iommu_listener_region_del,
};
static void vfio_listener_release(VFIOContainer *container)
{
- memory_listener_unregister(&container->iommu_data.type1.listener);
+ memory_listener_unregister(&container->iommu_listener.listener);
}
int vfio_mmap_region(Object *obj, VFIORegion *region,
@@ -676,27 +693,28 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as)
goto free_container_exit;
}
- ret = ioctl(fd, VFIO_SET_IOMMU,
- v2 ? VFIO_TYPE1v2_IOMMU : VFIO_TYPE1_IOMMU);
+ container->iommu_type = v2 ? VFIO_TYPE1v2_IOMMU : VFIO_TYPE1_IOMMU;
+ ret = ioctl(fd, VFIO_SET_IOMMU, container->iommu_type);
if (ret) {
error_report("vfio: failed to set iommu for container: %m");
ret = -errno;
goto free_container_exit;
}
- container->iommu_data.type1.listener = vfio_memory_listener;
- container->iommu_data.release = vfio_listener_release;
+ container->iommu_listener.container = container;
+ container->iommu_listener.listener = vfio_iommu_listener;
+ container->release = vfio_listener_release;
- memory_listener_register(&container->iommu_data.type1.listener,
+ memory_listener_register(&container->iommu_listener.listener,
container->space->as);
- if (container->iommu_data.type1.error) {
- ret = container->iommu_data.type1.error;
+ if (container->error) {
+ ret = container->error;
error_report("vfio: memory listener initialization failed for container");
goto listener_release_exit;
}
- container->iommu_data.type1.initialized = true;
+ container->initialized = true;
} else if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_IOMMU)) {
ret = ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &fd);
@@ -705,7 +723,8 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as)
ret = -errno;
goto free_container_exit;
}
- ret = ioctl(fd, VFIO_SET_IOMMU, VFIO_SPAPR_TCE_IOMMU);
+ container->iommu_type = VFIO_SPAPR_TCE_IOMMU;
+ ret = ioctl(fd, VFIO_SET_IOMMU, container->iommu_type);
if (ret) {
error_report("vfio: failed to set iommu for container: %m");
ret = -errno;
@@ -724,10 +743,11 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as)
goto free_container_exit;
}
- container->iommu_data.type1.listener = vfio_memory_listener;
- container->iommu_data.release = vfio_listener_release;
+ container->iommu_listener.container = container;
+ container->iommu_listener.listener = vfio_iommu_listener;
+ container->release = vfio_listener_release;
- memory_listener_register(&container->iommu_data.type1.listener,
+ memory_listener_register(&container->iommu_listener.listener,
container->space->as);
} else {
@@ -774,8 +794,8 @@ static void vfio_disconnect_container(VFIOGroup *group)
VFIOAddressSpace *space = container->space;
VFIOGuestIOMMU *giommu, *tmp;
- if (container->iommu_data.release) {
- container->iommu_data.release(container);
+ if (container->release) {
+ container->release(container);
}
QLIST_REMOVE(container, next);
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 59a321d..a0f9d36 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -62,24 +62,23 @@ typedef struct VFIOAddressSpace {
QLIST_ENTRY(VFIOAddressSpace) list;
} VFIOAddressSpace;
+typedef struct VFIOContainer VFIOContainer;
+
+typedef struct VFIOMemoryListener {
+ struct MemoryListener listener;
+ VFIOContainer *container;
+} VFIOMemoryListener;
+
struct VFIOGroup;
-typedef struct VFIOType1 {
- MemoryListener listener;
- int error;
- bool initialized;
-} VFIOType1;
-
typedef struct VFIOContainer {
VFIOAddressSpace *space;
int fd; /* /dev/vfio/vfio, empowered by the attached groups */
- struct {
- /* enable abstraction to support various iommu backends */
- union {
- VFIOType1 type1;
- };
- void (*release)(struct VFIOContainer *);
- } iommu_data;
+ unsigned iommu_type;
+ int error;
+ bool initialized;
+ VFIOMemoryListener iommu_listener;
+ void (*release)(struct VFIOContainer *);
QLIST_HEAD(, VFIOGuestIOMMU) giommu_list;
QLIST_HEAD(, VFIOGroup) group_list;
QLIST_ENTRY(VFIOContainer) next;
--
2.4.0.rc3.8.gfb3e7d5
next prev parent reply other threads:[~2015-07-20 7:47 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-20 7:46 [Qemu-devel] [RFC PATCH qemu 0/4] vfio: SPAPR IOMMU v2 (memory preregistration support) Alexey Kardashevskiy
2015-07-20 7:46 ` [Qemu-devel] [RFC PATCH qemu 1/4] memory: Add reporting of supported page sizes Alexey Kardashevskiy
2015-07-20 7:46 ` Alexey Kardashevskiy [this message]
2015-07-20 7:46 ` [Qemu-devel] [RFC PATCH qemu 3/4] vfio: Use different page size for different IOMMU types Alexey Kardashevskiy
2015-07-20 7:46 ` [Qemu-devel] [RFC PATCH qemu 4/4] vfio: spapr: Add SPAPR IOMMU v2 support (DMA memory preregistering) Alexey Kardashevskiy
2015-07-29 0:27 ` [Qemu-devel] [RFC PATCH qemu 0/4] vfio: SPAPR IOMMU v2 (memory preregistration support) Alexey Kardashevskiy
2015-08-06 3:16 ` Alexey Kardashevskiy
2015-08-07 20:20 ` Alex Williamson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1437378370-6128-3-git-send-email-aik@ozlabs.ru \
--to=aik@ozlabs.ru \
--cc=alex.williamson@redhat.com \
--cc=david@gibson.dropbear.id.au \
--cc=mdroth@linux.vnet.ibm.com \
--cc=peter.crosthwaite@xilinx.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).