鐵人賽
IOMMU 必須識別來自設備 MSI 的傳入,並根據實際機器的需求進行轉換。
設備 MSI 預期由運行在 VM 中的 guest os 進行配置,假設 VM 符合 AIA架構,MSI 透過寫入虛擬 IMSIC interrupt file 的 memory-mapped 暫存器,發送到 VM 內的虛擬 hart。每個虛擬 interrupt file 在 VM 的 guest 實體地址佔了 4kb 頁面大小,與真實 interrupt file 一樣。因此,如果寫入 VM 內的虛擬 IMSIC 的 interrupt file 的頁面,則 guest 實體地址的寫入可以被辨別為 VM 的 MSI。
設備 context 中指定的 MSI 地址 mask 以及 地址 pattern 用來識別 VM 的虛擬 interrupt file 的頁面,如果 target guest 實體頁面提供的地址 mask 中的所有bit 位置都與地址 pattern 相匹配,那設備傳入的32 bit 的data 會被識別為 MSI 寫入到虛擬 interrutp file。
具體來說,在以下情況下,guest 實體地址 A 的寫入被識別為虛擬 interrupt file 的 MSI
>> 12 表示右移 12bit , & 表示 AND, ~ 表示 not
當來自設備的寫入被識別為 MSI 時,會從 guest 實體地址選取一個 interrupt file 號碼,如下所示:
extract(x,y)表示為器 x 中,與 y 相同位置是0的值,保留是1的值,並用補0補齊到最高有效為
for example:
x = a b c d e f g h
y = 1 0 1 0 0 1 1 0
因此 extract(x,y) = 0000acfg (因為 acfg 為1)
當 IOMMU 將設備的傳入識別為 MSI 時,MSI 將透過設備配置的 MSI page table 進行轉換。只有從設備對齊32 bit的寫入,才有可能是 MSI。MSI page table 是由 MSI page entry 所組成,每個 16 byte,MSI page table 並沒有像 RISC-V page table 有多層級架構,每個 MSI PTE(page table entry)都是一個 leaf entry, 在相關 VM 中的 guest 實體頁面進行轉換。每個 MSI PTE 可以替換虛擬 interrupt file 的 guest interrupt file 地址,或是儲存虛擬 interrupt file 傳入 MSI 的 MRIF。
MSI page table 的 entry 數量為2的冪次,u也就是 2^K,其中 k 是 MSI 地址 mask
的位數,用來從目標 guest 實體地址中選取 interrupt file 號碼,如果 MSI page table entry 為256個或更少,則 talbe 與實際實體記憶體 4KB 對齊,如果 MSI page table entry 大於 256個,則該 table 需與 2^K*16
對齊,如果 MSI page table 沒按照要求對齊,則該 page table 所有 entry 在 IOMMU 中會顯示為未指定,並且從 page table 讀取單個 MSI PTE 的任何地址也表示為未指定。
每個 16 byte MSI PTE 被解釋為兩個 64 bit doubleword。MSI PTE 的第一個 doubleword 的 bit 0 是欄位 V(valid)。當 V = 0時,PTE無效,IOMMU會忽略這兩個 doubleword的所有其他 bit,使他們可以供軟體使用。
如果 V=1,第一個 doubleword的 bit 63 是欄位 C(custom),用於自定義,如果 MSI PTE 的 V=1和 C=1,則PTE其餘部分由實現時定義。
如果 V=1且C=0,則第一個 doubleword的 bit 2 欄位為 W(write-through)。如果 W=1,則MSI PTE 為傳入MSI表示為 write-through 模式,如果W=0,則表示為 MRIF 模式。這兩種模式下方更詳細說明。
當 MSI PTE 欄位 V=1,C=0以及 W=1,則 PTE 格式如下:
第一個 doubleword 的其他 bit 都是保留,必須由軟體設定為0,第二個 doubleword被 IOMMU 忽略,因此軟體可以直接使用。
透過將 MSI 寫入的 12 bit 轉換為 PTE 的 PPN(physical page number),同時保留原本地址的 bit 11:0(page offset),此轉換後的地址可以進行零擴展,也可以根據需要在高位元處進行裁剪,使其成為機器的實際實體地址的寬度。接著,從設備寫入的記憶體將會以新的地址傳遞給記憶體系統。
如果支援 MRIF 以及 MSI PTE 欄位 V=1,C=0以及 W=0(MRIF mode), PTE 格式如下:
其他 PTE bit 都是保留的,必須由軟體設為0。
PTE 的 MRIF 地址欄位提供 MRIF 的實體地址的 bit 55:9,在該檔案中儲存傳入的 MSI,稱之為目標 MRIF。由於個 MRIF 都與 512 byte 邊界對齊,因此目標 MRIF 地址 bit 8:0(2^9)必須為0,並且在 PTE 中未指定。
欄位 NPPN(Notice physical page number) 以及兩個欄位 NID(Notice Identifier)共同決定了 通知 MSI 的目標和值,該 通知 MSI 在每次更新目標 MRIF 後發送。
當 IMSIC interrupt file 實現 memory mapped 暫存器 seteipnum_be
以 big_endian順序接收 MSI 時,IOMMU 必須能夠支援以 little_endian和 big_endian 順序將 MSI 儲存到目標 MRIF。如果系統沒有實現 seteipnum_be
,則 IOMMU 通常只能支援 little-endian 順序將 MSI 儲存到目標 MRIF。如果目標地址的 bit 2 為0,則傳入的 MSI 以 little_endian 順序,如果目標地址的 bit 2 為1,則以big_endian 順序。