VIRTIO PCI 设备

news/2024/11/22 12:25:23/

Virtio的代码主要分两个部分:QEMU和内核驱动程序。Virtio设备的模拟就是通过QEMU完成的,QEMU代码在虚拟机启动之前,创建虚拟设备。虚拟机启动后检测到设备,调用内核的virtio设备驱动程序来加载这个virtio设备。

对于KVM虚拟机,都是通过QEMU这个用户空间程序创建的,每个KVM虚拟机都是一个QEMU进程,虚拟机的virtio设备是QEMU进程模拟的,虚拟机的内存也是从QEMU进程的地址空间内分配的。

VRING是由虚拟机virtio设备驱动创建的用于数据传输的共享内存,QEMU进程通过这块共享内存获取前端设备递交的IO请求。

如下图所示,虚拟机IO请求的整个流程:

1) 虚拟机产生的IO请求会被前端的virtio设备接收,并存放在virtio设备散列表scatterlist里;

2) Virtio设备的virtqueue提供add_buf将散列表中的数据映射至前后端数据共享区域Vring中;

3) Virtqueue通过kick函数来通知后端qemu进程。Kick通过写pci配置空间的寄存器产生kvm_exit;

4) Qemu端注册ioport_write/read函数监听PCI配置空间的改变,获取前端的通知消息;

5) Qemu端维护的virtqueue队列从数据共享区vring中获取数据

6)  Qemu将数据封装成virtioreq;

7)  Qemu进程将请求发送至硬件层。

前后端主要通过PCI配置空间的寄存器完成前后端的通信,而IO请求的数据地址则存在vring中,并通过共享vring这个区域来实现IO请求数据的共享。

从上图中可以看到,Virtio设备的驱动分为前端与后端:前端是虚拟机的设备驱动程序,后端是host上的QEMU用户态程序。为了实现虚拟机中的IO请求从前端设备驱动传递到后端QEMU进程中,Virtio框架提供了两个核心机制:前后端消息通知机制和数据共享机制。

消息通知机制,前端驱动设备产生IO请求后,可以通知后端QEMU进程去获取这些IO请求,递交给硬件。

数据共享机制,前端驱动设备在虚拟机内申请一块内存区域,将这个内存区域共享给后端QEMU进程,前端的IO请求数据就放入这块共享内存区域,QEMU接收到通知消息后,直接从共享内存取数据。由于KVM虚拟机就是一个QEMU进程,虚拟机的内存都是QEMU申请和分配的,属于QEMU进程的线性地址的一部分,因此虚拟机只需将这块内存共享区域的地址传递给QEMU进程,QEMU就能直接从共享区域存取数据。

PCI配置空间

由整体流程图可知,guest和host交互传送信息的两个重要结构分别的PCI config和vring,本节重点分析实现消息通知机制的PCI配置空间。

虚拟机是如何获取PCI配置空间的?

首先,我们为虚拟机创建的virtio设备都是PCI设备,它们挂在PCI总线上,遵循通用PCI设备的发现、挂载等机制。

当虚拟机启动发现virtio PCI设备时,只有配置空间可以被访问,配置空间内保存着该设备工作所需的信息,如厂家、功能、资源要求等,通过对这个空间信息的读取,完成对PCI设备的配置。同时配置空间上有一块存储器空间,里面包含了一些寄存器和IO空间。

前后端的通知消息就是写在这些存储空间的寄存器,virtio会为它的PCI设备注册一个PCI BAR来访问这块寄存器空间。配置空间如下图所示:

虚拟机系统在启动过程中在PCI总线上发现virtio-pci设备,就会调用virtio-pci的probe函数。该函数会将PCI配置空间上的寄存器映射到内存空间,并将这个地址赋值给virtio_pci_device的 ioaddr 变量。之后要对PCI配置空间上的寄存器操作时,只需要ioaddr+偏移量。

pci_iomap函数完成PCI BAR的映射,第一个参数是pci设备的指针,第二个参数指定我们要映射的是0号BAR,第三个参数确定要映射的BAR空间多大,当第三个参数为0时,就将整个BAR空间都映射到内存空间上。VirtioPCI设备的0号BAR指向的就是配置空间的寄存器空间,也就是配置空间上用于消息通知的寄存器。

通过pci_iomap之后,我们就可以像操作普通内存一样(调用ioread和iowrite)来读写pci硬件设备上的寄存器。

虚拟机是如何操作这个配置空间的?

1. kick
当前端设备的驱动程序需要通知后端QEMU程序执行某些操作的时候,就会调用kcik函数,来触发读写PCI配置空间寄存器的动作。
2. 读写PCI寄存器
ioread/iowrite实现了对配置空间寄存器的读写,例如:

vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY 表示写notify这个寄存器,位置如图 2 1所示。

