1. 什麼是SMMU?
SMMU(system mmu),是I/O device與總線之間的地址轉換橋。
它在系統的位置如下圖:
它與mmu的功能類似,可以實現地址轉換,內存屬性轉換,權限檢查等功能。
2. 爲什麼需要SMMU?
瞭解SMMU出現的背景,需要知道系統中的兩個概念: DMA和虛擬化。
DMA:((Direct Memory Access),直接內存存取, 是一種外部設備不通過CPU而直接與系統內存交換數據的接口技術 。外設可以通過DMA,將數據批量傳輸到內存,然後再發送一箇中斷通知CPU取,其傳輸過程並不經過CPU, 減輕了CPU的負擔。但由於DMA不能像CPU一樣通過MMU操作虛擬地址,所以DMA需要連續的物理地址。
虛擬化: 在虛擬化場景, 所有的VM都運行在中間層hypervisor上,每一個VM獨立運行自己的OS(guest OS),Hypervisor完成硬件資源的共享, 隔離和切換。
但對於Hypervisor + GuestOS的虛擬化系統來說, guest VM使用的物理地址是GPA, 看到的內存並非實際的物理地址(也就是HPA),因此Guest OS無法正常的將連續的物理地址分給硬件。
因此,爲了支持I/O透傳機制中的DMA設備傳輸,而引入了IOMMU技術(ARM稱作SMMU)。
總而言之,SMMU可以爲ARM架構下實現虛擬化擴展提供支持。它可以和MMU一樣,提供stage1轉換(VA->PA), 或者stage2轉換(IPA->PA),或者stage1 + stage2轉換(VA->IPA->PA)的靈活配置。
*[VA:虛擬地址; IPA: 中間物理地址; PA:物理地址]
3. SMMU常用概念
術語 | 概念 |
---|---|
StreamID | 一個平臺上可以有多個SMMU設備,每個SMMU設備下面可能連接着多個Endpoint, 多個設備互相之間可能不會複用同一個頁表,需要加以區分,SMMU用StreamID來做這個區分( SubstreamID的概念和PCIe PASID是等效的) |
STE | Stream Table Entry, STE裏面包含一個指向stage2地址翻譯表的指針,並且同時還包含一個指向CD(Context Descriptor)的指針. |
CD | Context Descriptor, 是一個特定格式的數據結構,包含了指向stage1地址翻譯表的基地址指針 |
4. SMMU數據結構查找
SMMU翻譯過程需要使用多種數據結構,如STE, CD等。
4.1 SID查找STE
Stream Table是存放在內存中的一張表,在SMMU驅動初始化時由驅動程序創建好。
Stream table有兩種格式,一種是Linear Stream Table, 一種是2-level Stream Table.
1. Linear Stream Table
Linear Stream Table是將整個stream table在內存中線性展開成一個數組, 用Stream Id作爲索引進行查找.
Linear Stream Table 實現簡單,只需要一次索引,速度快; 但是平臺上外設較少時,浪費連續的內存空間。
2. 2-level Stream Table
2-level Stream Table, 顧名思義,就是包含2級table, 第一級table, 即STD,包含了指向二級STE的基地址STD。 第二級STE是Linear stream Table. 2-level Stream Table的優點是更加節省內存。
SMMU根據寄存器配置的STRTAB_BASE地址找到STE, STRTAB_BASE定義了STE的基地值, Stream id定義了STE的偏移。如果使用linear 查找, 通過STRTAB_BASE + sid * 64(一個STE的大小爲64B)找到STE; 若使用2-level查找, 則先通過sid的高位找到L1_STD(STRTAB_BASE + sid[9:8] * 8, 一個L1_STD的大小爲8B), L1_STD定義了下一級查找的基地址,然後通過sid 找到具體的STE(l2ptr + sid[7:0] * 64).
最終找到的STE如下所示,表中的信息包含屬性相關信息, 翻譯模式信息(是否 stream bypass, 若否,選擇stage1, stage2或者stage1 + stage2翻譯模式)。
找到STE後可以進一步開始S1翻譯或S2翻譯.
4.2 SSID查找CD
CD包含了指向stage1地址翻譯表的基地址指針.
如下圖所示, STE指明瞭CD數據結構在DDR中的基地址S1ContextPTR, SSID(substream id)指明瞭CD數據結構的偏移,如果SMMU選擇進行linear, 則使用S1ContextPTR + 64 * ssid 找到CD。如果SMMU選擇2-level, 則使用ssid進行二級查找獲得CD(與上節STE的方式一致)。
最終找到的CD如下所示:
表中信息包含memory屬性,翻譯控制信息,異常控制信息以及Page table walk(PTW)的起始地址TTB0, TTB1, 找到TTBx後,就可以PTW了。
5. SMMU地址轉換
5.1 單stage的地址轉換:
- TTB 和 VA[47:39]組成獲取Level0頁表的地址PA;
- Level0頁表中的next-level table address 和 VA[38:30]組成獲取Level1的頁表地址PA;
- Level1頁表中的next-level table address 和 VA[29:21]組成獲取Level2的頁表地址PA;
- Level2頁表中的next-level table address 和 VA[20:12]組成獲取Leve3的頁表地址PA;
- level3頁表中的output address和va[12:0]組成獲取組後的鑽換地址
在stage1地址翻譯階段:硬件先通過StreamID索引到STE,然後用SubstreamID索引到CD, CD裏面包含了stage1地址翻譯(把進程的GVA/IOVA翻譯成IPA)過程中需要的頁表基地址信息、per-stream的配置信息以及ASID。 在stage1翻譯的過程中,多個CD對應着多個stage1的地址翻譯,通過Substream去確定對應的stage1地址翻譯頁表。 所以,Stage1地址翻譯其實是一個(RequestID, PASID) => GPA的映射查找過程。
5.2 stage1+stage2的地址轉換:
在使能SMMU兩階段地址翻譯的情況下,stage1負責將設備DMA請求發出的VA翻譯爲IPA並作爲stage2的輸入, stage2則利用stage1輸出的IPA再次進行翻譯得到PA,從而DMA請求正確地訪問到Guest的要操作的地址空間上。
在stage2地址翻譯階段:STE裏面包含了stage2地址翻譯的頁表基地址(IPA->HPA)和VMID信息。 如果多個設備被直通給同一個虛擬機,那麼意味着他們共享同一個stage2地址翻譯頁表。
在兩階段地址翻譯場景下, 地址轉換流程步驟:
- Guest驅動發起DMA請求,這個DMA請求包含VA + SID前綴
- DMA請求到達SMMU,SMMU提取DMA請求中的SID就知道這個請求是哪個設備發來的,然後去StreamTable索引對應的STE
- 從對應的STE表中查找到對應的CD,然後用ssid到CD中進行索引找到對應的S1 Page Table
- IOMMU進行S1 Page Table Walk,將VA翻譯成IPA並作爲S2的輸入
- IOMMU執行S2 Page Table Walk,將IPA翻譯成PA,地址轉化結束。
6. SMMU command queue 與 event queue
系統軟件通過Command Queue和Event Queue來和SMMU打交道,這2個Queue都是循環隊列。
Command queue用於軟件與SMMU的硬件交互,軟件寫命令到command queue, SMMU從command queue中 地區命令處理。
Event Queue用於SMMU發生軟件配置錯誤的狀態信息記錄,SMMU將配置錯誤信息寫到Event queue中,軟件通過讀取Event queue獲得配置錯誤信息並進行配置錯誤處理。
7. 參考資料
- 虛擬化技術 - I/O虛擬化(一)
- IHI0070_System_Memory_Management_Unit_Arm_Architecture_Specification
- ARMv8 Virtualization Overview