KVM

kernel-based Virtual Machine的简称,是一个开源的系统虚拟化模块,自Linux 2.6.20之后集成在Linux的各个主要发行版本中。它使用Linux自身的调度器进行管理,所以相对于Xen,其核心源码很少。KVM目前已成为学术界的主流VMM之一。 KVM的虚拟化需要硬件支持(如Intel VT技术或者AMD V技术)。是基于硬件的完全虚拟化。而Xen早期则是基于软件模拟的Para-Virtualization,新版本则是基于硬件支持的完全虚拟化。

Intel VT/AMD-V

Intel VT和AMD-V是intel和amd支持x86虚拟化技术的相应cpu指令集。

Intel VT即Intel公司的Virtualization Technology虚拟化技术。为解决纯软件虚拟化解决方案在可靠性、安全性和性能上的不足,Intel在它的硬件产品上引入了Intel VT(Virtualization Technology,虚拟化技术)。2005年8月,Intel首次公布了针对硬件辅助虚拟化的Vanderpool(Intel VT虚拟化技术的前身)技术细节。Vanderpool技术通过增加新的指令,使得Intel处理器支持硬件虚拟化。2005年11月,Intel宣布,虚拟化技术Vanderpool改成VT,被Acer和联想应用在其基于Intel Pentium 4的PC上。
AMD-V技术(AMD虚拟化技术)是对x86处理器系统架构的一组硬件扩展和硬件辅助虚拟化技术,可以简化纯软件的虚拟化解决方案,改进VMM(虚拟机监视器)的设计,更充分地利用硬件资源,提高服务器和数据中心的虚拟化效率。
Intel VT和AMD’s AMD-V是一套与支持该技术的虚拟机监视器相结合的硬件增强特性(指令集扩展)。kvm可在原始硬件速度下通过运行完全隔离的虚拟机来执行任务。

KVM架构

kvm基本结构有2个部分构成:
kvm 驱动,现在已经是linux kernel的一个模块了。其主要负责虚拟机的创建,虚拟内存的分配,VCPU寄存器的读写以及VCPU的运行。
另一个是Qemu,用于模拟虚拟机的用户空间组件,提供I/O设备模型,访问外设的途径。
image.png
kvm基本结构如上图。kvm已经是内核模块,被看作是一个标准的linux 字符集设备(/dev/kvm)。Qemu通过libkvm应用程序接口,用fd通过ioctl向设备驱动来发送创建,运行虚拟机命令。设备驱动kvm就会来解析命令(kvm_dev_ioctl函数在kvm_main.c文件中
image.png
kvm 模块让Linux主机成为一个虚拟机监视器(VMM),并且在原有的Linux两种执行模式基础上,新增加了客户模式,客户模式拥有自己的内核模式和用户模式。在虚拟机运行时,三种模式的工作各为:
客户模式: 执行非I/O的客户代码,虚拟机运行在这个模式下。
用户模式:代表用户执行I/O指令,qemu运行在这个模式下。
内核模式:实现客户模式的切换,处理因为I/O或者其他指令引起的从客户模式退出(VM_EXIT)。kvm 模块工作在这个模式下。
在kvm的模型中,每一个Guest OS都是作为一个标准的linux进程,都可以使用linux进程管理命令管理。
这里假如qemu通过ioctl发出KVM_CREATE_VM 指令,创建了一个VM后,qemu需要需要发送一些命令给VM,如KVM_CREATE_VCPU。这些命令当然也是通过ioctl发送的,用户程序中用ioctl发送KVM_CREATE_VM得到的返回值就是新创建的VM对应的fd(kvm_vm),fd是创建的指向特定虚拟机实例的文件描述符,之后利用这个fd发送命令给VM进行访问控制。kvm解析这些命令的函数是kvm_vm_ioctl。

kvm工作原理

kvm基本工作原理概述:
用户模式的qemu利用libkvm通过ioctl进入内核模式,kvm模块未虚拟机创建虚拟内存,虚拟CPU后执行VMLAUCH指令进入客户模式。加载Guest OS并执行。如果Guest OS 发生外部中断或者影子页表缺页之类的情况,会暂停Guest OS的执行,退出客户模式出行异常处理,之后重新进入客户模式,执行客户代码。如果发生I/O事件或者信号队列中有信号到达,就会进入用户模式处理。(如下图)

image.png