virtio:半虚拟化驱动
优点:环形缓冲区实现前端多次请求后端批量处理,有较好的IO性能,提高了信息交换的效率
限制:需要宿主机内核和客户机都支持virtio并按照virtio的规定格式进行数据传输

PCI device assignment :允许将宿主机中的物理PCI(或PCI-E) 设备直接分配给客户机完全使用,其中Intel定义的I/O虚拟化技术规范为“Intel®Virtualization Technology for Directed I/O”(VT-d) , 而AMD的I/O虚拟化技术规范为“AMD-Vi”(也叫作IOMMU) 。
VT-d环境配置:1.对硬件和宿主机内核进行配置;2.在宿主机中使用vfio_pci内核模块对需要分配给客户机的设备进行隐藏,从而让宿主机和未被分配该设备的客户机都无法使用该设备, 达到隔离和安全使用的目的;3.通过QEMU命令行分配设备给客户机 ;4.关闭客户机后需要在宿主机回复被隐藏的设备
SR-IOV(Single Root I/O Virtualization and Sharing) :实现多个虚拟机能够共享同一个物理设备的资源, 并且达到设备直接分配的性能,其中经常被使用到的功能:
Physical Function(PF, 物理功能) :PF就是一个普通的PCI-e设备(带有SR-IOV功能) , 可以放在宿主机中配置和管理其他VF, 它本身也可以作为一个完整独立的功能使用
Virtual Function(VF, 虚拟功能) : 拥有最小化的配置资源。 VF通过PF的配置之后, 可以分配到客户机中作为独立功能使用。 SR-IOV架构设计的目的是允许一个设备支持多个VF,同时也尽量减小每个VF的硬件成本。 每个VF都有自己独立的配置空间和完整的BAR(Base Address Register, 基址寄存器) 每个VF在同一个时刻只能被分配到一个客户机中, 因为VF需要真正的硬件资源

可以通过“lspci-v-s$BDF”的命令来查看网卡PCI信息的“Capabilities”项目, 以确定设备是否具备SR-IOV功能
在宿主机系统中可以用“modinfo”命令来查看某个驱动的信息, 其中包括驱动模块的可用参数,eg. modinfo igb
通过sysfs中开放出来的设备的信息, 我们可以知道具体某款网卡设备到底支持多少VF(sriov_totalvfs) , 以及当前有多少VF(sriov_numvfs)
使用SR-IOV常见问题:
使用Linux 3.9版本作为宿主机的内核, 在使用igb或ixgbe驱动的网卡(如: Intel 82576、 I350、 82599等) 的VF做SR-IOV时, 可能会在客户机中看到igbvf或ixgbevf网卡的 MAC地址全为零(即: 00: 00: 00: 00: 00: 00) 可通过两种方法解决:
1)在分配VF给客户机之前, 在宿主机中用ip命令来设置需要使用的VF的MAC地址 ip link set eno2 vf 0 mac 52:54:00:56:78:9a
2)可以升级客户机系统的内核或VF驱动程序
热插拔(hot plugging):即“带电插拔”, 指可以在计算机运行时(不关闭电源) 插上或拔除硬件。 热插拔功能只需要在QEMU monitor中使用device_add和device_del完成。
PCI设备热插拔/SATA硬盘控制器的热插拔
e.g. 将一个BDF为02: 00.0的PCI设备动态添加到客户机中(设置id为mydevice) , 在monitor中的命令如下:
device_add vfio-pci,host=02:00.0,id=mydevice
将一个设备(id为mydevice) 从客户机中动态移除 :device_del mydevice
可以通过“info pci”命令在QEMU monitor中查看到当前的客户机中的PCI设备及其id值
USB设备热插拔:
CPU的热插拔
(qemu) cpu-add 4内存的热插拔
内核社区将内存的热插拔分为两步骤: 物理内存热插拔(Physical Memory Hotplug)和逻辑内存热插拔(Logical Memory Hotplug)
内存热插拔的过程是: 物理内存热插入→逻辑内存热添加→逻辑内存热删除→物理内存热拔出。
QEMU/KVM中对内存热插拔的支持主要是通过对dimm设备的热插拔的支持来实现的, 对客户机的内核来说, 就相当于物理地插入和拔出内存条一样。 dimm设备的热插拔与PCI设备一样, 过“device_add”来完成,然而,device_add(或者-device参数) 是指定前端设备, 也就是QEMU模拟出来的客户机看到的设备, 它的实体是要靠一个对应的后端设备来实现的。 所以, 在device_add之前, 需要先要通过object_add来定义这个后端设备, 它的名字叫“memory-backend-ram”
(qemu) object_add memory-backend-ram,id=mem1,size=1G (qemu) device_add pc-dimm,id=dimm1,memdev=mem1
热拔出这根虚拟内存条, 注意要与跟热插入反序操作: 在QEMU monitor中先删除dimm, 再删除object
(qemu) device_del dimm1 (qemu) object_del mem1
磁盘的热插拔
在客户机中的磁盘一般在宿主机中表现为raw/qcow2等格式的一个文件 ,因此需要先创建一个对应的文件
启动一个客户机
[root@kvm-host ~]# qemu-system-x86_64 -enable-kvm -smp 4 -m 8G rhel7.img
在宿主机上用qemu-img命令给创建一个10GB大小的qcow2文件`
`[root@kvm-host ~]# qemu-img create -f qcow2 hotplug-10G.img 10G
在QEMU monitor中, 用drive_add命令添加一个基于前面创建的qcow2文件的磁盘驱动器, 再用device_add命令将磁盘驱动器以virtio-blk-pci设备的形式添加到客户机中。 这样就实现了给客户机热插入了一块磁盘。
(qemu) drive_add 0 file=/root/hotplug-10G.img,format=qcow2,id= drive-disk1,if=none OK #这个OK是命令执行成功后的输出信息 (qemu) device_add virtio-blk-pci,drive=drive-disk1,id=disk1
当客户机不在使用磁盘时可以使用deveice_del将添加的磁盘从客户机中拔出
(qemu) device_del disk1
网卡接口的热插拔
在QEMU monitor中, 用netdev_add命令添加宿主机上一个网卡设备, 再用device_add 命令将网卡设备以virtio-net-pci设备的形式添加到客户机中。 这样就实现了给客户机热插入了一块网卡。
(qemu) netdev_add user,id=net1 \# 这里设备类型选择了最简单的user模式的网卡, 还有其他tap、 bridge、 vhost-user等可供选择 (qemu) device_add virtio-net-pci,netdev=net1,id=nic1,mac=52:54:00:12:34:56
使用device_del命令(添加上device_add时的设备ID) 即可将添
加的网卡从客户机中拔出。
(qemu) device_del nic1