x86 vt-d在linux中的應用

最近因爲一個bug涉及到DMAR的問題,網上baidu居然搜到了自己5年前寫的一篇講vt-d的水文,可笑的是因爲百度博客的嗝屁我自己都沒有了,還好這位兄臺轉載了,現在再看好多東西一下就回憶起來了,趕緊接它回家嘍。


-------------------------------------------------------------------------------------------------------------------------------------------------


在新公司已近兩年,所學甚多甚雜,已經不能用一篇水文來記錄裏面的點點滴滴,這是我一直沒有寫一篇總結的原因.現在想想隨興所至一些更好。

翻看前文,發現還差一篇風河hypervisor硬件虛擬化的文章,懶得寫了,浪費時間.看過xen的代碼後覺得hypervisor就是隻小麻雀.以後有精力了寫寫xen裏面對x86硬件虛擬化技術的利用,那將是一個大篇幅.今天介紹下linux裏對x86硬件虛擬化技術的利用,算是個引子.xen裏面用到硬件虛擬化那是理所當然,有意思的是linux也用到了裏面的東西,vt-d,sr-iov.它當然不會用vt-x,這裏不講kvm,它本身就把linux變成了虛擬機而不是一個純內核了.同樣我不會寫代碼分析的細節,那是很無聊的事,只寫我認爲有意思的東西.

vt-d裏主要有兩個新技術,int remapping和dma remapping.
int remap在服務器配置中經常見到,如果系統中cpu超過255個或有apic_id>255的時候,intr是必須打開的,因爲ioxapic系統即使在物理目標模式也只支持8bit的cpu_id,沒有辦法把中斷分發給所有的cpu.而打開intr後,雖然ioapic中索引是16bit,但是irte中可以有32bit的物理地址或邏輯地址,最大能有2的32次個cpu.當然也有一些老系統只支持intr的xapic模式,也就是不能和x2apic配合,那和不打開也就沒什麼分別了,只在中斷遷移時能保證不丟中斷.intr關閉時,ioapic或msi/msix中觸發中斷後轉換成內存寫消息向上傳到北橋,被識別爲中斷後自動分發給相應的cpu,中間還會經過cpu的仲裁與選擇,識別是通過特殊地址信息fee來識別的.linux中已經基本有完善的支持了,只是缺msi這塊,msi目前只支持單箇中斷,倒不是無法實現,只是代碼要有大的改動,申請一段連續的vector和irq號都是比較困難的。msix比較不錯,沒有32個vector限制,而且每個vector和irq都不需要連續,缺點是會佔用一些mem空間。另外打開msi中斷後記得關閉legacy int。如果打開intr的話,rte或msix msg中要填的是一個索引,不是關於這個irq的所有信息,比如觸發模式,目標模式,目標地址,vector等。這個index會去索引內存中一個irte的表,找到後取出其中的信息轉發給apic。有意思的是這裏面的信息就是irq的所有信息。當然那個表未必是一個,要看這個系統是不是隻有一個pci段,或者說是不是隻有一個drhd單元。另外irte是有緩存的,修改irte後要有指令清除irte緩存.

所謂dmar就是給設備一個地址空間映射,設備對內存的訪問要通過一個頁表結構轉換成真正的訪存地址.也就是說設備地址就是個設備虛擬地址,真正的訪存地址是設備物理地址。這個頁表結構和cpu的頁表結構還有vmx的ept相似,可以有大頁,還有地址映射的緩存即所謂iotlb,等同於cpu的tlb,但是在北橋裏.有的系統爲了優化,在設備中也提供了device-iotlb,這些對軟件是透明的,只有特殊的刷新指令序列能改變它們.dmar在一些特殊場合有用,比如32bit pci設備要dma數據到4G以上地址,dmar可以提供這種映射,讓高端地址在pci設備中映射爲32bit的範圍之內.關閉dmar的話只能用軟件模擬了,即bounce-buffer.


整個iommu功能是在acpi表結構中提供的,目前有4種子表,drhd,rmrr,atsr,rhsa。其中drhd是最本文最關鍵的一個表,它枚舉了每個dma重映射單元及屬於它的下屬設備,每個drhd有指針指向一個reg集合,裏面會有irte表基址和dmar root entry,root entry數組,256項,指向context entry數組,context entry指向頂級頁表。整個結構是由sid索引的,sid通常是bus,dev,fn,對pci橋下的設備,是橋的sid,也就是說所有pci橋下的設備都只能處於同一個域,具體在xen中的話只能直接分配橋下所有的設備給同一個domain。hpet和ioapic這兩個特殊設備的sid是通過device scope得到的。rmrr指定保留內存,目前只在usb和顯卡中用到,要注意不要將頁表中含有這些保留內存的映射。否則會導致系統panic。atsr是關於device-iotlb,rhsa指定drhd單元的node親和性,可用於各種表項內存分配的優化。寫來寫去,又虎頭蛇尾了,但還是那句老話,隨興就好。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章