searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Virtio协议概述

2025-04-27 10:30:39
1
0

virtio详细介绍

virtio分为driver和device,driver部分运行于guest操作系统中,device部分运行于hypervisor中,driver和device是生产者和消费者模式动作,driver生产内存,device消费内存。不同virtio版本之间是互相兼容的,driver和device版本不同也可以互相运转。

 

 

协议简介

virtio协议标准最早由IBM提出,virtio作为一套标准协议现在有专门的技术委员会进行管理, 开发者可以向技术委员会提供新的virtio设备提案(RFC),经过委员会通过后可以增加新的virtio设备类型。

组成一个virtio设备的四要素包括: 设备状态域,feature bits,设备配置空间,一个或者多个virtqueue。 其中设备状态域包含6种状态:

  • ACKNOWLEDGE(1):GuestOS发现了这个设备,并且认为这是一个有效的virtio设备;
  • DRIVER (2) : GuestOS知道该如何驱动这个设备;
  • FAILED (128) : GuestOS无法正常驱动这个设备,Something is wriong;
  • FEATURES_OK (8) : GuestOS认识所有的feature,并且feature协商一完成;
  • DRIVER_OK (4) : 驱动load完成,设备可以投入使用了;
  • DEVICE_NEEDS_RESET (64) :设备触发了错误,需要重置才能继续工作。

feature bits用来标志设备支持那个特性,其中bit0-bit23是特定设备可以使用的feature bits, bit24-bit37预给队列和feature协商机制,bit38以上保留给未来其他用途。 例如:对于virtio-net设备而言,feature bit0表示网卡设备支持checksum校验。 VIRTIO_F_VERSION_1这个feature bit用来表示设备是否支持virtio 1.0 spec标准。

在virtio协议中,所有的设备都使用virtqueue来进行数据的传输。 每个设备可以有0个或者多个virtqueue,每个virtqueue占用2个或者更多个4K的物理页。 virtqueue有Split VirtqueuesPacked Virtqueues两种模式, 在Split virtqueues模式下virtqueue被分成若干个部分, 每个部分都是前端驱动或者后端单向可写的(不能两端同时写)。 每个virtqueue都有一个16bit的queue size参数,表示队列的总长度。 每个virtqueue由3个部分组成:

	+-------------------+--------------------------------+-----------------------+
	| Descriptor Table  |   Available Ring  (padding)    |       Used Ring       |
	+-------------------+--------------------------------+-----------------------+
  • Descriptor Table:存放IO传输请求信息;
  • Available Ring:记录了Descriptor Table表中的哪些项被更新了,前端Driver可写但后端只读;
  • Used Ring:记录Descriptor Table表中哪些请求已经被提交到硬件,前端Driver只读但后端可写。

整个virtio协议中设备IO请求的工作机制可以简单地概括为:

  1. 前端驱动将IO请求放到Descriptor Table中,然后将索引更新到Available Ring中,然后kick后端去取数据;
  2. 后端取出IO请求进行处理,然后结果刷新到Descriptor Table中再更新Using Ring,然后发送中断notify前端。

从virtio协议可以了解到virtio设备支持3种设备呈现模式

  • Virtio Over PCI BUS,依旧遵循PCI规范,挂在到PCI总线上,作为virtio-pci设备呈现;
  • Virtio Over MMIO,部分不支持PCI协议的虚拟化平台可以使用这种工作模式,直接load到系统总线上;
  • Virtio Over Channel I/O:主要用在s390平台上,virtio-ccw使用这种基于channel I/O的机制。

 

virtio主要cap

对于新的virtio modern,协议将配置结构划分为5种:

/* Common configuration */ 
#define VIRTIO_PCI_CAP_COMMON_CFG        1 
/* Notifications */ 
#define VIRTIO_PCI_CAP_NOTIFY_CFG        2
/* ISR Status */ 
#define VIRTIO_PCI_CAP_ISR_CFG           3 
/* Device specific configuration */ 
#define VIRTIO_PCI_CAP_DEVICE_CFG        4 
/* PCI configuration access */ 
#define VIRTIO_PCI_CAP_PCI_CFG           5

以上的每种配置结构是直接映射到virtio设备的BAR空间内,那么如何指定每种配置结构的位置呢? 答案是通过PCI Capability list方式去指定,这和物理PCI设备是一样的,体现了virtio-pci的协议兼容性。

struct virtio_pci_cap { 
        u8 cap_vndr;    /* Generic PCI field: PCI_CAP_ID_VNDR */ 
        u8 cap_next;    /* Generic PCI field: next ptr. */ 
        u8 cap_len;     /* Generic PCI field: capability length */ 
        u8 cfg_type;    /* Identifies the structure. */ 
        u8 bar;         /* Where to find it. */ 
        u8 padding[3];  /* Pad to full dword. */ 
        le32 offset;    /* Offset within bar. */ 
        le32 length;    /* Length of the structure, in bytes. */ 
};

只是略微不同的是,virtio-pci的Capability有一个统一的结构, 其中cfg_type表示Cap的类型,bar表示这个配置结构被映射到的BAR空间号。 这样每个配置结构都可以通过BAR空间直接访问,或者通过PCI配置空间的VIRTIO_PCI_CAP_PCI_CFG域进行访问。 每个Cap的具体结构定义可以参考virtio spec 4.1.4.3小节。

0条评论
作者已关闭评论
c****g
3文章数
0粉丝数
c****g
3 文章 | 0 粉丝
c****g
3文章数
0粉丝数
c****g
3 文章 | 0 粉丝
原创

