vfio-ccw: Refactor the unregister of the async regions
authorEric Farman <farman@linux.ibm.com>
Tue, 5 May 2020 12:27:40 +0000 (14:27 +0200)
committerCornelia Huck <cohuck@redhat.com>
Tue, 2 Jun 2020 11:14:08 +0000 (13:14 +0200)
This is mostly for the purposes of a later patch, since
we'll need to do the same thing later.

While we are at it, move the resulting function call to ahead
of the unregistering of the IOMMU notifier, so that it's done
in the reverse order of how it was created.

Signed-off-by: Eric Farman <farman@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Message-Id: <20200505122745.53208-4-farman@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
drivers/s390/cio/vfio_ccw_ops.c
drivers/s390/cio/vfio_ccw_private.h

index f0d71ab77c50e90c642ef666092ff77707c53ef4..d4fc84b8867f875d60609d4ded85dbd7d856ce4f 100644 (file)
@@ -181,7 +181,6 @@ static void vfio_ccw_mdev_release(struct mdev_device *mdev)
 {
        struct vfio_ccw_private *private =
                dev_get_drvdata(mdev_parent_dev(mdev));
-       int i;
 
        if ((private->state != VFIO_CCW_STATE_NOT_OPER) &&
            (private->state != VFIO_CCW_STATE_STANDBY)) {
@@ -191,15 +190,9 @@ static void vfio_ccw_mdev_release(struct mdev_device *mdev)
        }
 
        cp_free(&private->cp);
+       vfio_ccw_unregister_dev_regions(private);
        vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
                                 &private->nb);
-
-       for (i = 0; i < private->num_regions; i++)
-               private->region[i].ops->release(private, &private->region[i]);
-
-       private->num_regions = 0;
-       kfree(private->region);
-       private->region = NULL;
 }
 
 static ssize_t vfio_ccw_mdev_read_io_region(struct vfio_ccw_private *private,
@@ -482,6 +475,17 @@ int vfio_ccw_register_dev_region(struct vfio_ccw_private *private,
        return 0;
 }
 
+void vfio_ccw_unregister_dev_regions(struct vfio_ccw_private *private)
+{
+       int i;
+
+       for (i = 0; i < private->num_regions; i++)
+               private->region[i].ops->release(private, &private->region[i]);
+       private->num_regions = 0;
+       kfree(private->region);
+       private->region = NULL;
+}
+
 static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
                                   unsigned int cmd,
                                   unsigned long arg)
index 9b9bb4982972a20902ff1d736874bea8a7c41db5..ce3834159d985ad965037dd5e86ec0f5cf4e647f 100644 (file)
@@ -53,6 +53,7 @@ int vfio_ccw_register_dev_region(struct vfio_ccw_private *private,
                                 unsigned int subtype,
                                 const struct vfio_ccw_regops *ops,
                                 size_t size, u32 flags, void *data);
+void vfio_ccw_unregister_dev_regions(struct vfio_ccw_private *private);
 
 int vfio_ccw_register_async_dev_regions(struct vfio_ccw_private *private);