public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* RFC: vfio interface for platform devices (v2)
@ 2013-07-03 21:40 Yoder Stuart-B08248
  2013-07-03 22:53 ` Alex Williamson
  2013-07-04 14:44 ` Mario Smarduch
  0 siblings, 2 replies; 7+ messages in thread
From: Yoder Stuart-B08248 @ 2013-07-03 21:40 UTC (permalink / raw)
  To: Alex Williamson, Alexander Graf, Wood Scott-B07421
  Cc: Bhushan Bharat-R65777, Sethi Varun-B16395,
	virtualization@lists.linux-foundation.org, Antonios Motakis,
	kvm@vger.kernel.org list, kvm-ppc@vger.kernel.org,
	kvmarm@lists.cs.columbia.edu

Version 2
  -VFIO_GROUP_GET_DEVICE_FD-- specified that the path is a sysfs path
  -VFIO_DEVICE_GET_INFO-- defined 2 flags instead of 1
  -deleted VFIO_DEVICE_GET_DEVTREE_INFO ioctl
  -VFIO_DEVICE_GET_REGION_INFO-- updated as per AlexW's suggestion,
   defined 5 new flags and associated structs
  -VFIO_DEVICE_GET_IRQ_INFO-- updated as per AlexW's suggestion,
   defined 1 new flag and associated struct
  -removed redundant example

------------------------------------------------------------------------------
VFIO for Platform Devices

The existing kernel interface for vfio-pci is pretty close to what is needed
for platform devices:
   -mechanism to create a container
   -add groups/devices to a container
   -set the IOMMU model
   -map DMA regions
   -get an fd for a specific device, which allows user space to determine
    info about device regions (e.g. registers) and interrupt info
   -support for mmapping device regions
   -mechanism to set how interrupts are signaled

Many platform device are simple and consist of a single register
region and a single interrupt.  For these types of devices the
existing vfio interfaces should be sufficient.

However, platform devices can get complicated-- logically represented
as a device tree hierarchy of nodes.  For devices with multiple regions
and interrupts, new mechanisms are needed in vfio to correlate the
regions/interrupts with the device tree structure that drivers use
to determine the meaning of device resources.

In some cases there are relationships between device, and devices
reference other devices using phandle links.  The kernel won't expose
relationships between devices, but just exposes mappable register
regions and interrupts.

The changes needed for vfio are around some of the device tree
related info that needs to be available with the device fd.

1.  VFIO_GROUP_GET_DEVICE_FD

  User space knows by out-of-band means which device it is accessing
  and will call VFIO_GROUP_GET_DEVICE_FD passing a specific sysfs path
  to get the device information:

  fd = ioctl(group, VFIO_GROUP_GET_DEVICE_FD,
             "/sys/bus/platform/devices/ffe210000.usb"));

2.  VFIO_DEVICE_GET_INFO

   The number of regions corresponds to the regions defined
   in "reg" and "ranges" in the device tree.  

   Two new flags are added to struct vfio_device_info:

   #define VFIO_DEVICE_FLAGS_PLATFORM (1 << ?) /* A platform bus device */
   #define VFIO_DEVICE_FLAGS_DEVTREE  (1 << ?) /* device tree info available */

   It is possible that there could be platform bus devices 
   that are not in the device tree, so we use 2 flags to
   allow for that.

   If just VFIO_DEVICE_FLAGS_PLATFORM is set, it means
   that there are regions and IRQs but no device tree info
   available.

   If just VFIO_DEVICE_FLAGS_DEVTREE is set, it means
   there is device tree info available.

3. VFIO_DEVICE_GET_REGION_INFO

   For platform devices with multiple regions, information
   is needed to correlate the regions with the device 
   tree structure that drivers use to determine the meaning
   of device resources.
   
   The VFIO_DEVICE_GET_REGION_INFO is extended to provide
   device tree information.

   The following information is needed:
      -the device tree path to the node corresponding to the
       region
      -whether it corresponds to a "reg" or "ranges" property
      -there could be multiple sub-regions per "reg" or "ranges" and
       the sub-index within the reg/ranges is needed

   There are 5 new flags added to vfio_region_info :

   struct vfio_region_info {
        __u32   argsz;
        __u32   flags;
   #define VFIO_REGION_INFO_FLAG_CACHEABLE (1 << ?)
   #define VFIO_DEVTREE_REGION_INFO_FLAG_REG (1 << ?)
   #define VFIO_DEVTREE_REGION_INFO_FLAG_RANGE (1 << ?)
   #define VFIO_DEVTREE_REGION_INFO_FLAG_INDEX (1 << ?)
   #define VFIO_DEVTREE_REGION_INFO_FLAG_PATH (1 << ?)
        __u32   index;          /* Region index */
        __u32   resv;           /* Reserved for alignment */
        __u64   size;           /* Region size (bytes) */
        __u64   offset;         /* Region offset from start of device fd */
   };
 
   VFIO_REGION_INFO_FLAG_CACHEABLE
       -if set indicates that the region must be mapped as cacheable

   VFIO_DEVTREE_REGION_INFO_FLAG_REG
       -if set indicates that the region corresponds to a "reg" property
        in the device tree representation of the device

   VFIO_DEVTREE_REGION_INFO_FLAG_RANGE
       -if set indicates that the region corresponds to a "ranges" property
        in the device tree representation of the device

   VFIO_DEVTREE_REGION_INFO_FLAG_INDEX
       -if set indicates that there is a dword aligned struct
        struct vfio_devtree_region_info_index appended to the
        end of vfio_region_info:

        struct vfio_devtree_region_info_index
        {
	      u32 index;
        }

        A reg or ranges property may have multiple regsion.  The index
        specifies the index within the "reg" or "ranges"
        that this region corresponds to.

   VFIO_DEVTREE_REGION_INFO_FLAG_PATH
       -if set indicates that there is a dword aligned struct
        struct vfio_devtree_info_path appended to the
        end of vfio_region_info:

        struct vfio_devtree_info_path
        {
            u32 len;
            u8 path[];
        } 

        The path is the full path to the corresponding device
        tree node.  The len field specifies the length of the
        path string.

   If multiple flags are set that indicate that there is
   an appended struct, the order of the flags indicates
   the order of the structs.

   argsz is set by the kernel specifying the total size of
   struct vfio_region_info and all appended structs.

   Suggested usage:
      -call VFIO_DEVICE_GET_REGION_INFO with argsz =
       sizeof(struct vfio_region_info)
      -realloc the buffer
      -call VFIO_DEVICE_GET_REGION_INFO again, and the appended
       structs will be returned

