Re: [PATCH 3/7] Return info for device and its memory regions and interrupts

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 






On Mon, Sep 30, 2013 at 5:49 PM, Bhushan Bharat-R65777 <R65777@xxxxxxxxxxxxx> wrote:


> -----Original Message-----
> From: iommu-bounces@xxxxxxxxxxxxxxxxxxxxxxxxxx [mailto:iommu-
> bounces@xxxxxxxxxxxxxxxxxxxxxxxxxx] On Behalf Of Antonios Motakis
> Sent: Monday, September 30, 2013 8:59 PM
> To: kvmarm@xxxxxxxxxxxxxxxxxxxxx; alex.williamson@xxxxxxxxxx
> Cc: linux-samsung-soc@xxxxxxxxxxxxxxx; kvm@xxxxxxxxxxxxxxx; agraf@xxxxxxx; Yoder
> Stuart-B08248; iommu@xxxxxxxxxxxxxxxxxxxxxxxxxx; Antonios Motakis;
> tech@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [PATCH 3/7] Return info for device and its memory regions and
> interrupts
>
> 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 <a.motakis@xxxxxxxxxxxxxxxxxxxxxx>
> ---
>  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 <a.motakis@xxxxxxxxxxxxxxxxxxxxxx>"
> @@ -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);

Why are we calling the above function if not using res?

Good point, it is out of place now in this series. Though I will probably reintroduce it when IRQ supports starts being implemented.
 

> +
> +             info.flags = 0;
> +             info.count = 1;

I believe count here is number of interrupts, and we can have devices with more than 1 interrupt.


Count here is not the number of interrupts of the device; if a device has multiple interrupts, then we return multiple IRQ indexes. Count here is the number of consecutive interrupts within the same index, which we don't use. This is used for MSI-like interrupt blocks, but for platform devices we simply use a distinct index per interrupt.
 
-Bharat

> +
> +             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)
> --
> 1.8.1.2
>
> _______________________________________________
> iommu mailing list
> iommu@xxxxxxxxxxxxxxxxxxxxxxxxxx
> https://lists.linuxfoundation.org/mailman/listinfo/iommu



_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm

[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux