参考文档:intel vt-d
本文是intel vt-d技术的学习笔记。
一 DMA重映射
1.1 DMA请求的类型
Remapping hardware将DMA请求分成两类:
- Requests without address-space-identifier:这些是来自设备的正常内存请求。这些请求通常指定访问类型(读/写/原子)、目标DMA地址/大小和发起请求的设备的源id(例如pci的bus/device/function)。
- Requests with address-space-identifier:这些是带有附加信息的内存请求,这些信息标识来自端点设备的目标地址空间。除了常规请求中的属性之外,这些请求还指定目标进程地址空间标识符(PASID)和可选属性,例如Execute Requested(ER)标志(指示读取是指令获取)和Privileged mode Requested(PR)标志(区分用户和管理器访问)。
为了简单起见,本文将这些类别称为不带PASID的请求和带PASID的请求。使用唯一的PASID标记DMA流的请求可以实现I/O设备的可伸缩和细粒度共享,以及设备与主机应用程序的虚拟内存的操作。
后面的部分将描述使用PASID请求的这些用法。Intel早期仅支持重新映射不带PASID的请求。
1.2 域和地址转换
域被抽象地定义为平台中的一个独立环境,其中分配了物理内存的一个子集。DMA设备可以分配给一个域,并称为该域的设备。对于虚拟化应用,软件可以将每个虚拟机视为一个域。硬件保证未分配给某域的设备不允许访问该域的物理内存。通过将所有I/O设备分配给不同域(可能是空域),并确保它们只能访问分配给其域的物理资源。DMA重映射架构有助于将I/O设备灵活分配到任意数量的域。每个域都有一个物理地址空间视图,该视图可能与主机物理地址空间不同。重新映射硬件将请求中的地址视为DMA地址。根据软件使用模式,设备的DMA地址空间(无论是PF、VF还是Intel®Scalable IOV Assignable device Interface(ADI))可以是分配给它的虚拟机的Guest物理地址(GPA)空间,还可以是代表其执行DMA请求的主机应用程序的虚拟地址(VA)空间、在虚拟机内执行的客户端应用程序的Guest虚拟地址(GVA)空间、由主机软件管理的I/O虚拟地址(IOVA)空间或由Guest软件管理的Guest I/O虚拟地址(GIOVA)空间。以上所有情况下,DMA重新映射都会将I/O设备发出的DMA请求中的地址转换为其相应的主机物理地址(HPA)。
1.3 映射设备到域
每一个映射请求都需要一个‘source-id’来标识请求的设备来源。下图以PCIE设备为例:接下来描述将I/O设备映射到域的数据结构。
1.3.1 传统模式地址转换:
地址转换前通过设备的source-id找到对应的到Domain,转换过程如下。root table和Context table都位于内存中,内存的首地址可以通过寄存器指定。用source-id的bus部分选择root table的entry。root table的entry指向了context table的基地址。再利用source-id的device id加上function id来选择context table的entry。context table的entry指向了域的页表结构体基地址。
可以通过修改context table的entry来达到,不同的设备使用相同域,或者不同域。
1.3.2 可伸缩模式地址转换
可以通过设置寄存器的Scalable Mode Translation(SMTS=1)来使用可伸缩模式地址转换。Scalable Mode Root Table的大小跟传统模式一样;但是entry内容的含义不同。每个entry会指向一个upper context table和一个lower context table。
Context Table的entry指向Scalable Mode PASID Directory。
1.4 地址转换
地址转换过程跟intel的经典分页模式类似。使用多级页表进行转换。
二 中断重映射
2.1 中断映射
软件可以控制和审查所有的外部中断请求,包括来自中断控制器(I/OxAPICs)和MSI/MSI-X中断。重映射硬件自己产生的中断不会再被重映射,例如 Fault Event等。
中断请求在Root-complex中显示为对中断地址范围0xFEEX_XXXXh的upstream内存写请求。中断请求作为写请求到达Root-complex,中断重映射与重映射硬件单元位于同一位置。中断重映射功能通过扩展功能寄存器报告。
2.2 中断提交
中断发布功能是中断重映射硬件的扩展,用于可重映射格式中断请求的扩展处理。中断发布使可重设格式的中断请求能够被发布(记录)在一个一致的主存储器驻留数据结构中,并向CPU复合体发送一个可选的通知事件,以发出挂起的已发布中断信号。