From: Antonios Motakis <a.motakis@virtualopensystems.com>
To: kvmarm@lists.cs.columbia.edu, iommu@lists.linux-foundation.org,
alex.williamson@redhat.com
Cc: will.deacon@arm.com, tech@virtualopensystems.com,
christoffer.dall@linaro.org, eric.auger@linaro.org,
kim.phillips@freescale.com, marc.zyngier@arm.com,
Antonios Motakis <a.motakis@virtualopensystems.com>,
kvm@vger.kernel.org (open list:VFIO DRIVER),
linux-kernel@vger.kernel.org (open list)
Subject: [PATCH v8 08/18] vfio/platform: read and write support for the device fd
Date: Mon, 13 Oct 2014 15:10:15 +0200 [thread overview]
Message-ID: <1413205825-6370-9-git-send-email-a.motakis@virtualopensystems.com> (raw)
In-Reply-To: <1413205825-6370-1-git-send-email-a.motakis@virtualopensystems.com>
VFIO returns a file descriptor which we can use to manipulate the memory
regions of the device. Usually, the user will mmap memory regions that are
addressable on page boundaries, however for memory regions where this is
not the case we cannot provide mmap functionality due to security concerns.
For this reason we also need allow to read and write to the memory regions
via the file descriptor. Implement this funcionality only for MMIO regions
of platform devices; PIO regions are not being handled at this point.
Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
---
drivers/vfio/platform/vfio_platform_common.c | 150 ++++++++++++++++++++++++++
drivers/vfio/platform/vfio_platform_private.h | 1 +
2 files changed, 151 insertions(+)
diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c
index 8a7e474..ac74710 100644
--- a/drivers/vfio/platform/vfio_platform_common.c
+++ b/drivers/vfio/platform/vfio_platform_common.c
@@ -53,6 +53,10 @@ static int vfio_platform_regions_init(struct vfio_platform_device *vdev)
switch (resource_type(res)) {
case IORESOURCE_MEM:
vdev->regions[i].type = VFIO_PLATFORM_REGION_TYPE_MMIO;
+ vdev->regions[i].flags |= VFIO_REGION_INFO_FLAG_READ;
+ if (!(res->flags & IORESOURCE_READONLY))
+ vdev->regions[i].flags |=
+ VFIO_REGION_INFO_FLAG_WRITE;
break;
case IORESOURCE_IO:
vdev->regions[i].type = VFIO_PLATFORM_REGION_TYPE_PIO;
@@ -72,6 +76,11 @@ err:
static void vfio_platform_regions_cleanup(struct vfio_platform_device *vdev)
{
+ int i;
+
+ for (i = 0; i < vdev->num_regions; i++)
+ iounmap(vdev->regions[i].ioaddr);
+
vdev->num_regions = 0;
kfree(vdev->regions);
}
@@ -163,15 +172,156 @@ static long vfio_platform_ioctl(void *device_data,
return -ENOTTY;
}
+static ssize_t vfio_platform_read_mmio(struct vfio_platform_region reg,
+ char __user *buf, size_t count,
+ loff_t off)
+{
+ unsigned int done = 0;
+
+ if (!reg.ioaddr) {
+ reg.ioaddr =
+ ioremap_nocache(reg.addr, reg.size);
+
+ if (!reg.ioaddr)
+ return -ENOMEM;
+ }
+
+ while (count) {
+ size_t filled;
+
+ if (count >= 4 && !(off % 4)) {
+ u32 val;
+
+ val = ioread32(reg.ioaddr + off);
+ if (copy_to_user(buf, &val, 4))
+ goto err;
+
+ filled = 4;
+ } else if (count >= 2 && !(off % 2)) {
+ u16 val;
+
+ val = ioread16(reg.ioaddr + off);
+ if (copy_to_user(buf, &val, 2))
+ goto err;
+
+ filled = 2;
+ } else {
+ u8 val;
+
+ val = ioread8(reg.ioaddr + off);
+ if (copy_to_user(buf, &val, 1))
+ goto err;
+
+ filled = 1;
+ }
+
+
+ count -= filled;
+ done += filled;
+ off += filled;
+ buf += filled;
+ }
+
+ return done;
+err:
+ return -EFAULT;
+}
+
static ssize_t vfio_platform_read(void *device_data, char __user *buf,
size_t count, loff_t *ppos)
{
+ struct vfio_platform_device *vdev = device_data;
+ unsigned int index = VFIO_PLATFORM_OFFSET_TO_INDEX(*ppos);
+ loff_t off = *ppos & VFIO_PLATFORM_OFFSET_MASK;
+
+ if (index >= vdev->num_regions)
+ return -EINVAL;
+
+ if (!(vdev->regions[index].flags & VFIO_REGION_INFO_FLAG_READ))
+ return -EINVAL;
+
+ if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_MMIO)
+ return vfio_platform_read_mmio(vdev->regions[index],
+ buf, count, off);
+ else if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_PIO)
+ return -EINVAL; /* not implemented */
+
return -EINVAL;
}
+static ssize_t vfio_platform_write_mmio(struct vfio_platform_region reg,
+ const char __user *buf, size_t count,
+ loff_t off)
+{
+ unsigned int done = 0;
+
+ if (!reg.ioaddr) {
+ reg.ioaddr =
+ ioremap_nocache(reg.addr, reg.size);
+
+ if (!reg.ioaddr)
+ return -ENOMEM;
+ }
+
+ while (count) {
+ size_t filled;
+
+ if (count >= 4 && !(off % 4)) {
+ u32 val;
+
+ if (copy_from_user(&val, buf, 4))
+ goto err;
+ iowrite32(val, reg.ioaddr + off);
+
+ filled = 4;
+ } else if (count >= 2 && !(off % 2)) {
+ u16 val;
+
+ if (copy_from_user(&val, buf, 2))
+ goto err;
+ iowrite16(val, reg.ioaddr + off);
+
+ filled = 2;
+ } else {
+ u8 val;
+
+ if (copy_from_user(&val, buf, 1))
+ goto err;
+ iowrite8(val, reg.ioaddr + off);
+
+ filled = 1;
+ }
+
+ count -= filled;
+ done += filled;
+ off += filled;
+ buf += filled;
+ }
+
+ return done;
+err:
+ return -EFAULT;
+}
+
static ssize_t vfio_platform_write(void *device_data, const char __user *buf,
size_t count, loff_t *ppos)
{
+ struct vfio_platform_device *vdev = device_data;
+ unsigned int index = VFIO_PLATFORM_OFFSET_TO_INDEX(*ppos);
+ loff_t off = *ppos & VFIO_PLATFORM_OFFSET_MASK;
+
+ if (index >= vdev->num_regions)
+ return -EINVAL;
+
+ if (!(vdev->regions[index].flags & VFIO_REGION_INFO_FLAG_WRITE))
+ return -EINVAL;
+
+ if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_MMIO)
+ return vfio_platform_write_mmio(vdev->regions[index],
+ buf, count, off);
+ else if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_PIO)
+ return -EINVAL; /* not implemented */
+
return -EINVAL;
}
diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h
index 2a06035..db9f88d 100644
--- a/drivers/vfio/platform/vfio_platform_private.h
+++ b/drivers/vfio/platform/vfio_platform_private.h
@@ -31,6 +31,7 @@ struct vfio_platform_region {
u32 type;
#define VFIO_PLATFORM_REGION_TYPE_MMIO 1
#define VFIO_PLATFORM_REGION_TYPE_PIO 2
+ void __iomem *ioaddr;
};
struct vfio_platform_device {
--
2.1.1
next prev parent reply other threads:[~2014-10-13 13:11 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1413205825-6370-1-git-send-email-a.motakis@virtualopensystems.com>
2014-10-13 13:10 ` [PATCH v8 01/18] vfio/platform: initial skeleton of VFIO support for platform devices Antonios Motakis
2014-10-13 13:10 ` [PATCH v8 02/18] vfio: platform: probe to devices on the platform bus Antonios Motakis
2014-10-21 16:17 ` Alex Williamson
[not found] ` <54468BDA.6050606@linaro.org>
2014-10-22 13:53 ` Antonios Motakis
2014-10-13 13:10 ` [PATCH v8 03/18] vfio: platform: add the VFIO PLATFORM module to Kconfig Antonios Motakis
2014-10-13 13:10 ` [PATCH v8 04/18] vfio: amba: VFIO support for AMBA devices Antonios Motakis
2014-10-13 13:10 ` [PATCH v8 05/18] vfio: amba: add the VFIO for AMBA devices module to Kconfig Antonios Motakis
2014-10-13 13:10 ` [PATCH v8 06/18] vfio/platform: return info for bound device Antonios Motakis
2014-10-13 13:10 ` [PATCH v8 07/18] vfio/platform: return info for device memory mapped IO regions Antonios Motakis
2014-10-21 16:34 ` Alex Williamson
2014-10-21 18:18 ` Bharat.Bhushan
2014-10-21 18:57 ` Alex Williamson
2014-10-22 13:54 ` Antonios Motakis
2014-10-22 16:46 ` Alex Williamson
2014-10-22 17:53 ` Antonios Motakis
2014-10-13 13:10 ` Antonios Motakis [this message]
2014-10-13 13:10 ` [PATCH v8 09/18] vfio/platform: support MMAP of MMIO regions Antonios Motakis
2014-10-21 16:51 ` Alex Williamson
2014-10-22 13:55 ` Antonios Motakis
2014-10-22 16:56 ` Alex Williamson
2014-10-13 13:10 ` [PATCH v8 10/18] vfio/platform: return IRQ info Antonios Motakis
2014-10-13 13:10 ` [PATCH v8 11/18] vfio/platform: initial interrupts support code Antonios Motakis
2014-10-13 13:10 ` [PATCH v8 12/18] vfio/platform: trigger an interrupt via eventfd Antonios Motakis
2014-10-13 13:10 ` [PATCH v8 13/18] vfio/platform: support for maskable and automasked interrupts Antonios Motakis
2014-10-21 17:47 ` Alex Williamson
2014-10-22 13:55 ` Antonios Motakis
2014-10-13 13:10 ` [PATCH v8 14/18] vfio: move eventfd support code for VFIO_PCI to a separate file Antonios Motakis
2014-10-21 17:55 ` Alex Williamson
2014-10-22 13:56 ` Antonios Motakis
2014-10-13 13:10 ` [PATCH v8 15/18] vfio: add local lock in virqfd instead of depending on VFIO PCI Antonios Motakis
2014-10-13 13:10 ` [PATCH v8 16/18] vfio: pass an opaque pointer on virqfd initialization Antonios Motakis
2014-10-13 13:10 ` [PATCH v8 17/18] vfio: initialize the virqfd workqueue in VFIO generic code Antonios Motakis
2014-10-13 13:10 ` [PATCH v8 18/18] vfio/platform: implement IRQ masking/unmasking via an eventfd Antonios Motakis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1413205825-6370-9-git-send-email-a.motakis@virtualopensystems.com \
--to=a.motakis@virtualopensystems.com \
--cc=alex.williamson@redhat.com \
--cc=christoffer.dall@linaro.org \
--cc=eric.auger@linaro.org \
--cc=iommu@lists.linux-foundation.org \
--cc=kim.phillips@freescale.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=linux-kernel@vger.kernel.org \
--cc=marc.zyngier@arm.com \
--cc=tech@virtualopensystems.com \
--cc=will.deacon@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®