From: Jagannathan Raman <jag.ra...@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.ufimts...@oracle.com> Signed-off-by: John G Johnson <john.g.john...@oracle.com> Signed-off-by: Jagannathan Raman <jag.ra...@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 --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 3f81cef96e..f780b65181 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 dbd6ad2529..f541baae6a 100644 --- a/remote/remote-main.c +++ b/remote/remote-main.c @@ -35,6 +35,9 @@ #include "exec/ramlist.h" #include "remote/remote-common.h" +static void process_msg(GIOCondition cond, MPQemuLinkState *link, + MPQemuChannel *chan); + static MPQemuLinkState *mpqemu_link; gchar *print_pid_exec(gchar *str) @@ -48,6 +51,43 @@ gchar *print_pid_exec(gchar *str) return str; } +#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) { @@ -72,6 +112,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 in %s", print_pid_exec(pid_exec)); goto finalize_loop; -- 2.25.GIT