dc7afb
From db6a782f8b9ba062f195ff504b4d2f93e471fecc Mon Sep 17 00:00:00 2001
dc7afb
From: Thomas Huth <thuth@redhat.com>
dc7afb
Date: Tue, 11 May 2021 11:24:05 -0400
dc7afb
Subject: [PATCH 2/5] vfio-ccw: Connect the device request notifier
dc7afb
dc7afb
RH-Author: Thomas Huth <thuth@redhat.com>
dc7afb
Message-id: <20210511112405.297037-3-thuth@redhat.com>
dc7afb
Patchwork-id: 101536
dc7afb
O-Subject: [RHEL-8.5.0 qemu-kvm PATCH 2/2] vfio-ccw: Connect the device request notifier
dc7afb
Bugzilla: 1940450
dc7afb
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
dc7afb
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
dc7afb
RH-Acked-by: David Hildenbrand <david@redhat.com>
dc7afb
dc7afb
Now that the vfio-ccw code has a notifier interface to request that
dc7afb
a device be unplugged, let's wire that together.
dc7afb
dc7afb
Signed-off-by: Eric Farman <farman@linux.ibm.com>
dc7afb
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
dc7afb
Message-Id: <20210104202057.48048-4-farman@linux.ibm.com>
dc7afb
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
dc7afb
(cherry picked from commit b2f96f9e4f5fbc8f2770a436191cb328da4d5350)
dc7afb
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1940450
dc7afb
Signed-off-by: Thomas Huth <thuth@redhat.com>
dc7afb
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
dc7afb
---
dc7afb
 hw/vfio/ccw.c | 40 ++++++++++++++++++++++++++++++++++++----
dc7afb
 1 file changed, 36 insertions(+), 4 deletions(-)
dc7afb
dc7afb
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
dc7afb
index b72a505893..3d450fe1c9 100644
dc7afb
--- a/hw/vfio/ccw.c
dc7afb
+++ b/hw/vfio/ccw.c
dc7afb
@@ -49,6 +49,7 @@ struct VFIOCCWDevice {
dc7afb
     struct ccw_crw_region *crw_region;
dc7afb
     EventNotifier io_notifier;
dc7afb
     EventNotifier crw_notifier;
dc7afb
+    EventNotifier req_notifier;
dc7afb
     bool force_orb_pfch;
dc7afb
     bool warned_orb_pfch;
dc7afb
 };
dc7afb
@@ -287,6 +288,21 @@ static void vfio_ccw_crw_read(VFIOCCWDevice *vcdev)
dc7afb
     } while (1);
dc7afb
 }
dc7afb
 
dc7afb
+static void vfio_ccw_req_notifier_handler(void *opaque)
dc7afb
+{
dc7afb
+    VFIOCCWDevice *vcdev = opaque;
dc7afb
+    Error *err = NULL;
dc7afb
+
dc7afb
+    if (!event_notifier_test_and_clear(&vcdev->req_notifier)) {
dc7afb
+        return;
dc7afb
+    }
dc7afb
+
dc7afb
+    qdev_unplug(DEVICE(vcdev), &err;;
dc7afb
+    if (err) {
dc7afb
+        warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name);
dc7afb
+    }
dc7afb
+}
dc7afb
+
dc7afb
 static void vfio_ccw_crw_notifier_handler(void *opaque)
dc7afb
 {
dc7afb
     VFIOCCWDevice *vcdev = opaque;
dc7afb
@@ -386,6 +402,10 @@ static void vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev,
dc7afb
         notifier = &vcdev->crw_notifier;
dc7afb
         fd_read = vfio_ccw_crw_notifier_handler;
dc7afb
         break;
dc7afb
+    case VFIO_CCW_REQ_IRQ_INDEX:
dc7afb
+        notifier = &vcdev->req_notifier;
dc7afb
+        fd_read = vfio_ccw_req_notifier_handler;
dc7afb
+        break;
dc7afb
     default:
dc7afb
         error_setg(errp, "vfio: Unsupported device irq(%d)", irq);
dc7afb
         return;
dc7afb
@@ -440,6 +460,9 @@ static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice *vcdev,
dc7afb
     case VFIO_CCW_CRW_IRQ_INDEX:
dc7afb
         notifier = &vcdev->crw_notifier;
dc7afb
         break;
dc7afb
+    case VFIO_CCW_REQ_IRQ_INDEX:
dc7afb
+        notifier = &vcdev->req_notifier;
dc7afb
+        break;
dc7afb
     default:
dc7afb
         error_report("vfio: Unsupported device irq(%d)", irq);
dc7afb
         return;
dc7afb
@@ -657,20 +680,28 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
dc7afb
 
dc7afb
     vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, &err;;
dc7afb
     if (err) {
dc7afb
-        goto out_notifier_err;
dc7afb
+        goto out_io_notifier_err;
dc7afb
     }
dc7afb
 
dc7afb
     if (vcdev->crw_region) {
dc7afb
         vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX, &err;;
dc7afb
         if (err) {
dc7afb
-            vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
dc7afb
-            goto out_notifier_err;
dc7afb
+            goto out_crw_notifier_err;
dc7afb
         }
dc7afb
     }
dc7afb
 
dc7afb
+    vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, &err;;
dc7afb
+    if (err) {
dc7afb
+        goto out_req_notifier_err;
dc7afb
+    }
dc7afb
+
dc7afb
     return;
dc7afb
 
dc7afb
-out_notifier_err:
dc7afb
+out_req_notifier_err:
dc7afb
+    vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX);
dc7afb
+out_crw_notifier_err:
dc7afb
+    vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
dc7afb
+out_io_notifier_err:
dc7afb
     vfio_ccw_put_region(vcdev);
dc7afb
 out_region_err:
dc7afb
     vfio_ccw_put_device(vcdev);
dc7afb
@@ -692,6 +723,7 @@ static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
dc7afb
     S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
dc7afb
     VFIOGroup *group = vcdev->vdev.group;
dc7afb
 
dc7afb
+    vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX);
dc7afb
     vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX);
dc7afb
     vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX);
dc7afb
     vfio_ccw_put_region(vcdev);
dc7afb
-- 
dc7afb
2.27.0
dc7afb