这其实是我当时给同事分析讲解PASID留下的一些文字,很多东西都是照图上嘴说出来的;也因此本文中的各个配图都是PASID的关键所在(PASID本就是个小Feature,几张图其实也就能说清了)。也是几年过去啦,很多东西都是看过自己写的文字才想起来,当时是因为啥忙活忘了没发呢。。
PASID虽然只是个小Feature,但其实这里面勾连起来的背景知识还是很广阔的,本文最后还有描述当时(2022年)PASID在Intel AMD这些平台的开发情况(还不成熟),现在并不一定是文中所说的状态了(毕竟已经过去了两年)。
总之,小老弟水平一般,文笔更差,各位读者但凡觉着哪里有错漏一定要联系我,以免有错误的信息被其他人接受。
谢谢🙏
2024.3
前言
1. 我认为的PASID意义
无论在PF还是VF,PASID都是为了使Device(DMA/XPU)具备直接访问Host用户态进程内存空间的能力;在AMD和ARM,PASID都是通过与PRI/ATS合作,完成SVA(Shared Virtual Addressing),使设备具备与进程能共享虚拟地址空间。
2. 为什么不将设备内存mmap到用户态,提供给用户使用
PASID是使能Device master→Host DDR过程使用进程地址空间
3. 我查到的PASID的应用状态
在AMD和ARM,PASID都是与PRI/ATS绑定使用,不具备其中任意一项则此三项特性均无法打开。单挑出AMD的PASID,通观内核,仅有AMD自家PCI驱动使用了此三项特性,ARM平台未深入调查。
对于Intel,PASID应该是在11代支持PASID 4.0的平台才能支持外设PASID能力;而在此之前,Intel仅为自家i915集成显示芯片提供了私有的具备PASID能力的IOMMU(不提供给其他外设使用)。不过需要指出的是,从内核代码来看Intel平台PASID/PRI/ATS并不强行绑定,PASID可单独打开。同样的,内核中使用了Intel PASID能力的外设仅有其i915。
主题
1. PASID是怎么使用的
以AMD平台为例一个综合的图是这样的
1.1 设备发起的内存访问带有Device ID,用于在Device Table找到对应的DTE(Device Table Entry Format)
1.2 DTE中GCR3 Table Root Pointer指到一个CR3表,其中存有一组页表基地址,即一组内存空间GVA-GPA
1.3 DTE中Host Page Table Root Pointer指向GPA-SPA页表
最后需要指出,DTE中GCR3 Table Root Pointer在Guest Translation不支持/关闭的情况下是不生效的
2. Host进程中PASID如何使用,毕竟Host进程VA-PA转换并不需要嵌套
DTE中Bit[9:11] Mode字段控制Host Page Table Root Pointer指的页表如何做地址转换,其中000b表示是0级Page Table,也就是直接映射不必转换;其他001b-110b表示进行1-6级页表转换。如此Host进程不必GPA-SPA转换即可使用PASID。
3. AMD中,IOMMU如何与CPU共享页表
AMD尽可能使IOMMU与CPU页表兼容,然而IOMMU面向64Bit全寻址,CPU则一般处理到0-47 Bit,然后48-63Bit与Bit47相同;为了兼容,AMD做成了下图的样子,我理解是从3级页表开始共享。
3. 共享页表之后,如何做到页表的同步
mmu_notifier.h提供有struct mm_notifier_ops接口,如:
3.1 struct mm销毁时触发设备页表释放的:release
3.2 其他与页面最近是否有访问、是否回收交换相关的:clear_flush_young/clear_young/test_young接口
3.3 PTE映射变化,同步给设备页表的接口:change_pte
3.4 invalidate_range_start(page refcount降到1)/invalidate_range_end(page refcount降到0)/invalidate_range 一族invalid页表
4. 确定平台是否能使用PASID功能
首先是需要AMD IOMMU 2.0,之后,若设备PCI capability的EFRSup置位,则MMIO Offset 0030h寄存器中GTSup(Guest translation supported)可以知道是否支持Guest页表转换
5. 控制能否使用Guest页表转换
MMIO Offset 0018h寄存器中GTEn(Guest translation enable)可以开启Guest页表转换
6. DTE中一条Entry控制Guest能不能用上IOMMU的关键bit:V TV GV
7 . Guest用上了IOMMU,Device寻址Guest进程用户空间是如何发生的(1级PASID):
8 . Guest用上了IOMMU,Device寻址Guest进程用户空间是如何发生的(2级PASID):
一些有意义的备忘
1. 如果没有PRI,似乎用户进程可以大量pin内存,引起大量内存无法回收、交换
2. IOMMU是一个独立的PCI Function,
有IOMMU capability,没有BAR;
配置和状态信息通过PCI capability块映射到PCI配置空间;
多个IOMMU可以放入一个Function;
如果一个Function中有多个IOMMU则IOMMU必然支持MSI-X中断;
每个IOMMU都有自己的中断向量
4. AMD Guest virtual APCI的描述似乎与Intel interrupt posting是对应的,IOMMU 2.5开始支持
5 . 一个比较经典的中断翻译过程图:
软件适配最新状态(2022.3)
Shadow Guest PASID表 Intel VT-d SM特性
ioasid是内核管理pasid的库,5.5以后
Guest-Host PASD mapping
Partitioning Namespaces
Synchronization/Notifications
Lifecycles
Intel about pasid
https://www.youtube.com/watch?v=xTwA3kC7ShA
Shadow Guest PASID表 Intel VT-d SM特性
ioasid的补丁 https://lkml.org/lkml/2020/9/28/1186
Documentation/driver-api/ioasid.rst