diff options
author | Eric Farman <farman@linux.ibm.com> | 2021-01-04 21:20:57 +0100 |
---|---|---|
committer | Cornelia Huck <cohuck@redhat.com> | 2021-01-21 11:19:45 +0100 |
commit | b2f96f9e4f5fbc8f2770a436191cb328da4d5350 (patch) | |
tree | b15ebf11b76e3c7a55c6203c61838b188db87095 /hw/vfio | |
parent | b3c818a47f419b6e2f5508fe29e7a30843236fee (diff) | |
download | qemu-b2f96f9e4f5fbc8f2770a436191cb328da4d5350.zip qemu-b2f96f9e4f5fbc8f2770a436191cb328da4d5350.tar.gz qemu-b2f96f9e4f5fbc8f2770a436191cb328da4d5350.tar.bz2 |
vfio-ccw: Connect the device request notifier
Now that the vfio-ccw code has a notifier interface to request that
a device be unplugged, let's wire that together.
Signed-off-by: Eric Farman <farman@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Message-Id: <20210104202057.48048-4-farman@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'hw/vfio')
-rw-r--r-- | hw/vfio/ccw.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c index d2755d7..bc78a0a 100644 --- a/hw/vfio/ccw.c +++ b/hw/vfio/ccw.c @@ -49,6 +49,7 @@ struct VFIOCCWDevice { struct ccw_crw_region *crw_region; EventNotifier io_notifier; EventNotifier crw_notifier; + EventNotifier req_notifier; bool force_orb_pfch; bool warned_orb_pfch; }; @@ -287,6 +288,21 @@ static void vfio_ccw_crw_read(VFIOCCWDevice *vcdev) } while (1); } +static void vfio_ccw_req_notifier_handler(void *opaque) +{ + VFIOCCWDevice *vcdev = opaque; + Error *err = NULL; + + if (!event_notifier_test_and_clear(&vcdev->req_notifier)) { + return; + } + + qdev_unplug(DEVICE(vcdev), &err); + if (err) { + warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name); + } +} + static void vfio_ccw_crw_notifier_handler(void *opaque) { VFIOCCWDevice *vcdev = opaque; @@ -386,6 +402,10 @@ static void vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev, notifier = &vcdev->crw_notifier; fd_read = vfio_ccw_crw_notifier_handler; break; + case VFIO_CCW_REQ_IRQ_INDEX: + notifier = &vcdev->req_notifier; + fd_read = vfio_ccw_req_notifier_handler; + break; default: error_setg(errp, "vfio: Unsupported device irq(%d)", irq); return; @@ -440,6 +460,9 @@ static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice *vcdev, case VFIO_CCW_CRW_IRQ_INDEX: notifier = &vcdev->crw_notifier; break; + case VFIO_CCW_REQ_IRQ_INDEX: + notifier = &vcdev->req_notifier; + break; default: error_report("vfio: Unsupported device irq(%d)", irq); return; @@ -661,20 +684,28 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp) vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, &err); if (err) { - goto out_notifier_err; + goto out_io_notifier_err; } if (vcdev->crw_region) { vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX, &err); if (err) { - vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX); - goto out_notifier_err; + goto out_crw_notifier_err; } } + vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, &err); + if (err) { + goto out_req_notifier_err; + } + return; -out_notifier_err: +out_req_notifier_err: + vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX); +out_crw_notifier_err: + vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX); +out_io_notifier_err: vfio_ccw_put_region(vcdev); out_region_err: vfio_ccw_put_device(vcdev); @@ -696,6 +727,7 @@ static void vfio_ccw_unrealize(DeviceState *dev) S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev); VFIOGroup *group = vcdev->vdev.group; + vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX); vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX); vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX); vfio_ccw_put_region(vcdev); |