4.  VFIO_DEVICE_GET_IRQ_INFO

   For platform devices with multiple interrupts that 
   correspond to different subnodes in the device tree,
   information is needed to correlate the interrupts
   to the the device tree structure.

   The VFIO_DEVICE_GET_REGION_INFO is extended to provide
   device tree information.

   1 new flag is added to vfio_irq_info :

   struct vfio_irq_info {
        __u32   argsz;
        __u32   flags;
   #define VFIO_DEVTREE_IRQ_INFO_FLAG_PATH (1 << ?)
        __u32   index;    /* IRQ index */
        __u32   count;    /* Number of IRQs within this index */
    };

   VFIO_DEVTREE_IRQ_INFO_FLAG_PATH 
       -if set indicates that there is a dword aligned struct
        struct vfio_devtree_info_path appended to the
        end of vfio_irq_info :

        struct vfio_devtree_info_path
        {
            u32 len;
            u8 path[];
        } 

        The path is the full path to the corresponding device
        tree node.  The len field specifies the length of the
        path string.

   argsz is set by the kernel specifying the total size of
   struct vfio_region_info and all appended structs.

5.  EXAMPLE 1

    Example, Freescale SATA controller:

     sata@220000 {
         compatible = "fsl,p2041-sata", "fsl,pq-sata-v2";
         reg = <0x220000 0x1000>;
         interrupts = <0x44 0x2 0x0 0x0>;
     };

    request to get device FD would look like:
      fd = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "/sys/bus/platform/devices/ffe220000.sata");

    The VFIO_DEVICE_GET_INFO ioctl would return:
      -1 region
      -1 interrupts

    The VFIO_DEVICE_GET_REGION_INFO ioctl would return:
      -for index 0:
           offset=0, size=0x10000 -- allows mmap of physical 0xffe220000
           flags = VFIO_DEVTREE_REGION_INFO_FLAG_REG |
                   VFIO_DEVTREE_REGION_INFO_FLAG_PATH
           vfio_devtree_info_path
              len = 26
              path = "/soc@ffe000000/sata@220000"

    The VFIO_DEVICE_GET_IRQ_INFO ioctl would return:
      -for index 0:
          flags = VFIO_IRQ_INFO_EVENTFD | 
                  VFIO_IRQ_INFO_MASKABLE |
                  VFIO_DEVTREE_IRQ_INFO_FLAG_PATH  
          vfio_devtree_info_path
              len = 26
              path = "/soc@ffe000000/sata@220000"

6.  EXAMPLE 2

    Example, Freescale DMA engine (modified to illustrate):

    dma@101300 {
       cell-index = <0x1>;
       ranges = <0x0 0x101100 0x200>;
       reg = <0x101300 0x4>;
       compatible = "fsl,eloplus-dma";
       #size-cells = <0x1>;
       #address-cells = <0x1>;
       fsl,liodn = <0xc6>;
    
       dma-channel@180 {
          interrupts = <0x23 0x2 0x0 0x0>;
          cell-index = <0x3>;
          reg = <0x180 0x80>;
          compatible = "fsl,eloplus-dma-channel";
       };
    
       dma-channel@100 {
          interrupts = <0x22 0x2 0x0 0x0>;
          cell-index = <0x2>;
          reg = <0x100 0x80>;
          compatible = "fsl,eloplus-dma-channel";
       };

    };

    request to get device FD would look like:
      fd = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "/sys/bus/platform/devices/ffe101300.dma");

    The VFIO_DEVICE_GET_INFO ioctl would return:
      -2 regions
      -2 interrupts

    The VFIO_DEVICE_GET_REGION_INFO ioctl would return:
      -for index 0:
           offset=0x100, size=0x200 -- allows mmap of physical 0xffe101100
           flags = VFIO_DEVTREE_REGION_INFO_FLAG_RANGES |
                   VFIO_DEVTREE_REGION_INFO_FLAG_PATH
           vfio_devtree_info_path
              len = 25
              path = "/soc@ffe000000/dma@101300"

      -for index 1:
           offset=0x300, size=0x4 -- allows mmap of physical 0xffe101300
           flags = VFIO_DEVTREE_REGION_INFO_FLAG_REG |
                   VFIO_DEVTREE_REGION_INFO_FLAG_PATH
           vfio_devtree_info_path
              len = 25
              path = "/soc@ffe000000/dma@101300"

    The VFIO_DEVICE_GET_IRQ_INFO ioctl would return:
      -for index 0:
          flags = VFIO_IRQ_INFO_EVENTFD | 
                  VFIO_IRQ_INFO_MASKABLE |
                  VFIO_DEVTREE_IRQ_INFO_FLAG_PATH  
          vfio_devtree_info_path
              len = 41
              path = "/soc@ffe000000/dma@101300/dma-channel@180"

      -for index 0:
          flags = VFIO_IRQ_INFO_EVENTFD | 
                  VFIO_IRQ_INFO_MASKABLE |
                  VFIO_DEVTREE_IRQ_INFO_FLAG_PATH  
          vfio_devtree_info_path
              len = 41
              path = "/soc@ffe000000/dma@101300/dma-channel@100"


Regards,
Stuart

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: vfio interface for platform devices (v2)
  2013-07-03 21:40 RFC: vfio interface for platform devices (v2) Yoder Stuart-B08248
@ 2013-07-03 22:53 ` Alex Williamson
  2013-07-03 23:06   ` Scott Wood
  2013-07-16 21:57   ` Yoder Stuart-B08248
  2013-07-04 14:44 ` Mario Smarduch
  1 sibling, 2 replies; 7+ messages in thread
From: Alex Williamson @ 2013-07-03 22:53 UTC (permalink / raw)
  To: Yoder Stuart-B08248
  Cc: Alexander Graf, Wood Scott-B07421, Bhushan Bharat-R65777,
	Sethi Varun-B16395, virtualization@lists.linux-foundation.org,
	Antonios Motakis, kvm@vger.kernel.org list,
	kvm-ppc@vger.kernel.org, kvmarm@lists.cs.columbia.edu

On Wed, 2013-07-03 at 21:40 +0000, Yoder Stuart-B08248 wrote:
> Version 2
>   -VFIO_GROUP_GET_DEVICE_FD-- specified that the path is a sysfs path
>   -VFIO_DEVICE_GET_INFO-- defined 2 flags instead of 1
>   -deleted VFIO_DEVICE_GET_DEVTREE_INFO ioctl
>   -VFIO_DEVICE_GET_REGION_INFO-- updated as per AlexW's suggestion,
>    defined 5 new flags and associated structs
>   -VFIO_DEVICE_GET_IRQ_INFO-- updated as per AlexW's suggestion,
>    defined 1 new flag and associated struct
>   -removed redundant example
> 
> ------------------------------------------------------------------------------
> VFIO for Platform Devices
> 
> The existing kernel interface for vfio-pci is pretty close to what is needed
> for platform devices:
>    -mechanism to create a container
>    -add groups/devices to a container
>    -set the IOMMU model
>    -map DMA regions
>    -get an fd for a specific device, which allows user space to determine
>     info about device regions (e.g. registers) and interrupt info
>    -support for mmapping device regions
>    -mechanism to set how interrupts are signaled
> 
> Many platform device are simple and consist of a single register
> region and a single interrupt.  For these types of devices the
> existing vfio interfaces should be sufficient.
> 
> However, platform devices can get complicated-- logically represented
> as a device tree hierarchy of nodes.  For devices with multiple regions
> and interrupts, new mechanisms are needed in vfio to correlate the
> regions/interrupts with the device tree structure that drivers use
> to determine the meaning of device resources.
> 
> In some cases there are relationships between device, and devices
> reference other devices using phandle links.  The kernel won't expose
> relationships between devices, but just exposes mappable register
> regions and interrupts.
> 
> The changes needed for vfio are around some of the device tree
> related info that needs to be available with the device fd.
> 
> 1.  VFIO_GROUP_GET_DEVICE_FD
> 
>   User space knows by out-of-band means which device it is accessing
>   and will call VFIO_GROUP_GET_DEVICE_FD passing a specific sysfs path
>   to get the device information:
> 
>   fd = ioctl(group, VFIO_GROUP_GET_DEVICE_FD,
>              "/sys/bus/platform/devices/ffe210000.usb"));

