On Mon, Sep 30, 2013 at 7:39 PM, Alex Williamson <[email protected]
> wrote:

> On Mon, 2013-09-30 at 17:28 +0200, Antonios Motakis wrote:
> > A VFIO userspace driver will start by opening the VFIO device
> > that corresponds to an IOMMU group, and will use the ioctl interface
> > to get the basic device info, such as number of memory regions and
> > interrupts, and their properties.
> >
> > This patch implements the IOCTLs:
> >  - VFIO_DEVICE_GET_INFO
> >  - VFIO_DEVICE_GET_REGION_INFO
> >  - VFIO_DEVICE_GET_IRQ_INFO
> >
> > Signed-off-by: Antonios Motakis <[email protected]>
> > ---
> >  drivers/vfio/vfio_platform.c | 60
> ++++++++++++++++++++++++++++++++++++++------
> >  1 file changed, 53 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/vfio/vfio_platform.c b/drivers/vfio/vfio_platform.c
> > index b9686b0..a0abcfa 100644
> > --- a/drivers/vfio/vfio_platform.c
> > +++ b/drivers/vfio/vfio_platform.c
> > @@ -28,6 +28,10 @@
> >  #include <linux/types.h>
> >  #include <linux/uaccess.h>
> >  #include <linux/vfio.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_platform.h>
> >
> >  #define DRIVER_VERSION  "0.1"
> >  #define DRIVER_AUTHOR   "Antonios Motakis <
> [email protected]>"
> > @@ -54,10 +58,13 @@ static long vfio_platform_ioctl(void *device_data,
> >                          unsigned int cmd, unsigned long arg)
> >  {
> >       struct vfio_platform_device *vdev = device_data;
> > +     struct device_node *of_node = vdev->pdev->dev.of_node;
> >       unsigned long minsz;
> >
> >       if (cmd == VFIO_DEVICE_GET_INFO) {
> >               struct vfio_device_info info;
> > +             struct resource res;
> > +             int cnt = 0;
> >
> >               minsz = offsetofend(struct vfio_device_info, num_irqs);
> >
> > @@ -68,18 +75,57 @@ static long vfio_platform_ioctl(void *device_data,
> >                       return -EINVAL;
> >
> >               info.flags = VFIO_DEVICE_FLAGS_PLATFORM;
> > -             info.num_regions = 0;
> > -             info.num_irqs = 0;
> > +
> > +             while (!of_address_to_resource(of_node, cnt, &res))
> > +                     cnt++;
> > +
> > +             info.num_regions = cnt;
> > +
> > +             info.num_irqs = of_irq_count(of_node);
> >
> >               return copy_to_user((void __user *)arg, &info, minsz);
> >
> > -     } else if (cmd == VFIO_DEVICE_GET_REGION_INFO)
> > -             return -EINVAL;
> > +     } else if (cmd == VFIO_DEVICE_GET_REGION_INFO) {
> > +             struct vfio_region_info info;
> > +             struct resource res;
> >
> > -     else if (cmd == VFIO_DEVICE_GET_IRQ_INFO)
> > -             return -EINVAL;
> > +             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(of_address_to_resource(of_node, info.index, &res))
> > +                     return -EINVAL;
> > +
> > +             info.offset = res.start;        /* map phys addr with
> offset */
> > +             info.size = resource_size(&res);
> > +             info.flags = 0;
> > +
> > +             return copy_to_user((void __user *)arg, &info, minsz);
> > +
> > +     } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) {
> > +             struct vfio_irq_info info;
> > +             struct resource res;
> > +
> > +             minsz = offsetofend(struct vfio_irq_info, count);
> > +
> > +             if (copy_from_user(&info, (void __user *)arg, minsz))
> > +                     return -EFAULT;
> > +
> > +             if (info.argsz < minsz)
> > +                     return -EINVAL;
> > +
> > +             of_irq_to_resource(of_node, info.index, &res);
> > +
> > +             info.flags = 0;
> > +             info.count = 1;
> > +
> > +             return copy_to_user((void __user *)arg, &info, minsz);
> >
> > -     else if (cmd == VFIO_DEVICE_SET_IRQS)
> > +     } else if (cmd == VFIO_DEVICE_SET_IRQS)
> >               return -EINVAL;
> >
> >       else if (cmd == VFIO_DEVICE_RESET)
>
> I notice all the open firmware calls here and I'm curious, will all
> platform devices be making use of open firmware?  I don't know if this
> is synonymous with device tree or not.  Thanks,
>
> Alex
>
>
This VFIO driver will support only devices implemented on the device tree.
While there can be platform devices outside the device tree, I don't think
it makes sense to support them from the same driver. This is why I
originally called the driver VFIO_DT, however I renamed it to VFIO_PLATFORM
after feedback from the first RFC. However personally, I still think the
VFIO_DT name is more appropriate since we don't support all platform
devices, only those that use the device tree.
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to