From: Jagannathan Raman <jag.ra...@oracle.com> Associate the file descriptor for a PCIDevice in remote process with DeviceState object.
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> --- MAINTAINERS | 2 + hw/i386/meson.build | 1 + hw/i386/remote-obj.c | 140 +++++++++++++++++++++++++++++++++++ include/hw/i386/remote-obj.h | 42 +++++++++++ 4 files changed, 185 insertions(+) create mode 100644 hw/i386/remote-obj.c create mode 100644 include/hw/i386/remote-obj.h diff --git a/MAINTAINERS b/MAINTAINERS index 9885c9499f..ac8eefaa3f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3048,6 +3048,8 @@ F: include/hw/i386/remote.h F: io/mpqemu-link.c F: include/io/mpqemu-link.h F: hw/i386/remote-msg.c +F: include/hw/i386/remote-obj.h +F: hw/i386/remote-obj.c Build and test automation ------------------------- diff --git a/hw/i386/meson.build b/hw/i386/meson.build index 238ae0879d..7b35f35d86 100644 --- a/hw/i386/meson.build +++ b/hw/i386/meson.build @@ -25,6 +25,7 @@ i386_ss.add(when: 'CONFIG_PC', if_true: files( 'port92.c')) i386_ss.add(when: 'CONFIG_MPQEMU', if_true: files('remote.c')) i386_ss.add(when: 'CONFIG_MPQEMU', if_true: files('remote-msg.c')) +i386_ss.add(when: 'CONFIG_MPQEMU', if_true: files('remote-obj.c')) subdir('kvm') subdir('xen') diff --git a/hw/i386/remote-obj.c b/hw/i386/remote-obj.c new file mode 100644 index 0000000000..a88f78d6ef --- /dev/null +++ b/hw/i386/remote-obj.c @@ -0,0 +1,140 @@ +/* + * Copyright © 2020 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 "hw/i386/remote-obj.h" +#include "qemu/error-report.h" +#include "qom/object_interfaces.h" +#include "hw/qdev-core.h" +#include "io/channel.h" +#include "hw/qdev-core.h" +#include "hw/i386/remote.h" +#include "io/channel-util.h" +#include "qapi/error.h" +#include "sysemu/sysemu.h" +#include "hw/pci/pci.h" + +static void remote_object_set_fd(Object *obj, const char *str, Error **errp) +{ + RemoteObject *o = REMOTE_OBJECT(obj); + + o->fd = atoi(str); +} + +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 property_release_remote_object(Object *obj, const char *name, + void *opaque) +{ + Object *remote_object = OBJECT(opaque); + + object_unref(remote_object); +} + +static void remote_object_machine_done(Notifier *notifier, void *data) +{ + RemoteObject *o = container_of(notifier, RemoteObject, machine_done); + DeviceState *dev = NULL; + QIOChannel *ioc = 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); + + object_property_add(OBJECT(dev), "remote-object", "object", NULL, NULL, + property_release_remote_object, (void *)OBJECT(o)); + + qio_channel_add_watch(ioc, G_IO_IN | G_IO_HUP | G_IO_ERR, + mpqemu_process_msg, (void *)PCI_DEVICE(dev), NULL); +} + +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++; + + object_property_add_str(obj, "fd", NULL, remote_object_set_fd); + object_property_set_description(obj, "fd", + "file descriptor for the object"); + object_property_add_str(obj, "devid", NULL, remote_object_set_devid); + object_property_set_description(obj, "devid", + "id of device to associate"); + + 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); + + qio_channel_close(o->ioc, NULL); + k->nr_devs--; + g_free(o->devid); +} + +static void remote_object_class_init(ObjectClass *klass, void *data) +{ + RemoteObjectClass *k = REMOTE_OBJECT_CLASS(klass); + + k->max_devs = 1; + k->nr_devs = 0; +} + +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/include/hw/i386/remote-obj.h b/include/hw/i386/remote-obj.h new file mode 100644 index 0000000000..8513c2bb84 --- /dev/null +++ b/include/hw/i386/remote-obj.h @@ -0,0 +1,42 @@ +/* + * Copyright © 2020 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. + * + */ + +#ifndef REMOTE_OBJECT_H +#define REMOTE_OBJECT_H + +#include "io/channel.h" +#include "qemu/notify.h" + +#define TYPE_REMOTE_OBJECT "remote-object" +#define REMOTE_OBJECT(obj) \ + OBJECT_CHECK(RemoteObject, (obj), TYPE_REMOTE_OBJECT) +#define REMOTE_OBJECT_GET_CLASS(obj) \ + OBJECT_GET_CLASS(RemoteObjectClass, (obj), TYPE_REMOTE_OBJECT) +#define REMOTE_OBJECT_CLASS(klass) \ + OBJECT_CLASS_CHECK(RemoteObjectClass, (klass), TYPE_REMOTE_OBJECT) + +typedef struct { + ObjectClass parent_class; + + unsigned int nr_devs; + unsigned int max_devs; +} RemoteObjectClass; + +typedef struct { + /* private */ + Object parent; + + Notifier machine_done; + + int fd; + char *devid; + QIOChannel *ioc; +} RemoteObject; + +#endif -- 2.25.GIT