FWIW, I'm in favor of whichever way works out cleaner in the code for
pre-pending "/sys/bus" or not.  It sort of seems like it's unnecessary.
It's also a little inconsistent that the returned path doesn't
pre-pend /sys in the examples below.

> 2.  VFIO_DEVICE_GET_INFO
> 
>    The number of regions corresponds to the regions defined
>    in "reg" and "ranges" in the device tree.  
> 
>    Two new flags are added to struct vfio_device_info:
> 
>    #define VFIO_DEVICE_FLAGS_PLATFORM (1 << ?) /* A platform bus device */
>    #define VFIO_DEVICE_FLAGS_DEVTREE  (1 << ?) /* device tree info available */
> 
>    It is possible that there could be platform bus devices 
>    that are not in the device tree, so we use 2 flags to
>    allow for that.
> 
>    If just VFIO_DEVICE_FLAGS_PLATFORM is set, it means
>    that there are regions and IRQs but no device tree info
>    available.
> 
>    If just VFIO_DEVICE_FLAGS_DEVTREE is set, it means
>    there is device tree info available.

But it would be invalid to only have DEVTREE w/o PLATFORM for now,
right?

> 3. VFIO_DEVICE_GET_REGION_INFO
> 
>    For platform devices with multiple regions, information
>    is needed to correlate the regions with the device 
>    tree structure that drivers use to determine the meaning
>    of device resources.
>    
>    The VFIO_DEVICE_GET_REGION_INFO is extended to provide
>    device tree information.
> 
>    The following information is needed:
>       -the device tree path to the node corresponding to the
>        region
>       -whether it corresponds to a "reg" or "ranges" property
>       -there could be multiple sub-regions per "reg" or "ranges" and
>        the sub-index within the reg/ranges is needed
> 
>    There are 5 new flags added to vfio_region_info :
> 
>    struct vfio_region_info {
>         __u32   argsz;
>         __u32   flags;
>    #define VFIO_REGION_INFO_FLAG_CACHEABLE (1 << ?)
>    #define VFIO_DEVTREE_REGION_INFO_FLAG_REG (1 << ?)
>    #define VFIO_DEVTREE_REGION_INFO_FLAG_RANGE (1 << ?)
>    #define VFIO_DEVTREE_REGION_INFO_FLAG_INDEX (1 << ?)
>    #define VFIO_DEVTREE_REGION_INFO_FLAG_PATH (1 << ?)
>         __u32   index;          /* Region index */
>         __u32   resv;           /* Reserved for alignment */
>         __u64   size;           /* Region size (bytes) */
>         __u64   offset;         /* Region offset from start of device fd */
>    };
>  
>    VFIO_REGION_INFO_FLAG_CACHEABLE
>        -if set indicates that the region must be mapped as cacheable
> 
>    VFIO_DEVTREE_REGION_INFO_FLAG_REG
>        -if set indicates that the region corresponds to a "reg" property
>         in the device tree representation of the device
> 
>    VFIO_DEVTREE_REGION_INFO_FLAG_RANGE
>        -if set indicates that the region corresponds to a "ranges" property
>         in the device tree representation of the device
> 
>    VFIO_DEVTREE_REGION_INFO_FLAG_INDEX
>        -if set indicates that there is a dword aligned struct
>         struct vfio_devtree_region_info_index appended to the
>         end of vfio_region_info:
> 
>         struct vfio_devtree_region_info_index
>         {
> 	      u32 index;
>         }
> 
>         A reg or ranges property may have multiple regsion.  The index
>         specifies the index within the "reg" or "ranges"
>         that this region corresponds to.
> 
>    VFIO_DEVTREE_REGION_INFO_FLAG_PATH
>        -if set indicates that there is a dword aligned struct
>         struct vfio_devtree_info_path appended to the
>         end of vfio_region_info:
> 
>         struct vfio_devtree_info_path
>         {
>             u32 len;
>             u8 path[];
>         } 
> 
>         The path is the full path to the corresponding device
>         tree node.  The len field specifies the length of the
>         path string.
> 
>    If multiple flags are set that indicate that there is
>    an appended struct, the order of the flags indicates
>    the order of the structs.
> 
>    argsz is set by the kernel specifying the total size of
>    struct vfio_region_info and all appended structs.
> 
>    Suggested usage:
>       -call VFIO_DEVICE_GET_REGION_INFO with argsz =
>        sizeof(struct vfio_region_info)
>       -realloc the buffer
>       -call VFIO_DEVICE_GET_REGION_INFO again, and the appended
>        structs will be returned
> 
> 4.  VFIO_DEVICE_GET_IRQ_INFO
> 
>    For platform devices with multiple interrupts that 
>    correspond to different subnodes in the device tree,
>    information is needed to correlate the interrupts
>    to the the device tree structure.
> 
>    The VFIO_DEVICE_GET_REGION_INFO is extended to provide
>    device tree information.
> 
>    1 new flag is added to vfio_irq_info :
> 
>    struct vfio_irq_info {
>         __u32   argsz;
>         __u32   flags;
>    #define VFIO_DEVTREE_IRQ_INFO_FLAG_PATH (1 << ?)
>         __u32   index;    /* IRQ index */
>         __u32   count;    /* Number of IRQs within this index */
>     };
> 
>    VFIO_DEVTREE_IRQ_INFO_FLAG_PATH 
>        -if set indicates that there is a dword aligned struct
>         struct vfio_devtree_info_path appended to the
>         end of vfio_irq_info :
> 
>         struct vfio_devtree_info_path
>         {
>             u32 len;
>             u8 path[];
>         } 
> 
>         The path is the full path to the corresponding device
>         tree node.  The len field specifies the length of the
>         path string.
> 
>    argsz is set by the kernel specifying the total size of
>    struct vfio_region_info and all appended structs.
> 
> 5.  EXAMPLE 1
> 
>     Example, Freescale SATA controller:
> 
>      sata@220000 {
>          compatible = "fsl,p2041-sata", "fsl,pq-sata-v2";
>          reg = <0x220000 0x1000>;
>          interrupts = <0x44 0x2 0x0 0x0>;
>      };
> 
>     request to get device FD would look like:
>       fd = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "/sys/bus/platform/devices/ffe220000.sata");
> 
>     The VFIO_DEVICE_GET_INFO ioctl would return:
>       -1 region
>       -1 interrupts
> 
>     The VFIO_DEVICE_GET_REGION_INFO ioctl would return:
>       -for index 0:
>            offset=0, size=0x10000 -- allows mmap of physical 0xffe220000
>            flags = VFIO_DEVTREE_REGION_INFO_FLAG_REG |
>                    VFIO_DEVTREE_REGION_INFO_FLAG_PATH
>            vfio_devtree_info_path
>               len = 26
>               path = "/soc@ffe000000/sata@220000"
> 
>     The VFIO_DEVICE_GET_IRQ_INFO ioctl would return:
>       -for index 0:
>           flags = VFIO_IRQ_INFO_EVENTFD | 
>                   VFIO_IRQ_INFO_MASKABLE |
>                   VFIO_DEVTREE_IRQ_INFO_FLAG_PATH  
>           vfio_devtree_info_path
>               len = 26
>               path = "/soc@ffe000000/sata@220000"
> 
> 6.  EXAMPLE 2
> 
>     Example, Freescale DMA engine (modified to illustrate):
> 
>     dma@101300 {
>        cell-index = <0x1>;
>        ranges = <0x0 0x101100 0x200>;
>        reg = <0x101300 0x4>;
>        compatible = "fsl,eloplus-dma";
>        #size-cells = <0x1>;
>        #address-cells = <0x1>;
>        fsl,liodn = <0xc6>;
>     
>        dma-channel@180 {
>           interrupts = <0x23 0x2 0x0 0x0>;
>           cell-index = <0x3>;
>           reg = <0x180 0x80>;
>           compatible = "fsl,eloplus-dma-channel";
>        };
>     
>        dma-channel@100 {
>           interrupts = <0x22 0x2 0x0 0x0>;
>           cell-index = <0x2>;
>           reg = <0x100 0x80>;
>           compatible = "fsl,eloplus-dma-channel";
>        };
> 
>     };
> 
>     request to get device FD would look like:
>       fd = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "/sys/bus/platform/devices/ffe101300.dma");
> 
>     The VFIO_DEVICE_GET_INFO ioctl would return:
>       -2 regions
>       -2 interrupts
> 
>     The VFIO_DEVICE_GET_REGION_INFO ioctl would return:
>       -for index 0:
>            offset=0x100, size=0x200 -- allows mmap of physical 0xffe101100
>            flags = VFIO_DEVTREE_REGION_INFO_FLAG_RANGES |
>                    VFIO_DEVTREE_REGION_INFO_FLAG_PATH
>            vfio_devtree_info_path
>               len = 25
>               path = "/soc@ffe000000/dma@101300"
> 
>       -for index 1:
>            offset=0x300, size=0x4 -- allows mmap of physical 0xffe101300
>            flags = VFIO_DEVTREE_REGION_INFO_FLAG_REG |
>                    VFIO_DEVTREE_REGION_INFO_FLAG_PATH
>            vfio_devtree_info_path
>               len = 25
>               path = "/soc@ffe000000/dma@101300"
> 
>     The VFIO_DEVICE_GET_IRQ_INFO ioctl would return:
>       -for index 0:
>           flags = VFIO_IRQ_INFO_EVENTFD | 
>                   VFIO_IRQ_INFO_MASKABLE |
>                   VFIO_DEVTREE_IRQ_INFO_FLAG_PATH  
>           vfio_devtree_info_path
>               len = 41
>               path = "/soc@ffe000000/dma@101300/dma-channel@180"
> 
>       -for index 0:
>           flags = VFIO_IRQ_INFO_EVENTFD | 
>                   VFIO_IRQ_INFO_MASKABLE |
>                   VFIO_DEVTREE_IRQ_INFO_FLAG_PATH  
>           vfio_devtree_info_path
>               len = 41
>               path = "/soc@ffe000000/dma@101300/dma-channel@100"