Virtio协议概述

2025-04-27 10:30:39
1
0

virtio详细介绍

virtio分为driver和device,driver部分运行于guest操作系统中,device部分运行于hypervisor中,driver和device是生产者和消费者模式动作,driver生产内存,device消费内存。不同virtio版本之间是互相兼容的,driver和device版本不同也可以互相运转。

 

 

协议简介

virtio协议标准最早由IBM提出,virtio作为一套标准协议现在有专门的技术委员会进行管理, 开发者可以向技术委员会提供新的virtio设备提案(RFC),经过委员会通过后可以增加新的virtio设备类型。

组成一个virtio设备的四要素包括: 设备状态域,feature bits,设备配置空间,一个或者多个virtqueue。 其中设备状态域包含6种状态:

  • ACKNOWLEDGE(1):GuestOS发现了这个设备,并且认为这是一个有效的virtio设备;
  • DRIVER (2) : GuestOS知道该如何驱动这个设备;
  • FAILED (128) : GuestOS无法正常驱动这个设备,Something is wriong;
  • FEATURES_OK (8) : GuestOS认识所有的feature,并且feature协商一完成;
  • DRIVER_OK (4) : 驱动load完成,设备可以投入使用了;
  • DEVICE_NEEDS_RESET (64) :设备触发了错误,需要重置才能继续工作。

feature bits用来标志设备支持那个特性,其中bit0-bit23是特定设备可以使用的feature bits, bit24-bit37预给队列和feature协商机制,bit38以上保留给未来其他用途。 例如:对于virtio-net设备而言,feature bit0表示网卡设备支持checksum校验。 VIRTIO_F_VERSION_1这个feature bit用来表示设备是否支持virtio 1.0 spec标准。

在virtio协议中,所有的设备都使用virtqueue来进行数据的传输。 每个设备可以有0个或者多个virtqueue,每个virtqueue占用2个或者更多个4K的物理页。 virtqueue有Split VirtqueuesPacked Virtqueues两种模式, 在Split virtqueues模式下virtqueue被分成若干个部分, 每个部分都是前端驱动或者后端单向可写的(不能两端同时写)。 每个virtqueue都有一个16bit的queue size参数,表示队列的总长度。 每个virtqueue由3个部分组成:

	+-------------------+--------------------------------+-----------------------+
	| Descriptor Table  |   Available Ring  (padding)    |       Used Ring       |
	+-------------------+--------------------------------+-----------------------+
  • Descriptor Table:存放IO传输请求信息;
  • Available Ring:记录了Descriptor Table表中的哪些项被更新了,前端Driver可写但后端只读;
  • Used Ring:记录Descriptor Table表中哪些请求已经被提交到硬件,前端Driver只读但后端可写。

整个virtio协议中设备IO请求的工作机制可以简单地概括为:

  1. 前端驱动将IO请求放到Descriptor Table中,然后将索引更新到Available Ring中,然后kick后端去取数据;
  2. 后端取出IO请求进行处理,然后结果刷新到Descriptor Table中再更新Using Ring,然后发送中断notify前端。

从virtio协议可以了解到virtio设备支持3种设备呈现模式

  • Virtio Over PCI BUS,依旧遵循PCI规范,挂在到PCI总线上,作为virtio-pci设备呈现;
  • Virtio Over MMIO,部分不支持PCI协议的虚拟化平台可以使用这种工作模式,直接load到系统总线上;
  • Virtio Over Channel I/O:主要用在s390平台上,virtio-ccw使用这种基于channel I/O的机制。

 

virtio主要cap

对于新的virtio modern,协议将配置结构划分为5种:

/* Common configuration */ 
#define VIRTIO_PCI_CAP_COMMON_CFG        1 
/* Notifications */ 
#define VIRTIO_PCI_CAP_NOTIFY_CFG        2
/* ISR Status */ 
#define VIRTIO_PCI_CAP_ISR_CFG           3 
/* Device specific configuration */ 
#define VIRTIO_PCI_CAP_DEVICE_CFG        4 
/* PCI configuration access */ 
#define VIRTIO_PCI_CAP_PCI_CFG           5

以上的每种配置结构是直接映射到virtio设备的BAR空间内,那么如何指定每种配置结构的位置呢? 答案是通过PCI Capability list方式去指定,这和物理PCI设备是一样的,体现了virtio-pci的协议兼容性。

struct virtio_pci_cap { 
        u8 cap_vndr;    /* Generic PCI field: PCI_CAP_ID_VNDR */ 
        u8 cap_next;    /* Generic PCI field: next ptr. */ 
        u8 cap_len;     /* Generic PCI field: capability length */ 
        u8 cfg_type;    /* Identifies the structure. */ 
        u8 bar;         /* Where to find it. */ 
        u8 padding[3];  /* Pad to full dword. */ 
        le32 offset;    /* Offset within bar. */ 
        le32 length;    /* Length of the structure, in bytes. */ 
};

只是略微不同的是,virtio-pci的Capability有一个统一的结构, 其中cfg_type表示Cap的类型,bar表示这个配置结构被映射到的BAR空间号。 这样每个配置结构都可以通过BAR空间直接访问,或者通过PCI配置空间的VIRTIO_PCI_CAP_PCI_CFG域进行访问。 每个Cap的具体结构定义可以参考virtio spec 4.1.4.3小节。

文章来自个人专栏
文章 | 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0