[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC 4/8] ioregionfd: Introduce IORegionDFObject type
From: |
Elena Ufimtseva |
Subject: |
[RFC 4/8] ioregionfd: Introduce IORegionDFObject type |
Date: |
Mon, 7 Feb 2022 23:22:18 -0800 |
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
---
meson.build | 15 ++-
qapi/qom.json | 32 +++++-
include/hw/remote/ioregionfd.h | 40 +++++++
hw/remote/ioregionfd.c | 196 +++++++++++++++++++++++++++++++++
Kconfig.host | 3 +
MAINTAINERS | 2 +
hw/remote/Kconfig | 4 +
hw/remote/meson.build | 1 +
meson_options.txt | 2 +
scripts/meson-buildoptions.sh | 3 +
10 files changed, 294 insertions(+), 4 deletions(-)
create mode 100644 include/hw/remote/ioregionfd.h
create mode 100644 hw/remote/ioregionfd.c
diff --git a/meson.build b/meson.build
index 96de1a6ef9..6483e754bd 100644
--- a/meson.build
+++ b/meson.build
@@ -258,6 +258,17 @@ if targetos != 'linux' and
get_option('multiprocess').enabled()
endif
multiprocess_allowed = targetos == 'linux' and not
get_option('multiprocess').disabled()
+# TODO: drop this limitation
+if not multiprocess_allowed and not get_option('ioregionfd').disabled()
+ error('To enable ioregiofd support, enable mutliprocess option.')
+endif
+ioregionfd_allowed = multiprocess_allowed and not
get_option('ioregionfd').disabled()
+if ioregionfd_allowed
+ config_host += { 'CONFIG_IOREGIONFD': 'y' }
+else
+ config_host += { 'CONFIG_IOREGIONFD': 'n' }
+endif
+
libm = cc.find_library('m', required: false)
threads = dependency('threads')
util = cc.find_library('util', required: false)
@@ -1837,7 +1848,8 @@ host_kconfig = \
(have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
- (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
+ (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
+ (ioregionfd_allowed ? ['CONFIG_IOREGIONFD=y'] : [])
ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
@@ -3315,6 +3327,7 @@ summary_info += {'target list': '
'.join(target_dirs)}
if have_system
summary_info += {'default devices': get_option('default_devices')}
summary_info += {'out of process emulation': multiprocess_allowed}
+ summary_info += {'ioregionfd support': ioregionfd_allowed}
endif
summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
diff --git a/qapi/qom.json b/qapi/qom.json
index eeb5395ff3..439fb94c93 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -689,6 +689,29 @@
'data': { 'chardev': 'str',
'*log': 'str' } }
+##
+# @IORegionFDObjectProperties:
+#
+# Describes ioregionfd for the device
+#
+# @devid: the id of the device to be associated with the ioregionfd
+#
+# @iofd: File descriptor
+#
+# @bar: BAR number to use with ioregionfd
+#
+# @start: offset from the BAR start address of ioregionfd
+#
+# @size: size of the ioregionfd
+##
+# Since: 2.9
+{ 'struct': 'IORegionFDObjectProperties',
+ 'data': { 'devid': 'str',
+ 'iofd': 'str',
+ 'bar': 'int',
+ '*start': 'int',
+ '*size':'int' } }
+
##
# @RemoteObjectProperties:
#
@@ -842,8 +865,10 @@
'tls-creds-psk',
'tls-creds-x509',
'tls-cipher-suites',
- { 'name': 'x-remote-object', 'features': [ 'unstable' ] }
- ] }
+ { 'name': 'x-remote-object', 'features': [ 'unstable' ] },
+ { 'name' :'ioregionfd-object',
+ 'if': 'CONFIG_IOREGIONFD' }
+ ] }
##
# @ObjectOptions:
@@ -905,7 +930,8 @@
'tls-creds-psk': 'TlsCredsPskProperties',
'tls-creds-x509': 'TlsCredsX509Properties',
'tls-cipher-suites': 'TlsCredsProperties',
- 'x-remote-object': 'RemoteObjectProperties'
+ 'x-remote-object': 'RemoteObjectProperties',
+ 'ioregionfd-object': 'IORegionFDObjectProperties'
} }
##
diff --git a/include/hw/remote/ioregionfd.h b/include/hw/remote/ioregionfd.h
new file mode 100644
index 0000000000..c8a8b32ee0
--- /dev/null
+++ b/include/hw/remote/ioregionfd.h
@@ -0,0 +1,40 @@
+/*
+ * Ioregionfd headers
+ *
+ * Copyright © 2018, 2022 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.
+ *
+ */
+
+#ifndef IOREGIONFD_H
+#define IOREGIONFD_H
+
+#define PCI_BARS_NR 6
+
+typedef struct {
+ uint64_t val;
+ bool memory;
+} IORegionFDOp;
+
+typedef struct {
+ int fd;
+ char *devid;
+ uint32_t bar;
+ uint32_t start;
+ uint32_t size;
+ bool memory;
+} IORegionFD;
+
+struct IORegionFDObject {
+ /* private */
+ Object parent;
+
+ IORegionFD ioregfd;
+ QTAILQ_ENTRY(IORegionFDObject) next;
+};
+
+typedef struct IORegionFDObject IORegionFDObject;
+
+#endif /* IOREGIONFD_H */
diff --git a/hw/remote/ioregionfd.c b/hw/remote/ioregionfd.c
new file mode 100644
index 0000000000..ae95f702a6
--- /dev/null
+++ b/hw/remote/ioregionfd.c
@@ -0,0 +1,196 @@
+/*
+ * Memory manager for remote device
+ *
+ * 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 "sysemu/kvm.h"
+#include "linux/kvm.h"
+
+#include "exec/memory.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qom/object_interfaces.h"
+#include "exec/confidential-guest-support.h"
+#include "io/channel.h"
+#include "qemu/sockets.h"
+#include "qemu/cutils.h"
+#include "io/channel-socket.h"
+#include "monitor/monitor.h"
+#include "hw/remote/ioregionfd.h"
+#include "hw/pci/pci.h"
+#include "qapi/qapi-visit-qom.h"
+#include "hw/remote/remote.h"
+
+#define TYPE_IOREGIONFD_OBJECT "ioregionfd-object"
+OBJECT_DECLARE_TYPE(IORegionFDObject, IORegionFDObjectClass, IOREGIONFD_OBJECT)
+
+struct IORegionFDObjectClass {
+ ObjectClass parent_class;
+
+ unsigned int nr_ioregfds;
+ unsigned int max_ioregfds;
+};
+
+static void ioregionfd_object_init(Object *obj)
+{
+ IORegionFDObjectClass *k = IOREGIONFD_OBJECT_GET_CLASS(obj);
+
+ if (k->nr_ioregfds >= k->max_ioregfds) {
+ error_report("Reached max number of ioregions: %u", k->max_ioregfds);
+ return;
+ }
+}
+
+static void ioregionfd_object_set_fd(Object *obj, const char *str,
+ Error **errp)
+{
+ IORegionFDObject *o = IOREGIONFD_OBJECT(obj);
+ int fd = -1;
+
+ fd = monitor_fd_param(monitor_cur(), str, errp);
+ if (fd == -1) {
+ error_prepend(errp, "Could not parse ioregionfd fd %s:", str);
+ return;
+ }
+ o->ioregfd.fd = fd;
+}
+
+static void ioregionfd_object_set_devid(Object *obj, const char *str,
+ Error **errp)
+{
+ IORegionFDObject *o = IOREGIONFD_OBJECT(obj);
+
+ g_free(o->ioregfd.devid);
+
+ o->ioregfd.devid = g_strdup(str);
+}
+
+static char *ioregionfd_object_get_devid(Object *obj, Error **errp)
+{
+ IORegionFDObject *o = IOREGIONFD_OBJECT(obj);
+
+ return g_strdup(o->ioregfd.devid);
+}
+
+static void ioregionfd_object_set_bar(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ IORegionFDObject *o = IOREGIONFD_OBJECT(obj);
+ uint32_t value;
+
+ if (!visit_type_uint32(v, name, &value, errp)) {
+ return;
+ }
+
+ if (value > PCI_BARS_NR) {
+ error_setg(errp, "BAR number cannot be larger than %d", PCI_BARS_NR);
+ return;
+ }
+
+ o->ioregfd.bar = value;
+}
+
+static void ioregionfd_object_set_start(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ IORegionFDObject *o = IOREGIONFD_OBJECT(obj);
+ int64_t value;
+
+ if (!visit_type_int(v, name, &value, errp)) {
+ return;
+ }
+
+ if (value < 0) {
+ error_setg(errp, "BAR start %"PRId64" must be > 0", value);
+ return;
+ }
+
+ if (value > UINT32_MAX) {
+ error_setg(errp, "BAR start %"PRId64" is too big", value);
+ o->ioregfd.start = 0;
+ return;
+ }
+
+ o->ioregfd.start = value;
+}
+
+static void ioregionfd_object_set_size(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ IORegionFDObject *o = IOREGIONFD_OBJECT(obj);
+ int64_t value;
+
+ if (!visit_type_int(v, name, &value, errp)) {
+ return;
+ }
+
+ if (value < 0) {
+ error_setg(errp, "Invalid BAR size %"PRId64, value);
+ return;
+ }
+
+ if (value > UINT32_MAX) {
+ error_setg(errp, "BAR size %"PRId64" is too big", value);
+ o->ioregfd.size = 0;
+ return;
+ }
+
+
+ o->ioregfd.size = value;
+}
+
+static void ioregionfd_object_class_init(ObjectClass *klass, void *data)
+{
+ IORegionFDObjectClass *k = IOREGIONFD_OBJECT_CLASS(klass);
+
+ k->nr_ioregfds = 0;
+ k->max_ioregfds = 1;
+
+ object_class_property_add_str(klass, "devid", ioregionfd_object_get_devid,
+ ioregionfd_object_set_devid);
+ object_class_property_add_str(klass, "iofd", NULL,
+ ioregionfd_object_set_fd);
+ object_class_property_add(klass, "bar", "uint32", NULL,
+ ioregionfd_object_set_bar, NULL, NULL);
+ object_class_property_add(klass, "start", "uint64", NULL,
+ ioregionfd_object_set_start, NULL, NULL);
+ object_class_property_add(klass, "size", "uint64", NULL,
+ ioregionfd_object_set_size, NULL, NULL);
+}
+
+/* Assume that Object user released all allocated structures. */
+static void ioregionfd_object_finalize(Object *obj)
+{
+ IORegionFDObject *o = IOREGIONFD_OBJECT(obj);
+ g_free(o->ioregfd.devid);
+}
+
+static const TypeInfo ioregionfd_object_info = {
+ .name = TYPE_IOREGIONFD_OBJECT,
+ .parent = TYPE_OBJECT,
+ .instance_size = sizeof(IORegionFDObject),
+ .instance_init = ioregionfd_object_init,
+ .instance_finalize = ioregionfd_object_finalize,
+ .class_size = sizeof(IORegionFDObjectClass),
+ .class_init = ioregionfd_object_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_USER_CREATABLE },
+ { }
+ }
+};
+
+static void register_types(void)
+{
+ type_register_static(&ioregionfd_object_info);
+}
+
+type_init(register_types);
diff --git a/Kconfig.host b/Kconfig.host
index 60b9c07b5e..af01b75770 100644
--- a/Kconfig.host
+++ b/Kconfig.host
@@ -45,3 +45,6 @@ config MULTIPROCESS_ALLOWED
config FUZZ
bool
select SPARSE_MEM
+
+config IOREGIONFD
+ bool
diff --git a/MAINTAINERS b/MAINTAINERS
index 3c60a29760..d29fa8a7de 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3454,6 +3454,8 @@ F: include/hw/remote/proxy-memory-listener.h
F: hw/remote/iohub.c
F: include/hw/remote/iohub.h
F: include/hw/remote/remote.h
+F: include/hw/remote/ioregionfd.h
+F: hw/remote/ioregionfd.c
EBPF:
M: Jason Wang <jasowang@redhat.com>
diff --git a/hw/remote/Kconfig b/hw/remote/Kconfig
index 08c16e235f..caff3427e7 100644
--- a/hw/remote/Kconfig
+++ b/hw/remote/Kconfig
@@ -2,3 +2,7 @@ config MULTIPROCESS
bool
depends on PCI && PCI_EXPRESS && KVM
select REMOTE_PCIHOST
+config IOREGIONFD
+ bool
+ default n
+ depends on MULTIPROCESS
diff --git a/hw/remote/meson.build b/hw/remote/meson.build
index e6a5574242..b190c520c4 100644
--- a/hw/remote/meson.build
+++ b/hw/remote/meson.build
@@ -6,6 +6,7 @@ remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true:
files('message.c'))
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('remote-obj.c'))
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('proxy.c'))
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('iohub.c'))
+specific_ss.add(when: 'CONFIG_IOREGIONFD', if_true: files('ioregionfd.c'))
specific_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('memory.c'))
specific_ss.add(when: 'CONFIG_MULTIPROCESS', if_true:
files('proxy-memory-listener.c'))
diff --git a/meson_options.txt b/meson_options.txt
index e392323732..52b338c1b8 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -66,6 +66,8 @@ option('cfi_debug', type: 'boolean', value: 'false',
description: 'Verbose errors in case of CFI violation')
option('multiprocess', type: 'feature', value: 'auto',
description: 'Out of process device emulation support')
+option('ioregionfd', type: 'feature', value: 'auto',
+ description: 'Fast-path IO/MMIO support')
option('attr', type : 'feature', value : 'auto',
description: 'attr/xattr support')
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index 7a17ff4218..1cbd2984f5 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -98,6 +98,7 @@ meson_options_help() {
printf "%s\n" ' Xen PCI passthrough support'
printf "%s\n" ' xkbcommon xkbcommon support'
printf "%s\n" ' zstd zstd compression support'
+ printf "%s\n" ' ioregionfd ioregionfd support'
}
_meson_option_parse() {
case $1 in
@@ -270,6 +271,8 @@ _meson_option_parse() {
--disable-xkbcommon) printf "%s" -Dxkbcommon=disabled ;;
--enable-zstd) printf "%s" -Dzstd=enabled ;;
--disable-zstd) printf "%s" -Dzstd=disabled ;;
+ --enable-ioregionfd) printf "%s" -Dioregionfd=enabled ;;
+ --disable-ioregionfd) printf "%s" -Dioregionfd=disabled ;;
*) return 1 ;;
esac
}
--
2.25.1
- [RFC 0/8] ioregionfd introduction, Elena Ufimtseva, 2022/02/08
- [RFC 4/8] ioregionfd: Introduce IORegionDFObject type,
Elena Ufimtseva <=
- [RFC 2/8] multiprocess: place RemoteObject definition in a header file, Elena Ufimtseva, 2022/02/08
- [RFC 1/8] ioregionfd: introduce a syscall and memory API, Elena Ufimtseva, 2022/02/08
- [RFC 7/8] multiprocess: add ioregionfd memory region in proxy, Elena Ufimtseva, 2022/02/08
- [RFC 5/8] multiprocess: prepare ioregionfds for remote device, Elena Ufimtseva, 2022/02/08