From: David Gibson <david@gibson.dropbear.id.au>
To: alex.williamson@redhat.com, aik@ozlabs.ru
Cc: qemu-devel@nongnu.org, David Gibson <david@gibson.dropbear.id.au>
Subject: [Qemu-devel] [PATCH 3/5] vfio: Associate VFIO groups with DMAContexts
Date: Wed, 24 Apr 2013 22:01:19 +1000 [thread overview]
Message-ID: <1366804881-553-4-git-send-email-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <1366804881-553-1-git-send-email-david@gibson.dropbear.id.au>
The only model so far supported for VFIO passthrough devices is the model
usually used on x86, where all of the guest's RAM is mapped into the
(host) IOMMU and there is no IOMMU visible in the guest. Later, however
we want to also support guest visible IOMMUs.
In order to do that the vfio subsystem needs to know which address space
its devices are supposed to be in. In other words the PCI device's
DMAContext needs to be passed through to vfio. This patch updates the
internal interfaces to do that. So far it doesn't do much with it, except
to verify/enforce that a group is never added to multiple contexts.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
hw/misc/vfio.c | 38 +++++++++++++++++++++++++++-----------
1 file changed, 27 insertions(+), 11 deletions(-)
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index 693a9ff..f77a599 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -116,6 +116,7 @@ enum {
struct VFIOGroup;
typedef struct VFIOContainer {
+ DMAContext *dma;
int fd; /* /dev/vfio/vfio, empowered by the attached groups */
struct {
/* enable abstraction to support various iommu backends */
@@ -2612,13 +2613,19 @@ static int vfio_load_rom(VFIODevice *vdev)
return 0;
}
-static int vfio_connect_container(VFIOGroup *group)
+static int vfio_connect_context(VFIOGroup *group, DMAContext *dma)
{
VFIOContainer *container;
int ret, fd;
if (group->container) {
- return 0;
+ if (group->container->dma == dma) {
+ return 0;
+ } else {
+ error_report("vfio: group %d used in multiple DMA contexts",
+ group->groupid);
+ return -EBUSY;
+ }
}
QLIST_FOREACH(container, &container_list, next) {
@@ -2644,6 +2651,7 @@ static int vfio_connect_container(VFIOGroup *group)
}
container = g_malloc0(sizeof(*container));
+ container->dma = dma;
container->fd = fd;
if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU)) {
@@ -2683,12 +2691,12 @@ static int vfio_connect_container(VFIOGroup *group)
return 0;
}
-static void vfio_disconnect_container(VFIOGroup *group)
+static void vfio_disconnect_context(VFIOGroup *group)
{
VFIOContainer *container = group->container;
if (ioctl(group->fd, VFIO_GROUP_UNSET_CONTAINER, &container->fd)) {
- error_report("vfio: error disconnecting group %d from container",
+ error_report("vfio: error disconnecting group %d from context",
group->groupid);
}
@@ -2700,13 +2708,13 @@ static void vfio_disconnect_container(VFIOGroup *group)
container->iommu_data.release(container);
}
QLIST_REMOVE(container, next);
- DPRINTF("vfio_disconnect_container: close container->fd\n");
+ DPRINTF("vfio_disconnect_context: close container->fd\n");
close(container->fd);
g_free(container);
}
}
-static VFIOGroup *vfio_get_group(int groupid)
+static VFIOGroup *vfio_get_group(int groupid, DMAContext *dma)
{
VFIOGroup *group;
char path[32];
@@ -2714,7 +2722,15 @@ static VFIOGroup *vfio_get_group(int groupid)
QLIST_FOREACH(group, &group_list, next) {
if (group->groupid == groupid) {
- return group;
+ /* Found it. Now is it already in the right context? */
+ assert(group->container);
+ if (group->container->dma == dma) {
+ return group;
+ } else {
+ error_report("vfio: group %d used in multiple DMA contexts",
+ group->groupid);
+ return NULL;
+ }
}
}
@@ -2747,8 +2763,8 @@ static VFIOGroup *vfio_get_group(int groupid)
group->groupid = groupid;
QLIST_INIT(&group->device_list);
- if (vfio_connect_container(group)) {
- error_report("vfio: failed to setup container for group %d", groupid);
+ if (vfio_connect_context(group, dma)) {
+ error_report("vfio: failed to setup context for group %d", groupid);
close(group->fd);
g_free(group);
return NULL;
@@ -2765,7 +2781,7 @@ static void vfio_put_group(VFIOGroup *group)
return;
}
- vfio_disconnect_container(group);
+ vfio_disconnect_context(group);
QLIST_REMOVE(group, next);
DPRINTF("vfio_put_group: close group->fd\n");
close(group->fd);
@@ -2980,7 +2996,7 @@ static int vfio_initfn(PCIDevice *pdev)
DPRINTF("%s(%04x:%02x:%02x.%x) group %d\n", __func__, vdev->host.domain,
vdev->host.bus, vdev->host.slot, vdev->host.function, groupid);
- group = vfio_get_group(groupid);
+ group = vfio_get_group(groupid, pdev->dma);
if (!group) {
error_report("vfio: failed to get group %d", groupid);
return -ENOENT;
--
1.7.10.4
next prev parent reply other threads:[~2013-04-24 12:06 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-24 12:01 [Qemu-devel] [0/5] RFC: Preparations for supporting VFIO with guest IOMMUs David Gibson
2013-04-24 12:01 ` [Qemu-devel] [PATCH 1/5] pci: Simpler implementation of PCI_COMMAND_MASTER bit David Gibson
2013-04-24 12:36 ` Paolo Bonzini
2013-04-24 13:06 ` David Gibson
2013-04-24 12:01 ` [Qemu-devel] [PATCH 2/5] pci: Don't create an address space object for every PCI device David Gibson
2013-04-24 12:34 ` Paolo Bonzini
2013-04-24 13:07 ` David Gibson
2013-04-24 12:01 ` David Gibson [this message]
2013-04-24 12:01 ` [Qemu-devel] [PATCH 4/5] vfio: Move container list to DMAContext David Gibson
2013-04-24 15:12 ` Alex Williamson
2013-04-24 16:33 ` Paolo Bonzini
2013-04-25 6:36 ` David Gibson
2013-04-26 8:44 ` Paolo Bonzini
2013-04-26 8:46 ` Alexey Kardashevskiy
2013-04-26 8:52 ` Paolo Bonzini
2013-04-26 8:56 ` Alexey Kardashevskiy
2013-04-26 9:08 ` Paolo Bonzini
2013-04-25 6:35 ` David Gibson
2013-04-24 12:01 ` [Qemu-devel] [PATCH 5/5] vfio: Only use memory listeners when appropriate David Gibson
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=1366804881-553-4-git-send-email-david@gibson.dropbear.id.au \
--to=david@gibson.dropbear.id.au \
--cc=aik@ozlabs.ru \
--cc=alex.williamson@redhat.com \
--cc=qemu-devel@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).