kvm io设备管理架构采用IO总线方式,涉及到guest os陷入到hypervisor进行IO的设备都挂载在总线上。kvm提供四种总线:
- mmio(memory map input/output)
- pio(port input/output)
- virtio
- fast mmio
mmio和pio是常见的访问硬件设备寄存器的两种方式,所以mmio和pio总线是用来挂载支持硬件虚拟化的硬件设备,比如GICV3就是挂载在mmio总线上的。virtio总线则是挂载支持并实现相关virtio标准的设备,比如virtio-net、virtio-console、virtio-block等等。
以gicv3为例,kvm实现了三种结构体以支持IO。分别是:
- struct kvm_io_bus
- struct kvm_io_device
- struct vgic_io_device
其中vgic_io_device是gicv3设备私有的,不同的设备有着不同的结构体。本文第一部分简介读写gicv3的整个流程,第二部分介绍io总线和io设备,最后介绍vgic设备的IO。
1. kvm io总线读写流程
guest os访问gicv3的distributor寄存器会触发同步异常。相应的guest os访问的数据地址会保存在far_el2寄存器中。假设改地址是addr,那么kvm把addr交给io总线去处理,处理流程如下:

将地址信息和读/写信息传给io总线,io总线通过addr匹配找到相应的kvm_io_device,然后执行read/write。通过container_of函数找到私有的vgic_io_device,vgic_io_device将guest os可以修改的寄存器划分为不同的region。通过偏移地址(addr-gic_base_addr)和region的地址进行比较找到其所在的region,最后执行相应的读写操作。
2. io总线和io设备
kvm_io_bus结构体中dev_count是统计当前设备总数(一个vm的设备);ioeventfd_count是统计当前io的次数;range则指示一个设备的所处地址范围,以便于io总线根据地址找到相应的设备。
struct kvm_io_bus {
int dev_count;
int ioeventfd_count;
struct kvm_io_range range[];
};
struct kvm_io_range {
gpa_t addr;
int len;
struct kvm_io_device *dev;
};
io总线的api如下:
int kvm_io_bus_write(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr,
int len, const void *val);
int kvm_io_bus_write_cookie(struct kvm_vcpu *vcpu, enu

本文详细介绍了kvm的IO设备管理架构,包括IO总线读写流程、IO总线和设备的结构以及vgic IO设备。kvm通过mmio、pio、virtio和fast mmio总线挂载各种设备,如GICV3。在读写流程中,当guest OS访问硬件设备时,异常处理会通过io总线找到对应的kvm_io_device。kvm_io_bus统计设备和IO次数,kvm_io_device提供统一的读写接口。vgic_io_device则为gicv3设备提供了专用的结构和读写机制。
最低0.47元/天 解锁文章
:IO设备管理架构&spm=1001.2101.3001.5002&articleId=102572425&d=1&t=3&u=e5796df03b4b4e77b8c71fe0babd7adf)
2144

被折叠的 条评论
为什么被折叠?



