Re: [RFC v3 07/19] vfio-user: connect vfio proxy to remote server

2021-12-06 Thread John Johnson



> 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

2021-11-19 Thread Alex Williamson
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

2021-11-08 Thread John Johnson
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