• 虚拟化技术 - I/O虚拟化 [二]


    上文介绍了无需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成功截获。

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

    上图描述的是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虚拟化机制。

    学习地址: Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家-学习视频教程-腾讯课堂
    更多DPDK相关学习资料有需要的可以自行报名学习,免费订阅,久学习,或点击这里加qun免费
    领取,关注我持续更新哦! ! 

    还是以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实例对,并维护各自的状态信息。

    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透传,三者的实现原理分别大概是这样的:

    原文链接:”https://zhuanlan.zhihu.com/p/75649223

  • 相关阅读:
    如何查看网站的https的数字证书
    mysql面试题31:一条SQL语句在MySQL中如何执行的
    Linux 安装 miniconda
    008. 子集
    pytest parametrize多参数接口请求及展示中文响应数据
    CentOS 7安装Redis+Springboot整合Redis
    echarts关于一次性绘制多个饼图 (基于vue3)
    申博|2024国内985院校申博时间参考
    ABP微服务系列学习-搭建自己的微服务结构(一)
    这是什么代码 你能看懂吗
  • 原文地址:https://blog.csdn.net/lingshengxiyou/article/details/127753967