# RISC-V IOMMU Nested HPM **Repository Path**: WLLDD/riscv-iommu-nested-hpm ## Basic Information - **Project Name**: RISC-V IOMMU Nested HPM - **Description**: 本项目旨在为 `OpenEuler/OLK-6.6` 移植RISC-V IOMMU 硬件性能监控(hardware performance monitor)和嵌套 IOMMU支持,并提供完整的测试方案。 - **Primary Language**: Shell - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 5 - **Created**: 2025-06-01 - **Last Updated**: 2025-06-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # RISC-V IOMMU HPM/Nested 移植、测试 ## 1. 项目介绍 本项目旨在为 `openEuler/OLK-6.6` 移植RISC-V IOMMU 硬件性能监控(hardware performance monitor)和嵌套 IOMMU支持。同时,还引入了更多操作,这些操作是嵌套IOMMU 所需的,例如 `g-stage flush` 和 `iotlb_sync_map`。该项目基于的 RISC-V IOMMU 规范已经通过批准,并可在 [GitHub/riscv-non-isa](https://github.com/riscv-non-isa/riscv-iommu) 获取。 ### 1.1 Nested嵌套翻译 嵌套翻译(Nested translation)是一种被许多现代 IOMMU 硬件支持的硬件特性。它通过两阶段的地址转换来访问物理地址。第一阶段(stage-1)的翻译表由用户空间(例如,客户操作系统)管理,而第二阶段(stage-2)的翻译表由内核管理。对 stage-1 翻译表的任何更改都必须伴随一次 IOTLB(I/O 转换后备缓冲区)无效化操作。 以 Intel VT-d 为例,stage-1 翻译表是客户 I/O 页表。如下图所示,客户 I/O 页表指针位于 GPA(客户物理地址)中,并传递给主机以执行 stage-1 转换。与此同时,对客户 I/O 页表中的现有映射所做的任何修改都必须伴随一次 IOTLB 无效化操作。 ``` .-------------. .---------------------------. | vIOMMU | | Guest I/O page table | | | '---------------------------' .----------------/ | PASID Entry |--- PASID cache flush --+ '-------------' | | | V | | I/O page table pointer in GPA '-------------' Guest ------| Shadow |---------------------------|-------- v v v Host .-------------. .------------------------. | pIOMMU | | FS for GIOVA->GPA | | | '------------------------' .----------------/ | | PASID Entry | V (Nested xlate) '----------------\.----------------------------------. | | | SS for GPA->HPA, unmanaged domain| | | '----------------------------------' '-------------' ``` 其中: - FS = 第一阶段页表(First stage page tables) - SS = 第二阶段页表(Second stage page tables) 在 IOMMUFD 中,所有的翻译表都由 `hw_pagetable`(简称 hwpt)进行跟踪,每个 hwpt 都由从 IOMMU 驱动程序分配的 `iommu_domain` 支持。如果没有特别说明,`hw_pagetable` 和 `iommu_domain` 表示相同的概念。IOMMUFD 已经支持为与 IOAS(I/O 地址空间)关联的 hw_pagetable 分配资源。然而,在嵌套的情况下,需要 IOMMUFD 允许分配带有驱动程序特定参数的 hw_pagetable,并提供同步 stage-1 IOTLB 的接口,因为用户拥有 stage-1 翻译表。 > * https://lore.kernel.org/all/20231026043938.63898-1-yi.l.liu@intel.com/ > * https://lore.kernel.org/all/20231117130717.19875-1-yi.l.liu@intel.com/ ### 1.2 HPM硬件性能监控 随着 VT-d 规范 4.0 的发布,引入了一种性能监控基础设施——**perfmon**。perfmon 的目的是支持收集重映射硬件在运行过程中发生的关键事件的信息,以帮助性能调优和调试。本补丁系列的目标是为 IOMMU 提供对 perfmon 的支持。 用户可以使用 Linux 的 `perf` 工具收集 IOMMU 的性能数据。例如: ```bash $ perf stat -e dmar0/iommu_requests,filter_ats=0/ -a sleep 1 Performance counter stats for 'system wide': 2135 dmar0/iommu_requests,filter_ats=0/ 1.001087695 seconds time elapsed ``` IOMMU 的性能监控单元(PMU)可以在以下路径中找到: ``` /sys/bus/event_source/devices/dmar* ``` 可用的过滤器和事件格式可以在 `format` 文件夹中找到: ```bash $ ls /sys/bus/event_source/devices/dmar0/format/ event event_group filter_ats filter_page_table ``` 支持的事件可以在 `events` 文件夹中找到: ```bash $ ls /sys/bus/event_source/devices/dmar0/events/ ats_blocked int_cache_hit_nonposted iommu_mrds pasid_cache_lookup ctxt_cache_hit int_cache_hit_posted iommu_requests pg_req_posted ctxt_cache_lookup int_cache_lookup iotlb_hit pw_occupancy fs_nonleaf_hit iommu_clocks iotlb_lookup ss_nonleaf_hit fs_nonleaf_lookup iommu_mem_blocked pasid_cache_hit ss_nonleaf_lookup ``` 这些功能使得用户能够更精细地监控和分析 IOMMU 的性能行为,从而优化系统性能并排查潜在问题。 > 对于RISC-V IOMMU架构,也存在硬件性能监控装置,具体的软硬件支持如下: > > * `docs/riscv-iommu.pdf` > * 该补丁实现了 RISC-V IOMMU 硬件性能监控功能,支持计数模式(counting mode)和采样模式(sampling mode) : > * https://lore.kernel.org/all/20240614142156.29420-2-zong.li@sifive.com/ > * 该补丁在驱动初始化时设置性能监控单元(PMU)相关内容,并在驱动移除时进行清理。同时,还提供了中断处理功能。 > * https://lore.kernel.org/all/20240614142156.29420-3-zong.li@sifive.com/ ## 2. 任务规划 ### 2.1 特性移植 #### 项目1 **基于 `OpenEuler/OLK6.6` 移植适配 RISC-V IOMMU核心特性** 由于 [openEuler/OLK-6.6](https://gitee.com/openeuler/kernel/tree/OLK-6.6/) 对 RISC-V IOMMU 架构的支持较为落后,我们考虑从主线/社区移植完善相应的功能,除了基础的 RISC-V IOMMU 适配,还需要支持 `nested-iommu` (两阶段嵌套地址翻译),和 `riscv-iommu-hpm` (硬件性能监控) 的适配。我们可以参考以下仓库和补丁,backport 到 `openEuler/OLK-6.6` 上: * [tjeznach/linux at riscv_iommu_v7](https://github.com/tjeznach/linux/tree/riscv_iommu_v7) [1] * [[RFC PATCH v2 00/10\] RISC-V IOMMU HPM and nested IOMMU support - Zong Li](https://lore.kernel.org/all/20240614142156.29420-1-zong.li@sifive.com/) [2] * https://lore.kernel.org/all/20241114161845.502027-17-ajones@ventanamicro.com/ [3] ```shell git clone https://github.com/tjeznach/linux/tree/riscv_iommu_v7 --depth=1 -b riscv_iommu_v7 -j8 cd ./linux b4 am https://lore.kernel.org/all/20240614142156.29420-1-zong.li@sifive.com/ git am ./v2_20240614_zong_li_risc_v_iommu_hpm_and_nested_iommu_support.mbx ``` 在 [1] 基础上可以直接应用 [2] 系列补丁,不会产生冲突。 注:迁移 [3] 以支持 VFIO_IOMMU_TYPE1,这需要解决部分代码冲突。 > **产出物**(代码) > > 1. 参考 `[1][2]` 将上游RISC-V IOMMU核心功能移植到 `OpenEuler/OLK-6.6`,自行fork [openEuler/OLK-6.6](https://gitee.com/openeuler/kernel/tree/OLK-6.6/) 进行移植。 > 2. 扩展任务:探索 x86/arm 与 RISC-V IOMMU架构的软硬件实现差异,完善RISC-V内核实现。 ### 2.2 测试验证 #### 项目2 **基于RISC-V架构的 `iommu-selftests` 构建、测试、验证** 分析并区分 `iommu-selftests[1]` 所涉及的功能点,基于qemu构建完整的测试环境并验证,分析解决Bug,筛选出目前RISC-V架构所支持的功能,对于RISC-V所不支持的测试项(arm/x86支持),尽可能探索其不支持的原因(软硬件支持),作为我们后续进一步贡献内核社区的方向. 重点分析 `TEST_F(iommufd_ioas, alloc_hwpt_nested)` 该测试项,其余作为扩展任务,相关补丁见 [2]. [1] https://github.com/torvalds/linux/tree/master/tools/testing/selftests/iommu [2] https://lore.kernel.org/all/20231026043938.63898-11-yi.l.liu@intel.com/ > **产出物**(文档) > > 1. iommu-selftests功能分析文档,主要分析 `alloc_hwpt_nested` 子测试项,其余作为扩展任务 > 2. 基于qemu-riscv的完整构建、测试脚本 --- #### 项目3 **设计 `RISC-V IOMMU HPM/Nested` 测试方案** * RISC-V IOMMU 硬件性能监控(基础) * 嵌套 IOMMU(拓展) `iommu-selftests` 对于 RISC-V Nested/HPM 的测试较为有限,我们需要另外一套测试方案去验证这两项功能,可自定义测试项,也可参照其它架构(arm/x86)的测试方法。 > **产出物**(文档) > 1. `HPM` 测试代码、文档:在qemu环境中构建 riscv-perf 工具,来收集 riscv-iommu 的性能数据,并输出构建文档。 > 2. 基于qemu-riscv的完整构建、测试脚本 ## 3. 其它说明 各项任务都有基础和扩展子项目,基础是主攻方向,有余力的同学可以尝试扩展方向。优秀学员以及实习资格,将主要根据基础项目的完成情况来评定。