Seems like it should work.  My only API concern with this model of
appending structs is that a user needs to know the size of each struct
even if they don't otherwise care about it in order to step over it.  In
some cases, like the path, the size is variable and the user needs to
look into it.  The structs must also be strictly ordered based on the
order of the flags or all hope is lost.  If we assign flags sequentially
there should be no case where the user needs to step over something that
they doesn't know the size of.  Even so, we may still be ahead to define
the first word of each struct as the length (I'm guessing a byte might
be too limiting).  It would sure make walking it easier.  Thanks,

Alex

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: vfio interface for platform devices (v2)
  2013-07-03 22:53 ` Alex Williamson
@ 2013-07-03 23:06   ` Scott Wood
  2013-07-16 21:57   ` Yoder Stuart-B08248
  1 sibling, 0 replies; 7+ messages in thread
From: Scott Wood @ 2013-07-03 23:06 UTC (permalink / raw)
  To: Alex Williamson
  Cc: Yoder Stuart-B08248, Alexander Graf, Wood Scott-B07421,
	Bhushan Bharat-R65777, Sethi Varun-B16395,
	virtualization@lists.linux-foundation.org, Antonios Motakis,
	kvm@vger.kernel.org list, kvm-ppc@vger.kernel.org,
	kvmarm@lists.cs.columbia.edu

On 07/03/2013 05:53:09 PM, Alex Williamson wrote:
> Seems like it should work.  My only API concern with this model of
> appending structs is that a user needs to know the size of each struct
> even if they don't otherwise care about it in order to step over it.

In that case, it might be better to make the struct grow linearly  
rather than with options, and just have a version number on the struct  
indicating how far the caller thinks struct has grown.  The kernel  
could respond back with a lower version to reflect that it only filled  
in the fields it knows about.  Flags could still be used to indicate  
which portions of the struct are relevant, but not the physical layout  
of the struct.

> In some cases, like the path, the size is variable and the user needs  
> to
> look into it.

For things like path, maybe the caller should just pass in a string  
buffer that is separate from the struct buffer?

-Scott

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: vfio interface for platform devices (v2)
  2013-07-03 21:40 RFC: vfio interface for platform devices (v2) Yoder Stuart-B08248
  2013-07-03 22:53 ` Alex Williamson
