aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/821-vfio-0004-vfio-fsl-mc-Implement-VFIO_DEVICE_GET_REGION_INFO-io.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-5.4/821-vfio-0004-vfio-fsl-mc-Implement-VFIO_DEVICE_GET_REGION_INFO-io.patch')
-rw-r--r--target/linux/layerscape/patches-5.4/821-vfio-0004-vfio-fsl-mc-Implement-VFIO_DEVICE_GET_REGION_INFO-io.patch153
1 files changed, 153 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-5.4/821-vfio-0004-vfio-fsl-mc-Implement-VFIO_DEVICE_GET_REGION_INFO-io.patch b/target/linux/layerscape/patches-5.4/821-vfio-0004-vfio-fsl-mc-Implement-VFIO_DEVICE_GET_REGION_INFO-io.patch
new file mode 100644
index 0000000000..c538ed0d5c
--- /dev/null
+++ b/target/linux/layerscape/patches-5.4/821-vfio-0004-vfio-fsl-mc-Implement-VFIO_DEVICE_GET_REGION_INFO-io.patch
@@ -0,0 +1,153 @@
+From 10abb46294d1569826854f77bcdb5d38d8db8e79 Mon Sep 17 00:00:00 2001
+From: Diana Craciun <diana.craciun@nxp.com>
+Date: Thu, 26 Sep 2019 15:13:24 +0300
+Subject: [PATCH] vfio/fsl-mc: Implement VFIO_DEVICE_GET_REGION_INFO ioctl call
+
+Expose to userspace information about the memory regions.
+
+Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
+Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
+---
+ drivers/vfio/fsl-mc/vfio_fsl_mc.c | 76 ++++++++++++++++++++++++++++++-
+ drivers/vfio/fsl-mc/vfio_fsl_mc_private.h | 19 ++++++++
+ 2 files changed, 94 insertions(+), 1 deletion(-)
+
+--- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c
++++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
+@@ -16,16 +16,70 @@
+ #include "vfio_fsl_mc_private.h"
+
+
++static int vfio_fsl_mc_regions_init(struct vfio_fsl_mc_device *vdev)
++{
++ struct fsl_mc_device *mc_dev = vdev->mc_dev;
++ int count = mc_dev->obj_desc.region_count;
++ int i;
++
++ vdev->regions = kcalloc(count, sizeof(struct vfio_fsl_mc_region),
++ GFP_KERNEL);
++ if (!vdev->regions)
++ return -ENOMEM;
++
++ for (i = 0; i < count; i++) {
++ struct resource *res = &mc_dev->regions[i];
++
++ vdev->regions[i].addr = res->start;
++ vdev->regions[i].size = PAGE_ALIGN((resource_size(res)));
++ vdev->regions[i].flags = 0;
++ }
++
++ vdev->num_regions = mc_dev->obj_desc.region_count;
++ return 0;
++}
++static void vfio_fsl_mc_regions_cleanup(struct vfio_fsl_mc_device *vdev)
++{
++ vdev->num_regions = 0;
++ kfree(vdev->regions);
++}
++
+ static int vfio_fsl_mc_open(void *device_data)
+ {
++ struct vfio_fsl_mc_device *vdev = device_data;
++ int ret;
++
+ if (!try_module_get(THIS_MODULE))
+ return -ENODEV;
+
++ mutex_lock(&vdev->driver_lock);
++ if (!vdev->refcnt) {
++ ret = vfio_fsl_mc_regions_init(vdev);
++ if (ret)
++ goto err_reg_init;
++ }
++ vdev->refcnt++;
++
++ mutex_unlock(&vdev->driver_lock);
+ return 0;
++
++err_reg_init:
++ mutex_unlock(&vdev->driver_lock);
++ module_put(THIS_MODULE);
++ return ret;
+ }
+
+ static void vfio_fsl_mc_release(void *device_data)
+ {
++ struct vfio_fsl_mc_device *vdev = device_data;
++
++ mutex_lock(&vdev->driver_lock);
++
++ if (!(--vdev->refcnt))
++ vfio_fsl_mc_regions_cleanup(vdev);
++
++ mutex_unlock(&vdev->driver_lock);
++
+ module_put(THIS_MODULE);
+ }
+
+@@ -59,7 +113,26 @@ static long vfio_fsl_mc_ioctl(void *devi
+ }
+ case VFIO_DEVICE_GET_REGION_INFO:
+ {
+- return -EINVAL;
++ struct vfio_region_info info;
++
++ minsz = offsetofend(struct vfio_region_info, offset);
++
++ if (copy_from_user(&info, (void __user *)arg, minsz))
++ return -EFAULT;
++
++ if (info.argsz < minsz)
++ return -EINVAL;
++
++ if (info.index >= vdev->num_regions)
++ return -EINVAL;
++
++ /* map offset to the physical address */
++ info.offset = VFIO_FSL_MC_INDEX_TO_OFFSET(info.index);
++ info.size = vdev->regions[info.index].size;
++ info.flags = vdev->regions[info.index].flags;
++
++ return copy_to_user((void __user *)arg, &info, minsz);
++
+ }
+ case VFIO_DEVICE_GET_IRQ_INFO:
+ {
+@@ -206,6 +279,7 @@ static int vfio_fsl_mc_probe(struct fsl_
+ vfio_iommu_group_put(group, dev);
+ return ret;
+ }
++ mutex_init(&vdev->driver_lock);
+
+ return ret;
+ }
+--- a/drivers/vfio/fsl-mc/vfio_fsl_mc_private.h
++++ b/drivers/vfio/fsl-mc/vfio_fsl_mc_private.h
+@@ -7,8 +7,27 @@
+ #ifndef VFIO_FSL_MC_PRIVATE_H
+ #define VFIO_FSL_MC_PRIVATE_H
+
++#define VFIO_FSL_MC_OFFSET_SHIFT 40
++#define VFIO_FSL_MC_OFFSET_MASK (((u64)(1) << VFIO_FSL_MC_OFFSET_SHIFT) - 1)
++
++#define VFIO_FSL_MC_OFFSET_TO_INDEX(off) (off >> VFIO_FSL_MC_OFFSET_SHIFT)
++
++#define VFIO_FSL_MC_INDEX_TO_OFFSET(index) \
++ ((u64)(index) << VFIO_FSL_MC_OFFSET_SHIFT)
++
++struct vfio_fsl_mc_region {
++ u32 flags;
++ u32 type;
++ u64 addr;
++ resource_size_t size;
++};
++
+ struct vfio_fsl_mc_device {
+ struct fsl_mc_device *mc_dev;
++ int refcnt;
++ u32 num_regions;
++ struct vfio_fsl_mc_region *regions;
++ struct mutex driver_lock;
+ };
+
+ #endif /* VFIO_PCI_PRIVATE_H */