diff mbox series

[v6,19/36] multi-process: Connect Proxy Object with device in the remote process

Message ID 0b56423127fe29ddd74ce1162038d028f9ba7fe3.1586165556.git.elena.ufimtseva@oracle.com (mailing list archive)
State New, archived
Headers show
Series Initial support for multi-process qemu | expand

Commit Message

Elena Ufimtseva April 6, 2020, 9:41 a.m. UTC
From: Jagannathan Raman <jag.raman@oracle.com>

Send a message to the remote process to connect PCI device with the
corresponding Proxy object in QEMU

Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
---
 hw/proxy/qemu-proxy.c    | 34 +++++++++++++++++++++++++++++++
 include/io/mpqemu-link.h |  5 +++++
 io/mpqemu-link.c         |  3 +++
 remote/remote-main.c     | 43 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 85 insertions(+)
diff mbox series

Patch

diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
index 40bf56fd37..9b5e429a88 100644
--- a/hw/proxy/qemu-proxy.c
+++ b/hw/proxy/qemu-proxy.c
@@ -17,11 +17,45 @@ 
 static void proxy_set_socket(Object *obj, const char *str, Error **errp)
 {
     PCIProxyDev *pdev = PCI_PROXY_DEV(obj);
+    DeviceState *dev = DEVICE(obj);
+    MPQemuMsg msg = { 0 };
+    int wait, fd[2];
 
     pdev->socket = atoi(str);
 
     mpqemu_init_channel(pdev->mpqemu_link, &pdev->mpqemu_link->com,
                         pdev->socket);
+
+    if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) {
+        error_setg(errp, "Failed to create socket for device channel");
+        return;
+    }
+
+    wait = GET_REMOTE_WAIT;
+
+    msg.cmd = CONNECT_DEV;
+    msg.bytestream = 1;
+    msg.data2 = (uint8_t *)g_strdup(dev->id);
+    msg.size = sizeof(msg.data2);
+    msg.num_fds = 2;
+    msg.fds[0] = wait;
+    msg.fds[1] = fd[1];
+
+    mpqemu_msg_send(&msg, pdev->mpqemu_link->com);
+
+    if (wait_for_remote(wait)) {
+        error_setg(errp, "Failed to connect device to the remote");
+        close(fd[0]);
+    } else {
+        mpqemu_init_channel(pdev->mpqemu_link, &pdev->mpqemu_link->dev,
+                            fd[0]);
+    }
+
+    PUT_REMOTE_WAIT(wait);
+
+    close(fd[1]);
+
+    g_free(msg.data2);
 }
 
 static void proxy_init(Object *obj)
diff --git a/include/io/mpqemu-link.h b/include/io/mpqemu-link.h
index 73cc59b874..ebae9afc45 100644
--- a/include/io/mpqemu-link.h
+++ b/include/io/mpqemu-link.h
@@ -38,6 +38,7 @@ 
 typedef enum {
     INIT = 0,
     SYNC_SYSMEM,
+    CONNECT_DEV,
     MAX,
 } mpqemu_cmd_t;
 
@@ -120,8 +121,12 @@  struct MPQemuLinkState {
     GMainLoop *loop;
 
     MPQemuChannel *com;
+    MPQemuChannel *dev;
 
     mpqemu_link_callback callback;
+
+    void *opaque;
+    QemuThread thread;
 };
 
 MPQemuLinkState *mpqemu_link_create(void);
diff --git a/io/mpqemu-link.c b/io/mpqemu-link.c
index 330a6deffe..b395869a22 100644
--- a/io/mpqemu-link.c
+++ b/io/mpqemu-link.c
@@ -46,6 +46,9 @@  MPQemuLinkState *mpqemu_link_create(void)
     MPQemuLinkState *link = MPQEMU_LINK(object_new(TYPE_MPQEMU_LINK));
 
     link->com = NULL;
+    link->dev = NULL;
+
+    link->opaque = NULL;
 
     return link;
 }
diff --git a/remote/remote-main.c b/remote/remote-main.c
index 51595f3141..22319cb5ea 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -34,8 +34,48 @@ 
 #include "block/block.h"
 #include "exec/ramlist.h"
 
+static void process_msg(GIOCondition cond, MPQemuLinkState *link,
+                        MPQemuChannel *chan);
+
 static MPQemuLinkState *mpqemu_link;
 
+#define LINK_TO_DEV(link) ((PCIDevice *)link->opaque)
+
+static gpointer dev_thread(gpointer data)
+{
+    MPQemuLinkState *link = data;
+
+    mpqemu_start_coms(link, link->dev);
+
+    return NULL;
+}
+
+static void process_connect_dev_msg(MPQemuMsg *msg)
+{
+    char *devid = (char *)msg->data2;
+    MPQemuLinkState *link = NULL;
+    DeviceState *dev = NULL;
+    int wait = msg->fds[0];
+    int ret = 0;
+
+    dev = qdev_find_recursive(sysbus_get_default(), devid);
+    if (!dev) {
+        ret = 0xff;
+        goto exit;
+    }
+
+    link = mpqemu_link_create();
+    link->opaque = (void *)PCI_DEVICE(dev);
+
+    mpqemu_init_channel(link, &link->dev, msg->fds[1]);
+    mpqemu_link_set_callback(link, process_msg);
+    qemu_thread_create(&link->thread, "dev_thread", dev_thread, link,
+                       QEMU_THREAD_JOINABLE);
+
+exit:
+    notify_proxy(wait, ret);
+}
+
 static void process_msg(GIOCondition cond, MPQemuLinkState *link,
                         MPQemuChannel *chan)
 {
@@ -56,6 +96,9 @@  static void process_msg(GIOCondition cond, MPQemuLinkState *link,
     switch (msg->cmd) {
     case INIT:
         break;
+    case CONNECT_DEV:
+        process_connect_dev_msg(msg);
+        break;
     default:
         error_setg(&err, "Unknown command");
         goto finalize_loop;