[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC 2/3] vfio: support getting VFIOGroup from groupfd
From: |
Tiwei Bie |
Subject: |
[Qemu-devel] [RFC 2/3] vfio: support getting VFIOGroup from groupfd |
Date: |
Mon, 23 Jul 2018 12:59:55 +0800 |
This patch introduces an API to support getting
VFIOGroup from groupfd. This is useful when the
groupfd is opened and shared by another process
via UNIX socket.
Signed-off-by: Tiwei Bie <address@hidden>
---
hw/vfio/common.c | 44 +++++++++++++++++++++++++++++++++++
include/hw/vfio/vfio-common.h | 1 +
2 files changed, 45 insertions(+)
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 52a05532cd..4c19a33dd5 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1279,6 +1279,30 @@ static void vfio_disconnect_container(VFIOGroup *group)
}
}
+static int vfio_groupfd_to_groupid(int groupfd)
+{
+ char *tmp, group_path[PATH_MAX], *group_name;
+ int groupid, len;
+
+ tmp = g_strdup_printf("/proc/self/fd/%d", groupfd);
+ len = readlink(tmp, group_path, sizeof(group_path));
+ g_free(tmp);
+
+ if (len <= 0 || len >= sizeof(group_path)) {
+ return -1;
+ }
+
+ group_path[len] = '\0';
+
+ group_name = g_path_get_basename(group_path);
+ if (sscanf(group_name, "%d", &groupid) != 1) {
+ groupid = -1;
+ }
+ g_free(group_name);
+
+ return groupid;
+}
+
static VFIOGroup *vfio_init_group(int groupfd, int groupid, AddressSpace *as,
Error **errp)
{
@@ -1373,6 +1397,26 @@ VFIOGroup *vfio_get_group(int groupid, AddressSpace *as,
Error **errp)
return group;
}
+VFIOGroup *vfio_get_group_from_fd(int groupfd, AddressSpace *as, Error **errp)
+{
+ VFIOGroup *group;
+ int groupid;
+
+ groupid = vfio_groupfd_to_groupid(groupfd);
+ if (groupid < 0) {
+ error_setg(errp, "failed to get group id from group fd %d",
+ groupfd);
+ return NULL;
+ }
+
+ group = vfio_find_group(groupid, as, errp);
+ if (group) {
+ return group;
+ }
+
+ return vfio_init_group(groupfd, groupid, as, errp);
+}
+
void vfio_put_group(VFIOGroup *group)
{
if (!group || !QLIST_EMPTY(&group->device_list)) {
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index a9036929b2..9bb1068a36 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -170,6 +170,7 @@ void vfio_region_exit(VFIORegion *region);
void vfio_region_finalize(VFIORegion *region);
void vfio_reset_handler(void *opaque);
VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp);
+VFIOGroup *vfio_get_group_from_fd(int groupfd, AddressSpace *as, Error **errp);
void vfio_put_group(VFIOGroup *group);
int vfio_get_device(VFIOGroup *group, const char *name,
VFIODevice *vbasedev, Error **errp);
--
2.18.0