Message ID | 01f4837eaa73d340542961cf36a6028f4a681a0e.1642626515.git.jag.raman@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | vfio-user server in QEMU | expand |
On Wed, Jan 19, 2022 at 04:42:00PM -0500, Jagannathan Raman wrote: > Find the PCI device with specified id. Initialize the device context > with the QEMU 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> > --- > hw/remote/vfio-user-obj.c | 60 +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 60 insertions(+) > > diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c > index 810a7c3943..10db78eb8d 100644 > --- a/hw/remote/vfio-user-obj.c > +++ b/hw/remote/vfio-user-obj.c > @@ -44,6 +44,8 @@ > #include "qemu/notify.h" > #include "sysemu/sysemu.h" > #include "libvfio-user.h" > +#include "hw/qdev-core.h" > +#include "hw/pci/pci.h" > > #define TYPE_VFU_OBJECT "x-vfio-user-server" > OBJECT_DECLARE_TYPE(VfuObject, VfuObjectClass, VFU_OBJECT) > @@ -89,6 +91,10 @@ struct VfuObject { > Notifier machine_done; > > vfu_ctx_t *vfu_ctx; > + > + PCIDevice *pci_dev; > + > + Error *unplug_blocker; > }; > > static void vfu_object_init_ctx(VfuObject *o, Error **errp); > @@ -161,6 +167,9 @@ static void vfu_object_machine_done(Notifier *notifier, void *data) > static void vfu_object_init_ctx(VfuObject *o, Error **errp) > { > ERRP_GUARD(); > + DeviceState *dev = NULL; > + vfu_pci_type_t pci_type = VFU_PCI_TYPE_CONVENTIONAL; > + int ret; > > if (o->vfu_ctx || !o->socket || !o->device || > !phase_check(PHASE_MACHINE_READY)) { > @@ -179,6 +188,49 @@ static void vfu_object_init_ctx(VfuObject *o, Error **errp) > error_setg(errp, "vfu: Failed to create context - %s", strerror(errno)); > return; > } > + > + dev = qdev_find_recursive(sysbus_get_default(), o->device); > + if (dev == NULL) { > + error_setg(errp, "vfu: Device %s not found", o->device); > + goto fail; > + } > + > + if (!object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { > + error_setg(errp, "vfu: %s not a PCI device", o->device); > + goto fail; > + } > + > + o->pci_dev = PCI_DEVICE(dev); > + > + if (pci_is_express(o->pci_dev)) { > + pci_type = VFU_PCI_TYPE_EXPRESS; > + } > + > + ret = vfu_pci_init(o->vfu_ctx, pci_type, PCI_HEADER_TYPE_NORMAL, 0); > + if (ret < 0) { > + error_setg(errp, > + "vfu: Failed to attach PCI device %s to context - %s", > + o->device, strerror(errno)); > + goto fail; > + } > + > + error_setg(&o->unplug_blocker, "%s is in use", o->device); More detailed error message: "x-vfio-user-server for %s must be deleted before unplugging" Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
> On Jan 25, 2022, at 9:48 AM, Stefan Hajnoczi <stefanha@redhat.com> wrote: > > On Wed, Jan 19, 2022 at 04:42:00PM -0500, Jagannathan Raman wrote: >> Find the PCI device with specified id. Initialize the device context >> with the QEMU 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> >> --- >> hw/remote/vfio-user-obj.c | 60 +++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 60 insertions(+) >> >> diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c >> index 810a7c3943..10db78eb8d 100644 >> --- a/hw/remote/vfio-user-obj.c >> +++ b/hw/remote/vfio-user-obj.c >> @@ -44,6 +44,8 @@ >> #include "qemu/notify.h" >> #include "sysemu/sysemu.h" >> #include "libvfio-user.h" >> +#include "hw/qdev-core.h" >> +#include "hw/pci/pci.h" >> >> #define TYPE_VFU_OBJECT "x-vfio-user-server" >> OBJECT_DECLARE_TYPE(VfuObject, VfuObjectClass, VFU_OBJECT) >> @@ -89,6 +91,10 @@ struct VfuObject { >> Notifier machine_done; >> >> vfu_ctx_t *vfu_ctx; >> + >> + PCIDevice *pci_dev; >> + >> + Error *unplug_blocker; >> }; >> >> static void vfu_object_init_ctx(VfuObject *o, Error **errp); >> @@ -161,6 +167,9 @@ static void vfu_object_machine_done(Notifier *notifier, void *data) >> static void vfu_object_init_ctx(VfuObject *o, Error **errp) >> { >> ERRP_GUARD(); >> + DeviceState *dev = NULL; >> + vfu_pci_type_t pci_type = VFU_PCI_TYPE_CONVENTIONAL; >> + int ret; >> >> if (o->vfu_ctx || !o->socket || !o->device || >> !phase_check(PHASE_MACHINE_READY)) { >> @@ -179,6 +188,49 @@ static void vfu_object_init_ctx(VfuObject *o, Error **errp) >> error_setg(errp, "vfu: Failed to create context - %s", strerror(errno)); >> return; >> } >> + >> + dev = qdev_find_recursive(sysbus_get_default(), o->device); >> + if (dev == NULL) { >> + error_setg(errp, "vfu: Device %s not found", o->device); >> + goto fail; >> + } >> + >> + if (!object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { >> + error_setg(errp, "vfu: %s not a PCI device", o->device); >> + goto fail; >> + } >> + >> + o->pci_dev = PCI_DEVICE(dev); >> + >> + if (pci_is_express(o->pci_dev)) { >> + pci_type = VFU_PCI_TYPE_EXPRESS; >> + } >> + >> + ret = vfu_pci_init(o->vfu_ctx, pci_type, PCI_HEADER_TYPE_NORMAL, 0); >> + if (ret < 0) { >> + error_setg(errp, >> + "vfu: Failed to attach PCI device %s to context - %s", >> + o->device, strerror(errno)); >> + goto fail; >> + } >> + >> + error_setg(&o->unplug_blocker, "%s is in use", o->device); > > More detailed error message: > "x-vfio-user-server for %s must be deleted before unplugging" Got it, thank you! -- Jag > > Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c index 810a7c3943..10db78eb8d 100644 --- a/hw/remote/vfio-user-obj.c +++ b/hw/remote/vfio-user-obj.c @@ -44,6 +44,8 @@ #include "qemu/notify.h" #include "sysemu/sysemu.h" #include "libvfio-user.h" +#include "hw/qdev-core.h" +#include "hw/pci/pci.h" #define TYPE_VFU_OBJECT "x-vfio-user-server" OBJECT_DECLARE_TYPE(VfuObject, VfuObjectClass, VFU_OBJECT) @@ -89,6 +91,10 @@ struct VfuObject { Notifier machine_done; vfu_ctx_t *vfu_ctx; + + PCIDevice *pci_dev; + + Error *unplug_blocker; }; static void vfu_object_init_ctx(VfuObject *o, Error **errp); @@ -161,6 +167,9 @@ static void vfu_object_machine_done(Notifier *notifier, void *data) static void vfu_object_init_ctx(VfuObject *o, Error **errp) { ERRP_GUARD(); + DeviceState *dev = NULL; + vfu_pci_type_t pci_type = VFU_PCI_TYPE_CONVENTIONAL; + int ret; if (o->vfu_ctx || !o->socket || !o->device || !phase_check(PHASE_MACHINE_READY)) { @@ -179,6 +188,49 @@ static void vfu_object_init_ctx(VfuObject *o, Error **errp) error_setg(errp, "vfu: Failed to create context - %s", strerror(errno)); return; } + + dev = qdev_find_recursive(sysbus_get_default(), o->device); + if (dev == NULL) { + error_setg(errp, "vfu: Device %s not found", o->device); + goto fail; + } + + if (!object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { + error_setg(errp, "vfu: %s not a PCI device", o->device); + goto fail; + } + + o->pci_dev = PCI_DEVICE(dev); + + if (pci_is_express(o->pci_dev)) { + pci_type = VFU_PCI_TYPE_EXPRESS; + } + + ret = vfu_pci_init(o->vfu_ctx, pci_type, PCI_HEADER_TYPE_NORMAL, 0); + if (ret < 0) { + error_setg(errp, + "vfu: Failed to attach PCI device %s to context - %s", + o->device, strerror(errno)); + goto fail; + } + + error_setg(&o->unplug_blocker, "%s is in use", o->device); + qdev_add_unplug_blocker(DEVICE(o->pci_dev), o->unplug_blocker, errp); + if (*errp) { + goto fail; + } + + return; + +fail: + vfu_destroy_ctx(o->vfu_ctx); + if (o->unplug_blocker && o->pci_dev) { + qdev_del_unplug_blocker(DEVICE(o->pci_dev), o->unplug_blocker); + error_free(o->unplug_blocker); + o->unplug_blocker = NULL; + } + o->vfu_ctx = NULL; + o->pci_dev = NULL; } static void vfu_object_init(Object *obj) @@ -219,6 +271,14 @@ static void vfu_object_finalize(Object *obj) o->device = NULL; + if (o->unplug_blocker && o->pci_dev) { + qdev_del_unplug_blocker(DEVICE(o->pci_dev), o->unplug_blocker); + error_free(o->unplug_blocker); + o->unplug_blocker = NULL; + } + + o->pci_dev = NULL; + if (!k->nr_devs && k->auto_shutdown) { qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); }