VFIO代码分析(3)VFIO-PCI驱动2
3 VFIO PCI設備操作回調vfio_pci_ops
????????對VFIO設備文件描述符fd的操作,它調用device->ops的回調,這些回調最終會調用vfio_pci_ops所定義的回調函數。
(1).open_device = vfio_pci_open_device
????????該函數主要是使能PCI設備,進行初始化設備,并將配置空間拷貝到相關結構體中。
(2).read = vfio_pci_core_read
????????對VFIO設備的讀寫操作包括對配置空間的讀寫,對BAR空間的讀寫,以及region特定的讀寫操作。
????????對于配置空間的讀寫,調用vfio_pci_config_rw();對于BAR0~BAR5以及ROM區域的讀寫,調用vfio_pci_bar_rw();其他區域,默認調用region[i].ops->rw()特定的讀寫函數。
-?配置空間的讀寫
????????對配置空間不同的區域或CAP_ID,進行不同的設置,且有些區域只支持讀,這里分幾種情況:
????????對于PCI_CAP_ID_INVALID,調用vfio_raw_config_*()進行讀寫,主要是調用pci_user_{read|write}_config來處理(與memcpy的差別?);
????????對于PCI_CAP_ID_INVALID_VIRT,調用vfio_virt_config_*()進行讀寫,主要是調用memcpy將結構體vdev->config上模擬的內部讀取;
????????對于PCI_CAP_ID和PCI_ECAP_ID,調用vfio_direct_config_*()進行讀寫,先嘗試pci_user_{read|write}_config,若失敗再調用memcpy進行讀取;
????????對于PCI_CAP_ID_MSI,暫時不分析;
-?對BAR空間的讀寫
????????通過調用vfio_pci_bar_rw()對BAR空間進行讀寫。調用如下所示:
????????對于BAR0~BAR5區域的讀寫,通過vfio_pci_setup_barmap()將BAR區域映射到vdev->barmap[]中,這樣在內核態直接訪問它;
????????對于ROM區域的讀寫,通過pci_map_rom()最終通過io_remap()對ROM區域映射;
????????對于MSIX區域的讀寫,暫不分析[待分析]。
(3).mmap = vfio_pci_core_mmap
????????通過調用vfio_pci_core_mmap()對BAR空間進行映射。調用如下:
?????????當需要映射的區域并不是PCI定義的區域時,會調用區域特定的mmap回調;
????????當需要映射的區域為PCI定義的區域時,通過函數pci_iomap()將BAR空間映射到vdev->barmap[],并為vma設置回調函數vfio_pci_mmap_ops。
(4).request = vfio_pci_core_request
????????對于vfio_pci_core_request()函數,若定義vdev->req_trigger,通過eventfd_signal()往虛擬機中注入模擬中斷。
(5).unlocked_ioctl = vfio_device_fops_unl_ioctl
????????QEMU要獲取設備的信息并設置設備,需要通過設備API進行調用,它們是通過函數vfio_device_fops_unl_ioctl()來分別對不同的設備API進行處理。
?其中VFIO_DEVICE_GET_INFO用于獲取設備region數目和中斷的數目;
VFIO_DEVICE_GET_REGION_INFO用于獲取設備某個region在設備文件描述符fd中的偏移和大小 ;
VFIO_DEVICE_IRQ_INFO用于獲取設備對應的中斷數目和標志;
VFIO_DEVICE_SET_IRQS用于請求中斷并設置中斷處理函數,這里在中斷章節進行更詳細描述。
?
總結
以上是生活随笔為你收集整理的VFIO代码分析(3)VFIO-PCI驱动2的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ubuntu安装docker + 配置国
- 下一篇: VUE中的鼠标右键功能