VFIO代码分析(6)QEMU中VFIO实例化1

        看QEMU中执行的流程可以将内核中VFIO相关的API串连起来,QEMU中的VFIO部分和内核中的VFIO部分两者结合起来才是VFIO整个过程。

        我们从vfio_realize()这个函数开始看,这个是VFIO设备在QEMU中实现具现化函数。

该操作简要操作大体如下所示:

  1. 根据设备BDF找到对应/dev/group/<groupid>对应的group id;
  2. 调用vfio_get_group(),通过API获取group信息,关联iommu_driver等,后面详细分析;
  3. 调用vfio_get_device()将设备与fd关联;
  4. 调用vfio_populate_device()获取设备的region/中断信息等,后续调用vfio_bars_prepare()和vfio_bars_register()进行设备IO地址空间模拟;
  5. 调用vfio_msix_early_setup()进行MSIX中断设置;
  6. 调用vfio_migration_probe()进行VFIO设备热迁移设置;

        下面分成几个部分进行较详细分析。

1 函数vfio_get_group()

        该函数实现的内容比较多,主要有如下部分:

  1. 调用qemu_open_old(“/dev/vfio/<groupid>”)打开group对应的文件,后面可以通过Group API进行GROUP相关的API;
  2. 调用VFIO_GROUP_SET_STATUS获取iommu_group的状态,是否可见,是否设置了group->container;
  3. 调用vfio_connect_container()将VFIOGroup与VFIOContainer关联起来,并将VFIOC ontainer与iommu_driver关联起来;
  4. 调用qemu_register_reset()注册reset接口;

        其中最重要的部分vfio_connect_container()操作如下所示:

  1. 调用qemu_open_old(“/dev/vfio/vfio”)打开/dev/vfio/vfio接口,后面可以通过该fd进行vfio_container相关API的调用;
  2. 调用VFIO_GET_API_VERSION Container API,返回VFIO_API_VERSION;
  3. 分配VFIOContainer,并设备其他fd/地址空间等;
  4. 调用vfio_init_container(),调用VFIO_GROUP_SET_CONTAINER将内部vfio_group与vfio_container关联,调用VFIO_SET_IOMMU将vfio_container与iommu_driver关联上,这样可以通过vfio_container进行IOMMU相关的操作;
  5. 若使用VFIO_TYPE1_IOMMU,调用VFIO_IOMMU_GET_INFO获取iommu信息,调用vfio_host_win_add()(作用?),并调用vfio_get_iommu_info_migration()获取热迁移信息,后面单独对VFIO热迁移作单独分析;
  6. 调用vfio_kvm_device_add()将VFIO设备添加到KVM子系统;
  7. 注册MR的vfio_region_listener,当MR中发生内存的变化时,会调用vfio_region_listener中相应的回调函数;

2 函数vfio_get_group()

        该函数主要是为VFIO设备分配文件描述符fd并关联起来,后续可直接对设备文件描述符fd访问即可访问到设备相关的信息。

  1. 调用VFIO_GROUP_GET_DEVICE_FD为VFIO设备分配fd;
  2. 调用VFIO_DEVICE_GET_INFO获取VFIO设备的region数目,irq中断数目等;
  3. 将VFIO设备与fd关联,并将获取的VFIO设备信息赋值给vbasedev;

猜你喜欢

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