Re: [RFC v3 07/19] vfio-user: connect vfio proxy to remote server
> On Nov 19, 2021, at 2:42 PM, Alex Williamson > wrote: > > On Mon, 8 Nov 2021 16:46:35 -0800 > John Johnson wrote: > >> >> >> static void vfio_user_instance_finalize(Object *obj) >> { >> +VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj); >> +VFIODevice *vbasedev = &vdev->vbasedev; >> + >> +vfio_put_device(vdev); > > This looks suspiciously like the initial function in the previous patch > should not have been empty. Thanks, > It can go in the other patch JJ
Re: [RFC v3 07/19] vfio-user: connect vfio proxy to remote server
On Mon, 8 Nov 2021 16:46:35 -0800 John Johnson wrote: > Signed-off-by: John G Johnson > Signed-off-by: Elena Ufimtseva > Signed-off-by: Jagannathan Raman > --- > hw/vfio/user.h| 78 +++ > include/hw/vfio/vfio-common.h | 2 + > hw/vfio/pci.c | 20 + > hw/vfio/user.c| 170 > ++ > MAINTAINERS | 4 + > hw/vfio/meson.build | 1 + > 6 files changed, 275 insertions(+) > create mode 100644 hw/vfio/user.h > create mode 100644 hw/vfio/user.c > > diff --git a/hw/vfio/user.h b/hw/vfio/user.h > new file mode 100644 > index 000..301ef6a > --- /dev/null > +++ b/hw/vfio/user.h > @@ -0,0 +1,78 @@ > +#ifndef VFIO_USER_H > +#define VFIO_USER_H > + > +/* > + * vfio protocol over a UNIX socket. > + * > + * Copyright © 2018, 2021 Oracle and/or its affiliates. > + * > + * This work is licensed under the terms of the GNU GPL, version 2. See > + * the COPYING file in the top-level directory. > + * > + */ > + > +typedef struct { > +int send_fds; > +int recv_fds; > +int *fds; > +} VFIOUserFDs; > + > +enum msg_type { > +VFIO_MSG_NONE, > +VFIO_MSG_ASYNC, > +VFIO_MSG_WAIT, > +VFIO_MSG_NOWAIT, > +VFIO_MSG_REQ, > +}; > + > +typedef struct VFIOUserMsg { > +QTAILQ_ENTRY(VFIOUserMsg) next; > +VFIOUserFDs *fds; > +uint32_t rsize; > +uint32_t id; > +QemuCond cv; > +bool complete; > +enum msg_type type; > +} VFIOUserMsg; > + > + > +enum proxy_state { > +VFIO_PROXY_CONNECTED = 1, > +VFIO_PROXY_ERROR = 2, > +VFIO_PROXY_CLOSING = 3, > +VFIO_PROXY_CLOSED = 4, > +}; > + > +typedef QTAILQ_HEAD(VFIOUserMsgQ, VFIOUserMsg) VFIOUserMsgQ; > + > +typedef struct VFIOProxy { > +QLIST_ENTRY(VFIOProxy) next; > +char *sockname; > +struct QIOChannel *ioc; > +void (*request)(void *opaque, VFIOUserMsg *msg); > +void *req_arg; > +int flags; > +QemuCond close_cv; > +AioContext *ctx; > +QEMUBH *req_bh; > + > +/* > + * above only changed when BQL is held > + * below are protected by per-proxy lock > + */ > +QemuMutex lock; > +VFIOUserMsgQ free; > +VFIOUserMsgQ pending; > +VFIOUserMsgQ incoming; > +VFIOUserMsgQ outgoing; > +VFIOUserMsg *last_nowait; > +enum proxy_state state; > +} VFIOProxy; > + > +/* VFIOProxy flags */ > +#define VFIO_PROXY_CLIENT 0x1 > + > +VFIOProxy *vfio_user_connect_dev(SocketAddress *addr, Error **errp); > +void vfio_user_disconnect(VFIOProxy *proxy); > + > +#endif /* VFIO_USER_H */ > diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h > index c0dbbfb..224dbf8 100644 > --- a/include/hw/vfio/vfio-common.h > +++ b/include/hw/vfio/vfio-common.h > @@ -76,6 +76,7 @@ typedef struct VFIOAddressSpace { > > struct VFIOGroup; > typedef struct VFIOContIO VFIOContIO; > +typedef struct VFIOProxy VFIOProxy; > > typedef struct VFIOContainer { > VFIOAddressSpace *space; > @@ -150,6 +151,7 @@ typedef struct VFIODevice { > Error *migration_blocker; > OnOffAuto pre_copy_dirty_page_tracking; > struct vfio_region_info **regions; > +VFIOProxy *proxy; > } VFIODevice; > > struct VFIODeviceOps { > diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c > index fa3e028..ebfabb1 100644 > --- a/hw/vfio/pci.c > +++ b/hw/vfio/pci.c > @@ -43,6 +43,7 @@ > #include "qapi/error.h" > #include "migration/blocker.h" > #include "migration/qemu-file.h" > +#include "hw/vfio/user.h" > > #define TYPE_VFIO_PCI_NOHOTPLUG "vfio-pci-nohotplug" > > @@ -3476,6 +3477,9 @@ static void vfio_user_pci_realize(PCIDevice *pdev, > Error **errp) > VFIOUserPCIDevice *udev = VFIO_USER_PCI(pdev); > VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev); > VFIODevice *vbasedev = &vdev->vbasedev; > +SocketAddress addr; > +VFIOProxy *proxy; > +Error *err = NULL; > > /* > * TODO: make option parser understand SocketAddress > @@ -3488,6 +3492,16 @@ static void vfio_user_pci_realize(PCIDevice *pdev, > Error **errp) > return; > } > > +memset(&addr, 0, sizeof(addr)); > +addr.type = SOCKET_ADDRESS_TYPE_UNIX; > +addr.u.q_unix.path = udev->sock_name; > +proxy = vfio_user_connect_dev(&addr, &err); > +if (!proxy) { > +error_setg(errp, "Remote proxy not found"); > +return; > +} > +vbasedev->proxy = proxy; > + > vbasedev->name = g_strdup_printf("VFIO user <%s>", udev->sock_name); > vbasedev->dev = DEVICE(vdev); > vbasedev->fd = -1; > @@ -3500,6 +3514,12 @@ static void vfio_user_pci_realize(PCIDevice *pdev, > Error **errp) > > static void vfio_user_instance_finalize(Object *obj) > { > +VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj); > +VFIODevice *vbasedev = &vdev->vbasedev; > + > +vfio_put_device(vdev); This looks suspiciously like the initial function in the previous patch should not have been empty. Thanks, Alex > + > +vfio_user
[RFC v3 07/19] vfio-user: connect vfio proxy to remote server
Signed-off-by: John G Johnson Signed-off-by: Elena Ufimtseva Signed-off-by: Jagannathan Raman --- hw/vfio/user.h| 78 +++ include/hw/vfio/vfio-common.h | 2 + hw/vfio/pci.c | 20 + hw/vfio/user.c| 170 ++ MAINTAINERS | 4 + hw/vfio/meson.build | 1 + 6 files changed, 275 insertions(+) create mode 100644 hw/vfio/user.h create mode 100644 hw/vfio/user.c diff --git a/hw/vfio/user.h b/hw/vfio/user.h new file mode 100644 index 000..301ef6a --- /dev/null +++ b/hw/vfio/user.h @@ -0,0 +1,78 @@ +#ifndef VFIO_USER_H +#define VFIO_USER_H + +/* + * vfio protocol over a UNIX socket. + * + * Copyright © 2018, 2021 Oracle and/or its affiliates. + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +typedef struct { +int send_fds; +int recv_fds; +int *fds; +} VFIOUserFDs; + +enum msg_type { +VFIO_MSG_NONE, +VFIO_MSG_ASYNC, +VFIO_MSG_WAIT, +VFIO_MSG_NOWAIT, +VFIO_MSG_REQ, +}; + +typedef struct VFIOUserMsg { +QTAILQ_ENTRY(VFIOUserMsg) next; +VFIOUserFDs *fds; +uint32_t rsize; +uint32_t id; +QemuCond cv; +bool complete; +enum msg_type type; +} VFIOUserMsg; + + +enum proxy_state { +VFIO_PROXY_CONNECTED = 1, +VFIO_PROXY_ERROR = 2, +VFIO_PROXY_CLOSING = 3, +VFIO_PROXY_CLOSED = 4, +}; + +typedef QTAILQ_HEAD(VFIOUserMsgQ, VFIOUserMsg) VFIOUserMsgQ; + +typedef struct VFIOProxy { +QLIST_ENTRY(VFIOProxy) next; +char *sockname; +struct QIOChannel *ioc; +void (*request)(void *opaque, VFIOUserMsg *msg); +void *req_arg; +int flags; +QemuCond close_cv; +AioContext *ctx; +QEMUBH *req_bh; + +/* + * above only changed when BQL is held + * below are protected by per-proxy lock + */ +QemuMutex lock; +VFIOUserMsgQ free; +VFIOUserMsgQ pending; +VFIOUserMsgQ incoming; +VFIOUserMsgQ outgoing; +VFIOUserMsg *last_nowait; +enum proxy_state state; +} VFIOProxy; + +/* VFIOProxy flags */ +#define VFIO_PROXY_CLIENT 0x1 + +VFIOProxy *vfio_user_connect_dev(SocketAddress *addr, Error **errp); +void vfio_user_disconnect(VFIOProxy *proxy); + +#endif /* VFIO_USER_H */ diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index c0dbbfb..224dbf8 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -76,6 +76,7 @@ typedef struct VFIOAddressSpace { struct VFIOGroup; typedef struct VFIOContIO VFIOContIO; +typedef struct VFIOProxy VFIOProxy; typedef struct VFIOContainer { VFIOAddressSpace *space; @@ -150,6 +151,7 @@ typedef struct VFIODevice { Error *migration_blocker; OnOffAuto pre_copy_dirty_page_tracking; struct vfio_region_info **regions; +VFIOProxy *proxy; } VFIODevice; struct VFIODeviceOps { diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index fa3e028..ebfabb1 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -43,6 +43,7 @@ #include "qapi/error.h" #include "migration/blocker.h" #include "migration/qemu-file.h" +#include "hw/vfio/user.h" #define TYPE_VFIO_PCI_NOHOTPLUG "vfio-pci-nohotplug" @@ -3476,6 +3477,9 @@ static void vfio_user_pci_realize(PCIDevice *pdev, Error **errp) VFIOUserPCIDevice *udev = VFIO_USER_PCI(pdev); VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev); VFIODevice *vbasedev = &vdev->vbasedev; +SocketAddress addr; +VFIOProxy *proxy; +Error *err = NULL; /* * TODO: make option parser understand SocketAddress @@ -3488,6 +3492,16 @@ static void vfio_user_pci_realize(PCIDevice *pdev, Error **errp) return; } +memset(&addr, 0, sizeof(addr)); +addr.type = SOCKET_ADDRESS_TYPE_UNIX; +addr.u.q_unix.path = udev->sock_name; +proxy = vfio_user_connect_dev(&addr, &err); +if (!proxy) { +error_setg(errp, "Remote proxy not found"); +return; +} +vbasedev->proxy = proxy; + vbasedev->name = g_strdup_printf("VFIO user <%s>", udev->sock_name); vbasedev->dev = DEVICE(vdev); vbasedev->fd = -1; @@ -3500,6 +3514,12 @@ static void vfio_user_pci_realize(PCIDevice *pdev, Error **errp) 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 new file mode 100644 index 000..92d4e03 --- /dev/null +++ b/hw/vfio/user.c @@ -0,0 +1,170 @@ +/* + * vfio protocol over a UNIX socket. + * + * Copyright © 2018, 2021 Oracle and/or its affiliates. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include +#i