实现一个基于主存的虚拟块设备驱动程序_虚拟化技术 - I/O虚拟化 [二]

8507e7a7bd7c86abbfdd16a00778f919.png

上文介绍了无需VM exit(参考这篇文章),性能优良,但不利于实现设备共享和迁移的device passthrough(I/O透传)机制,本文将介绍I/O虚拟化的另一种实现方式。

Device Emulation

前面的文章提到,直接基于bare-metal的VMM分为两种,一种是由加入了虚拟化功能的操作系统组成的hypervisor模型,一种是像Xen和Acrn这种VMM层相对精简,主要负责CPU管理和内存管理的混合模型。

在hypervisor模型中,VMM直接就可以提供各种外设驱动,因此实现对guest VM所访问设备的模拟是很方便的。对于混合模型,设备模拟的方法就要稍微复杂一些。在混合模型中,guest VM访问设备的请求依然是会被VMM“截获”,根据I/O编址类型的不同,截获的方法也不一样。

对于I/O单独编址的PMIO(Port Mapped I/O),是使用in/out, ins/outs指令来读写的,所以只需要将这几个指令设定为会产生VM exit的敏感指令就可以了。对于和memory统一编址的MMIO(Memory Maped I/O),如果不为其使用的I/O地址设置对应的页表项,那么在访问这些地址的时候势必会产生page fault,这样的I/O访问也可以被VMM成功截获。

885c102f936031af68ad9fb84614d6c3.png

如果是一些简单的外设,比如RTC(参考这篇文章),VMM只需要读取一下现在硬件RTC的时间信息,返回给guest VM就可以了。如果是比较复杂的外设,VMM中没有相应的驱动,那么它就会把这个请求转发给一个拥有该设备驱动程序的guest VM,在Xen中,承担这个角色的VM是Dom0,其他的guest VM则是DomU,分别对应Acrn中的SOS(Service OS)和UOS(User OS)。

3cc8af00175f0062b5f1587615b4f39e.png

上图描述的是Acrn hypervisor中I/O处理的流程,当UOS发出访问I/O的请求触发VM exit后,VMM将解析产生VM exit的原因,并判断这个I/O请求是不是自己能提供驱动服务的,如果是(图的左下部分),就直接调用对应的I/O handler处理,如果不是(图的右下部分),就提交一个I/O request给SOS。

由SOS为UOS提供设备的驱动服务,就相当于实现了对UOS所使用I/O的模拟。在这个过程中,VMM只是起了一个中间调度的作用,并不直接参与驱动数据的传输,用通信的数据来说就是,VMM负责的是"control plane",而"data plane"则留给了SOS和UOS自己去实现。

SOS和UOS之间关于驱动数据的交互可以有很多种方式,目前最常用的一种方式是virtio。Virtio最早由Rusty Russell于2007年在IBM工作期间开发,之后迅速成为KVM等主流虚拟化方案中默认的I/O虚拟化机制。

还是以Acrn为例,在virtio模型中,UOS为驱动数据的交互提供的接口被称为Frontend virtio driver (FE),FE只需要负责建立共享缓冲区,并产生I/O请求即可。SOS中提供的驱动交互接口则被称为Backend virtio driver (BE),BE会接收VMM转发的来自FE的请求,并交给SOS中的设备驱动程序处理。

当SOS中的设备驱动程序处理完成了这一请求,BE将通过VMM告知对接的FE。BE和FE是一一对应的关系,共享同一个硬件设备的多个UOS会拥有独立的FE, BE实例对,并维护各自的状态信息。

70af56bbed5f8376e72c56513f3ff2ff.png

BE和FE之间是通过一个被称为virtqueue的结构来传递驱动数据的。一个驱动程序可以使用一个或多个virtqueue,其数量取决于具体的需求,比如virtio网络驱动程序通常使用两个virtqueue(一个用于接收,另一个用于发送),而virtio块驱动程序则通常只使用一个virtqueue。

virtqueue由ringbuffer和descriptor机制组成,本质上是一块基于授权机制的共享内存,由请求服务的FE创建。作为一个standard,同时考虑到扩展性,它会包含一些feature bits,需要BE和FE之间就此进行negotiate。

一个guest VM可以申明它所拥有的哪些内存页可以被其他VM共享,另一个VM可以将这些内存页映射到自己的地址空间中。每个VM都有一个授权表,来控制其他VM访问自己所拥有的共享页的权限,授权表的每个entry定义了对于当前VM的某一内存页,其他的某个VM具有哪些访问权限(读/写)。

这里介绍的device emlution需要修改guest OS的代码,将普通的设备驱动程序转换为FE和BE的形式,因此属于I/O para virtualization(I/O半/类/准虚拟化),而对guest OS完全透明的模拟方式则属于I/O full virtualization(I/O全虚拟化)。

要想使用I/O全虚拟化,必须从设备硬件的最底层开始模拟,尽管这样可以模拟得很彻底,以至于guest OS完全不会感知到自己是运行在一个模拟环境中,但它的效率相对较低。结合上文讲的I/O透传,三者的实现原理分别大概是这样的:

8a7ee8e9c7c2aef773b89f68c28fdb9f.png

原创文章,转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值