@ 2013-07-04 14:44 ` Mario Smarduch
  2013-07-04 14:47   ` Alexander Graf
  2013-07-16 15:25   ` Yoder Stuart-B08248
  1 sibling, 2 replies; 7+ messages in thread
From: Mario Smarduch @ 2013-07-04 14:44 UTC (permalink / raw)
  To: Yoder Stuart-B08248
  Cc: Alex Williamson, Alexander Graf, Wood Scott-B07421,
	kvm@vger.kernel.org list, Bhushan Bharat-R65777,
	kvm-ppc@vger.kernel.org,
	virtualization@lists.linux-foundation.org, Sethi Varun-B16395,
	kvmarm@lists.cs.columbia.edu


I'm having trouble understanding how this works where
the Guest Device Model != Host. How do you inform the guest
where the device is mapped in its physical address space,
and handle GPA faults?

- Mario

On 7/3/2013 11:40 PM, Yoder Stuart-B08248 wrote:
> Version 2
>   -VFIO_GROUP_GET_DEVICE_FD-- specified that the path is a sysfs path
>   -VFIO_DEVICE_GET_INFO-- defined 2 flags instead of 1
>   -deleted VFIO_DEVICE_GET_DEVTREE_INFO ioctl
>   -VFIO_DEVICE_GET_REGION_INFO-- updated as per AlexW's suggestion,
>    defined 5 new flags and associated structs
>   -VFIO_DEVICE_GET_IRQ_INFO-- updated as per AlexW's suggestion,
>    defined 1 new flag and associated struct
>   -removed redundant example
> 
> ------------------------------------------------------------------------------
> VFIO for Platform Devices
> 
> The existing kernel interface for vfio-pci is pretty close to what is needed
> for platform devices:
>    -mechanism to create a container
>    -add groups/devices to a container
>    -set the IOMMU model
>    -map DMA regions
>    -get an fd for a specific device, which allows user space to determine
>     info about device regions (e.g. registers) and interrupt info
>    -support for mmapping device regions
>    -mechanism to set how interrupts are signaled
> 
> Many platform device are simple and consist of a single register
> region and a single interrupt.  For these types of devices the
> existing vfio interfaces should be sufficient.
> 
> However, platform devices can get complicated-- logically represented
> as a device tree hierarchy of nodes.  For devices with multiple regions
> and interrupts, new mechanisms are needed in vfio to correlate the
> regions/interrupts with the device tree structure that drivers use
> to determine the meaning of device resources.
> 
> In some cases there are relationships between device, and devices
> reference other devices using phandle links.  The kernel won't expose
> relationships between devices, but just exposes mappable register
> regions and interrupts.
> 
> The changes needed for vfio are around some of the device tree
> related info that needs to be available with the device fd.
> 
> 1.  VFIO_GROUP_GET_DEVICE_FD
> 
>   User space knows by out-of-band means which device it is accessing
>   and will call VFIO_GROUP_GET_DEVICE_FD passing a specific sysfs path
>   to get the device information:
> 
>   fd = ioctl(group, VFIO_GROUP_GET_DEVICE_FD,
>              "/sys/bus/platform/devices/ffe210000.usb"));
> 
> 2.  VFIO_DEVICE_GET_INFO
> 
>    The number of regions corresponds to the regions defined
>    in "reg" and "ranges" in the device tree.  
> 
>    Two new flags are added to struct vfio_device_info:
> 
>    #define VFIO_DEVICE_FLAGS_PLATFORM (1 << ?) /* A platform bus device */
>    #define VFIO_DEVICE_FLAGS_DEVTREE  (1 << ?) /* device tree info available */
> 
>    It is possible that there could be platform bus devices 
>    that are not in the device tree, so we use 2 flags to
>    allow for that.
> 
>    If just VFIO_DEVICE_FLAGS_PLATFORM is set, it means
>    that there are regions and IRQs but no device tree info
>    available.
> 
>    If just VFIO_DEVICE_FLAGS_DEVTREE is set, it means
>    there is device tree info available.
> 
> 3. VFIO_DEVICE_GET_REGION_INFO
> 
>    For platform devices with multiple regions, information
>    is needed to correlate the regions with the device 
>    tree structure that drivers use to determine the meaning
>    of device resources.
>    
>    The VFIO_DEVICE_GET_REGION_INFO is extended to provide
>    device tree information.
> 
>    The following information is needed:
>       -the device tree path to the node corresponding to the
>        region
>       -whether it corresponds to a "reg" or "ranges" property
>       -there could be multiple sub-regions per "reg" or "ranges" and
>        the sub-index within the reg/ranges is needed
> 
>    There are 5 new flags added to vfio_region_info :
> 
>    struct vfio_region_info {
>         __u32   argsz;
>         __u32   flags;
>    #define VFIO_REGION_INFO_FLAG_CACHEABLE (1 << ?)
>    #define VFIO_DEVTREE_REGION_INFO_FLAG_REG (1 << ?)
>    #define VFIO_DEVTREE_REGION_INFO_FLAG_RANGE (1 << ?)
>    #define VFIO_DEVTREE_REGION_INFO_FLAG_INDEX (1 << ?)
>    #define VFIO_DEVTREE_REGION_INFO_FLAG_PATH (1 << ?)
>         __u32   index;          /* Region index */
>         __u32   resv;           /* Reserved for alignment */
>         __u64   size;           /* Region size (bytes) */
>         __u64   offset;         /* Region offset from start of device fd */
>    };
>  
>    VFIO_REGION_INFO_FLAG_CACHEABLE
>        -if set indicates that the region must be mapped as cacheable
> 
>    VFIO_DEVTREE_REGION_INFO_FLAG_REG
>        -if set indicates that the region corresponds to a "reg" property
>         in the device tree representation of the device
> 
>    VFIO_DEVTREE_REGION_INFO_FLAG_RANGE
>        -if set indicates that the region corresponds to a "ranges" property
>         in the device tree representation of the device
> 
>    VFIO_DEVTREE_REGION_INFO_FLAG_INDEX
>        -if set indicates that there is a dword aligned struct
>         struct vfio_devtree_region_info_index appended to the
>         end of vfio_region_info:
> 
>         struct vfio_devtree_region_info_index
>         {
> 	      u32 index;
>         }
> 
>         A reg or ranges property may have multiple regsion.  The index
>         specifies the index within the "reg" or "ranges"
>         that this region corresponds to.
> 
>    VFIO_DEVTREE_REGION_INFO_FLAG_PATH
>        -if set indicates that there is a dword aligned struct
>         struct vfio_devtree_info_path appended to the
>         end of vfio_region_info:
> 
>         struct vfio_devtree_info_path
>         {
>             u32 len;
>             u8 path[];
>         } 
> 
>         The path is the full path to the corresponding device
>         tree node.  The len field specifies the length of the
>         path string.
> 
>    If multiple flags are set that indicate that there is
>    an appended struct, the order of the flags indicates
>    the order of the structs.
> 
>    argsz is set by the kernel specifying the total size of
>    struct vfio_region_info and all appended structs.
> 
>    Suggested usage:
>       -call VFIO_DEVICE_GET_REGION_INFO with argsz =
>        sizeof(struct vfio_region_info)
>       -realloc the buffer
>       -call VFIO_DEVICE_GET_REGION_INFO again, and the appended
>        structs will be returned
> 
> 4.  VFIO_DEVICE_GET_IRQ_INFO
> 
>    For platform devices with multiple interrupts that 
>    correspond to different subnodes in the device tree,
>    information is needed to correlate the interrupts
>    to the the device tree structure.
> 
>    The VFIO_DEVICE_GET_REGION_INFO is extended to provide
>    device tree information.
> 
>    1 new flag is added to vfio_irq_info :
> 
>    struct vfio_irq_info {
>         __u32   argsz;
>         __u32   flags;
>    #define VFIO_DEVTREE_IRQ_INFO_FLAG_PATH (1 << ?)
>         __u32   index;    /* IRQ index */
>         __u32   count;    /* Number of IRQs within this index */
>     };
> 
>    VFIO_DEVTREE_IRQ_INFO_FLAG_PATH 
>        -if set indicates that there is a dword aligned struct
>         struct vfio_devtree_info_path appended to the
>         end of vfio_irq_info :
> 
>         struct vfio_devtree_info_path
>         {
>             u32 len;
>             u8 path[];
>         } 
> 
>         The path is the full path to the corresponding device
>         tree node.  The len field specifies the length of the
>         path string.
> 
>    argsz is set by the kernel specifying the total size of
>    struct vfio_region_info and all appended structs.
> 
> 5.  EXAMPLE 1
> 
>     Example, Freescale SATA controller:
> 
>      sata@220000 {
>          compatible = "fsl,p2041-sata", "fsl,pq-sata-v2";
>          reg = <0x220000 0x1000>;
>          interrupts = <0x44 0x2 0x0 0x0>;
>      };
> 
>     request to get device FD would look like:
>       fd = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "/sys/bus/platform/devices/ffe220000.sata");
> 
>     The VFIO_DEVICE_GET_INFO ioctl would return:
>       -1 region
>       -1 interrupts
> 
>     The VFIO_DEVICE_GET_REGION_INFO ioctl would return:
>       -for index 0:
>            offset=0, size=0x10000 -- allows mmap of physical 0xffe220000
>            flags = VFIO_DEVTREE_REGION_INFO_FLAG_REG |
>                    VFIO_DEVTREE_REGION_INFO_FLAG_PATH
>            vfio_devtree_info_path
>               len = 26
>               path = "/soc@ffe000000/sata@220000"
> 
>     The VFIO_DEVICE_GET_IRQ_INFO ioctl would return:
>       -for index 0:
>           flags = VFIO_IRQ_INFO_EVENTFD | 
>                   VFIO_IRQ_INFO_MASKABLE |
>                   VFIO_DEVTREE_IRQ_INFO_FLAG_PATH  
>           vfio_devtree_info_path
>               len = 26
>               path = "/soc@ffe000000/sata@220000"
> 
> 6.  EXAMPLE 2
> 
>     Example, Freescale DMA engine (modified to illustrate):
> 
>     dma@101300 {
>        cell-index = <0x1>;
>        ranges = <0x0 0x101100 0x200>;
>        reg = <0x101300 0x4>;
>        compatible = "fsl,eloplus-dma";
>        #size-cells = <0x1>;
>        #address-cells = <0x1>;
>        fsl,liodn = <0xc6>;
>     
>        dma-channel@180 {
>           interrupts = <0x23 0x2 0x0 0x0>;
>           cell-index = <0x3>;
>           reg = <0x180 0x80>;
>           compatible = "fsl,eloplus-dma-channel";
>        };
>     
>        dma-channel@100 {
>           interrupts = <0x22 0x2 0x0 0x0>;
>           cell-index = <0x2>;
>           reg = <0x100 0x80>;
>           compatible = "fsl,eloplus-dma-channel";
>        };
> 
>     };
> 
>     request to get device FD would look like:
>       fd = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "/sys/bus/platform/devices/ffe101300.dma");
> 
>     The VFIO_DEVICE_GET_INFO ioctl would return:
>       -2 regions
>       -2 interrupts
> 
>     The VFIO_DEVICE_GET_REGION_INFO ioctl would return:
>       -for index 0:
>            offset=0x100, size=0x200 -- allows mmap of physical 0xffe101100
>            flags = VFIO_DEVTREE_REGION_INFO_FLAG_RANGES |
>                    VFIO_DEVTREE_REGION_INFO_FLAG_PATH
>            vfio_devtree_info_path
>               len = 25
>               path = "/soc@ffe000000/dma@101300"
> 
>       -for index 1:
>            offset=0x300, size=0x4 -- allows mmap of physical 0xffe101300
>            flags = VFIO_DEVTREE_REGION_INFO_FLAG_REG |
>                    VFIO_DEVTREE_REGION_INFO_FLAG_PATH
>            vfio_devtree_info_path
>               len = 25
>               path = "/soc@ffe000000/dma@101300"
> 
>     The VFIO_DEVICE_GET_IRQ_INFO ioctl would return:
>       -for index 0:
>           flags = VFIO_IRQ_INFO_EVENTFD | 
>                   VFIO_IRQ_INFO_MASKABLE |
>                   VFIO_DEVTREE_IRQ_INFO_FLAG_PATH  
>           vfio_devtree_info_path
>               len = 41
>               path = "/soc@ffe000000/dma@101300/dma-channel@180"
> 
>       -for index 0:
>           flags = VFIO_IRQ_INFO_EVENTFD | 
>                   VFIO_IRQ_INFO_MASKABLE |
>                   VFIO_DEVTREE_IRQ_INFO_FLAG_PATH  
>           vfio_devtree_info_path
>               len = 41
>               path = "/soc@ffe000000/dma@101300/dma-channel@100"
> 
> 
> Regards,
> Stuart
> 
> 
> _______________________________________________
> kvmarm mailing list
> kvmarm@lists.cs.columbia.edu
> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
> 



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: vfio interface for platform devices (v2)
  2013-07-04 14:44 ` Mario Smarduch
