IOMMU & iomap &VFIO & uio


https://www.jianshu.com/p/dd8ab6b68c6a

http://bbs.chinaunix.net/thread-2072818-1-1.html

IOMMU https://blog.csdn.net/sdulibh/article/details/86611777

https://blog.csdn.net/wentyoon/article/details/60144824

 

UIO  https://blog.csdn.net/xy010902100449/article/details/46917623

         https://www.cnblogs.com/SZLLQ2000/p/5257475.html

         http://www.voidcn.com/article/p-umqpermh-no.html

         http://www.voidcn.com/article/p-dpylthzt-gx.html

VFIO

這篇 https://www.ibm.com/developerworks/community/blogs/5144904d-5d75-45ed-9d2b-cf1754ee936a/entry/20160605?lang=en

這篇 https://hhb584520.github.io/kvm_blog/2017/04/14/passthrough.html

這篇 https://ggaaooppeenngg.github.io/zh-CN/2017/06/05/VFIO-%E2%80%94%E2%80%94%E5%B0%86-DMA-%E6%98%A0%E5%B0%84%E6%9A%B4%E9%9C%B2%E7%BB%99%E7%94%A8%E6%88%B7%E6%80%81/

         vfio使用參考kernel/Documentation/vfio.txt

 

 

UIO -->IOMMU --> VFIO

