Message ID | ff8864013462e53eb0bed0aa609b55b21c0b18e0.1630084211.git.jag.raman@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | vfio-user server in QEMU | expand |
On Fri, Aug 27, 2021 at 01:53:21PM -0400, Jagannathan Raman wrote: > Define vfio-user object which is remote process server for QEMU. Setup > object initialization functions and properties necessary to instantiate > the 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> > --- > qapi/qom.json | 20 ++++++- > hw/remote/vfio-user-obj.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++ > MAINTAINERS | 1 + > hw/remote/meson.build | 1 + > hw/remote/trace-events | 3 + > 5 files changed, 168 insertions(+), 2 deletions(-) > create mode 100644 hw/remote/vfio-user-obj.c > > diff --git a/qapi/qom.json b/qapi/qom.json > index a25616b..3e941ee 100644 > --- a/qapi/qom.json > +++ b/qapi/qom.json > @@ -689,6 +689,20 @@ > 'data': { 'fd': 'str', 'devid': 'str' } } > > ## > +# @VfioUserProperties: > +# > +# Properties for vfio-user objects. > +# > +# @socket: path to be used as socket by the libvfiouser library > +# > +# @devid: the id of the device to be associated with the file descriptor > +# > +# Since: 6.0 > +## > +{ 'struct': 'VfioUserProperties', > + 'data': { 'socket': 'str', 'devid': 'str' } } Please use 'SocketAddress' for socket instead of 'str'. That way file descriptor passing is easy to support and additional socket address families can be supported in the future. > + > +## > # @RngProperties: > # > # Properties for objects of classes derived from rng. > @@ -812,7 +826,8 @@ > 'tls-creds-psk', > 'tls-creds-x509', > 'tls-cipher-suites', > - 'x-remote-object' > + 'x-remote-object', > + 'vfio-user' > ] } > > ## > @@ -868,7 +883,8 @@ > 'tls-creds-psk': 'TlsCredsPskProperties', > 'tls-creds-x509': 'TlsCredsX509Properties', > 'tls-cipher-suites': 'TlsCredsProperties', > - 'x-remote-object': 'RemoteObjectProperties' > + 'x-remote-object': 'RemoteObjectProperties', > + 'vfio-user': 'VfioUserProperties' "vfio-user" doesn't communicate whether this is a client or server. Is "vfio-user-server" clearer? > } } > > ## > diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c > new file mode 100644 > index 0000000..4a1e297 > --- /dev/null > +++ b/hw/remote/vfio-user-obj.c > @@ -0,0 +1,145 @@ > +/** > + * QEMU vfio-user server object > + * > + * Copyright © 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. > + * > + */ > + > +/** > + * Usage: add options: > + * -machine x-remote > + * -device <PCI-device>,id=<pci-dev-id> > + * -object vfio-user,id=<id>,socket=<socket-path>,devid=<pci-dev-id> I suggest renaming devid= to device= or pci-device= (similar to drive= and netdev=) for consistency and to avoid confusion with PCI Device IDs. > diff --git a/hw/remote/meson.build b/hw/remote/meson.build > index fb35fb8..cd44dfc 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')) > +remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('vfio-user-obj.c')) If you use CONFIG_VFIO_USER_SERVER then it's easier to separate mpqemu from vfio-user. Sharing CONFIG_MULTIPROCESS could become messy later.
> On Sep 8, 2021, at 8:37 AM, Stefan Hajnoczi <stefanha@redhat.com> wrote: > > On Fri, Aug 27, 2021 at 01:53:21PM -0400, Jagannathan Raman wrote: >> Define vfio-user object which is remote process server for QEMU. Setup >> object initialization functions and properties necessary to instantiate >> the 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> >> --- >> qapi/qom.json | 20 ++++++- >> hw/remote/vfio-user-obj.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++ >> MAINTAINERS | 1 + >> hw/remote/meson.build | 1 + >> hw/remote/trace-events | 3 + >> 5 files changed, 168 insertions(+), 2 deletions(-) >> create mode 100644 hw/remote/vfio-user-obj.c >> >> diff --git a/qapi/qom.json b/qapi/qom.json >> index a25616b..3e941ee 100644 >> --- a/qapi/qom.json >> +++ b/qapi/qom.json >> @@ -689,6 +689,20 @@ >> 'data': { 'fd': 'str', 'devid': 'str' } } >> >> ## >> +# @VfioUserProperties: >> +# >> +# Properties for vfio-user objects. >> +# >> +# @socket: path to be used as socket by the libvfiouser library >> +# >> +# @devid: the id of the device to be associated with the file descriptor >> +# >> +# Since: 6.0 >> +## >> +{ 'struct': 'VfioUserProperties', >> + 'data': { 'socket': 'str', 'devid': 'str' } } > > Please use 'SocketAddress' for socket instead of 'str'. That way file > descriptor passing is easy to support and additional socket address > families can be supported in the future. OK, will do. > >> + >> +## >> # @RngProperties: >> # >> # Properties for objects of classes derived from rng. >> @@ -812,7 +826,8 @@ >> 'tls-creds-psk', >> 'tls-creds-x509', >> 'tls-cipher-suites', >> - 'x-remote-object' >> + 'x-remote-object', >> + 'vfio-user' >> ] } >> >> ## >> @@ -868,7 +883,8 @@ >> 'tls-creds-psk': 'TlsCredsPskProperties', >> 'tls-creds-x509': 'TlsCredsX509Properties', >> 'tls-cipher-suites': 'TlsCredsProperties', >> - 'x-remote-object': 'RemoteObjectProperties' >> + 'x-remote-object': 'RemoteObjectProperties', >> + 'vfio-user': 'VfioUserProperties' > > "vfio-user" doesn't communicate whether this is a client or server. Is > "vfio-user-server" clearer? “vfio-user-server” sounds better. > >> } } >> >> ## >> diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c >> new file mode 100644 >> index 0000000..4a1e297 >> --- /dev/null >> +++ b/hw/remote/vfio-user-obj.c >> @@ -0,0 +1,145 @@ >> +/** >> + * QEMU vfio-user server object >> + * >> + * Copyright © 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. >> + * >> + */ >> + >> +/** >> + * Usage: add options: >> + * -machine x-remote >> + * -device <PCI-device>,id=<pci-dev-id> >> + * -object vfio-user,id=<id>,socket=<socket-path>,devid=<pci-dev-id> > > I suggest renaming devid= to device= or pci-device= (similar to drive= > and netdev=) for consistency and to avoid confusion with PCI Device IDs. OK, will do. > >> diff --git a/hw/remote/meson.build b/hw/remote/meson.build >> index fb35fb8..cd44dfc 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')) >> +remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('vfio-user-obj.c')) > > If you use CONFIG_VFIO_USER_SERVER then it's easier to separate mpqemu > from vfio-user. Sharing CONFIG_MULTIPROCESS could become messy later. OK, got it. -- Jag
diff --git a/qapi/qom.json b/qapi/qom.json index a25616b..3e941ee 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -689,6 +689,20 @@ 'data': { 'fd': 'str', 'devid': 'str' } } ## +# @VfioUserProperties: +# +# Properties for vfio-user objects. +# +# @socket: path to be used as socket by the libvfiouser library +# +# @devid: the id of the device to be associated with the file descriptor +# +# Since: 6.0 +## +{ 'struct': 'VfioUserProperties', + 'data': { 'socket': 'str', 'devid': 'str' } } + +## # @RngProperties: # # Properties for objects of classes derived from rng. @@ -812,7 +826,8 @@ 'tls-creds-psk', 'tls-creds-x509', 'tls-cipher-suites', - 'x-remote-object' + 'x-remote-object', + 'vfio-user' ] } ## @@ -868,7 +883,8 @@ 'tls-creds-psk': 'TlsCredsPskProperties', 'tls-creds-x509': 'TlsCredsX509Properties', 'tls-cipher-suites': 'TlsCredsProperties', - 'x-remote-object': 'RemoteObjectProperties' + 'x-remote-object': 'RemoteObjectProperties', + 'vfio-user': 'VfioUserProperties' } } ## diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c new file mode 100644 index 0000000..4a1e297 --- /dev/null +++ b/hw/remote/vfio-user-obj.c @@ -0,0 +1,145 @@ +/** + * QEMU vfio-user server object + * + * Copyright © 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. + * + */ + +/** + * Usage: add options: + * -machine x-remote + * -device <PCI-device>,id=<pci-dev-id> + * -object vfio-user,id=<id>,socket=<socket-path>,devid=<pci-dev-id> + * + * Note that vfio-user object must be used with x-remote machine only. This + * server could only support PCI devices for now. + * + * socket is path to a file. This file will be created by the server. It is + * a required option + * + * devid is the id of a PCI device on the server. It is also a required option. + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" + +#include "qom/object.h" +#include "qom/object_interfaces.h" +#include "qemu/error-report.h" +#include "trace.h" +#include "sysemu/runstate.h" + +#define TYPE_VFU_OBJECT "vfio-user" +OBJECT_DECLARE_TYPE(VfuObject, VfuObjectClass, VFU_OBJECT) + +struct VfuObjectClass { + ObjectClass parent_class; + + unsigned int nr_devs; + + /* Maximum number of devices the server could support */ + unsigned int max_devs; +}; + +struct VfuObject { + /* private */ + Object parent; + + char *socket; + char *devid; +}; + +static void vfu_object_set_socket(Object *obj, const char *str, Error **errp) +{ + VfuObject *o = VFU_OBJECT(obj); + + g_free(o->socket); + + o->socket = g_strdup(str); + + trace_vfu_prop("socket", str); +} + +static void vfu_object_set_devid(Object *obj, const char *str, Error **errp) +{ + VfuObject *o = VFU_OBJECT(obj); + + g_free(o->devid); + + o->devid = g_strdup(str); + + trace_vfu_prop("devid", str); +} + +static void vfu_object_init(Object *obj) +{ + VfuObjectClass *k = VFU_OBJECT_GET_CLASS(obj); + + if (!object_dynamic_cast(OBJECT(current_machine), TYPE_REMOTE_MACHINE)) { + error_report("vfu: %s only compatible with %s machine", + TYPE_VFU_OBJECT, TYPE_REMOTE_MACHINE); + return; + } + + if (k->nr_devs >= k->max_devs) { + error_report("Reached maximum number of vfio-user devices: %u", + k->max_devs); + return; + } + + k->nr_devs++; +} + +static void vfu_object_finalize(Object *obj) +{ + VfuObjectClass *k = VFU_OBJECT_GET_CLASS(obj); + VfuObject *o = VFU_OBJECT(obj); + + k->nr_devs--; + + g_free(o->socket); + g_free(o->devid); + + if (k->nr_devs == 0) { + qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); + } +} + +static void vfu_object_class_init(ObjectClass *klass, void *data) +{ + VfuObjectClass *k = VFU_OBJECT_CLASS(klass); + + /* Limiting maximum number of devices to 1 until IOMMU support is added */ + k->max_devs = 1; + k->nr_devs = 0; + + object_class_property_add_str(klass, "socket", NULL, + vfu_object_set_socket); + object_class_property_add_str(klass, "devid", NULL, + vfu_object_set_devid); +} + +static const TypeInfo vfu_object_info = { + .name = TYPE_VFU_OBJECT, + .parent = TYPE_OBJECT, + .instance_size = sizeof(VfuObject), + .instance_init = vfu_object_init, + .instance_finalize = vfu_object_finalize, + .class_size = sizeof(VfuObjectClass), + .class_init = vfu_object_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_USER_CREATABLE }, + { } + } +}; + +static void vfu_register_types(void) +{ + type_register_static(&vfu_object_info); +} + +type_init(vfu_register_types); diff --git a/MAINTAINERS b/MAINTAINERS index 0c5a18e..f9d8092 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3391,6 +3391,7 @@ F: hw/remote/proxy-memory-listener.c F: include/hw/remote/proxy-memory-listener.h F: hw/remote/iohub.c F: include/hw/remote/iohub.h +F: hw/remote/vfio-user-obj.c EBPF: M: Jason Wang <jasowang@redhat.com> diff --git a/hw/remote/meson.build b/hw/remote/meson.build index fb35fb8..cd44dfc 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')) +remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('vfio-user-obj.c')) remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: vfiouser) diff --git a/hw/remote/trace-events b/hw/remote/trace-events index 0b23974..7da12f0 100644 --- a/hw/remote/trace-events +++ b/hw/remote/trace-events @@ -2,3 +2,6 @@ mpqemu_send_io_error(int cmd, int size, int nfds) "send command %d size %d, %d file descriptors to remote process" mpqemu_recv_io_error(int cmd, int size, int nfds) "failed to receive %d size %d, %d file descriptors to remote process" + +# vfio-user-obj.c +vfu_prop(const char *prop, const char *val) "vfu: setting %s as %s"