转自
https://www.kernel.org/doc/Documentation/vfio.txt
introduction to vfio https://insujang.github.io/2017-04-27/introduction-to-vfio/
https://luohao-brian.gitbooks.io/interrupt-virtualization/vfio-she-bei-zhi-tong-jian-jie.html
vfio直通设备简介 https://luohao-brian.gitbooks.io/interrupt-virtualization/vfio-she-bei-zhi-tong-jian-jie.html
vfio中实现的关键点 https://kernelgo.org/vfio-insight.html
- IOMMU和VFIO http://element-ui.cn/news/show-44900.aspx
vfio文件描述符在/dev/vfio 下
ls -all /dev/vfio total 0 drwxr-xr-x 2 root root 80 Feb 25 22:08 . drwxr-xr-x 18 root root 4360 Feb 25 22:08 .. crw------- 1 linux root 237, 0 Feb 25 22:08 2 crw-rw-rw- 1 root root 10, 196 Jan 13 10:09 vfio
vfio-pci device driver
看dpdk里面怎么用vfio:
vfio_type1_dma_map
1 static int 2 vfio_type1_dma_mem_map(int vfio_container_fd, uint64_t vaddr, uint64_t iova, 3 uint64_t len, int do_map) 4 { 5 struct vfio_iommu_type1_dma_map dma_map; 6 struct vfio_iommu_type1_dma_unmap dma_unmap; 7 int ret; 8 9 if (do_map != 0) { 10 memset(&dma_map, 0, sizeof(dma_map)); 11 dma_map.argsz = sizeof(struct vfio_iommu_type1_dma_map); 12 dma_map.vaddr = vaddr; 13 dma_map.size = len; 14 dma_map.iova = iova; 15 dma_map.flags = VFIO_DMA_MAP_FLAG_READ | 16 VFIO_DMA_MAP_FLAG_WRITE; 17 18 //VFIO_IOMMU_MAP_DMA这个命令就是将iova通过IOMMU映射到vaddr对应的物理地址上去。 19 ret = ioctl(vfio_container_fd, VFIO_IOMMU_MAP_DMA, &dma_map); 20 if (ret) { 21 /** 22 * In case the mapping was already done EEXIST will be 23 * returned from kernel. 24 */ 25 if (errno == EEXIST) { 26 RTE_LOG(DEBUG, EAL, 27 " Memory segment is already mapped," 28 " skipping"); 29 } else { 30 RTE_LOG(ERR, EAL, 31 " cannot set up DMA remapping," 32 " error %i (%s) ", 33 errno, strerror(errno)); 34 return -1; 35 } 36 } 37 } else { 38 memset(&dma_unmap, 0, sizeof(dma_unmap)); 39 dma_unmap.argsz = sizeof(struct vfio_iommu_type1_dma_unmap); 40 dma_unmap.size = len; 41 dma_unmap.iova = iova; 42 43 ret = ioctl(vfio_container_fd, VFIO_IOMMU_UNMAP_DMA, 44 &dma_unmap); 45 if (ret) { 46 RTE_LOG(ERR, EAL, " cannot clear DMA remapping, error %i (%s) ", 47 errno, strerror(errno)); 48 return -1; 49 } 50 } 51 52 return 0; 53 }