http://blog.chinaunix.net/uid-28541347-id-5836399.html
DMA重定向硬件一般位於Root Complex中,Root-Complex是PCIe系統中引入的概念,它將CPU、內存子系統和PCIe子系連接起來。如下圖所示:
而Root Complex則經常被集成到CPU芯片上、MCH(Memory Controller Hub)上或者是IOH(I/O hub)上。
DMA重定向硬件將來自於I/O子系統的內存訪問請求分為兩類:
- 不帶地址空間ID的請求(Request without Process Address Space Identifier,即Request-without_PASID),相當於GPA(Guest Physical Address),這是一般Endpoint設備發出的內存訪問請求,這類請求通常會表明該請求的類型(讀、寫或原子操作),DMA目標的地址、大小和發起請求的源設備的ID。
- 帶有地址空間ID的請求(Request with Process Address Space Identifier,即Request-with-PASID),相當於GVA(Guest Virtual Address),能夠發出這類請求的源PCI設備需要擁有virtual address capability,該請求帶有額外的信息用於定位目標地址空間和一些其他信息。
不同虛擬機之間的隔離是通過防止分配到其他虛擬機的資源(CPU、I/O設備)訪問到本虛擬機的物理地址。每個虛擬機都會有自己獨立的物理地址空間,即GPA(Guest Physical Address)空間,該空間不同於主機物理地址空間,即HPA(Host Physical Address)空間。DMA重定向硬件將從I/O設備發過來的訪問請求中包含的地址看做是DMA地址,根據不同的使用配置,該DMA地址可能是GPA;可能是跟PASID(Process Address Space ID)相關的VA(application Virtual Address);也可能是由軟件定義的I/O虛擬地址(IOVA)。不管怎樣,DMA重定向硬件將DMA地址最終轉化為HPA(Host Physical Address)實現最終主機物理地址的訪問
pCI和PCIe區別
先分別看下基於pci總線和pcie總線的拓撲圖:
PCIe與PCI兩者在電器特性上差別很大,這里不做主要闡述。兩類總線拓撲結構上的主要變化就是PCIe支持端到端的連接,無法像PCI一樣,在一條總線上掛接多個設備或橋。PCIe在軟件上是兼容PCI總線的,對於這兩種總線的拓撲結構是有一定的轉換關系的:
對於PCIe的RC等價於PCI中的Host Bridge
device都是相同的
對於Bridge和switch的轉換關系如下圖
IOMMU
IOMMU功能簡介
IOMMU主要功能包括DMA Remapping和Interrupt Remapping,這里主要講解DMA Remapping,Interrupt Remapping會獨立講解。對於DMA Remapping,IOMMU與MMU類似。IOMMU可以將一個設備訪問地址轉換為存儲器地址,下圖針對有無IOMMU情況說明IOMMU作用。
在沒有IOMMU的情況下,網卡接收數據時地址轉換流程,RC會將網卡請求寫入地址addr1直接發送到DDR控制器,然后訪問DRAM上的addr1地址,這里的RC對網卡請求地址不做任何轉換,網卡訪問的地址必須是物理地址。
對於有IOMMU的情況,網卡請求寫入地址addr1會被IOMMU轉換為addr2,然后發送到DDR控制器,最終訪問的是DRAM上addr2地址,網卡訪問的地址addr1會被IOMMU轉換成真正的物理地址addr2,這里可以將addr1理解為虛機地址。
左圖是沒有IOMMU的情況,對於此種情況虛機無法實現設備的透傳,原因主要有兩個:一是因為在沒有IOMMU的情況下,設備必須訪問真實的物理地址HPA,而虛機可見的是GPA;二是如果讓虛機填入真正的HPA,那樣的話相當於虛機可以直接訪問物理地址,會有安全隱患。所以針對沒有IOMMU的情況,不能用透傳的方式,對於設備的直接訪問都會有VMM接管,這樣就不會對虛機暴露HPA。
右圖是有IOMMU的情況,虛機可以將GPA直接寫入到設備,當設備進行DMA傳輸時,設備請求地址GPA由IOMMU轉換為HPA(硬件自動完成),進而DMA操作真實的物理空間。IOMMU的映射關系是由VMM維護的,HPA對虛機不可見,保障了安全問題,利用IOMMU可實現設備的透傳。這里先留一個問題,既然IOMMU可以將設備訪問地址映射成真實的物理地址,那么對於右圖中的Device A和Device B,IOMMU必須保證兩個設備映射后的物理空間不能存在交集,否則兩個虛機可以相互干擾,這和IOMMU的映射原理有關,后面會詳細介紹。
IOMMU作用
根據上一節內容,總結IOMMU主要作用如下:
l 屏蔽物理地址,起到保護作用。典型應用包括兩個:一是實現用戶態驅動,由於IOMMU的映射功能,使HPA對用戶空間不可見,在vfio部分還會舉例。二是將設備透傳給虛機,使HPA對虛機不可見,並將GPA映射為HPA。
l IOMMU可以將連續的虛擬地址映射到不連續的多個物理內存片段,這部分功能於MMU類似,對於沒有IOMMU的情況,設備訪問的物理空間必須是連續的,IOMMU可有效的解決這個問題。
如下圖所示,系統中存在兩個Domain,1和2,也可以理解為存在兩個虛擬機,這兩個虛擬機發出的內存請求通過在CPU上的內存管理單元(MMU),在x86 CPU上可以理解為分頁機制和EPT(Extended Page Table)的組合,將發出的內存請求地址最終轉化為主機的物理內存地址,即HPA,對應到主機物理內存上。而Device 1和2,則可以理解為分別分配給Domain 1和2的I/O設備,雖然它們發出訪問請求的地址數值一樣,但是由於它們所屬的Domain不一樣,導致DMA Memory Management將會使用不同的地址轉換頁表,將其分別轉換到不同Domain所對應的HPA。VMM/Hypervisor負責對DMA Memory Management所使用的I/O地址轉換頁表進行創建和維護,同時需要對DMA重定向和I/O設備進行配置,協商好使用什么類型的地址,GPA或者GVA。
每個DMA重定向硬件的實現可以是一個硬件單元包含整個PCI Segment,也可以是多個硬件單元,每個硬件單元各自包含PCI Segment中的部分PCI設備。系統的BIOS或者UEFI負責在系統啟動的時候對VT-d硬件進行檢測,並分配相應的地址空間,讓系統軟件能夠訪問到VT-d硬件及其配置寄存器。BIOS/ACPI以ACPI表的子表(DMAR:DMA Remapping Reporting ACPT Table)的形式將VT-d硬件資源描述出來,這樣VMM值需要找到DMAR表,就可以對相應的VT-d硬件進行訪問或配置了。