QEMU + KVM对于 SMMU IO passthrough(直通)实现分析

1 篇文章 0 订阅
1 篇文章 0 订阅

引子:

虚拟化实现中,如果将一个设备透传给GuestOS直接使用,必须配置SMMU中的页表,使得guestOS在使用这个设备的DMA能力时不会访问到不该访问的地方。那谁在什么时候去配置的SMMU呢?本文主要就是分析了QEMU + KVM方面的代码得到的一点启示,和大家一起分享(时间、能力有限,如果讲的不对的对方还请指正)。阅读本文前,需要有基本的arm virtualization概念,知道SMMU,VFIO等基本知识,知道虚拟化中所谓的IPA, HPA等概念

 

QEMU对于IO 直通的实现

QEMU+KVM在实现直通时, 配置给guest OS的虚拟硬件环境并没有SMMU,换句话说guest OS根本感知不到SMMU的存在,所以 guest OS根本不需要配置SMMU页表,也就不存在hypervisor截获了。关键问题就来了,guest OS 中使用的IPA是怎么被SMMU转换为HPA的(这里只是说明SMMU对于地址的转换,MMU的转换机制有一些不一样)?

 

QEMU中SMMU实现IPA到HPA的方法

假设真实的硬件环境如下图,同时假设QEMU模拟出来的guest 环境是0 -- 2GB memory(GPA, 也叫IPA)。 QEMU在使能这个Guest 模拟环境之前,会调用mmap(  )向kernel 锁定(kernel中叫pin)真实的2GB物理内存。简单代码描述是hva = mmap( 2GB ),hva就是QEMU这个user mode APP得到的虚拟地址; mmap( )调用到kernel时真正锁定(pin)的地址假设是【1GB—3GB】,这个地址也叫HPA,也即真实的物理地址。注意这个时候,物理地址只是Pin住,并没有固定分配给了谁来使用。现在QEMU知道了Guest 虚拟地址环境是0 – 2GB(IPA),可以映射的物理地址范围是[1GB –3GB] (HPA)。 QEMU就直接调用了VFIO框架中的配置SMMU的IOCTL接口,将IPA---》HPA这个映射关系直接写入了SMMU stage 1 CD页表描述中,也 就是说QEMU一上来就直接把2GB的地址空间全部映射好了。GUEST OS中的DMA操作所用到的IPA会直接被SMMU转换到HPA。同时HPA都是kernel所管理的,保证了guest OS中使用DMA的安全。

整个流程说明(没有验证过,请保持谨慎阅读):

  1. QEMU APP为了模拟一个2GB的虚拟硬件环境,使用mmap(2GB) 调用让kernel 锁定了2GB的物理地址空间(HPA),假设kernel返回的地址值是1GB  – 3GB
  2. QEMU 调用VFIO接口配置SMMU 页表的映射 [0 –2GB](IPA)  --》 [1GB --- 3GB ](HPA), 再次说明这里的HPA物理地址只是被pin住了,并没有真正被谁所使用
  3. QEMU + KVM启动了模拟的虚拟机,Guest OS driver尝试去配置设备DMA,比如driver 调用dma_alloc( )来申请Guest OS中的IPA(这种DMA类的API会同时返回虚拟地址VA和它所认为的物理地址GPA)
  4. 尝试使用这个IPA地址时,会造成MMU page fault(不是SMMU),hypervisor 处理这个page fault,将这个IPA对应的物理地址HPA(之前pin住的)真正的使用起来。
  5. Guest OS driver启动设备DMA时,由于之前dma_alloc( )使用的IPA已经被SMMU映射到HPA了,IO 直通完成。

 

以上QEMU只是默认实现了Stage 1的SMMU直通操作,stage 2没有去做。

如果期望实现stage 1 + stage 2,也就是说在guest OS里面也要有机会去配置SMMU,我觉得就需要QEMU去模拟一个SMMU设备,然后guest OS在配置模拟的SMMU时,hypervisor截获这类操作,再去配置SMMU stage1, stage2 页表

 

参考链接(强烈推荐)

https://www.cnblogs.com/yi-mu-xi/p/12370626.html

http://element-ui.cn/news/show-44900.aspx

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,这是一个关于QEMU虚拟机的配置问题。具体来说,这个问题涉及到如何在x86_64主机上为x86_64 QEMU域配置CPU模式为“passthrough”。 为了解决这个问题,您需要按照以下步骤进行操作: 1. 确保您的主机支持Intel VT-x或AMD-V虚拟化技术,并且已经启用了这些技术。 2. 安装QEMU和相关的虚拟化软件包。您可以使用以下命令在Ubuntu上安装它们: ```shell sudo apt-get install qemu-kvm libvirt-bin virtinst bridge-utils cpu-checker ``` 3. 检查您的CPU是否支持虚拟化,并且已经启用了虚拟化支持。您可以使用以下命令检查: ```shell kvm-ok ``` 如果输出结果为“INFO: /dev/kvm exists”和“KVM acceleration can be used”,则表示您的CPU支持虚拟化,并且已经启用了虚拟化支持。 4. 创建一个QEMU域,并将CPU模式设置为“passthrough”。您可以使用以下命令创建一个名为“vm1”的QEMU域,并将CPU模式设置为“passthrough”: ```shell virt-install \ --name vm1 \ --ram 2048 \ --disk path=/var/lib/libvirt/images/vm1.img,size=20 \ --vcpus=2 \ --cpu host-passthrough \ --cdrom /path/to/iso \ --os-type linux \ --os-variant ubuntu18.04 \ --network bridge=br0 \ --graphics vnc,listen=0.0.0.0 ``` 在这个命令中,您需要将“/path/to/iso”替换为您要安装的操作系统的ISO文件的路径。此外,您还需要将“br0”替换为您要使用的网络桥接的名称。 至此,您已经成功地为x86_64 QEMU域配置了CPU模式为“passthrough”。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值