@ 2013-07-04 14:47   ` Alexander Graf
  2013-07-16 15:25   ` Yoder Stuart-B08248
  1 sibling, 0 replies; 7+ messages in thread
From: Alexander Graf @ 2013-07-04 14:47 UTC (permalink / raw)
  To: Mario Smarduch
  Cc: Yoder Stuart-B08248, Alex Williamson, Wood Scott-B07421,
	kvm@vger.kernel.org list, Bhushan Bharat-R65777,
	kvm-ppc@vger.kernel.org,
	virtualization@lists.linux-foundation.org, Sethi Varun-B16395,
	kvmarm@lists.cs.columbia.edu


On 04.07.2013, at 16:44, Mario Smarduch wrote:

> 
> I'm having trouble understanding how this works where
> the Guest Device Model != Host. How do you inform the guest
> where the device is mapped in its physical address space,
> and handle GPA faults?

The same way as you would for emulated devices.


Alex

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: RFC: vfio interface for platform devices (v2)
  2013-07-04 14:44 ` Mario Smarduch
  2013-07-04 14:47   ` Alexander Graf
@ 2013-07-16 15:25   ` Yoder Stuart-B08248
  1 sibling, 0 replies; 7+ messages in thread
From: Yoder Stuart-B08248 @ 2013-07-16 15:25 UTC (permalink / raw)
  To: Mario Smarduch
  Cc: Wood Scott-B07421, kvm@vger.kernel.org list,
	kvm-ppc@vger.kernel.org,
	virtualization@lists.linux-foundation.org, Bhushan Bharat-R65777,
	Sethi Varun-B16395, kvmarm@lists.cs.columbia.edu



> -----Original Message-----
> From: Mario Smarduch [mailto:mario.smarduch@huawei.com]
> Sent: Thursday, July 04, 2013 9:45 AM
> To: Yoder Stuart-B08248
> Cc: Alex Williamson; Alexander Graf; Wood Scott-B07421; kvm@vger.kernel.org list; Bhushan Bharat-R65777;
> kvm-ppc@vger.kernel.org; virtualization@lists.linux-foundation.org; Sethi Varun-B16395;
> kvmarm@lists.cs.columbia.edu
> Subject: Re: RFC: vfio interface for platform devices (v2)
> 
> 
> I'm having trouble understanding how this works where
> the Guest Device Model != Host. How do you inform the guest
> where the device is mapped in its physical address space,
> and handle GPA faults?

The vfio mechanisms just expose hardware to user space
and the user space app may or may not QEMU.  So there
may be no 'guest' at all.

The intent of this RFC is to provide enough info to user space so
an application can use the device, or in the case of QEMU expose
the device to a VM.  Platform devices are typically exposed via
the device tree and that is how I envision them being presented
to a guest.

Are there real cases you see where guest device model != host?
I don't envision ever presenting a platform device as a PCI device
or vise versa.

Stuart

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: RFC: vfio interface for platform devices (v2)
  2013-07-03 22:53 ` Alex Williamson
  2013-07-03 23:06   ` Scott Wood
@ 2013-07-16 21:57   ` Yoder Stuart-B08248
  1 sibling, 0 replies; 7+ messages in thread
