diff options
author | Jagannathan Raman <jag.raman@oracle.com> | 2022-06-13 16:26:26 -0400 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2022-06-15 16:43:42 +0100 |
commit | 87f7249ff6e37c541609e40b17d249af533003e1 (patch) | |
tree | 0e177b236df40e5e0fd03cdcf87f59f9dca7329c | |
parent | 8f9a9259d32c1b6ba41a38ad99fc67bcc0da0131 (diff) |
vfio-user: instantiate vfio-user context
create a context with the vfio-user library to run a PCI device
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: a452871ac8c812ff96fc4f0ce6037f4769953fab.1655151679.git.jag.raman@oracle.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r-- | hw/remote/vfio-user-obj.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c index bc49adcc27..68f8a9dfa9 100644 --- a/hw/remote/vfio-user-obj.c +++ b/hw/remote/vfio-user-obj.c @@ -40,6 +40,9 @@ #include "hw/remote/machine.h" #include "qapi/error.h" #include "qapi/qapi-visit-sockets.h" +#include "qemu/notify.h" +#include "sysemu/sysemu.h" +#include "libvfio-user.h" #define TYPE_VFU_OBJECT "x-vfio-user-server" OBJECT_DECLARE_TYPE(VfuObject, VfuObjectClass, VFU_OBJECT) @@ -73,8 +76,14 @@ struct VfuObject { char *device; Error *err; + + Notifier machine_done; + + vfu_ctx_t *vfu_ctx; }; +static void vfu_object_init_ctx(VfuObject *o, Error **errp); + static bool vfu_object_auto_shutdown(void) { bool auto_shutdown = true; @@ -107,6 +116,11 @@ static void vfu_object_set_socket(Object *obj, Visitor *v, const char *name, { VfuObject *o = VFU_OBJECT(obj); + if (o->vfu_ctx) { + error_setg(errp, "vfu: Unable to set socket property - server busy"); + return; + } + qapi_free_SocketAddress(o->socket); o->socket = NULL; @@ -122,17 +136,69 @@ static void vfu_object_set_socket(Object *obj, Visitor *v, const char *name, } trace_vfu_prop("socket", o->socket->u.q_unix.path); + + vfu_object_init_ctx(o, errp); } static void vfu_object_set_device(Object *obj, const char *str, Error **errp) { VfuObject *o = VFU_OBJECT(obj); + if (o->vfu_ctx) { + error_setg(errp, "vfu: Unable to set device property - server busy"); + return; + } + g_free(o->device); o->device = g_strdup(str); trace_vfu_prop("device", str); + + vfu_object_init_ctx(o, errp); +} + +/* + * TYPE_VFU_OBJECT depends on the availability of the 'socket' and 'device' + * properties. It also depends on devices instantiated in QEMU. These + * dependencies are not available during the instance_init phase of this + * object's life-cycle. As such, the server is initialized after the + * machine is setup. machine_init_done_notifier notifies TYPE_VFU_OBJECT + * when the machine is setup, and the dependencies are available. + */ +static void vfu_object_machine_done(Notifier *notifier, void *data) +{ + VfuObject *o = container_of(notifier, VfuObject, machine_done); + Error *err = NULL; + + vfu_object_init_ctx(o, &err); + + if (err) { + error_propagate(&error_abort, err); + } +} + +static void vfu_object_init_ctx(VfuObject *o, Error **errp) +{ + ERRP_GUARD(); + + if (o->vfu_ctx || !o->socket || !o->device || + !phase_check(PHASE_MACHINE_READY)) { + return; + } + + if (o->err) { + error_propagate(errp, o->err); + o->err = NULL; + return; + } + + o->vfu_ctx = vfu_create_ctx(VFU_TRANS_SOCK, o->socket->u.q_unix.path, 0, + o, VFU_DEV_TYPE_PCI); + if (o->vfu_ctx == NULL) { + error_setg(errp, "vfu: Failed to create context - %s", strerror(errno)); + return; + } } static void vfu_object_init(Object *obj) @@ -147,6 +213,12 @@ static void vfu_object_init(Object *obj) TYPE_VFU_OBJECT, TYPE_REMOTE_MACHINE); return; } + + if (!phase_check(PHASE_MACHINE_READY)) { + o->machine_done.notify = vfu_object_machine_done; + qemu_add_machine_init_done_notifier(&o->machine_done); + } + } static void vfu_object_finalize(Object *obj) @@ -160,6 +232,11 @@ static void vfu_object_finalize(Object *obj) o->socket = NULL; + if (o->vfu_ctx) { + vfu_destroy_ctx(o->vfu_ctx); + o->vfu_ctx = NULL; + } + g_free(o->device); o->device = NULL; @@ -167,6 +244,11 @@ static void vfu_object_finalize(Object *obj) if (!k->nr_devs && vfu_object_auto_shutdown()) { qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); } + + if (o->machine_done.notify) { + qemu_remove_machine_init_done_notifier(&o->machine_done); + o->machine_done.notify = NULL; + } } static void vfu_object_class_init(ObjectClass *klass, void *data) |