一、IOMMU
虚拟化技术:多进程共享一个CPU ,多进程虚拟空间共享同一物理内存,一个处理器系统运行多个处理系统技术。也就是虚拟环境相互独立互不干扰使用相同物理资源。
虚拟化核心技术VMM(Virtual Machine Monitor)集中管理物理资源,每个虚拟处理器系统需要通过VMM访问物理资源。VMM管理PCI设备机制有:IOMMU, PCIe总线ATS机制,SR-IOV(Single Root I/O Virtualization)和MR-IOV(Multi-Root I/O Virtualization)。
多进程共享一个CPU:MMU机制使每个进程有独立虚拟地址空间,互不干扰。从两方面实现一是进行地址转换,将不听进程的虚拟地址转换为物理地址;二是对物理地址访问进行权限检查,判断地址转化合理性。
IOMMU与MMU相似,IOMMU是把外部设备地址到存储器地址的转换。IOMMU中存放了IO页表虚实地址转换关系和访问权限,而且处理器加速虚实地址转换,还设置了IOTLB作为IO页表的Cache。
PCI Device A/B进行DMA操作时使用的物理地址是PCI总线域的物理地址,用地址路由或者ID路由进行存储器读写TLP传递,这个PCI总线地址与GAP地址一一对应相等。在虚拟环境下PCI设备与Domain有明确对应关系,当PCI设备进行DMA读写时,TLP首先到达地址转换部件TA(Translation Agent),并通过ATPT(Address Translation and Protection Table)将PCI总线域的物理地址转换为与GPA地址对应的HPA地址,然后对主存储器进行读写操作。PCI设备并不知道PCI设备与Domain有明确对应关系,这种操作是由TA和ATPT决定的。RC把PCI总线地址转换为存储器域地址,TA转换为合适的HPA地址。
IA处理器和AMD处理器使用不同技术实现TA和ATPT,其中IA使用VT-d,AMD使用IOMMU。
PCI设备进行DMA操作是,首先从相应的Device Table的Entry 获取“Level 4 Page Table Address”指针,并定位设备使用的I/0页表,最后使用多级页表结构完成PCI总线地址到HPA地址的转换。
二、ATS
ATC(Address Translation Cache)存放了ATPT部分内容,当PCIE使用地址路由方式发送TLP时,地址首先通过ATC转换为HPA地址。如果地址没有在ATC命中,PCIe设备将通过存储器读TLP从ATPT中获取相应的地址转换信息,更新ATC后,再发送TLP。与其他Cache类似,ATC还可以被Invalidate。当ATPT被更改时,处理器将发送Invalidate报文,同步ATC。
2.1TLP中AT字段
PCIe总线在TLP中设置了AT字段支持ATS机制,并且只有处理器支持IOMMU时,PCIe设备才可以使用ATS机制。
AT字段为0b00:
当AT字段为0b00时,表示TLP的Address没有通过ATC转换,存放是PCI总线域的物理地址。
1.不支持ATS 机制,处理器不支持IOMMU;TLP的Address是PCI总线域的物理地址,进行DMA操作时,该地址被RC转换为存储器域的物理地址,然后对存储器进行读写操作。
2. 不支持ATS机制,处理器支持IOMMU;TLP的Address是PCI总线域的物理地址,进行DMA操作时,该地址被TA根据I/O页表转换为存储器域的物理地址,然后对存储器进行读写操作。
3. 支持ATS机制,处理器支持IOMMU;进行DMA操作时,该数据被传送到对存储器进行读写操作。
AT字段为0b01:
支持ATS机制的设备必须支持0b01报文,该报文为“Translation Request”,该报文由PCIe设备通过存储器读请求TLP发出,其目的为TA。TA收到报文后将根据I/O页表设置,将合适的地址转换关系通过存储器读完成TLP,发送给PCIe设备,PCIe设备收到这个地址转换关系后,将更新ATC。该TLP有64位和32位两种格式。
AT字段为0b10:
当AT字段为0b10时,表示TLP的Address已经通过ATC转换,进行DMA操作时,RC收到这些报文将不会通过TA和ATPT转换,而直接将数据发送给存储器。经过ATC转换后TLP的Address字段存放的依然是PCI总线域的物理地址,该物理地址为HPA地址在PCI总线域中的映像。
无论PCIe设备是否使用ATC机制,在TLP中存放的Address字段仍然保存是PCI总线地址。
2.2地址转换请求-- Translation Request
PCIe使用地址转换请求(Translation Request)TLP向TA提交地址转换请求。该TLP具有64位和32位两种地址格式,并且AT字段为0b01表示当前报文为地址转换请求TLP。该报文将Untranslated Address 字段发送到TA,而TA根据ATPT将Untranslated Address数据区域进行翻译,如果翻译成功TA使用CpI(从存储器读完成TLP)将地址转换关系发送给PCIe设备,PCIe设备收到这个存储器读完成TLP将这个地址转换关系保存在PCIe设备的ATC中。否则使用CpI将失败信息发送给PCIe设备。PCIe设备发送一个地址转换请求后,可能会从TA得到多个地址转换关系,这些地址转换关系可以使用一个存储器读完成TLP发送给PCIe设备。
ATC未命中处理方式:
- 使用AT 为0b00 的TLP使用Untranslated Address直接访问存储器,因此TA根据ATPT将Untranslated Address进行地址转换,然后再将报文发送到存储器中。
- 使用地址转换请求(Translation Request)TLP向TA提交地址转换请求,并从ATPT获得地址转换关系后,使用TA为0b10的存储器读写TLP,使用Translated Address与主存储器进行数据交换。
2.3Invalidate ATC
当ATPT被更改时,需要使用MsgD报文通知PCIe设备,并用Invalidate ATC中相应Entry,该MsgD被称为“Invalidate Request Message”,收到一个MsgD只能Invalidate ATC中一个Entry。
三、IOMMU Enable
Ubuntu:
- 在vbios中打开iommu
- 在hygon CPU IOMMU默认是打开不用配置, 其余CPU /etc/default/grub GRUB_CMDLINE_LINUX="intel_iommu=on(或者amd_iommu=on,iommu=off可关闭)"
- 生成配置文件grub-mkconfig -o /boot/grub/grub.cfg,
- 重启系统
- dmesg | grep -e DMAR -e IOMMU查看IOMMU是否打开,下图为打开状态:
Centos:
- 打开BIOS中的虚拟化开关(VT-d)
- 激活linux内核的VT-d开关。
- 编辑/etc/sysconfig/grub文件(系统引导文件),找到rhgb quiet,在后面添加intel_iommu=on或者amd_iommu=on。
- 使用grub-mkconfig –o /boot/grub/grub.cfg生成新的系统引导菜单(或者是grub2-mkconfig)
- 重启使设置生效
- 使用dmesg | grep -e DMAR -e IOMMU,查看IOMMU是否启用