[轉自 https://blog.csdn.net/zgy666/article/details/78649777]

1、UIO的出現,允許將驅動程序用到用戶態空間里實現,但UIO有它的不足之處,如 不支持DMA、中斷等;
2、隨着虛擬化的出現,IOMMU也隨之出現, IOMMU為每個直通的設備分配獨立的頁表,因此不同的直通設備(passthrough),彼此之間相互隔離;
3、有一些場景,多個PCI設備之間是有相互聯系的,他們互相組成一個功能實體,彼此之間是可以相互訪問的,因此IOMMU針對這些設備是行不通的,隨之出現VFIO技術,VFIO兼顧了UIO和IOMMU的優點,在 VFIO里,直通的最小單元不再是某個單獨的設備了,而是分布在同一個group的所有設備;VFIO可以安全地把 設備IO、中斷、DMA等暴露到用戶空間
4、kvm的PCI、PCIE設備直通,默認都是通過VFIO實現的(通過virsh attach-device xxx會自動插vfio的相關ko,自動生成vfio的container);
5、PCIE與PCI直通的區別是:PCI只能直通給某個特定的虛擬機,而PCIE有可能可以給多個虛擬機用,如具有SR-IOV功能的PCIE設備,通過在HOST上抽象出多個的VF,每個VF再通過VFIO直通給虛擬機,最終的表現就是一個物理PCIE網卡可以直通給多個虛擬機用;
6、SR-IOV是針對PCIE設備的,PCI設備理論上不具有SR-IOV功能;
---------------------
 
 

UIO

 

UIO

 

UIO 框架導出sysfs和/dev/uioX 2套用戶態接口,用戶對設備節點/dev/uioX進行設備控制,mmap()接口用於映射設備寄存器空間,write()接口用於控制中斷關閉/打開,read()接口用於等待一個設備中斷。

因為對於設備中斷的應答必須在內核空間進行,所以在內核空間有一小部分代碼用來應答中斷和禁止中斷,其余的工作全部留給用戶空間處理。如果用戶空間要等待一個設備中斷,它只需要簡單的阻塞在對 /dev/uioX的read()操作上。 當設備產生中斷時,read()操作立即返回。UIO 也實現了poll()系統調用,你可以使用 select()來等待中斷的發生。select()有一個超時參數可以用來實現有限時間內等待中斷。

UIO的幾個特點:

  • 一個UIO設備最多支持5個mem和portio空間mmap映射。 
  • UIO設備的中斷用戶態通信機制基於wait_queue實現。
  • 一個UIO設備只支持一個中斷號注冊,支持中斷共享。

總的來說,UIO框架適用於簡單設備的驅動,因為它不支持DMA,不能支持多個中斷線,缺乏邏輯設備抽象能力。

 

IOMMU

 

我說的IOMMU是指位於北橋上的IOMMU,那種設備自帶IOMMU的情況我還不了解。
在沒有IOMMU的情況下,設備(指32bit或64bit設備,老的16bit的不提)的DMA操作可以訪問整個物理地址空間,所以理論上設備可以向操作系統的代碼段、數據段等內存區域做DMA,從而破壞整個系統。當然,通常來說不會有這樣的設備。IOMMU的出現,可以實現地址空間上的隔離,使設備只能訪問規定的內存區域。下面簡要說一下intel的IOMMU怎么做到這點的:
目前PC架構最多有256PCI總線,於是IOMMU用一個稱為root entry的數據結構描述PCI總線,總共256個root entry構成一張表。每條PCI總線最多允許256個設備,IOMMU用context entry描述一個PCI設備(或者是PCI橋),256個context entry構成一張表。所以就有了如圖的關系。我們知道,PCI設備用 {BUSEV:FUNC}(當然,還有個segment,不過似乎PC架構都只有一個segment,這個暫時忽略)描述一個設備。所以對於一個特定設備,用bus號做索引root entry表,用dev號索引context entry表可以找到描述該設備的的context entry。context entry中有一個指針指向一章I/O頁表,當設備發起DMA操作時,IOMMU會根據該頁表把設備的DMA地址轉換成該設備可以訪問內存區域的地址。
所以只要為設備建一張I/O頁表,就可以使設備只能訪問規定的內存區域了。當然,也可以把該頁表當成跳板,讓只能尋址32bit地址空間的設備訪問到64bit地址空間中去。

Many platforms contain an extra piece of hardware called an I/O Memory Management Unit (IOMMU). An IOMMU is much like a regular MMU, except it provides virtualized address spaces to peripheral devices (i.e. on the PCI bus). The MMU knows about virtual to physical mappings per process on the system, so the IOMMU associates a particular device with one of these mappings and then allows the user to assign arbitrary bus addresses to virtual addresses in their process. All DMA operations between the PCI device and system memory are then translated through the IOMMU by converting the bus address to a virtual address and then the virtual address to the physical address. This allows the operating system to freely modify the virtual to physical address mapping without breaking ongoing DMA operations. Linux provides a device driver, vfio-pci, that allows a user to configure the IOMMU with their current process.

大概就是這么回事了,似乎寫的有點亂,具體問題看spec。

rootentry.jpg

 

VFIO

vfio使用參考kernel/Documentation/vfio.txt

 

 

 

 

 上文提到,UIO不支持DMA,所以通過DMA傳輸大流量數據的IO設備,如網卡、顯卡等設備,無法使用UIO框架,VFIO做為UIO的升級版,主要就是解決了這個問題。通過用戶態配置IOMMU接口,可以將DMA地址空間映射限制在進程虛擬空間中。這對高性能驅動和虛擬化場景device passthrough尤其重要。

 

在VFIO框架中,有幾個核心概念或對象:IOMMU、/dev/vfio、container、iommu_group。

 

  • IOMMU是一個硬件單元,它可以把設備的IO地址映射成虛擬地址,為設備提供頁表映射,設備通過IOMMU將數據直接DMA寫到用戶空間。之所以不共用MMU單元,是為了保證和進程的頁表相互獨立,防止設備訪問進程的任意地址空間。所以VFIO的IOMMU功能保障了安全的非特權級別的用戶態設備驅動機制。
  •  /dev/vfio是一個設備文件,作為一個IOMMU設備的用戶態呈現
  • container是內核對象,表示一個IOMMU設備,是一個IOMMU設備的內核態呈現。所以在VFIO中,container是IOMMU操作的最小對象(container中有多個iommu_group)
  • 在虛擬化場景下,一個物理網卡可能要虛擬成幾個虛擬網卡,或者說虛擬功能設備(VF),這幾個VF共用一個IOMMU,所以VFIO模型增加一個iommu_group的概念,用來表示共享同一個IOMMU的一組device。

 

VFIO的幾個特點

 

  • VFIO設備支持多中斷號注冊。
  • 設備的中斷用戶態通信機制基於eventfd/irqfd實現。用戶通過/dev/vfio設備select/poll/epoll,從而實現中斷從內核態到用戶態的異步事件通知。
  • 支持對物理設備進行邏輯抽象。
  • 僅支持pci intx中斷共享,其他類型中斷不支持共享。
  • VFIO僅支持特定IOMMU設備,如x86與PowerPC平台的PCI設備和ARM平台的platform設備。

 

概述

VFIO是一套用戶態驅動框架,它提供兩種基本服務:

  • 向用戶態提供訪問硬件設備的接口
  • 向用戶態提供配置IOMMU的接口

VFIO由平台無關的接口層平台相關的實現層組成。接口層將服務抽象為IOCTL命令,規化操作流程,定義通用數據結構,與用戶態交互。實現層完成承諾的服務。據此,可在用戶態實現支持DMA操作的高性能驅動。在虛擬化場景中,亦可借此完全在用戶態實現device passthrough

VFIO實現層又分為設備實現層IOMMU實現層。當前VFIO僅支持PCI設備。IOMMU實現層則有x86與PowerPC兩種。VFIO設計靈活,可以很方便地加入對其它種類硬件及IOMMU的支持。

接口

與KVM一樣,用戶態通過IOCTL與VFIO交互。可作為操作對象的幾種文件描述符有:

  • Container文件描述符
    • 打開/dev/vfio字符設備可得
  • IOMMU group文件描述符
    • 打開/dev/vfio/N文件可得 (詳見后文)
  • Device文件描述符
    • 向IOMMU group文件描述符發起相關ioctl可得

邏輯上來說,IOMMU group是IOMMU操作的最小對象。某些IOMMU硬件支持將若干IOMMU group組成更大的單元。VFIO據此做出container的概念,可容納多個IOMMU group打開/dev/vfio文件即新建一個空的container在VFIO中,container是IOMMU操作的最小對象

要使用VFIO,需先將設備與原驅動撥離,並與VFIO綁定。

用VFIO訪問硬件的步驟:

  • 打開設備所在IOMMU group在/dev/vfio/目錄下的文件
  • 使用VFIO_GROUP_GET_DEVICE_FD得到表示設備的文件描述 (參數為設備名稱,一個典型的PCI設備名形如0000:03.00.01)
  • 對設備進行read/write/mmap等操作

用VFIO配置IOMMU的步驟:

  • 打開/dev/vfio,得到container文件描述符
  • 用VFIO_SET_IOMMU綁定一種IOMMU實現層
  • 打開/dev/vfio/N,得到IOMMU group文件描述符
  • 用VFIO_GROUP_SET_CONTAINER將IOMMU group加入container
  • 用VFIO_IOMMU_MAP_DMA將此IOMMU group的DMA地址映射至進程虛擬地址空間

邏輯

VFIO設備實現層與Linux設備模型緊密相連,當前,VFIO中僅有針對PCI的設備實現層(實現在vfio-pci模塊中)。設備實現層的作用與普通設備驅動的作用類似。普通設備驅動向上穿過若干抽象層,最終以Linux里廣為人知的抽象設備(網絡設備,塊設備等等)展現於世。VFIO設備實現層在/dev/vfio/目錄下為設備所在IOMMU group生成相關文件,繼而將設備暴露出來。兩者起點相同,最終呈現給用戶態不同的接口。欲使設備置於VFIO管轄之下,需將其與舊驅動解除綁定,由VFIO設備實現層接管。用戶態能感知到的,是一個設備的消失(如eth0),及/dev/vfio/N文件的誕生(其中N為設備所在IOMMU group的序號)。由於IOMMU group內的設備相互影響,只有組內全部設備被VFIO管理時,方能經VFIO配置此IOMMU group

把設備歸於IOMMU group的策略由平台決定。在PowerNV平台,一個IOMMU group與一個PE對應。PowerPC平台不支持將多個IOMMU group作為更大的IOMMU操作單元,故而container只是IOMMU group的簡單包裝而已。對container進行的IOMMU操作最終會被路由至底層的IOMMU實現層,這實際上將用戶態與內核里的IOMMU驅動接連了起來。

總結

VFIO是一套用戶態驅動框架,可用於編寫高效用戶態驅動;在虛擬化情景下,亦可用來在用戶態實現device passthrough。通過VFIO訪問硬件並無新意,VFIO可貴之處在於第一次向用戶態開放了IOMMU接口,能完全在用戶態配置IOMMU,將DMA地址空間映射進而限制在進程虛擬地址空間之內。這對高性能用戶態驅動以及在用戶態實現device passthrough意義重大。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM