ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

QEMU RISC-V IOMMU 虚拟化实战:riscv-iommu-pci 与 riscv-iommu-sys 设备详解

QEMU RISC-V IOMMU 虚拟化实战:riscv-iommu-pci 与 riscv-iommu-sys 设备详解 虚拟化硬件仿真【免费下载链接】qemuOfficial QEMU mirror. Please see https://www.qemu.org/contribute/ for how to submit changes to QEMU. Pull Requests are disabled. Please only use release tarballs from the QEMU website.项目地址https://gitcode.com/gh_mirrors/qe/qemu点击查看免费下载QEMU 依据 RISC-V IOMMU 规范 1.0 版本实现了完整的 IOMMU 模拟包含 PCIe 参考设备riscv-iommu-pci和平台总线设备riscv-iommu-sys两种形态。本文以仓库文档 docs/specs/riscv-iommu.rst 为主体结合 hw/riscv/riscv-iommu.c、hw/riscv/riscv-iommu-pci.c、hw/riscv/riscv-iommu-sys.c 等源码实现讲解在 virt 机器上启用两种 IOMMU 设备的完整方法、全部可配置参数及其底层含义帮助读者快速上手 RISC-V 平台的 DMA 重映射与直通实验。背景QEMU 中的 RISC-V IOMMU 支持QEMU 实现了基于 RISC-V IOMMU 规范 1.0riscv-iommu.pdf即iommu1.0.0发布版本的 IOMMU 模拟。该规范定义了设备如何通过内存驻留的数据结构Device Directory Table、进程上下文、命令队列、故障队列等完成从设备请求的 IOVAI/O Virtual Address到系统物理地址的翻译并提供 MSI 重映射、ATSAddress Translation Services等能力。这套模拟在仓库中由以下几个文件共同构成hw/riscv/riscv-iommu.cIOMMU 核心状态机与翻译实现约 3000 行涵盖 DDT 解析、命令队列/故障队列处理、地址翻译缓存、HPM 硬件性能计数器等hw/riscv/riscv-iommu.h核心状态结构RISCVIOMMUState与翻译上下文定义hw/riscv/riscv-iommu-bits.h寄存器偏移、能力位等规范位域定义hw/riscv/riscv-iommu-pci.cPCIe 参考设备hw/riscv/riscv-iommu-sys.c平台总线设备hw/riscv/riscv-iommu-hpm.c 与 hw/riscv/riscv-iommu-hpm.h硬件性能计数器HPM实现include/hw/riscv/iommu.h对外接口头文件。模拟分为两种设备形态virtRISC-V 机器对两者都兼容。riscv-iommu-pci 参考 PCIe 设备设备形态与 PCI IDriscv-iommu-pci按照规范中 Integrating an IOMMU as a PCIe device将 IOMMU 集成进 PCIe 设备一节的建议实现PCI 基础类base class为 08h子类sub-class为 06h编程接口为 00h即标准 System peripheral / IOMMU 类型。这一点在源码 hw/riscv/riscv-iommu-pci.c 中通过RISCV_PCI_CLASS_SYSTEM_IOMMU 0x0806常量体现。作为参考设备它不实现规范之外的任何扩展因此使用 QEMU 提供的通用默认 PCI ID1b36:0014vendor 0x1b36 为 Red Hat 在 QEMU 中使用的通用厂商 IDdevice ID 0014 对应 riscv-iommu。源码中默认值由 hw/riscv/riscv-iommu-pci.c 的DEFINE_PROP_UINT16(vendor-id, ...PCI_VENDOR_ID_REDHAT)和DEFINE_PROP_UINT16(device-id, ...PCI_DEVICE_ID_REDHAT_RISCV_IOMMU)给出并且支持通过属性覆盖。设备实例化时riscv_iommu_pci_realize还会在 BAR0 中注册 IOMMU 寄存器内存区域并初始化 5 个 MSI-X 向量hw/riscv/riscv-iommu-pci.c其中 4 个用于 ICVEC命令队列/故障队列/性能监控/页请求四种中断向量1 个用于 MRIF内存驻留中断文件的通知 MSI。若平台不支持 MSI-X驱动可退化为基于定时器/轮询的通知处理方式代码中通过msix_init返回-ENOTSUP时打印告警处理hw/riscv/riscv-iommu-pci.c。在 virt 机器上启用将设备加入 virt 机器非常简单$ qemu-system-riscv64 -M virt -device riscv-iommu-pci,[optional_pci_opts] (...)这会在板卡上添加一个 RISC-V IOMMU PCI 设备并可附带额外的 PCI 参数例如 PCI 总线地址addr1.0。IOMMU 的行为由规范定义但其具体运作方式与操作系统实现相关OS dependent。与 Linux 内核的配合现状Linux 内核的 RISC-V IOMMU 支持在v6.13合入主线。QEMU 的 IOMMU 模拟可以与主线内核配合用于简单的 IOMMU PCIe 支持场景。截至 v6.17主线内核尚不支持 VFIO 直通等特性存在一个尚未合入的 VFIO RFC 系列补丁Ventana Micro Systems 公开维护的 ventana-linux 内核仓库可用于测试 VFIO 相关功能。需要特别说明的是v6.13 的 Linux 内核驱动会使用 IOMMU 设备为系统中所有符合条件的网卡创建 IOMMU 组与设备在命令行中添加的先后顺序无关。因此下面两条命令行在 IOMMU 内核驱动看来是等价的——都会为两张 e1000e 网卡创建 IOMMU 组$ qemu-system-riscv64 \ -M virt,aiaaplic-imsic,aia-guests5 \ -device riscv-iommu-pci,addr1.0 \ -device e1000e,netdevnet1 -netdev user,idnet1,net192.168.0.0/24 \ -device e1000e,netdevnet2 -netdev user,idnet2,net192.168.200.0/24 \ (...) $ qemu-system-riscv64 \ -M virt,aiaaplic-imsic,aia-guests5 \ -device e1000e,netdevnet1 -netdev user,idnet1,net192.168.0.0/24 \ -device e1000e,netdevnet2 -netdev user,idnet2,net192.168.200.0/24 \ -device riscv-iommu-pci,addr3.0 \ (...)注意-M virt,aiaaplic-imsic,aia-guests5中的 AIA 相关选项IOMMU 的中断通知依赖 AIAAdvanced Interrupt Architecture中断控制器aiaaplic-imsic指定使用 APLIC IMSIC 组合aia-guests5指定 IMSIC 的 guest MMIO 页数量。另外在 virt 机器上热插 riscv-iommu-pci 设备时virt_machine_device_plug_cbQEMU 会自动为设备生成 FDT 节点create_fdt_iommu并关闭平台 IOMMU 设备s-iommu_sys ON_OFF_AUTO_OFF见 hw/riscv/virt.c二者互斥、不会同时启用。可配置属性一览riscv-iommu-pci提供了下列属性来控制设备能力属性由 hw/riscv/riscv-iommu.c 的核心属性表与 hw/riscv/riscv-iommu-pci.c 的 PCI 属性表共同定义通过qdev_alias_all_properties暴露给 PCI 设备属性含义默认值busIOMMU 设备所使用的 PCI 总线0ioatc-limit地址翻译缓存I/O Address Translation Cache大小2MB源码中LIMIT_CACHE_IOT即 1 20 条目intremap启用/禁用 MSI 中断重映射trueats启用 ATSAddress Translation Services支持trueoff复位后out-of-reset的翻译模式on表示 DMA 禁用OFF 模式off表示 BARE直通/passthroughtrues-stage启用 S/VS-Stage 地址翻译单级 S 阶段trueg-stage启用 G-Stage 地址翻译guest 阶段truehpm-counters硬件性能计数器HPM数量最大 31默认 31设为 0 关闭 HPM31vendor-id/device-idPCI 设备 ID1b36:0014Red HatrevisionPCI 修订号0x01每个布尔属性都直接映射到核心状态结构 hw/riscv/riscv-iommu.h 中的对应开关enable_msi、enable_ats、enable_off、enable_s_stage、enable_g_stage在设备复位时决定cap能力寄存器与fctl功能控制寄存器的初始状态。例如off属性对应enable_off复位时直接决定 DDTPDevice Directory Table Pointer寄存器翻译模式的初始值——为on时初始化为 OFF 模式DMA 全部被拒绝为off时初始化为 BARE 模式直通不翻译相关逻辑见 hw/riscv/riscv-iommu.c。使用示例$ qemu-system-riscv64 -M virt \ -device riscv-iommu-pci,addr1.0,intremapoff,atsoff \ -device riscv-iommu-pci,offoff \ (...)其中第一条关闭 MSI 重映射与 ATS第二条让 IOMMU 复位后直接处于 BARE 直通模式相当于 passthrough 启动便于先验证整机启动、再在 guest 中动态开启 IOMMU。riscv-iommu-sys 平台总线设备设备形态riscv-iommu-sys将同一套 RISC-V IOMMU 模拟实现为平台总线platform bus / sysbus设备供 RISC-V 板卡使用。与 PCI 版本相比它不通过 PCI 配置空间暴露而是通过 MMIO 寄存器直接映射到系统内存空间。从源码 hw/riscv/riscv-iommu-sys.c 可以看出其实现要点包括继承SysBusDevice寄存器内存区域iommu.regs_mr通过sysbus_init_mmio暴露支持两种中断通知方式riscv_iommu_sysdev_notify当 FCTL 寄存器的WSIWired/软件中断位被置位时通过qemu_irq_pulse触发有线中断否则通过 MMIO 模拟的 MSI-X 表msix_table_mmio向内存写入 MSI二者由RISCV_IOMMU_CAP_IGS_BOTH能力位IGS 模式为 both支持定义 4 个中断RISCV_IOMMU_INTR_COUNT从base-irq开始接入irqchipAIA 中断控制器物理地址宽度按机器位数设置riscv64 使用 56 位44 位 PPNriscv32 使用 34 位22 位 PPN见 hw/riscv/riscv-iommu-sys.c。在 virt 机器上启用virt 板卡上该设备默认禁用。使用iommu-sys机器选项启用$ qemu-system-riscv64 -M virt,iommu-syson (...)该选项在 hw/riscv/virt.c 中注册为OnOffAuto类型的机器属性默认值为auto见 hw/riscv/virt.cvirt_is_iommu_sys_enabled只在ON_OFF_AUTO_ON时返回 true见 hw/riscv/virt.c。启用时virt 机器会调用riscv_create_iommu_sys创建设备映射到 VIRT_IOMMU_SYS 固定地址0x3010000大小 0x1000见 hw/riscv/virt.c并接入IOMMU_SYS_IRQ见 hw/riscv/virt.c同时在 FDT 中生成对应节点。关键互斥逻辑在 virt 机器上当插入 PCI 形态的 riscv-iommu-pci或 virtio-iommu-pci时virt_machine_get_hotplug_handler会自动把iommu_sys置为 offhw/riscv/virt.c避免同一板卡上同时出现两个 IOMMU。固定能力配置virt 板卡上无法通过 QEMU 命令行配置该设备的能力设备以固定的 riscv-iommu 选项组合初始化ioatc-limit默认值2MBintremap启用MSI 重映射开启ats启用offon复位后 DMA 禁用即 OFF 模式s-stage启用g-stage启用即平台设备默认启用全部能力包括 S/G 两阶段翻译与 MSI 重映射但复位后处于 OFF 模式DMA 默认被拦截需要软件固件/内核驱动在运行时显式配置并切换到 BARE 或翻译模式。IOMMU 内部工作原理解读理解了两种设备形态与参数再结合核心实现 hw/riscv/riscv-iommu.c 可以更清楚地把握其运作方式。核心状态结构RISCVIOMMUStatehw/riscv/riscv-iommu.h承载了 IOMMU 的全部状态规范版本号、进程 ID 位宽、物理地址位宽、能力寄存器cap、已启用功能fctl、DDT 根指针ddtp、命令/故障/页请求三个队列的基地址与索引掩码cq_addr/cq_mask、fq_addr/fq_mask、pq_addr/pq_mask以及两张软件缓存——设备翻译上下文缓存ctx_cache与 I/O 地址翻译缓存iot_cache容量由iot_limit即ioatc-limit属性控制。地址翻译缓存IATC与上下文缓存规范要求的 I/O 地址翻译缓存上限为 2MBLIMIT_CACHE_IOT即1U 20上下文缓存上限为 128 条LIMIT_CACHE_CTX即1U 7见 hw/riscv/riscv-iommu.c。翻译缓存条目RISCVIOMMUEntryhw/riscv/riscv-iommu.c记录翻译标签bypass/单级/仅 G 级/嵌套、IOVA 页号、进程软上下文 IDpscid、物理页号、guest 软上下文 IDgscid与读写权限。翻译模式通过RISCVIOMMUTransTag枚举区分hw/riscv/riscv-iommu.c其中嵌套翻译Nested即同时使用 S 级与 G 级两阶段页表。中断与故障上报路径IOMMU 的四类事件命令队列 CQ、故障队列 FQ、性能监控 PM、页请求队列 PQ通过icvec寄存器选择 MSI-X 向量riscv_iommu_get_icvec_vectorhw/riscv/riscv-iommu.c随后调用设备形态注册的通知回调notify——PCI 版本走msix_notifyhw/riscv/riscv-iommu-pci.c平台版本按 WSI 位选择有线中断或内存写 MSIhw/riscv/riscv-iommu-sys.c。故障如 MSI 写失败会被记录进故障队列fq_record事件原因cause包括 MSI 写故障RISCV_IOMMU_FQ_CAUSE_MSI_WR_FAULT等hw/riscv/riscv-iommu-sys.c。设备 DMA 空间绑定每个接入的设备都会在 IOMMU 下创建一个RISCVIOMMUSpacehw/riscv/riscv-iommu.c包含该设备的 IOVA 内存区域与地址空间并记录其总线与devfn即规范中的 requester/device_id。设备 ID 由PCI_BUILD_BDF结合总线号构成hw/riscv/riscv-iommu.c。riscv_iommu_pci_setup_iommu在两种设备 realize 时都会调用将该 IOMMU 挂接到 PCI 总线的pci_setup_iommu回调上使总线上的所有设备 DMA 都经过 IOMMU 翻译。复位行为两种设备的复位都委托给riscv_iommu_reset分别见 hw/riscv/riscv-iommu-pci.c 与 hw/riscv/riscv-iommu-sys.c复位时根据enable_off决定 DDTP 初始翻译模式OFF 或 BARE并清零队列基地址与缓存。这正是前面命令行示例中off参数影响启动行为的底层原因。迁移限制与注意事项当前riscv-iommu设备的 VMState 描述被标记为unmigratable 1hw/riscv/riscv-iommu-pci.c即该设备暂不支持虚拟机迁移live migration在涉及迁移的场景中需要留意。此外设备不支持热插拔hotpluggable false但属于用户可创建设备user_creatable true见 hw/riscv/riscv-iommu-pci.c核心 IOMMU 内部设备则相反user_creatable false只能由 PCI/sys 外壳创建见 hw/riscv/riscv-iommu.c。实践建议小结快速体验使用-M virt -device riscv-iommu-pci配合 v6.13 主线内核即可验证基础 IOMMU 组创建与 DMA 重映射如需同时使用 AIA 中断请加上-M virt,aiaaplic-imsic,aia-guests5。对比两种形态PCI 版本灵活可控可在命令行逐项开关能力、指定 PCI 地址与设备 ID平台版本不可配置但固定启用全能力适合固定板卡拓扑场景两者互斥不可同时启用。排查启动问题若 guest 启动后 DMA 异常先检查off参数——默认复位后为 OFF 模式DMA 被拒需要 guest 驱动完成初始化切换到翻译或 BARE 模式需要直通启动时显式传offoff。性能与监控默认 31 个 HPM 计数器可观测 IOMMU 行为需要关闭时设hpm-counters0。生产部署注意该设备当前不支持迁移且主线内核截至 v6.17尚不支持 VFIO 直通直通场景需使用 Ventana Micro Systems 的 ventana-linux 内核分支测试。赞分享虚拟化硬件仿真【免费下载链接】qemuOfficial QEMU mirror. Please see https://www.qemu.org/contribute/ for how to submit changes to QEMU. Pull Requests are disabled. Please only use release tarballs from the QEMU website.项目地址https://gitcode.com/gh_mirrors/qe/qemu点击查看免费下载相关推荐QEMU iommu-testdev 深度解析用于裸机 IOMMU 翻译验证的测试 PCI 设备QEMU iommu testdev 深度解析用于裸机 IOMMU 翻译验证的测试 PCI 设备 iommu testdev 是 QEMU 仓库中一个最小化、虚拟化硬件仿真Cloud Hypervisor 虚拟 IOMMU 实战基于 virtio-iommu 的 DMA 隔离、嵌套虚拟化与性能调优Cloud Hypervisor 虚拟 IOMMU 实战基于 virtio iommu 的 DMA 隔离、嵌套虚拟化与性能调优 虚拟 IOMMUVirtuaAgent 沙箱虚拟化云原生人工智能后端容器运行时Cloud Hypervisor 虚拟 IOMMUvirtio-iommu使用指南从嵌套虚拟化保护到 VFIO 直通与巨页优化Cloud Hypervisor 虚拟 IOMMUvirtio iommu使用指南从嵌套虚拟化保护到 VFIO 直通与巨页优化 导读 本文基于 Cloud云原生上一篇ERNIE-4.5-300B-A47B-PT未来展望大语言模型的发展趋势与社区生态下一篇Back In Time 开源项目教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表