diff options
Diffstat (limited to 'target/linux/layerscape/patches-5.4/821-vfio-0009-vfio-fsl-mc-Add-read-write-support-for-fsl-mc-device.patch')
-rw-r--r-- | target/linux/layerscape/patches-5.4/821-vfio-0009-vfio-fsl-mc-Add-read-write-support-for-fsl-mc-device.patch | 183 |
1 files changed, 0 insertions, 183 deletions
diff --git a/target/linux/layerscape/patches-5.4/821-vfio-0009-vfio-fsl-mc-Add-read-write-support-for-fsl-mc-device.patch b/target/linux/layerscape/patches-5.4/821-vfio-0009-vfio-fsl-mc-Add-read-write-support-for-fsl-mc-device.patch deleted file mode 100644 index 5d3d9632ae..0000000000 --- a/target/linux/layerscape/patches-5.4/821-vfio-0009-vfio-fsl-mc-Add-read-write-support-for-fsl-mc-device.patch +++ /dev/null @@ -1,183 +0,0 @@ -From c4fbb93e85b13edc174fa6fc3105341f646305e4 Mon Sep 17 00:00:00 2001 -From: Diana Craciun <diana.craciun@nxp.com> -Date: Wed, 2 Oct 2019 11:14:52 +0300 -Subject: [PATCH] vfio/fsl-mc: Add read/write support for fsl-mc devices - -This patch adds support to read and write ioctls for -fsl-mc devices. Only read-write to DPRC/DPMCP devices -are supported while read writes on other fsl-mc devices -is not supported by this patch. - -Also current patch limits userspace to write complete -64byte command once and read 64byte response by one ioctl. - -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 | 125 +++++++++++++++++++++++++++++- - drivers/vfio/fsl-mc/vfio_fsl_mc_private.h | 1 + - 2 files changed, 124 insertions(+), 2 deletions(-) - ---- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c -+++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c -@@ -12,6 +12,7 @@ - #include <linux/types.h> - #include <linux/vfio.h> - #include <linux/fsl/mc.h> -+#include <linux/delay.h> - - #include "vfio_fsl_mc_private.h" - -@@ -112,6 +113,11 @@ static int vfio_fsl_mc_regions_init(stru - } - static void vfio_fsl_mc_regions_cleanup(struct vfio_fsl_mc_device *vdev) - { -+ int i; -+ -+ for (i = 0; i < vdev->num_regions; i++) -+ iounmap(vdev->regions[i].ioaddr); -+ - vdev->num_regions = 0; - kfree(vdev->regions); - } -@@ -308,13 +314,128 @@ static long vfio_fsl_mc_ioctl(void *devi - static ssize_t vfio_fsl_mc_read(void *device_data, char __user *buf, - size_t count, loff_t *ppos) - { -- return -EINVAL; -+ struct vfio_fsl_mc_device *vdev = device_data; -+ unsigned int index = VFIO_FSL_MC_OFFSET_TO_INDEX(*ppos); -+ loff_t off = *ppos & VFIO_FSL_MC_OFFSET_MASK; -+ struct vfio_fsl_mc_region *region; -+ uint64_t data[8]; -+ int i; -+ -+ /* Read ioctl supported only for DPRC and DPMCP device */ -+ if (strcmp(vdev->mc_dev->obj_desc.type, "dprc") && -+ strcmp(vdev->mc_dev->obj_desc.type, "dpmcp")) -+ return -EINVAL; -+ -+ if (index >= vdev->num_regions) -+ return -EINVAL; -+ -+ region = &vdev->regions[index]; -+ -+ if (!(region->flags & VFIO_REGION_INFO_FLAG_READ)) -+ return -EINVAL; -+ -+ -+ if (!region->ioaddr) { -+ region->ioaddr = ioremap_nocache(region->addr, region->size); -+ if (!region->ioaddr) -+ return -ENOMEM; -+ } -+ -+ if (count != 64 || off != 0) -+ return -EINVAL; -+ -+ for (i = 7; i >= 0; i--) -+ data[i] = readq(region->ioaddr + i * sizeof(uint64_t)); -+ -+ if (copy_to_user(buf, data, 64)) -+ return -EFAULT; -+ -+ return count; - } - -+#define MC_CMD_COMPLETION_TIMEOUT_MS 5000 -+#define MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS 500 -+ -+static int vfio_fsl_mc_send_command(void __iomem *ioaddr, uint64_t *cmd_data) -+{ -+ int i; -+ enum mc_cmd_status status; -+ unsigned long timeout_usecs = MC_CMD_COMPLETION_TIMEOUT_MS * 1000; -+ -+ /* Write at command parameter into portal */ -+ for (i = 7; i >= 1; i--) -+ writeq_relaxed(cmd_data[i], ioaddr + i * sizeof(uint64_t)); -+ -+ /* Write command header in the end */ -+ writeq(cmd_data[0], ioaddr); -+ -+ /* Wait for response before returning to user-space -+ * This can be optimized in future to even prepare response -+ * before returning to user-space and avoid read ioctl. -+ */ -+ for (;;) { -+ u64 header; -+ struct mc_cmd_header *resp_hdr; -+ -+ header = cpu_to_le64(readq_relaxed(ioaddr)); -+ -+ resp_hdr = (struct mc_cmd_header *)&header; -+ status = (enum mc_cmd_status)resp_hdr->status; -+ if (status != MC_CMD_STATUS_READY) -+ break; -+ -+ udelay(MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS); -+ timeout_usecs -= MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS; -+ if (timeout_usecs == 0) -+ return -ETIMEDOUT; -+ } -+ -+ return 0; -+} -+ -+ - static ssize_t vfio_fsl_mc_write(void *device_data, const char __user *buf, - size_t count, loff_t *ppos) - { -- return -EINVAL; -+ struct vfio_fsl_mc_device *vdev = device_data; -+ unsigned int index = VFIO_FSL_MC_OFFSET_TO_INDEX(*ppos); -+ loff_t off = *ppos & VFIO_FSL_MC_OFFSET_MASK; -+ struct vfio_fsl_mc_region *region; -+ uint64_t data[8]; -+ int ret; -+ -+ -+ /* Write ioctl supported only for DPRC and DPMCP device */ -+ if (strcmp(vdev->mc_dev->obj_desc.type, "dprc") && -+ strcmp(vdev->mc_dev->obj_desc.type, "dpmcp")) -+ return -EINVAL; -+ -+ if (index >= vdev->num_regions) -+ return -EINVAL; -+ -+ region = &vdev->regions[index]; -+ -+ if (!(region->flags & VFIO_REGION_INFO_FLAG_WRITE)) -+ return -EINVAL; -+ -+ if (!region->ioaddr) { -+ region->ioaddr = ioremap_nocache(region->addr, region->size); -+ if (!region->ioaddr) -+ return -ENOMEM; -+ } -+ -+ if (count != 64 || off != 0) -+ return -EINVAL; -+ -+ if (copy_from_user(&data, buf, 64)) -+ return -EFAULT; -+ -+ ret = vfio_fsl_mc_send_command(region->ioaddr, data); -+ if (ret) -+ return ret; -+ -+ return count; -+ - } - - static int vfio_fsl_mc_mmap_mmio(struct vfio_fsl_mc_region region, ---- a/drivers/vfio/fsl-mc/vfio_fsl_mc_private.h -+++ b/drivers/vfio/fsl-mc/vfio_fsl_mc_private.h -@@ -32,6 +32,7 @@ struct vfio_fsl_mc_region { - u32 type; - u64 addr; - resource_size_t size; -+ void __iomem *ioaddr; - }; - - struct vfio_fsl_mc_device { |