在设备做DMA访问内存的时候,系统返回给设备驱动的不再是物理地址,而是虚拟地址,这个地址一般叫IOVA,设备访问内存时,由IOMMU来将这个虚拟地址转换为物理地址。...IOMMU是个硬件单元 IOMMU和MMU一样是个硬件单元,通常是实现在北桥之中,现在北桥通常被集成进SOC中,所以IOMMU通常都放在SOC内部了。...在SOC上可能有一个或多个IOMMU硬件单元,例如多路服务器上可能集成有多个IOMMU硬件单元。 每个IOMMU硬件单元负责管理挂载到它所在的PCIe Root Port下所有设备的DMA请求。...IOMMU Group 在虚拟化设备透传时还涉及到PCI设备的iommu group分组问题。 根据IOMMU拓扑结构,一个iommu group里可能有一个或多个设备。...另外PCI总线上的设备都归一个iommu group。最后同一个iommu group中所有的设备将会共享一个IOVA地址空间。 关于IOMMU的介绍以及在虚拟化中的作用就介绍这些。
然后在虚拟机中把网卡绑定内核模块igb_uio,问题是igb_uio的代码没有upstream,依赖于内核版本,提前编译好的内核模块换个版本就不能运行,就想着用vfio-pci,这家伙早早upsteam,一般linux...iommu硬件单元,意思就是qemu没有模拟出iommu硬件单元,把模拟的iommu称为虚拟的iommu,就是viommu。...Userspace API,通道下去再调用到硬件的驱动,好处就是可以和内核vfio-iommu那一套结合起来,自然而然就可以利用到fault handling,cache invalidation和PASID...request queue中,然后给CPU来个page request event中断,IOMMU驱动开始处理,指导IOMMU给device回复一个Page Group Response消息,device...再重试刚才的request,这样的好处就是软件通用,代码都在IOMMU驱动中,device硬件要配合IOMMU硬件,整体上来说对硬件的要求很高。
vt-d post interrupt IOMMU硬件单元也可以借用post interrupt机制把passthrough设备产生的中断直接投递到虚拟机中,不需要虚拟机exit出来,不需要VMM软件介入...interrupt remapping格式变成post interrupt格式,IRTE中内容也变了,它中存放post interrupt descriptor的地址和虚拟中断vector,物理中断到了IOMMU...vt-d posted interrupt就是IOMMU硬件单元更新了vcpu的post interrupt descriptor。...但vt-d相比vt-x就弱智多了,一个vcpu有没有运行,运行在哪个物理cpu上,这个vcpu可不可以接收中断,或者vcpu从一个物理cpu迁移到另一个物理cpu,vt-d IOMMU都不能自己判断,只能通过...kvm告诉它,所以kvm就把这些信息写到post interrupt descriptor的其它位中,IOMMU来读,这些位就是SN,NDST和NV。
惠伟:IOMMU(三)-初始化zhuanlan.zhihu.com DMA remapping就是在DMA的过程中IOMMU进行了一次转换,MMU把CPU的虚拟地址(va)转换成物理地址(pa),IOMMU...的作用就是把DMA的虚拟地址(iova)转换成物理地址(pa),MMU转换时用到了pagetable,IOMMU转换也要用到io pagetable,两者都是软件负责创建pagetable,硬件负责转换...IOMMU的作用就是限制DMA可操作的物理内存范围,当一个PCI设备passthrough给虚拟机后,PCI设备DMA的目的地址是虚拟机指定的,必须要有IOMMU限制这个PCI设备只能操作虚拟机用到的物理内存...io pagetable IOMMU的pagetable和MMU的pagetable一模一样,转换方式也一样,都支持4KB/2M/1G大小的page,都支持4级和5级页表,4级和5级的区别就是va/iova...IOMMU工作模式 intel vt-d iommu可以工作于legacy和scale模式。
Debian 开启 IOMMU 支持# vi /etc/default/grub 找到 GRUB_CMDLINE_LINUX_DEFAULT="quiet" 修改为 intel: GRUB_CMDLINE_LINUX_DEFAULT...="quiet intel_iommu=on" AMD: GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on" 保存并退出,输入以下命令: update-grub
惠伟:IOMMU(四)-dma remappingzhuanlan.zhihu.com MSI 通过DMA写物理地址0x0FEE_XXXX来产生中断,PCI config space中有MSI Address...和Data寄存器,驱动配置这两个寄存器,Address寄存器中有Destination ID,表示Local APIC ID,Address寄存器所有字段组合起来就是x0FEE_XXXX,Data寄存器有...apic_bsp_setup └─irq_remap_enable_fault_handling └─enable_drhd_fault_handling linux...中断处理子系统有两个很重要的概念就是irq_chip和irq_domain,IOMMU为了支持interrupt remapping也增加了这两个东西。...虽然函数名字有pi(post interrupt),但硬件不支持post interrupt的情况也可以搞定,kvm调用irq_set_vcpu_affinity时参数vcpu_info设置为空即可,这样IOMMU
vfio-pci是内核驱动,网卡和NVME盘等设备就可以使用这个驱动,使用vfio-pci就会调用到vfio-pci的probe。...sr-iov是pci标准的设备虚拟化方案,mdev就厂商私有的设备虚拟化方案,驱动是厂商实现的,硬件也是厂商搞的,驱动和硬件配合能达到虚拟化的效果就行。...dev -r--r--r--. 1 root root 4096 May 28 10:31 /sys/class/vfio/81/dev vfio group不是凭空造出的一个概念,vfio group和IOMMU...硬件的group紧密相关,所以vfio还有一个重要的函数就是vfio_register_iommu_driver,vfio_iommu_type1.ko就调用这个函数给vfio注册了操作IOMMU的ops...,一个设备DMA用到的pagetable就可以通过这个ops配置到IOMMU中。
MSI 通过DMA写物理地址0x0FEE_XXXX来产生中断,PCI config space中有MSI Address和Data寄存器,驱动配置这两个寄存器,Address寄存器中有Destination...apic_bsp_setup └─irq_remap_enable_fault_handling └─enable_drhd_fault_handling linux...中断处理子系统有两个很重要的概念就是irq_chip和irq_domain,IOMMU为了支持interrupt remapping也增加了这两个东西。...虽然函数名字有pi(post interrupt),但硬件不支持post interrupt的情况也可以搞定,kvm调用irq_set_vcpu_affinity时参数vcpu_info设置为空即可,这样IOMMU...intel_ir_set_vcpu_affinity └─modify_irte kvm的物理中断号来自于vfio,vfio_msi_set_vector_signal向系统申请物理中断号,传递给kvm,当外设触发中断后,IOMMU
enable vt-d 意思很明确,BIOS收集IOMMU硬件相关的信息以及它和PCI设备连接关系的信息,通过ACPI的表上报给操作系统 intel_iommu=on 用intel_iommu驱动来驱动...IOMMU硬件单元,IOMMU硬件有intel/amd/arm的等,我们一般用intel的硬件,当然用intel的iommu驱动了。...kvm_iommu_map_pages └─iommu_map └─intel_iommu_map(domain->ops->map) └─domain_pfn_mapping...mapping 说明配置了iommu=pt上面的函数iommu_no_mapping返回1,那么i40e驱动就直接return paddr,并不会真正调用到domain_pfn_mapping,直接用了物理地址少了一次映射性能当然会高一些...总结 iommu=pt并不会影响kvm/dpdk/spdk的性能,这三者本质上都是用户态驱动,iommu=pt只会影响内核驱动,能让内核驱动设备性能更高。
DMA remapping就是在DMA的过程中IOMMU进行了一次转换,MMU把CPU的虚拟地址(va)转换成物理地址(pa),IOMMU的作用就是把DMA的虚拟地址(iova)转换成物理地址(pa),...MMU转换时用到了pagetable,IOMMU转换也要用到io pagetable,两者都是软件负责创建pagetable,硬件负责转换。...IOMMU的作用就是限制DMA可操作的物理内存范围,当一个PCI设备passthrough给虚拟机后,PCI设备DMA的目的地址是虚拟机指定的,必须要有IOMMU限制这个PCI设备只能操作虚拟机用到的物理内存...io pagetable IOMMU的pagetable和MMU的pagetable一模一样,转换方式也一样,都支持4KB/2M/1G大小的page,都支持4级和5级页表,4级和5级的区别就是va/iova...IOMMU工作模式 intel vt-d iommu可以工作于legacy和scale模式。
惠伟:IOMMU(五)-interrupt remmapingzhuanlan.zhihu.com post interrupt post interrupt是intel提供的一种硬件机制,不用物理cpu...vt-d post interrupt IOMMU硬件单元也可以借用post interrupt机制把passthrough设备产生的中断直接投递到虚拟机中,不需要虚拟机exit出来,不需要VMM软件介入...,IOMMU硬件单元直接IRTE中虚拟中断vector写到post interrupt descriptor中pir对应的位,然后给vcpu所在的物理cpu发送一个中断,中断号就是post interrupt...vt-d posted interrupt就是IOMMU硬件单元更新了vcpu的post interrupt descriptor。...kvm告诉它,所以kvm就把这些信息写到post interrupt descriptor的其它位中,IOMMU来读,这些位就是SN,NDST和NV。
1.无操作系统时的硬件、驱动、应用软件要满足高内聚、低耦合。 2.有操作系统时的驱动, 3.LINUX驱动与整个软硬件的关系
长期从事Linux内核驱动开发、Linux内核开发和Linux系统虚拟化(QEMU/KVM),喜欢分析Linux内核子系统基本原理并撰写技术博客,长期关注kernel、QEMU的开源项目,经常参加相关开源社区活动...2.2 软件支持 Linux系统下,基于SR-IOV有三种应用场景:HostOS使用PF、HOstOS使用VF、将VF直通到VM(虚拟机),见图2.2.1: 图2.2.1 Linux系统中PCI驱动框架...3.1.1.1 DMA物理地址重映射 (DMA Remapping ) 1)地址空间隔离 在没有iommu的时候,用户态驱动可以通过设备dma可以访问到机器的全部的地址空间,如何保护机器物理内存区对于用户态驱动框架设计带来挑战...VFIO提供了IOMMU重映射驱动,向用户空间暴露DMA操作。...当GuestOS中直通设备的驱动分配内存并配置DMA时,QEMU通过VFIO接口将GPA下发到PCI Device的DMA,DMA读取数据时经由IOMMU映射,找到相应的HPA。 图3.2.1.1
惠伟:IOMMU(一)-简单介绍zhuanlan.zhihu.com 惠伟:IOMMU(二)-从配置说起zhuanlan.zhihu.com BIOS收集IOMMU相关的信息,通过ACPI中的特定表组织数据...,放置在内存中,等操作系统接管硬件后,它会加载驱动,驱动再详细解析ACPI表中的信息。...驱动 内核编译的时候生成IOMMU相关的数据结构,所有IOMMU厂商注册自己的IOMMU硬件的detect/depend/early_init/late_init函数,intel注册了detect_intel_iommu...iommu_init符值intel_iommu_init。...的si,如果内核参数iommu=nopt就是类型为IOMMU_DOMAIN_DMA的domain,内核参数没有iommu,默认为IOMMU_DOMAIN_IDENTITY。
BIOS收集IOMMU相关的信息,通过ACPI中的特定表组织数据,放置在内存中,等操作系统接管硬件后,它会加载驱动,驱动再详细解析ACPI表中的信息。...驱动 内核编译的时候生成IOMMU相关的数据结构,所有IOMMU厂商注册自己的IOMMU硬件的detect/depend/early_init/late_init函数,intel注册了detect_intel_iommu...iommu_init符值intel_iommu_init。...| └─iommu_alloc_root_entry ├─for_each_active_iommu | ├─iommu_flush_write_buffer | └─iommu_set_root_entry...的si,如果内核参数iommu=nopt就是类型为IOMMU_DOMAIN_DMA的domain,内核参数没有iommu,默认为IOMMU_DOMAIN_IDENTITY。
我们知道DMA通常需要访问连续的物理内存,除非设备支持iommu,当设备不支持iommu的话可以用以下方式: 在内核启动时为设备保留内存 将MMU内嵌到设备中,如GPU 这里GPU MMU的方式算是个例外...= { .alloc = __iommu_alloc_attrs, .free = __iommu_free_attrs, .mmap = __iommu_mmap_attrs, .get_sgtable...= __iommu_get_sgtable, .map_page = __iommu_map_page, .unmap_page = __iommu_unmap_page, .map_sg =...__iommu_map_sg_attrs, .unmap_sg = __iommu_unmap_sg_attrs, .sync_single_for_cpu = __iommu_sync_single_for_cpu...= iommu_dma_unmap_resource, .mapping_error = iommu_dma_mapping_error, }; 非iommu的话即调用__dma_alloc: static
,内核参数配置intel_iommu=on iommu=pt 好多人对这些配置很疑惑,不知道这些配置的是做什么的,配或者不配对性能有什么影响。...enable vt-d 意思很明确,BIOS收集IOMMU硬件相关的信息以及它和PCI设备连接关系的信息,通过ACPI的表上报给操作系统 intel_iommu=on 用intel_iommu驱动来驱动...IOMMU硬件单元,IOMMU硬件有intel/amd/arm的等,我们一般用intel的硬件,当然用intel的iommu驱动了。...mapping 说明配置了iommu=pt上面的函数iommu_no_mapping返回1,那么i40e驱动就直接return paddr,并不会真正调用到domain_pfn_mapping,直接用了物理地址少了一次映射性能当然会高一些...总结 iommu=pt并不会影响kvm/dpdk/spdk的性能,这三者本质上都是用户态驱动,iommu=pt只会影响内核驱动,能让内核驱动设备性能更高。
="quiet intel_iommu=on video=efifb:off" GRUB_CMDLINE_LINUX="" # Uncomment to enable BadRAM filtering...="true" # Uncomment to get a beep at grub start #GRUB_INIT_TUNE="480 440 1" root@pve:~# 开启IOMMU支持...: GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on video=efifb:off" 如果是AMD的CPU: GRUB_CMDLINE_LINUX_DEFAULT...bin Found memtest86+ multiboot image: /boot/memtest86+_multiboot.bin done root@pve:~# 复制代码 添加所需的系统模块(驱动...vfio_pci vfio_virqfd 复制代码 接着添加模块(驱动)黑名单,即让GPU设备在下次系统启动之后不使用这些驱动,把设备腾出来给vfio驱动用: Intel核显: echo "blacklist