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@xxxxxxxxxxxxxxxxxxxxx > https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm > -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html