Merge tag 'iommu-updates-v5.13' of git://git.kernel.org/pub/scm/linux/kernel/git...
[platform/kernel/linux-rpi.git] / drivers / vfio / vfio_iommu_type1.c
index 3c8048d..a0747c3 100644 (file)
@@ -16,7 +16,7 @@
  * IOMMU to support the IOMMU API and have few to no restrictions around
  * the IOVA range that can be mapped.  The Type1 IOMMU is currently
  * optimized for relatively static mappings of a userspace process with
- * userpsace pages pinned into memory.  We also assume devices and IOMMU
+ * userspace pages pinned into memory.  We also assume devices and IOMMU
  * domains are PCI based as the IOMMU API is still centered around a
  * device/bus interface rather than a group interface.
  */
@@ -77,7 +77,6 @@ struct vfio_iommu {
        bool                    v2;
        bool                    nesting;
        bool                    dirty_page_tracking;
-       bool                    pinned_page_dirty_scope;
        bool                    container_open;
 };
 
@@ -877,7 +876,7 @@ again:
 
        /*
         * If iommu capable domain exist in the container then all pages are
-        * already pinned and accounted. Accouting should be done if there is no
+        * already pinned and accounted. Accounting should be done if there is no
         * iommu capable domain in the container.
         */
        do_accounting = !IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu);
@@ -960,7 +959,7 @@ static int vfio_iommu_type1_unpin_pages(void *iommu_data,
        bool do_accounting;
        int i;
 
-       if (!iommu || !user_pfn)
+       if (!iommu || !user_pfn || npage <= 0)
                return -EINVAL;
 
        /* Supported for v2 version only */
@@ -977,13 +976,13 @@ static int vfio_iommu_type1_unpin_pages(void *iommu_data,
                iova = user_pfn[i] << PAGE_SHIFT;
                dma = vfio_find_dma(iommu, iova, PAGE_SIZE);
                if (!dma)
-                       goto unpin_exit;
+                       break;
+
                vfio_unpin_page_external(dma, iova, do_accounting);
        }
 
-unpin_exit:
        mutex_unlock(&iommu->lock);
-       return i > npage ? npage : (i > 0 ? i : -EINVAL);
+       return i > 0 ? i : -EINVAL;
 }
 
 static long vfio_sync_unpin(struct vfio_dma *dma, struct vfio_domain *domain,
@@ -1933,28 +1932,13 @@ static bool vfio_iommu_has_sw_msi(struct list_head *group_resv_regions,
        return ret;
 }
 
-static struct device *vfio_mdev_get_iommu_device(struct device *dev)
-{
-       struct device *(*fn)(struct device *dev);
-       struct device *iommu_device;
-
-       fn = symbol_get(mdev_get_iommu_device);
-       if (fn) {
-               iommu_device = fn(dev);
-               symbol_put(mdev_get_iommu_device);
-
-               return iommu_device;
-       }
-
-       return NULL;
-}
-
 static int vfio_mdev_attach_domain(struct device *dev, void *data)
 {
+       struct mdev_device *mdev = to_mdev_device(dev);
        struct iommu_domain *domain = data;
        struct device *iommu_device;
 
-       iommu_device = vfio_mdev_get_iommu_device(dev);
+       iommu_device = mdev_get_iommu_device(mdev);
        if (iommu_device) {
                if (iommu_dev_feature_enabled(iommu_device, IOMMU_DEV_FEAT_AUX))
                        return iommu_aux_attach_device(domain, iommu_device);
@@ -1967,10 +1951,11 @@ static int vfio_mdev_attach_domain(struct device *dev, void *data)
 
 static int vfio_mdev_detach_domain(struct device *dev, void *data)
 {
+       struct mdev_device *mdev = to_mdev_device(dev);
        struct iommu_domain *domain = data;
        struct device *iommu_device;
 
-       iommu_device = vfio_mdev_get_iommu_device(dev);
+       iommu_device = mdev_get_iommu_device(mdev);
        if (iommu_device) {
                if (iommu_dev_feature_enabled(iommu_device, IOMMU_DEV_FEAT_AUX))
                        iommu_aux_detach_device(domain, iommu_device);
@@ -2018,9 +2003,10 @@ static bool vfio_bus_is_mdev(struct bus_type *bus)
 
 static int vfio_mdev_iommu_device(struct device *dev, void *data)
 {
+       struct mdev_device *mdev = to_mdev_device(dev);
        struct device **old = data, *new;
 
-       new = vfio_mdev_get_iommu_device(dev);
+       new = mdev_get_iommu_device(mdev);
        if (!new || (*old && *old != new))
                return -EINVAL;
 
@@ -2177,7 +2163,7 @@ static int vfio_iommu_resv_exclude(struct list_head *iova,
                                continue;
                        /*
                         * Insert a new node if current node overlaps with the
-                        * reserve region to exlude that from valid iova range.
+                        * reserve region to exclude that from valid iova range.
                         * Note that, new node is inserted before the current
                         * node and finally the current node is deleted keeping
                         * the list updated and sorted.