vfio 直通设备的 memory region 初始化

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路径

Leave a Reply

Your email address will not be published. Required fields are marked *