From: Yoder Stuart-B08248 @ 2013-07-16 21:57 UTC (permalink / raw)
  To: Alex Williamson
  Cc: Alexander Graf, Wood Scott-B07421, Bhushan Bharat-R65777,
	Sethi Varun-B16395, virtualization@lists.linux-foundation.org,
	Antonios Motakis, kvm@vger.kernel.org list,
	kvm-ppc@vger.kernel.org, kvmarm@lists.cs.columbia.edu

(sorry for the delayed response, but I've been on PTO)

> > 1.  VFIO_GROUP_GET_DEVICE_FD
> >
> >   User space knows by out-of-band means which device it is accessing
> >   and will call VFIO_GROUP_GET_DEVICE_FD passing a specific sysfs path
> >   to get the device information:
> >
> >   fd = ioctl(group, VFIO_GROUP_GET_DEVICE_FD,
> >              "/sys/bus/platform/devices/ffe210000.usb"));
> 
> FWIW, I'm in favor of whichever way works out cleaner in the code for
> pre-pending "/sys/bus" or not.  It sort of seems like it's unnecessary.
> It's also a little inconsistent that the returned path doesn't
> pre-pend /sys in the examples below.

Ok.  For the returned path in the examples I have the actual device tree
path which is slightly different from the path in /sys.  The device
tree path is what user space would need to interpret /proc/device-tree.

> > 2.  VFIO_DEVICE_GET_INFO
> >
> >    The number of regions corresponds to the regions defined
> >    in "reg" and "ranges" in the device tree.
> >
> >    Two new flags are added to struct vfio_device_info:
> >
> >    #define VFIO_DEVICE_FLAGS_PLATFORM (1 << ?) /* A platform bus device */
> >    #define VFIO_DEVICE_FLAGS_DEVTREE  (1 << ?) /* device tree info available */
> >
> >    It is possible that there could be platform bus devices
> >    that are not in the device tree, so we use 2 flags to
> >    allow for that.
> >
> >    If just VFIO_DEVICE_FLAGS_PLATFORM is set, it means
> >    that there are regions and IRQs but no device tree info
> >    available.
> >
> >    If just VFIO_DEVICE_FLAGS_DEVTREE is set, it means
> >    there is device tree info available.
> 
> But it would be invalid to only have DEVTREE w/o PLATFORM for now,
> right?

Right.  The way I stated it is incorrect. DEVTREE would never
be set by itself.

