IOMMU 扫盲

本文主要介绍下IOMMU的相关知识点,相关细节,将在后续的文章中,结合代码,详细讲解。

本文内容是对相关材料的汇总,并非原创。详情参见文章末尾的参考资料。

1. 什么是IOMMU

IOMMU(Input/Output Memory Management Unit)是一个内存管理单元(Memory Management Unit),它的作用是连接DMA-capable I/O总线(Direct Memory Access-capable I/O Bus)和主存(main memory)。传统的内存管理单元会把CPU访问的虚拟地址转化成实际的物理地址。而IOMMU则是把设备(device)访问的虚拟地址转化成物理地址。

2. 为什么要有IOMMU

首先,我们看下没有IOMMU的世界吧。

2.1 physical DMA without IOMMU

  • 一些设备需要大量的物理连续内存,但是os无法为其分配。可以有如下解决方案:
    • 在内核启动是为设备保留内存
    • 将MMU内嵌到设备中,如GPU
  • 一些设备有DMA寻址限制,例如,只支持32位的DMA寻址。可以有如下解决方案:
  • 没有内存保护机制,设备可能会错误地访问内存地址
  • 不能支持PCI设备的pass-through

接下来,我们看下拥有IOMMU的世界吧。

2.2 with IOMMU

  • 使用更大的DMA寻址空间
    • 每个设备都用自己独立的DMA内存寻址空间
  • 使用更大的连续DMA内存
    • 可以将非连续的物理内存映射到连续的DMA内存空间中
    • 避免使用scatter-gather list
  • 避免使用Bounce buffer
  • 提供了访问内存保护机制
    • 防止设备错误地访问内存
  • 支持PCI设备的pass-through

3. IOMMU在虚拟化中的用途

IOMMU的一个重要用途是在虚拟化技术(virtualization):虚拟机上运行的操作系统(guest OS)通常不知道它所访问的host-physical内存地址。如果要进行DMA操作,就有可能破坏内存,因为实际的硬件(hardware)不知道guest-physical和host-physical内存地址之间的映射关系。IOMMU根据guest-physical和host-physical内存地址之间的转换表(translation table),re-mapping硬件访问的地址,就可以解决这个问题。

在AMD的VIRTUALIZING IO THROUGH THE IO MEMORY MANAGEMENT UNIT (IOMMU)文档中,也有一个更全面的总结图:

引入虚拟化后,带来的问题是:设备看到的是GPA(guest physical address),但是访问的是HPA(host physical address)。

3.1 per-BDF DMA remapping

DMA Remapping通过IOMMU页表方式将直通设备对内存的访问限制到特定的domain中,在提高IO性能的同时完成了直通设备的隔离,保证了直通设备DMA的安全性。

3.2 interrupt remapping

Interrupt Remapping则提供IO设备的中断重映射和路由功能,来达到中断隔离和中断迁移的目的,提升了虚拟化环境下直通设备的中断处理效率。

为什么要搞中断重映射这么一套东西呢?直通设备的中断不能直通到虚拟机内部吗? 我们知道直通场景下直通设备的MSI/MSI-X Msg信息都是由Guest直接分配的,那么问题来了:设备发送中断的时候写的Msg地址是GPA,肯定不能直接往host上投递,否则就乱套了。在虚拟化场景下,直通设备的中断是无法直接投递到Guest中的,那么我们该怎么办?我们可以由IOMMU截获中断,先将中断映射到host的某个中断上,然后再重定向(由VMM投递)到Guest内部。

对于MSI/MSI-X中断机制的相关知识,会在后续的文章中陆续推出。


参考资料:

  1. Kai Huang mail.kai.huang at gmail.com
  2. 什么是IOMMU?
  3. Software attacks against Intel(R) VT-d technology
  4. VT-d Interrupt Remapping
  5. IOMMU introduction
  6. Input–output memory management unit
### PCIE IOMMU 的配置与使用 #### 背景介绍 输入/输出内存管理单元(IOMMU)是一种硬件组件,用于虚拟化环境中隔离设备访问并提高安全性。它通过映射物理地址空间到虚拟机的独立地址空间来实现资源隔离[^2]。这种技术对于现代虚拟化平台至关重要,因为它不仅缩小了性能差距,还增强了系统的安全性和稳定性。 #### 配置方法概述 在 Linux 系统中启用和配置 PCIe IOMMU 主要涉及以下几个方面: 1. **BIOS 设置** 启动计算机时进入 BIOS 或 UEFI 设置界面,查找名为 Intel VT-d(Intel 平台)或 AMD-Vi(AMD 平台)的功能选项,并将其开启。这是支持 IOMMU 功能的前提条件[^3]。 2. **内核参数调整** 编辑引导加载程序(如 GRUB)中的内核命令行参数,在 `/etc/default/grub` 文件中添加以下内容: ```bash GRUB_CMDLINE_LINUX="intel_iommu=on iommu=pt" ``` 对于基于 AMD 的系统,则应改为 `amd_iommu=on`。完成修改后运行更新脚本使更改生效: ```bash sudo update-grub ``` 3. **验证 IOMMU 是否已激活** 使用 dmesg 命令检查启动日志以确认 IOMMU 已成功初始化: ```bash dmesg | grep -e DMAR -e IOMMU ``` 如果看到类似 “DMAR: IOMMU enabled” 的消息,则表示设置正确[^4]。 4. **分配 PCI 设备给特定 VM** 利用工具如 libvirt 和 QEMU/KVM 创建 XML 定义文件指定需传递至客户操作系统的硬件设备 ID。例如: ```xml <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x07' slot='0x00' function='0x0'/> </source> </hostdev> ``` 5. **测试功能正常性** 在目标虚拟机内部安装驱动程序并与实际硬件交互验证一切运作无误。 #### 技术优势 采用 IOMMU 可带来显著好处包括但不限于减少上下文切换开销、增强数据保护机制以及简化 Hypervisor 架构设计等方面。 ```python import os def check_iommu_status(): """Check if IOMMU is active.""" result = os.popen('dmesg | grep -e DMAR -e IOMMU').read() return 'enabled' in result.lower() if __name__ == "__main__": status = check_iommu_status() print(f"IOMMU Status: {'Active' if status else 'Inactive'}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值