vfio特别用一个数据结构来管理设备的memory region
typedef struct VFIORegion { struct VFIODevice *vbasedev; off_t fd_offset; /* offset of region within device fd */ MemoryRegion *mem; /* slow, read/write access */ size_t size; uint32_t flags; /* VFIO region flags (rd/wr/mmap) */ uint32_t nr_mmaps; VFIOMmap *mmaps; uint8_t nr; /* cache the region number for debug */ } VFIORegion;
注意到它还有个域是VFIOMmap结构的指针:
typedef struct VFIOMmap { MemoryRegion mem; void *mmap; off_t offset; size_t size; } VFIOMmap;
感觉是不是有冗余,那么外层结构里面的mem是不是指向内层中的mem呢?
上面的mem还有个奇怪的注释:slow,难道还有一种快一点的MR?那是不是指这里是IO的MR,另外还有个RAM的mr?
回到代码:
vfio_region_setup => memory_region_init_io
这里提供了ops,走退出到qemu的传统IO路径,确实很慢。。
而另外在vfio_map_bar里面却又做了一个RAM的MR:
vfio_region_mmap => memory_region_init_ram_ptr
所以这里实现了两种region,一个io一个ram,后者是一种加速优化,即直接把vfio映射到用户态的设备mmio bar作为MR透给VM
region->mmaps[i].mmap = mmap(NULL, region->mmaps[i].size, prot, MAP_SHARED, region->vbasedev->fd, region->fd_offset + region->mmaps[i].offset);
mmap参数里需要的信息前面vfio_region_setup里面都已经获取到了,只有当此处mmap失败,不得已才会走IO MR的slow路径