VFIO代码分析(7)QEMU中VFIO实例化2

3 VFIO设备的内存信息和地址空间模拟

        先介绍VFIO中虚拟机中Guest中是如何访问BAR空间的。先看如下图:

  1. 在Host中通过pci_iomap()将PCI设备的BAR0空间映射到内核地址空间;
  2. 通过之前VFIO_GROUP_GET_DEVICE_FD将文件描述符fd与PCI设备进行关联,后面对fd的操作最终会操作PCI设备对应的内核地址空间;
  3. 在QEMU中将文件描述符fd中region通过mmap()映射到QEMU的地址(虚拟地址空间),并通过memory_region_init_ram()生成MR,并导出给Guest。

        这样在Guest中访问设备对应的BAR空间时VM exit到QEMU中,这样在QEMU中通过read()/write()对fd操作,最终访问到实际设备的BAR空间。

        下面介绍QEMU中对PCIE的配置空间和BAR空间的处理。

        对于配置空间,直接通过pread()获取VFIO设备的配置空间,并保存在pdev.config中,并对配置空间通过memory_region_init_io()分配MR,注册到QEMU。当guest对配置空间读写访问时,由于没有分配内存(QEMU虚拟地址),最终会调用QEMU中注册的读写模拟函数vfio_pci_config_write()和vfio_pci_config_read()。

        对于BAR空间,将BAR空间映射到QEMU的虚拟地址空间,并通过memory_region_init_ram_device_ptr()将其作为MR。当guest对BAR空间读写访问时,存在内存,可以直接进行读写。

        调用vfio_populate_device()获取VFIO设备的BAR信息和配置信息。调用如下所示:

  1. 获取VFIO设备的BAR0~ROM区域的信息,如BAR空间在fd文件描述符中的偏移及大小,分配IO MR(region->mem),没有分配实际内存,并注册vfio_region_ops,当guest访问时会调到注册的回调vfio_region_ops;
  2. 获取VFIO设备的CONFIG配置区域的信息,并设置vbasedev对应的配置信息;
  3. 调用VFIO_DEVICE_GET_IRQ_INFO获取中断的信息;

        调用vfio_bars_prepare()和vfio_bars_region()进行VFIO设备的IO地址空间模拟。

扫描二维码关注公众号,回复: 14480485 查看本文章

上述将设备的每个BAR空间映射到QEMU用户空间,并最后注册给虚拟机。

  1. 调用vfio_bar_prepare()对每个bar读取BAR空间信息,在QEMU下通过pread()函数通过设备的文件描述符fd读取到BAR空间信息;
  2. 分配bar->region.mem MR作为bar->mr MR的子MR;
  3. 采用mmap()将设备BAR空间映射到QEMU用户空间region->mmaps[i].mem;
  4. 将QEMU用户空间注册到虚拟机中;

猜你喜欢

转载自blog.csdn.net/flyingnosky/article/details/123748011