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