VFIO returns a file descriptor which we can use to manipulate the memory
regions of the device. Since some memory regions we cannot mmap due to
security concerns, we also allow to read and write to this file descriptor
directly.

Signed-off-by: Antonios Motakis <a.mota...@virtualopensystems.com>
---
 drivers/vfio/vfio_platform.c | 37 ++++++++++++++++++++++++++++++++++---
 1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/drivers/vfio/vfio_platform.c b/drivers/vfio/vfio_platform.c
index 6364316..b92d7bb 100644
--- a/drivers/vfio/vfio_platform.c
+++ b/drivers/vfio/vfio_platform.c
@@ -102,7 +102,8 @@ static long vfio_platform_ioctl(void *device_data,
 
                info.offset = res.start;        /* map phys addr with offset */
                info.size = resource_size(&res);
-               info.flags = 0;
+               info.flags = VFIO_REGION_INFO_FLAG_READ
+                               | VFIO_REGION_INFO_FLAG_WRITE;
                /* Only regions addressed with PAGE granularity can be MMAPed
                 * securely. */
                if (!(info.offset & ~PAGE_MASK) && !(info.size & ~PAGE_MASK))
@@ -153,13 +154,43 @@ static bool is_in_resource(struct resource res, u64 addr, 
u64 size)
 static ssize_t vfio_platform_read(void *device_data, char __user *buf,
                             size_t count, loff_t *ppos)
 {
-       return 0;
+       struct vfio_platform_device *vdev = device_data;
+       struct device_node *of_node = vdev->pdev->dev.of_node;
+       struct resource res;
+       int i;
+
+       for (i = 0; !of_address_to_resource(of_node, i, &res); i++) {
+               if (!is_in_resource(res, *ppos, count))
+                       continue;
+
+               if (copy_to_user(buf, ppos, count))
+                       return -EFAULT;
+               else
+                       return count;
+       }
+
+       return -EINVAL;
 }
 
 static ssize_t vfio_platform_write(void *device_data, const char __user *buf,
                              size_t count, loff_t *ppos)
 {
-       return 0;
+       struct vfio_platform_device *vdev = device_data;
+       struct device_node *of_node = vdev->pdev->dev.of_node;
+       struct resource res;
+       int i;
+
+       for (i = 0; !of_address_to_resource(of_node, i, &res); i++) {
+               if (!is_in_resource(res, *ppos, count))
+                       continue;
+
+               if (copy_from_user(ppos, buf, count))
+                       return -EFAULT;
+               else
+                       return count;
+       }
+
+       return -EINVAL;
 }
 
 static int vfio_platform_mmap(void *device_data, struct vm_area_struct *vma)
-- 
1.8.1.2

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to