ioread读取QEMU端在配置空间寄存器上写下的值。
在读写PCI设备配置空间的操作中,我们可以看到都是通过iodaar+偏移,来指向某个寄存器,ioaddr这个变量是我们在Virtio-pci设备初始化的时候对它赋值,并指向配置空间寄存器的首地址位置。

QEMU如何感知虚拟机的操作的?

虚拟机内调用kick函数实现通知之后,会产生KVM_EXIT。Host端的kvm模块捕获到这个EXIT之后,根据它退出的原因来做处理。如果是一个IO_EXIT,kvm会将这个退出交给用户态的QEMU程序来完成IO操作。
QEMU为kvm虚拟机模拟了virtio设备,因此后端的virtio-pci设备也是在QEMU进程中模拟生成的。QEMU对模拟的PCI设备的配置空间注册了回调函数,当虚拟机产生IO_EXIT,就调用这些函数来处理事件。

这里只分析legacy模式,其实在初始化阶段guest会判断设备是否支持modern模式,如果支持,回调函数会发生一些变化。挖个坑有时间以后补。
1. 监听PCI寄存器
virtio_ioport_write/read就是QEMU进程监听PCI配置空间上寄存器消息的函数,针对前端iowrite/ioread读写了哪个PCI寄存器,来决定下一步操作:

2. 监听函数的注册
PCI寄存器的这些监听函数,都是在QEMU为虚拟机创建虚拟设备的时候注册。

QEMU先为虚拟机的virtio-pci设备创建PCI配置空间,配置空间内包含了设备的一些基本信息;在配置空间的存储空间位置注册了一个PCI BAR,并为这个BAR注册了回调函数监听寄存器的改变。

这部分代码是初始化配置空间的基本信息。  

给PCI设备注册了PCI BAR,指定起始地址为PCI_BASE_ADDRESS_SPACE_IO(即PCI配置空间中存储空间到配置空间首地址的偏移值);

指定这个BAR的大小为size,回调函数为virtio_pci_config_ops中的读写函数。

 这里的read/write最终都会调用virtio_ioport_write(virtio_ioport_write处理前端写寄存器时触发的事件,virtio_ioport_read处理前端要读寄存器时触发的事件)来统一的管理。


http://www.ppmy.cn/news/507169.html

相关文章

【我所認知的BIOS】—PCI 的中斷(PIC下)

【我所認知的BIOS】—>PCI 的中斷(PIC下) LightSeed 2009-5-13 1、PCI中斷概述 注:整篇都是討論在PIC(8259)下的中斷過程。當PCI設備插到主板上後(本來南橋裏含有的當然就不用插啦&…

2D降噪3D降噪(NR:Noise Reduce)

2D降噪:只在2维空间域上进行降噪处理。基本方法:对一个像素将其与周围像素平均,平均后噪声降低,但缺点是会造成画面模糊,特别是物体边缘部分。因此对这种算法的改进主要是进行边缘检测,边缘部分的像素不用来…

语音增强与降噪

目前,语音信号处理已经从传统的信号处理发展到深度学习方法,基本上所有的问题都有了对应的深度学习方法,可以说深度学习无孔不入、遍地开花。 之所以有需求,还是因为问题的存在。特别是在直播中,噪声的问题更为严重。…

信号降噪方法

傅里叶变换 只能获取一段信号总体上包含哪些频率的成分,但是对各成分出现的时刻并无所知。“对非平稳过程,傅里叶变换有局限性”。 短时傅里叶变换(Short-time Fourier Transform, STFT) 把整个时域过程分解成无数个等长的小过…

降噪耳机简介及降噪技术-ANC、ENC、DSP、CVC

一、降噪技术 降噪是指利用某种方法达到降低噪音。 目前降噪技术有两种分别为:主动降噪和被动降噪。 1、物理背景 (1)噪声的本质:是频率、强弱变化无规律、杂乱无章的机械波。机械波又可以按人耳的识别程度分为一下几个部分&am…

消灭非稳态噪音的利器 - AI 降噪

一、轻量级神经网络降噪——ZegoAIDenoise 当下,用户在进行音频通话时常常置身于各种不同的场景中,嘈杂的背景声音以及非稳态噪音往往会对通话产生干扰,其中非稳态噪音是指在时间分布上不连续,并有其形态特征的噪声,是…

堆叠降噪自动编码器 Stacked Denoising Auto Encoder(SDAE)

原文链接 自动编码器(Auto-Encoder,AE) 自动编码器(Auto-Encoder,AE)自编码器(autoencoder)是神经网络的一种,经过训练后能尝试将输入复制到输出。自编码器内部有一个隐…

塞班手机刷linux,14年前的E680携带linux系统把诺基亚塞班系统按在地板摩擦

原标题:14年前的E680携带linux系统把诺基亚塞班系统按在地板摩擦 在android系统和IOS系统没有大展手脚的时候,智能手机的操作系统还是被诺基亚的塞班系统占领,除此之外还有为微软的windows mobile系统等都活跃在智能手机的操作系统市场。摩托…