> > 3. VFIO_DEVICE_GET_REGION_INFO
> >
> >    For platform devices with multiple regions, information
> >    is needed to correlate the regions with the device
> >    tree structure that drivers use to determine the meaning
> >    of device resources.
> >
> >    The VFIO_DEVICE_GET_REGION_INFO is extended to provide
> >    device tree information.
> >
> >    The following information is needed:
> >       -the device tree path to the node corresponding to the
> >        region
> >       -whether it corresponds to a "reg" or "ranges" property
> >       -there could be multiple sub-regions per "reg" or "ranges" and
> >        the sub-index within the reg/ranges is needed
> >
> >    There are 5 new flags added to vfio_region_info :
> >
> >    struct vfio_region_info {
> >         __u32   argsz;
> >         __u32   flags;
> >    #define VFIO_REGION_INFO_FLAG_CACHEABLE (1 << ?)
> >    #define VFIO_DEVTREE_REGION_INFO_FLAG_REG (1 << ?)
> >    #define VFIO_DEVTREE_REGION_INFO_FLAG_RANGE (1 << ?)
> >    #define VFIO_DEVTREE_REGION_INFO_FLAG_INDEX (1 << ?)
> >    #define VFIO_DEVTREE_REGION_INFO_FLAG_PATH (1 << ?)
> >         __u32   index;          /* Region index */
> >         __u32   resv;           /* Reserved for alignment */
> >         __u64   size;           /* Region size (bytes) */
> >         __u64   offset;         /* Region offset from start of device fd */
> >    };
> >
> >    VFIO_REGION_INFO_FLAG_CACHEABLE
> >        -if set indicates that the region must be mapped as cacheable
> >
> >    VFIO_DEVTREE_REGION_INFO_FLAG_REG
> >        -if set indicates that the region corresponds to a "reg" property
> >         in the device tree representation of the device
> >
> >    VFIO_DEVTREE_REGION_INFO_FLAG_RANGE
> >        -if set indicates that the region corresponds to a "ranges" property
> >         in the device tree representation of the device
> >
> >    VFIO_DEVTREE_REGION_INFO_FLAG_INDEX
> >        -if set indicates that there is a dword aligned struct
> >         struct vfio_devtree_region_info_index appended to the
> >         end of vfio_region_info:
> >
> >         struct vfio_devtree_region_info_index
> >         {
> > 	      u32 index;
> >         }
> >
> >         A reg or ranges property may have multiple regsion.  The index
> >         specifies the index within the "reg" or "ranges"
> >         that this region corresponds to.
> >
> >    VFIO_DEVTREE_REGION_INFO_FLAG_PATH
> >        -if set indicates that there is a dword aligned struct
> >         struct vfio_devtree_info_path appended to the
> >         end of vfio_region_info:
> >
> >         struct vfio_devtree_info_path
> >         {
> >             u32 len;
> >             u8 path[];
> >         }
> >
> >         The path is the full path to the corresponding device
> >         tree node.  The len field specifies the length of the
> >         path string.
> >
> >    If multiple flags are set that indicate that there is
> >    an appended struct, the order of the flags indicates
> >    the order of the structs.
> >
> >    argsz is set by the kernel specifying the total size of
> >    struct vfio_region_info and all appended structs.
> >
> >    Suggested usage:
> >       -call VFIO_DEVICE_GET_REGION_INFO with argsz =
> >        sizeof(struct vfio_region_info)
> >       -realloc the buffer
> >       -call VFIO_DEVICE_GET_REGION_INFO again, and the appended
> >        structs will be returned
> >
> > 4.  VFIO_DEVICE_GET_IRQ_INFO
> >
> >    For platform devices with multiple interrupts that
> >    correspond to different subnodes in the device tree,
> >    information is needed to correlate the interrupts
> >    to the the device tree structure.
> >
> >    The VFIO_DEVICE_GET_REGION_INFO is extended to provide
> >    device tree information.
> >
> >    1 new flag is added to vfio_irq_info :
> >
> >    struct vfio_irq_info {
> >         __u32   argsz;
> >         __u32   flags;
> >    #define VFIO_DEVTREE_IRQ_INFO_FLAG_PATH (1 << ?)
> >         __u32   index;    /* IRQ index */
> >         __u32   count;    /* Number of IRQs within this index */
> >     };
> >
> >    VFIO_DEVTREE_IRQ_INFO_FLAG_PATH
> >        -if set indicates that there is a dword aligned struct
> >         struct vfio_devtree_info_path appended to the
> >         end of vfio_irq_info :
> >
> >         struct vfio_devtree_info_path
> >         {
> >             u32 len;
> >             u8 path[];
> >         }
> >
> >         The path is the full path to the corresponding device
> >         tree node.  The len field specifies the length of the
> >         path string.
> >
> >    argsz is set by the kernel specifying the total size of
> >    struct vfio_region_info and all appended structs.
> >
> > 5.  EXAMPLE 1
> >
> >     Example, Freescale SATA controller:
> >
> >      sata@220000 {
> >          compatible = "fsl,p2041-sata", "fsl,pq-sata-v2";
> >          reg = <0x220000 0x1000>;
> >          interrupts = <0x44 0x2 0x0 0x0>;
> >      };
> >
> >     request to get device FD would look like:
> >       fd = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "/sys/bus/platform/devices/ffe220000.sata");
> >
> >     The VFIO_DEVICE_GET_INFO ioctl would return:
> >       -1 region
> >       -1 interrupts
> >
> >     The VFIO_DEVICE_GET_REGION_INFO ioctl would return:
> >       -for index 0:
> >            offset=0, size=0x10000 -- allows mmap of physical 0xffe220000
> >            flags = VFIO_DEVTREE_REGION_INFO_FLAG_REG |
> >                    VFIO_DEVTREE_REGION_INFO_FLAG_PATH
> >            vfio_devtree_info_path
> >               len = 26
> >               path = "/soc@ffe000000/sata@220000"
> >
> >     The VFIO_DEVICE_GET_IRQ_INFO ioctl would return:
> >       -for index 0:
> >           flags = VFIO_IRQ_INFO_EVENTFD |
> >                   VFIO_IRQ_INFO_MASKABLE |
> >                   VFIO_DEVTREE_IRQ_INFO_FLAG_PATH
> >           vfio_devtree_info_path
> >               len = 26
> >               path = "/soc@ffe000000/sata@220000"
> >
> > 6.  EXAMPLE 2
> >
> >     Example, Freescale DMA engine (modified to illustrate):
> >
> >     dma@101300 {
> >        cell-index = <0x1>;
> >        ranges = <0x0 0x101100 0x200>;
> >        reg = <0x101300 0x4>;
> >        compatible = "fsl,eloplus-dma";
> >        #size-cells = <0x1>;
> >        #address-cells = <0x1>;
> >        fsl,liodn = <0xc6>;
> >
> >        dma-channel@180 {
> >           interrupts = <0x23 0x2 0x0 0x0>;
> >           cell-index = <0x3>;
> >           reg = <0x180 0x80>;
> >           compatible = "fsl,eloplus-dma-channel";
> >        };
> >
> >        dma-channel@100 {
> >           interrupts = <0x22 0x2 0x0 0x0>;
> >           cell-index = <0x2>;
> >           reg = <0x100 0x80>;
> >           compatible = "fsl,eloplus-dma-channel";
> >        };
> >
> >     };
> >
> >     request to get device FD would look like:
> >       fd = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "/sys/bus/platform/devices/ffe101300.dma");
> >
> >     The VFIO_DEVICE_GET_INFO ioctl would return:
> >       -2 regions
> >       -2 interrupts
> >
> >     The VFIO_DEVICE_GET_REGION_INFO ioctl would return:
> >       -for index 0:
> >            offset=0x100, size=0x200 -- allows mmap of physical 0xffe101100
> >            flags = VFIO_DEVTREE_REGION_INFO_FLAG_RANGES |
> >                    VFIO_DEVTREE_REGION_INFO_FLAG_PATH
> >            vfio_devtree_info_path
> >               len = 25
> >               path = "/soc@ffe000000/dma@101300"
> >
> >       -for index 1:
> >            offset=0x300, size=0x4 -- allows mmap of physical 0xffe101300
> >            flags = VFIO_DEVTREE_REGION_INFO_FLAG_REG |
> >                    VFIO_DEVTREE_REGION_INFO_FLAG_PATH
> >            vfio_devtree_info_path
> >               len = 25
> >               path = "/soc@ffe000000/dma@101300"
> >
> >     The VFIO_DEVICE_GET_IRQ_INFO ioctl would return:
> >       -for index 0:
> >           flags = VFIO_IRQ_INFO_EVENTFD |
> >                   VFIO_IRQ_INFO_MASKABLE |
> >                   VFIO_DEVTREE_IRQ_INFO_FLAG_PATH
> >           vfio_devtree_info_path
> >               len = 41
> >               path = "/soc@ffe000000/dma@101300/dma-channel@180"
> >
> >       -for index 0:
> >           flags = VFIO_IRQ_INFO_EVENTFD |
> >                   VFIO_IRQ_INFO_MASKABLE |
> >                   VFIO_DEVTREE_IRQ_INFO_FLAG_PATH
> >           vfio_devtree_info_path
> >               len = 41
> >               path = "/soc@ffe000000/dma@101300/dma-channel@100"
> 
> 
> Seems like it should work.  My only API concern with this model of
> appending structs is that a user needs to know the size of each struct
> even if they don't otherwise care about it in order to step over it.  In
> some cases, like the path, the size is variable and the user needs to
> look into it.  The structs must also be strictly ordered based on the
> order of the flags or all hope is lost.  If we assign flags sequentially
> there should be no case where the user needs to step over something that
> they doesn't know the size of.  Even so, we may still be ahead to define
> the first word of each struct as the length (I'm guessing a byte might
> be too limiting).  It would sure make walking it easier.  

The 'path' structs already start with the length, so the only change 
would be to add a length to the vfio_devtree_region_info_index
struct right?   I guess will make it a u32.

Stuart

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-07-16 21:55 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-03 21:40 RFC: vfio interface for platform devices (v2) Yoder Stuart-B08248
2013-07-03 22:53 ` Alex Williamson
2013-07-03 23:06   ` Scott Wood
2013-07-16 21:57   ` Yoder Stuart-B08248
2013-07-04 14:44 ` Mario Smarduch
2013-07-04 14:47   ` Alexander Graf
2013-07-16 15:25   ` Yoder Stuart-B08248

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox