All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@redhat.com>
To: Peter Maydell <peter.maydell@linaro.org>, qemu-devel@nongnu.org
Cc: "Elena Ufimtseva" <elena.ufimtseva@oracle.com>,
	"John G Johnson" <john.g.johnson@oracle.com>,
	"Thomas Huth" <thuth@redhat.com>,
	"Jagannathan Raman" <jag.raman@oracle.com>,
	"Eduardo Habkost" <ehabkost@redhat.com>,
	qemu-block@nongnu.org, "Michael S. Tsirkin" <mst@redhat.com>,
	"Denis V. Lunev" <den@openvz.org>,
	"Alex Bennée" <alex.bennee@linaro.org>,
	"Wainer dos Santos Moschetta" <wainersm@redhat.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Stefan Hajnoczi" <stefanha@redhat.com>,
	"Igor Mammedov" <imammedo@redhat.com>,
	"Daniel P. Berrangé" <berrange@redhat.com>,
	"Fam Zheng" <fam@euphon.net>,
	"Philippe Mathieu-Daudé" <philmd@redhat.com>
Subject: [PULL v2 17/27] multi-process: Associate fd of a PCIDevice with its object
Date: Thu,  4 Feb 2021 15:43:17 +0000	[thread overview]
Message-ID: <20210204154327.386529-18-stefanha@redhat.com> (raw)
In-Reply-To: <20210204154327.386529-1-stefanha@redhat.com>

From: Jagannathan Raman <jag.raman@oracle.com>

Associate the file descriptor for a PCIDevice in remote process with
DeviceState object.

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>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: f405a2ed5d7518b87bea7c59cfdf334d67e5ee51.1611938319.git.jag.raman@oracle.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 MAINTAINERS            |   1 +
 hw/remote/remote-obj.c | 203 +++++++++++++++++++++++++++++++++++++++++
 hw/remote/meson.build  |   1 +
 3 files changed, 205 insertions(+)
 create mode 100644 hw/remote/remote-obj.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 771513bc34..e37fc4b226 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3208,6 +3208,7 @@ F: include/hw/remote/machine.h
 F: hw/remote/mpqemu-link.c
 F: include/hw/remote/mpqemu-link.h
 F: hw/remote/message.c
+F: hw/remote/remote-obj.c
 
 Build and test automation
 -------------------------
diff --git a/hw/remote/remote-obj.c b/hw/remote/remote-obj.c
new file mode 100644
index 0000000000..4f21254219
--- /dev/null
+++ b/hw/remote/remote-obj.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright © 2020, 2021 Oracle and/or its affiliates.
+ *
+ * This work is licensed under the terms of the GNU GPL-v2, version 2 or later.
+ *
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+
+#include "qemu/error-report.h"
+#include "qemu/notify.h"
+#include "qom/object_interfaces.h"
+#include "hw/qdev-core.h"
+#include "io/channel.h"
+#include "hw/qdev-core.h"
+#include "hw/remote/machine.h"
+#include "io/channel-util.h"
+#include "qapi/error.h"
+#include "sysemu/sysemu.h"
+#include "hw/pci/pci.h"
+#include "qemu/sockets.h"
+#include "monitor/monitor.h"
+
+#define TYPE_REMOTE_OBJECT "x-remote-object"
+OBJECT_DECLARE_TYPE(RemoteObject, RemoteObjectClass, REMOTE_OBJECT)
+
+struct RemoteObjectClass {
+    ObjectClass parent_class;
+
+    unsigned int nr_devs;
+    unsigned int max_devs;
+};
+
+struct RemoteObject {
+    /* private */
+    Object parent;
+
+    Notifier machine_done;
+
+    int32_t fd;
+    char *devid;
+
+    QIOChannel *ioc;
+
+    DeviceState *dev;
+    DeviceListener listener;
+};
+
+static void remote_object_set_fd(Object *obj, const char *str, Error **errp)
+{
+    RemoteObject *o = REMOTE_OBJECT(obj);
+    int fd = -1;
+
+    fd = monitor_fd_param(monitor_cur(), str, errp);
+    if (fd == -1) {
+        error_prepend(errp, "Could not parse remote object fd %s:", str);
+        return;
+    }
+
+    if (!fd_is_socket(fd)) {
+        error_setg(errp, "File descriptor '%s' is not a socket", str);
+        close(fd);
+        return;
+    }
+
+    o->fd = fd;
+}
+
+static void remote_object_set_devid(Object *obj, const char *str, Error **errp)
+{
+    RemoteObject *o = REMOTE_OBJECT(obj);
+
+    g_free(o->devid);
+
+    o->devid = g_strdup(str);
+}
+
+static void remote_object_unrealize_listener(DeviceListener *listener,
+                                             DeviceState *dev)
+{
+    RemoteObject *o = container_of(listener, RemoteObject, listener);
+
+    if (o->dev == dev) {
+        object_unref(OBJECT(o));
+    }
+}
+
+static void remote_object_machine_done(Notifier *notifier, void *data)
+{
+    RemoteObject *o = container_of(notifier, RemoteObject, machine_done);
+    DeviceState *dev = NULL;
+    QIOChannel *ioc = NULL;
+    Coroutine *co = NULL;
+    RemoteCommDev *comdev = NULL;
+    Error *err = NULL;
+
+    dev = qdev_find_recursive(sysbus_get_default(), o->devid);
+    if (!dev || !object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+        error_report("%s is not a PCI device", o->devid);
+        return;
+    }
+
+    ioc = qio_channel_new_fd(o->fd, &err);
+    if (!ioc) {
+        error_report_err(err);
+        return;
+    }
+    qio_channel_set_blocking(ioc, false, NULL);
+
+    o->dev = dev;
+
+    o->listener.unrealize = remote_object_unrealize_listener;
+    device_listener_register(&o->listener);
+
+    /* co-routine should free this. */
+    comdev = g_new0(RemoteCommDev, 1);
+    *comdev = (RemoteCommDev) {
+        .ioc = ioc,
+        .dev = PCI_DEVICE(dev),
+    };
+
+    co = qemu_coroutine_create(mpqemu_remote_msg_loop_co, comdev);
+    qemu_coroutine_enter(co);
+}
+
+static void remote_object_init(Object *obj)
+{
+    RemoteObjectClass *k = REMOTE_OBJECT_GET_CLASS(obj);
+    RemoteObject *o = REMOTE_OBJECT(obj);
+
+    if (k->nr_devs >= k->max_devs) {
+        error_report("Reached maximum number of devices: %u", k->max_devs);
+        return;
+    }
+
+    o->ioc = NULL;
+    o->fd = -1;
+    o->devid = NULL;
+
+    k->nr_devs++;
+
+    o->machine_done.notify = remote_object_machine_done;
+    qemu_add_machine_init_done_notifier(&o->machine_done);
+}
+
+static void remote_object_finalize(Object *obj)
+{
+    RemoteObjectClass *k = REMOTE_OBJECT_GET_CLASS(obj);
+    RemoteObject *o = REMOTE_OBJECT(obj);
+
+    device_listener_unregister(&o->listener);
+
+    if (o->ioc) {
+        qio_channel_shutdown(o->ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
+        qio_channel_close(o->ioc, NULL);
+    }
+
+    object_unref(OBJECT(o->ioc));
+
+    k->nr_devs--;
+    g_free(o->devid);
+}
+
+static void remote_object_class_init(ObjectClass *klass, void *data)
+{
+    RemoteObjectClass *k = REMOTE_OBJECT_CLASS(klass);
+
+    /*
+     * Limit number of supported devices to 1. This is done to avoid devices
+     * from one VM accessing the RAM of another VM. This is done until we
+     * start using separate address spaces for individual devices.
+     */
+    k->max_devs = 1;
+    k->nr_devs = 0;
+
+    object_class_property_add_str(klass, "fd", NULL, remote_object_set_fd);
+    object_class_property_add_str(klass, "devid", NULL,
+                                  remote_object_set_devid);
+}
+
+static const TypeInfo remote_object_info = {
+    .name = TYPE_REMOTE_OBJECT,
+    .parent = TYPE_OBJECT,
+    .instance_size = sizeof(RemoteObject),
+    .instance_init = remote_object_init,
+    .instance_finalize = remote_object_finalize,
+    .class_size = sizeof(RemoteObjectClass),
+    .class_init = remote_object_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+static void register_types(void)
+{
+    type_register_static(&remote_object_info);
+}
+
+type_init(register_types);
diff --git a/hw/remote/meson.build b/hw/remote/meson.build
index 9f5c57f35a..71d0a5689e 100644
--- a/hw/remote/meson.build
+++ b/hw/remote/meson.build
@@ -3,5 +3,6 @@ remote_ss = ss.source_set()
 remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('machine.c'))
 remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('mpqemu-link.c'))
 remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('message.c'))
+remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('remote-obj.c'))
 
 softmmu_ss.add_all(when: 'CONFIG_MULTIPROCESS', if_true: remote_ss)
-- 
2.29.2


  parent reply	other threads:[~2021-02-04 16:04 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-04 15:43 [PULL v2 00/27] Block patches Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 01/27] .github: point Repo Lockdown bot to GitLab repo Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 02/27] gitmodules: use GitLab repos instead of qemu.org Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 03/27] gitlab-ci: remove redundant GitLab repo URL command Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 04/27] docs: update README to use GitLab repo URLs Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 05/27] pc-bios: update mirror URLs to GitLab Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 06/27] get_maintainer: update repo URL " Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 07/27] multi-process: add the concept description to docs/devel/qemu-multiprocess Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 08/27] multi-process: add configure and usage information Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 09/27] memory: alloc RAM from file at offset Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 10/27] multi-process: Add config option for multi-process QEMU Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 11/27] multi-process: setup PCI host bridge for remote device Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 12/27] multi-process: setup a machine object for remote device process Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 13/27] io: add qio_channel_writev_full_all helper Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 14/27] io: add qio_channel_readv_full_all_eof & qio_channel_readv_full_all helpers Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 15/27] multi-process: define MPQemuMsg format and transmission functions Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 16/27] multi-process: Initialize message handler in remote device Stefan Hajnoczi
2021-02-04 15:43 ` Stefan Hajnoczi [this message]
2021-02-04 15:43 ` [PULL v2 18/27] multi-process: setup memory manager for " Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 19/27] multi-process: introduce proxy object Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 20/27] multi-process: add proxy communication functions Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 21/27] multi-process: Forward PCI config space acceses to the remote process Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 22/27] multi-process: PCI BAR read/write handling for proxy & remote endpoints Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 23/27] multi-process: Synchronize remote memory Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 24/27] multi-process: create IOHUB object to handle irq Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 25/27] multi-process: Retrieve PCI info from remote process Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 26/27] multi-process: perform device reset in the " Stefan Hajnoczi
2021-02-04 15:43 ` [PULL v2 27/27] docs: fix Parallels Image "dirty bitmap" section Stefan Hajnoczi
2021-02-04 17:35 ` [PULL v2 00/27] Block patches Peter Maydell
2021-02-04 18:49   ` elena
2021-02-05 16:18     ` Stefan Hajnoczi
2021-02-05 16:21   ` Stefan Hajnoczi
2021-02-05 16:23     ` Peter Maydell
2021-02-05 16:52       ` Thomas Huth
2021-02-05 16:58         ` Daniel P. Berrangé

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210204154327.386529-18-stefanha@redhat.com \
    --to=stefanha@redhat.com \
    --cc=alex.bennee@linaro.org \
    --cc=berrange@redhat.com \
    --cc=den@openvz.org \
    --cc=ehabkost@redhat.com \
    --cc=elena.ufimtseva@oracle.com \
    --cc=fam@euphon.net \
    --cc=imammedo@redhat.com \
    --cc=jag.raman@oracle.com \
    --cc=john.g.johnson@oracle.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=philmd@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=thuth@redhat.com \
    --cc=wainersm@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.