From: John G Johnson <john.g.john...@oracle.com> Signed-off-by: Elena Ufimtseva <elena.ufimts...@oracle.com> Signed-off-by: John G Johnson <john.g.john...@oracle.com> Signed-off-by: Jagannathan Raman <jag.ra...@oracle.com> --- hw/vfio/user.h | 2 ++ hw/vfio/pci.c | 16 ++++++++++ hw/vfio/user.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+)
diff --git a/hw/vfio/user.h b/hw/vfio/user.h index cdbc074579..12106ccb6a 100644 --- a/hw/vfio/user.h +++ b/hw/vfio/user.h @@ -117,4 +117,6 @@ typedef struct VFIOProxy { void vfio_user_recv(void *opaque); void vfio_user_send_reply(VFIOProxy *proxy, char *buf, int ret); +VFIOProxy *vfio_user_connect_dev(char *sockname, Error **errp); +void vfio_user_disconnect(VFIOProxy *proxy); #endif /* VFIO_USER_H */ diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 554b562769..1effdcd5c0 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -3332,16 +3332,32 @@ static void vfio_user_pci_realize(PCIDevice *pdev, Error **errp) { ERRP_GUARD(); VFIOUserPCIDevice *udev = VFIO_USER_PCI(pdev); + VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev); + VFIODevice *vbasedev = &vdev->vbasedev; + VFIOProxy *proxy; + Error *err = NULL; if (!udev->sock_name) { error_setg(errp, "No socket specified"); error_append_hint(errp, "Use -device vfio-user-pci,socket=<name>\n"); return; } + proxy = vfio_user_connect_dev(udev->sock_name, &err); + if (!proxy) { + error_setg(errp, "Remote proxy not found"); + return; + } + vbasedev->proxy = proxy; } static void vfio_user_instance_finalize(Object *obj) { + VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj); + VFIODevice *vbasedev = &vdev->vbasedev; + + vfio_put_device(vdev); + + vfio_user_disconnect(vbasedev->proxy); } static Property vfio_user_pci_dev_properties[] = { diff --git a/hw/vfio/user.c b/hw/vfio/user.c index 021d5540e0..371ee9cd8b 100644 --- a/hw/vfio/user.c +++ b/hw/vfio/user.c @@ -284,3 +284,90 @@ static void vfio_user_send(VFIOProxy *proxy, vfio_user_hdr_t *msg, qemu_mutex_lock_iothread(); } } + +static QLIST_HEAD(, VFIOProxy) vfio_user_sockets = + QLIST_HEAD_INITIALIZER(vfio_user_sockets); + +VFIOProxy *vfio_user_connect_dev(char *sockname, Error **errp) +{ + VFIOProxy *proxy; + struct QIOChannel *ioc; + int sockfd; + + sockfd = unix_connect(sockname, errp); + if (sockfd == -1) { + return NULL; + } + + ioc = qio_channel_new_fd(sockfd, errp); + if (ioc == NULL) { + close(sockfd); + return NULL; + } + qio_channel_set_blocking(ioc, true, NULL); + + proxy = g_malloc0(sizeof(VFIOProxy)); + proxy->sockname = sockname; + proxy->ioc = ioc; + proxy->flags = VFIO_PROXY_CLIENT; + proxy->state = CONNECTED; + qemu_cond_init(&proxy->close_cv); + + if (vfio_user_iothread == NULL) { + vfio_user_iothread = iothread_create("VFIO user", errp); + } + + qemu_mutex_init(&proxy->lock); + QTAILQ_INIT(&proxy->free); + QTAILQ_INIT(&proxy->pending); + QLIST_INSERT_HEAD(&vfio_user_sockets, proxy, next); + + return proxy; +} + +void vfio_user_disconnect(VFIOProxy *proxy) +{ + VFIOUserReply *r1, *r2; + + qemu_mutex_lock(&proxy->lock); + + /* our side is quitting */ + if (proxy->state == CONNECTED) { + vfio_user_shutdown(proxy); + if (!QTAILQ_EMPTY(&proxy->pending)) { + error_printf("vfio_user_disconnect: outstanding requests\n"); + } + } + qio_channel_close(proxy->ioc, NULL); + proxy->state = CLOSING; + + QTAILQ_FOREACH_SAFE(r1, &proxy->pending, next, r2) { + qemu_cond_destroy(&r1->cv); + QTAILQ_REMOVE(&proxy->pending, r1, next); + g_free(r1); + } + QTAILQ_FOREACH_SAFE(r1, &proxy->free, next, r2) { + qemu_cond_destroy(&r1->cv); + QTAILQ_REMOVE(&proxy->free, r1, next); + g_free(r1); + } + + /* drop locks so the iothread can make progress */ + qemu_mutex_unlock_iothread(); + qemu_cond_wait(&proxy->close_cv, &proxy->lock); + + /* we now hold the only ref to proxy */ + qemu_mutex_unlock(&proxy->lock); + qemu_cond_destroy(&proxy->close_cv); + qemu_mutex_destroy(&proxy->lock); + + qemu_mutex_lock_iothread(); + + QLIST_REMOVE(proxy, next); + if (QLIST_EMPTY(&vfio_user_sockets)) { + iothread_destroy(vfio_user_iothread); + vfio_user_iothread = NULL; + } + + g_free(proxy); +} -- 2.25.1