當(dāng)DMA想“越獄”:IOMMU怎么硬核攔截?
在計(jì)算機(jī)的底層架構(gòu)中,DMA(直接內(nèi)存訪問)技術(shù)原本旨在提升數(shù)據(jù)傳輸效率,讓硬件設(shè)備能繞開 CPU,直接與內(nèi)存高速交互,極大地加快了諸如磁盤存取、圖像處理等場景中的數(shù)據(jù)吞吐速度 。然而,這一特性卻被別有用心之人利用,成為惡意攻擊的 “幫兇”,如同試圖 “越獄” 一般,突破系統(tǒng)既定的安全邊界。攻擊者借助 DMA,可通過惡意硬件接入,繞開操作系統(tǒng)常規(guī)防護(hù),肆意讀取敏感數(shù)據(jù)、篡改內(nèi)核代碼,甚至繞過屏幕密碼,威脅用戶信息安全與系統(tǒng)穩(wěn)定。
此時(shí),IOMMU(輸入輸出內(nèi)存管理單元)挺身而出,作為守護(hù)系統(tǒng)安全的關(guān)鍵防線,發(fā)揮硬核攔截作用。它如同一位嚴(yán)謹(jǐn)?shù)?“交通管制員”,對 DMA 的內(nèi)存訪問行為進(jìn)行精細(xì)管控,重新映射設(shè)備地址,限定其可觸及的內(nèi)存范圍,讓惡意的 DMA “越獄” 企圖無處遁形。接下來,就讓我們深入這場安全攻防的幕后,一探 IOMMU 如何憑借精妙設(shè)計(jì),成功抵御 DMA 的危險(xiǎn)沖擊 。
Part1IOMMU是什么?
1.1 IOMMU概述
IOMMU,全稱 Input/Output Memory Management Unit,即輸入輸出內(nèi)存管理單元 ,從名字就可以看出,這是一種內(nèi)存管理單元(MMU),主要負(fù)責(zé)將具有直接存儲器訪問(DMA)能力的 I/O 總線連接至主內(nèi)存。我們可以把它想象成一個(gè) “翻譯官”,在計(jì)算機(jī)的硬件世界里,承擔(dān)著至關(guān)重要的地址轉(zhuǎn)換工作。
在計(jì)算機(jī)系統(tǒng)中,CPU 訪問內(nèi)存時(shí),內(nèi)存管理單元(MMU)會把 CPU 可見的虛擬地址轉(zhuǎn)換為物理地址。與之類似,IOMMU 的作用是將設(shè)備可見的虛擬地址(在 IOMMU 的語境中,也被稱為設(shè)備地址或 I/O 地址)映射到物理地址。簡單來說,當(dāng)設(shè)備想要訪問內(nèi)存時(shí),它給出的地址可能是一個(gè)虛擬的 “想法”,而 IOMMU 會將這個(gè) “想法” 翻譯成內(nèi)存能夠理解的物理地址,從而實(shí)現(xiàn)設(shè)備與內(nèi)存之間的有效溝通。
除了地址轉(zhuǎn)換,部分 IOMMU 還具備內(nèi)存保護(hù)功能,就像是給內(nèi)存區(qū)域加上了一把 “安全鎖”,能夠防止故障設(shè)備或者惡意設(shè)備對內(nèi)存進(jìn)行錯(cuò)誤訪問,確保系統(tǒng)的穩(wěn)定性和安全性。
1.2 IOMMU 的由來
在計(jì)算機(jī)發(fā)展的早期階段,硬件系統(tǒng)的結(jié)構(gòu)相對簡單,設(shè)備在訪問內(nèi)存時(shí)采用的是直接物理尋址方式。那時(shí)候,設(shè)備可以直接訪問物理內(nèi)存,雖然這種方式簡單直接,但也帶來了一系列的問題。
隨著計(jì)算機(jī)技術(shù)的發(fā)展,計(jì)算機(jī)系統(tǒng)中的設(shè)備種類和數(shù)量不斷增加,這些設(shè)備在進(jìn)行內(nèi)存訪問時(shí)遇到了一些挑戰(zhàn)。比如,早期的設(shè)備地址空間有限,像 32 位的 PCI 設(shè)備,就無法直接訪問超過 4GB 的內(nèi)存 。如果操作系統(tǒng)需要訪問超出這個(gè)范圍的內(nèi)存,就不得不采用一些復(fù)雜且低效的方法,如設(shè)置彈跳緩沖區(qū)(bounce buffer),即先將數(shù)據(jù)從高端內(nèi)存復(fù)制到設(shè)備可訪問的低端內(nèi)存區(qū)域,設(shè)備再從這里讀取數(shù)據(jù),操作完成后再把數(shù)據(jù)復(fù)制回高端內(nèi)存,這個(gè)過程大大增加了數(shù)據(jù)傳輸?shù)臅r(shí)間和系統(tǒng)開銷。
再比如,早期的設(shè)備訪問內(nèi)存時(shí)缺乏有效的內(nèi)存保護(hù)機(jī)制,一旦設(shè)備驅(qū)動程序出現(xiàn)錯(cuò)誤,或者設(shè)備本身出現(xiàn)故障,就可能導(dǎo)致內(nèi)存數(shù)據(jù)被錯(cuò)誤地讀取或?qū)懭耄踔翋阂庠O(shè)備可能會對系統(tǒng)內(nèi)存進(jìn)行任意訪問,從而引發(fā)系統(tǒng)崩潰或數(shù)據(jù)泄露等嚴(yán)重問題。這就好比在一個(gè)沒有門禁的倉庫里,任何人都可以隨意進(jìn)出并拿走或修改里面的物品,安全性完全無法保障。
為了解決這些問題,IOMMU 應(yīng)運(yùn)而生。它的出現(xiàn)就像是在設(shè)備和內(nèi)存之間建立了一個(gè)智能的 “中介”,解決了設(shè)備內(nèi)存訪問中的尋址限制和內(nèi)存保護(hù)缺失等問題。通過 IOMMU,設(shè)備可以訪問更大的內(nèi)存空間,并且能夠有效地保護(hù)內(nèi)存不被錯(cuò)誤或惡意訪問,提高了系統(tǒng)的穩(wěn)定性和安全性。
而隨著虛擬化技術(shù)的興起,IOMMU 的重要性更是日益凸顯。在虛擬化環(huán)境中,多個(gè)虛擬機(jī)共享同一臺物理主機(jī)的硬件資源。如果沒有 IOMMU,當(dāng)虛擬機(jī)中的設(shè)備進(jìn)行 DMA 操作時(shí),就可能會訪問到其他虛擬機(jī)或者宿主機(jī)的內(nèi)存空間,導(dǎo)致數(shù)據(jù)泄露和系統(tǒng)不穩(wěn)定。IOMMU 通過對設(shè)備地址的轉(zhuǎn)換和內(nèi)存訪問的控制,確保每個(gè)虛擬機(jī)的設(shè)備只能訪問其所屬虛擬機(jī)的內(nèi)存,為虛擬機(jī)提供了安全隔離的運(yùn)行環(huán)境,使得虛擬化技術(shù)能夠更加可靠地應(yīng)用于云計(jì)算、數(shù)據(jù)中心等領(lǐng)域。
Part2IOMMU的底層原理
IOMMU的核心思想是將物理內(nèi)存劃分為多個(gè)區(qū)域,每個(gè)區(qū)域都有一個(gè)唯一的ID。這些區(qū)域可以是連續(xù)的,也可以是不連續(xù)的。當(dāng)CPU需要訪問某個(gè)內(nèi)存區(qū)域時(shí),IOMMU會將該請求轉(zhuǎn)換為一個(gè)虛擬地址,然后將這個(gè)虛擬地址與對應(yīng)的物理地址進(jìn)行映射。這樣,IOMMU是DMA直接內(nèi)存訪問,即設(shè)備與內(nèi)存直接通信,而無需經(jīng)過CPU。
IOMMU的主要組成部分包括:
- MMU(Memory Management Unit):負(fù)責(zé)將物理內(nèi)存映射到虛擬地址空間。MMU通常包含一個(gè)硬件緩存,用于存儲虛擬地址到物理地址的映射關(guān)系。此外,MMU還可以實(shí)現(xiàn)一些高級功能,如內(nèi)存保護(hù)和地址轉(zhuǎn)換。
- IOMMU軟件模塊:負(fù)責(zé)管理IOMMU的設(shè)置和配置。這通常包括創(chuàng)建和管理內(nèi)存區(qū)域,以及處理來自操作系統(tǒng)的內(nèi)存訪問請求。
- 硬件支持:IOMMU需要硬件的支持才能正常工作。這包括一個(gè)支持IOMMU的CPU,以及一個(gè)能夠識別IOMMU的設(shè)備驅(qū)動程序。
2.1 DMA 重映射原理
IOMMU 的核心功能之一是 DMA 重映射,它就像是一座橋梁,連接了設(shè)備和內(nèi)存之間的地址空間。我們知道,在計(jì)算機(jī)系統(tǒng)中,內(nèi)存管理單元(MMU)通過頁表將 CPU 的虛擬地址轉(zhuǎn)換為物理地址,使得不同進(jìn)程的虛擬地址空間能夠相互隔離,同時(shí)也提高了內(nèi)存的利用率 。IOMMU 在 DMA 操作中也采用了類似的機(jī)制。
設(shè)備看到的地址空間(連續(xù)):
[0x1000] [0x2000] [0x3000] [0x4000]
↓ ↓ ↓ ↓
實(shí)際物理內(nèi)存(分散):
[0xA000] [0xF000] [0xB000] [0xD000]在 IOMMU 的世界里,設(shè)備使用的地址被稱為 I/O 虛擬地址(IOVA) ,這是設(shè)備在發(fā)起 DMA 請求時(shí)所使用的地址。而 IOMMU 的任務(wù)就是將這些 IOVA 轉(zhuǎn)換為物理地址(PA),以便設(shè)備能夠正確地訪問內(nèi)存。為了實(shí)現(xiàn)這一轉(zhuǎn)換,IOMMU 使用了一種類似于 MMU 頁表的數(shù)據(jù)結(jié)構(gòu),我們可以稱之為 I/O 頁表。
當(dāng)設(shè)備發(fā)起 DMA 請求時(shí),它會將自己的 Source Identifier(包含 Bus、Device、Func,即總線號、設(shè)備號和功能號)包含在請求中。IOMMU 根據(jù)這個(gè)標(biāo)識,以 RTADDR_REG(根表地址寄存器)指向空間為基地址,然后利用 Bus、Device、Func 在 Context Table(上下文表)中找到對應(yīng)的 Context Entry(上下文條目) ,這個(gè) Context Entry 實(shí)際上就是頁表首地址。找到了頁表首地址后,IOMMU 就可以利用頁表將設(shè)備請求的虛擬地址翻譯成物理地址,就像 MMU 利用頁表進(jìn)行地址轉(zhuǎn)換一樣。
例如,在一個(gè)具有多個(gè) PCI 設(shè)備的系統(tǒng)中,每個(gè) PCI 設(shè)備都有自己的 Source Identifier。當(dāng)某個(gè) PCI 設(shè)備發(fā)起 DMA 請求時(shí),IOMMU 會根據(jù)其 Source Identifier 在 Context Table 中找到對應(yīng)的 Context Entry,進(jìn)而定位到該設(shè)備專用的頁表。通過這個(gè)頁表,IOMMU 將設(shè)備請求的 IOVA 轉(zhuǎn)換為正確的物理地址,確保數(shù)據(jù)能夠準(zhǔn)確無誤地在設(shè)備和內(nèi)存之間傳輸。
這種機(jī)制不僅解決了設(shè)備地址空間有限的問題,還為系統(tǒng)提供了內(nèi)存保護(hù)功能。因?yàn)樵O(shè)備只能通過 IOMMU 訪問經(jīng)過映射的物理地址,所以即使設(shè)備驅(qū)動程序出現(xiàn)錯(cuò)誤,也無法直接訪問到非法的內(nèi)存區(qū)域,從而提高了系統(tǒng)的穩(wěn)定性和安全性。
2.2中斷重映射原理
除了 DMA 重映射,IOMMU 還具備中斷重映射的功能,這在虛擬化場景中尤為重要。在傳統(tǒng)的非虛擬化環(huán)境中,設(shè)備的中斷請求可以直接發(fā)送到 CPU,由操作系統(tǒng)進(jìn)行處理。但在虛擬化環(huán)境下,情況變得復(fù)雜起來。當(dāng)一個(gè)設(shè)備被直通給虛擬機(jī)時(shí),它的中斷請求需要被正確地投遞到對應(yīng)的虛擬機(jī)中,而不是直接發(fā)送到宿主機(jī)的 CPU,這就需要 IOMMU 來進(jìn)行中斷重映射。
在現(xiàn)代計(jì)算機(jī)系統(tǒng)中,許多設(shè)備使用以 message signal 形式觸發(fā)的中斷,如 MSI(Message Signaled Interrupts)或 MSIX(Message Signaled Interrupts Extension) 。這些中斷的實(shí)現(xiàn)方式是通過向特定的地址發(fā)起一個(gè) DMA 寫操作來觸發(fā)。IOMMU 正是通過識別這個(gè)特定的地址前綴(如 0xFEE)來判斷某個(gè) DMA 寫操作是否是一個(gè)中斷請求。
以 PCI 或 PCIE 設(shè)備為例,在中斷重映射模式下,當(dāng)設(shè)備發(fā)起 MSI 或 MSIX 中斷請求時(shí),其 message address 和 message data 的格式會有所不同。比如,address register bit 4 需要置為 1,表示為中斷重映射模式;address register bit 3 表示的是 SubHandle Valid(SHV) ,這里強(qiáng)制為 1 即 SubHandle 是有效的;address register bits 19:5 表示的是 interrupt_index 的 0~14 位,bit 2 表示的是 interrupt_index 的第 15 位。這些信息用于 IOMMU 在中斷重映射表中查找對應(yīng)的中斷描述符,從而確定中斷的目標(biāo)虛擬機(jī)或 CPU。
再看 ioapic(I/O Advanced Programmable Interrupt Controller) ,它在系統(tǒng)中負(fù)責(zé)中斷的路由。在中斷重映射模式下,ioapic 的 redirection table entry(重定向表項(xiàng))的格式也發(fā)生了變化,新增了一些字段,如 bits 49:63 對應(yīng)的是 interrupt_index [14:0],bit 11 對應(yīng)的是 interrup_index [15] ,bit 48 表示是否為 remapping 的中斷格式等。這些字段幫助 ioapic 在 IOMMU 的協(xié)助下,將設(shè)備的中斷請求正確地路由到目標(biāo)位置。
當(dāng) IOMMU 接收到一個(gè)中斷請求時(shí),它會根據(jù)請求中的相關(guān)信息(如 interrupt_index、SHV 等)在中斷重映射表(Interrupt Remapping Table)中查找對應(yīng)的中斷描述符(Interrupt Remapping Table Entry,IRTE) 。找到 IRTE 后,IOMMU 根據(jù)其中記錄的信息,將中斷請求發(fā)送到正確的目標(biāo),可能是虛擬機(jī)中的虛擬 CPU,也可能是宿主機(jī)的特定 CPU 核心,從而實(shí)現(xiàn)了中斷在虛擬化環(huán)境中的正確投遞和處理。
中斷重映射功能確保了虛擬化環(huán)境中設(shè)備中斷的正確處理,避免了中斷混亂和錯(cuò)誤投遞的問題,為虛擬機(jī)的穩(wěn)定運(yùn)行提供了保障。
2.3IOMMU的主要實(shí)現(xiàn)
(1)Intel VT-d (Virtualization Technology for Directed I/O)
// Intel VT-d 功能特性
- DMA 重映射
- 中斷重映射
- 設(shè)備隔離
- 熱插拔支持(2)AMD-Vi (AMD I/O Virtualization)
// AMD-Vi 功能特性
- I/O 虛擬化
- 設(shè)備表管理
- 命令處理
- 事件日志(3) ARM SMMU (System Memory Management Unit)
// ARM SMMU 功能特性
- 流表 (Stream Table)
- 上下文描述符
- 頁表遍歷
- 故障處理Part3IOMMU的應(yīng)用場景
隨著云計(jì)算和虛擬化技術(shù)的飛速發(fā)展,虛擬化環(huán)境在企業(yè)和數(shù)據(jù)中心中得到了廣泛應(yīng)用。在虛擬化環(huán)境中,多個(gè)虛擬機(jī)共享同一物理硬件資源,這就對系統(tǒng)的安全性和隔離性提出了極高的要求。IOMMU 作為虛擬化技術(shù)的關(guān)鍵支撐,在保障虛擬機(jī)之間的隔離與安全方面發(fā)揮著不可或缺的作用。
在一個(gè)典型的云計(jì)算數(shù)據(jù)中心中,可能同時(shí)運(yùn)行著多個(gè)不同租戶的虛擬機(jī),每個(gè)虛擬機(jī)都承載著不同的業(yè)務(wù)應(yīng)用,這些應(yīng)用可能包含著租戶的敏感數(shù)據(jù)。如果沒有有效的隔離機(jī)制,一旦某個(gè)虛擬機(jī)中的 DMA 操作出現(xiàn)異常或被惡意利用,就可能導(dǎo)致其他虛擬機(jī)的數(shù)據(jù)泄露或系統(tǒng)故障。
IOMMU 通過地址轉(zhuǎn)換和訪問控制功能,為每個(gè)虛擬機(jī)建立了獨(dú)立的內(nèi)存訪問空間 。當(dāng)虛擬機(jī)中的設(shè)備發(fā)起 DMA 請求時(shí),IOMMU 會將虛擬機(jī)的設(shè)備地址(GPA)轉(zhuǎn)換為物理地址(PA),并確保該請求只能訪問分配給該虛擬機(jī)的內(nèi)存區(qū)域。即使某個(gè)虛擬機(jī)被黑客攻擊,黑客試圖利用 DMA 操作竊取其他虛擬機(jī)的數(shù)據(jù),IOMMU 也會嚴(yán)格按照訪問權(quán)限規(guī)則,攔截非法的內(nèi)存訪問請求,從而保障了其他虛擬機(jī)的數(shù)據(jù)安全和正常運(yùn)行。
假設(shè)在一個(gè)虛擬化的服務(wù)器環(huán)境中,有一臺虛擬機(jī)運(yùn)行著企業(yè)的財(cái)務(wù)系統(tǒng),存儲著重要的財(cái)務(wù)數(shù)據(jù);另一臺虛擬機(jī)運(yùn)行著企業(yè)的辦公自動化系統(tǒng)。如果沒有 IOMMU 的保護(hù),當(dāng)辦公自動化系統(tǒng)所在的虛擬機(jī)中存在惡意軟件,利用 DMA “越獄” 嘗試訪問財(cái)務(wù)系統(tǒng)所在虛擬機(jī)的內(nèi)存時(shí),就可能導(dǎo)致財(cái)務(wù)數(shù)據(jù)泄露。而有了 IOMMU,它會對每一個(gè) DMA 請求進(jìn)行嚴(yán)格審查,一旦發(fā)現(xiàn)辦公自動化系統(tǒng)虛擬機(jī)的 DMA 請求試圖訪問財(cái)務(wù)系統(tǒng)虛擬機(jī)的內(nèi)存區(qū)域,就會立即阻止該請求,確保了財(cái)務(wù)數(shù)據(jù)的安全性和保密性 。IOMMU 在虛擬化環(huán)境中的應(yīng)用,極大地提高了云計(jì)算和虛擬化系統(tǒng)的安全性和可靠性,為企業(yè)和用戶的數(shù)據(jù)安全提供了堅(jiān)實(shí)的保障,推動了虛擬化技術(shù)在更廣泛領(lǐng)域的應(yīng)用和發(fā)展。
3.1虛擬化環(huán)境
IOMMU 是設(shè)備直通 (Device Passthrough) 的基礎(chǔ):
# KVM 虛擬機(jī)配置示例
<hostdev mode='subsystem' type='pci' managed='yes'>
<driver name='vfio'/>
<source>
<address domain='0x0000' bus='0x01' slot='0x00' functinotallow='0x0'/>
</source>
</hostdev>VFIO (Virtual Function I/O) 框架
// VFIO 使用 IOMMU 實(shí)現(xiàn)設(shè)備隔離
struct vfio_group *group;
struct vfio_device *device;
// 將設(shè)備綁定到 VFIO 驅(qū)動
echo 0000:01:00.0 > /sys/bus/pci/drivers/nvidia/unbind
echo 0000:01:00.0 > /sys/bus/pci/drivers/vfio-pci/bind
// 在虛擬機(jī)中直接使用設(shè)備
qemu-kvm -device vfio-pci,host=01:00.0 ...3.2容器化和微服務(wù)
# Docker 容器使用 GPU 示例
docker run --gpus all \
--device=/dev/dri \
--security-opt apparmor:unconfined \
nvidia/cuda:11.0-base3.3安全隔離
// 防止惡意設(shè)備的 DMA 攻擊
Bad Device ─── DMA Request ──→ IOMMU ──→ Access Denied
(惡意地址) (權(quán)限檢查失敗)Part4IOMMU配置和管理
4.1系統(tǒng)啟動配置
# GRUB 配置啟用 IOMMU
# Intel 系統(tǒng)
GRUB_CMDLINE_LINUX="intel_iommu=on iommu=pt"
# AMD 系統(tǒng)
GRUB_CMDLINE_LINUX="amd_iommu=on iommu=pt"
# 更新 GRUB
sudo update-grub
sudo reboot4.2檢查 IOMMU 狀態(tài)
# 檢查 IOMMU 是否啟用
dmesg | grep -i iommu
dmesg | grep -i dmar # Intel VT-d
dmesg | grep -i amd_iommu # AMD-Vi
# 查看 IOMMU 組
find /sys/kernel/iommu_groups/ -type l
# 查看設(shè)備的 IOMMU 組
ls -la /sys/bus/pci/devices/0000:01:00.0/iommu_group4.3 IOMMU 組管理
#!/bin/bash
# 顯示所有 IOMMU 組和對應(yīng)設(shè)備
for g in /sys/kernel/iommu_groups/*; do
echo "IOMMU Group ${g##*/}:"
for d in $g/devices/*; do
echo -e "\t$(lspci -nns ${d##*/})"
done
donePart5IOMMU編程接口
5.1內(nèi)核IOMMU API
#include <linux/iommu.h>
// 分配 IOMMU 域
struct iommu_domain *domain = iommu_domain_alloc(&pci_bus_type);
// 附加設(shè)備到域
iommu_attach_device(domain, &pdev->dev);
// 建立映射
iommu_map(domain, iova, paddr, size, IOMMU_READ | IOMMU_WRITE);
// 取消映射
iommu_unmap(domain, iova, size);
// 分離設(shè)備
iommu_detach_device(domain, &pdev->dev);5.2用戶空間VFIO API
#include <linux/vfio.h>
// 打開 VFIO 容器
int container = open("/dev/vfio/vfio", O_RDWR);
// 打開 IOMMU 組
int group = open("/dev/vfio/1", O_RDWR);
// 設(shè)置 IOMMU 類型
ioctl(container, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU);
// DMA 映射
struct vfio_iommu_type1_dma_map dma_map = {
.argsz = sizeof(dma_map),
.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE,
.vaddr = (uintptr_t)buffer,
.iova = device_address,
.size = buffer_size,
};
ioctl(container, VFIO_IOMMU_MAP_DMA, &dma_map);Part6IOMMU硬核攔截原理剖析
6.1地址翻譯:識破 “偽裝”
當(dāng) DMA 發(fā)起訪問請求時(shí),IOMMU 首先會對請求中的 I/O 虛擬地址(IOVA)進(jìn)行地址翻譯 。IOMMU 中維護(hù)著類似于 CPU 頁表的 IO 頁表,通過查詢 IO 頁表,IOMMU 可以將 IOVA 準(zhǔn)確地轉(zhuǎn)換為物理地址(PA) 。這個(gè)過程就像是在一本詳細(xì)的地址翻譯詞典中查找對應(yīng)的翻譯,詞典(IO 頁表)里記錄著 IOVA 和 PA 的對應(yīng)關(guān)系,IOMMU 根據(jù)這個(gè)關(guān)系完成翻譯工作。
假設(shè)一個(gè)設(shè)備的DMA請求中包含的 IOVA 是 0x1000,IOMMU 通過查詢 IO 頁表,發(fā)現(xiàn)這個(gè) IOVA 對應(yīng)的 PA 是 0x20000,那么 IOMMU 就會將這個(gè)正確的物理地址傳遞給內(nèi)存訪問操作。通過這種地址翻譯機(jī)制,IOMMU 能夠清晰地識別 DMA 請求的真實(shí)目標(biāo)。如果 DMA 請求的 IOVA 存在異常,比如指向了一個(gè)不存在的或非法的地址映射,IOMMU 就能立刻察覺,從而防止 DMA 訪問非法內(nèi)存地址 。這就好比一個(gè)人拿著錯(cuò)誤的地圖導(dǎo)航(非法的 IOVA),而 IOMMU 作為專業(yè)的導(dǎo)航修正員,能夠發(fā)現(xiàn)錯(cuò)誤并阻止其前往錯(cuò)誤的目的地(非法內(nèi)存區(qū)域)。
6.2訪問控制:嚴(yán)守 “關(guān)卡”
在完成地址翻譯后,IOMMU 并不會立刻放行 DMA 請求,而是會對設(shè)備對目標(biāo)內(nèi)存的訪問權(quán)限進(jìn)行嚴(yán)格檢查 。IOMMU 中存儲著每個(gè)設(shè)備的訪問權(quán)限信息,這些信息規(guī)定了設(shè)備可以訪問的內(nèi)存區(qū)域以及訪問的類型(讀、寫、執(zhí)行等) 。就像每個(gè)員工都有自己的門禁權(quán)限,只能進(jìn)入被授權(quán)的辦公室區(qū)域,設(shè)備也只能訪問被授予權(quán)限的內(nèi)存區(qū)域。
例如,一個(gè)網(wǎng)絡(luò)設(shè)備被授權(quán)只能讀取內(nèi)存中特定的網(wǎng)絡(luò)數(shù)據(jù)緩沖區(qū),當(dāng)它發(fā)起 DMA 請求想要寫入其他內(nèi)存區(qū)域時(shí),IOMMU 會迅速檢查到這種越權(quán)行為,立即阻止該 DMA 請求的執(zhí)行,并向系統(tǒng)報(bào)告錯(cuò)誤 。通過這樣的權(quán)限檢查,IOMMU 就像是一個(gè)忠誠的衛(wèi)士,嚴(yán)守著內(nèi)存的 “關(guān)卡”,有效地阻止了 DMA 對未經(jīng)授權(quán)內(nèi)存區(qū)域的讀寫操作,實(shí)現(xiàn)了對系統(tǒng)內(nèi)存的嚴(yán)密保護(hù),確保了系統(tǒng)內(nèi)存中數(shù)據(jù)的安全性和完整性。
6.3多級頁表與緩存機(jī)制:高效運(yùn)作的秘訣
為了提高地址翻譯的效率和靈活性,IOMMU采用了多級頁表結(jié)構(gòu) 。以常見的三級頁表為例,虛擬地址會被劃分為多個(gè)部分,每個(gè)部分對應(yīng)不同級別的頁表索引 。當(dāng)IOMMU接收到一個(gè) IOVA 時(shí),它首先會根據(jù)虛擬地址的最高位部分作為索引,在一級頁表(頁全局目錄)中查找對應(yīng)的頁目錄項(xiàng)(PDE) 。
這個(gè) PDE 指向二級頁表(頁目錄表),IOMMU再根據(jù)虛擬地址的次高位部分在二級頁表中查找對應(yīng)的頁表項(xiàng)(PTE) ,最終通過PTE找到對應(yīng)的物理頁框,完成地址翻譯 。這種多級頁表結(jié)構(gòu)就像一個(gè)層層分類的大型圖書館索引系統(tǒng),每一級頁表都是一個(gè)分類索引,通過逐級查找,能夠快速定位到所需的物理地址,大大提高了地址翻譯的效率,同時(shí)也使得內(nèi)存的管理更加靈活,可以支持更大的地址空間。
為了進(jìn)一步加速地址翻譯過程,IOMMU 還引入了 IOTLB(I/O Translation Lookaside Buffer) ,即 I/O 轉(zhuǎn)譯后備緩沖器,它相當(dāng)于 IO 頁表的高速緩存 。IOTLB 中緩存了最近使用的 IOVA 到 PA 的地址轉(zhuǎn)換信息 。當(dāng) IOMMU 接收到 DMA 請求時(shí),它會首先在 IOTLB 中查找是否有對應(yīng)的地址轉(zhuǎn)換信息 。如果 IOTLB 命中,即找到了緩存的轉(zhuǎn)換信息,IOMMU 可以直接使用這些信息快速完成地址翻譯,而無需再去查詢多級頁表,大大節(jié)省了時(shí)間 。
只有當(dāng) IOTLB 未命中時(shí),IOMMU 才會去查詢多級頁表進(jìn)行地址翻譯 。這就好比你經(jīng)常使用的常用物品放在一個(gè)隨手可及的小抽屜(IOTLB)里,當(dāng)你需要時(shí)可以快速拿到,而不需要去大型倉庫(多級頁表)中慢慢尋找,大大提高了效率。通過多級頁表和 IOTLB 的協(xié)同工作,在面對大量 DMA 請求時(shí),IOMMU 仍能快速、準(zhǔn)確地進(jìn)行攔截操作,保障系統(tǒng)的穩(wěn)定運(yùn)行。























