QEMU-KVM框架总结
kvm模块的加载
arch/x86/kvm/vmx/vmx.c
载入kvm模块时,调用顺序为module_init()
->vmx_init()
->kvm_init()
,所以kvm_init()
为核心函数
kvm模块加载完成后,在系统的/dev
目录下出现kvm
设备,用于外界与kvm交互
kvm模块向外界提供的ioctl分类
virt/kvm/kvm_main.c
分为3大类,大多都在kvm_main.c中实现,剩余一小部分在arch/x86/kvm/vmx/vmx.c
中.3类ioctl分别为设备、虚拟机、虚拟cpu级别
.3个层次逐级概念变小,虚拟机由设备层面的ioctl创建,而虚拟cpu由虚拟机级别的ioctl创建.
设备级别ioctl
以kvm_dev_ioctl
为前缀,负责以下通用
设备级别的ioctl功能的处理
其余设备级别的ioctl功能与架构
有关,因此在kvm_arch_dev_ioctl()
中实现.
虚拟机级别ioctl
以kvm_vm_ioctl
为前缀,负责以下通用
虚拟机级别的ioctl功能的处理
其余虚拟机级别的ioctl功能与架构
有关,因此在kvm_arch_vm_ioctl()
中实现.
虚拟CPU级别ioctl
以kvm_vcpu_ioctl
为前缀,负责以下通用
虚拟CPU级别的ioctl功能的处理
其余虚拟CPU级别的ioctl功能与架构
有关,因此在kvm_arch_vcpu_ioctl()
中实现.
kvm中虚拟机的创建流程
主要创建流程就是dev->vm->vcpu,这期间最重要的数据结构为kvm_x86_ops(在vmx.c中定义)
,但是在ioctl函数中展现的形式与实际调用的函数形式有些许不同. 如在创建vm
时,函数调用流程为:
kvm_dev_ioctl_create_vm()
-> kvm_create_vm()
-> kvm_arch_alloc_vm()
在kvm_arch_alloc_vm()
中,具体实现只有一句return kvm_x86_ops->vm_alloc()
,此时使用vim
插件无法找到vm_alloc()
的定义,但在vmx.c
中可以看到类似.vm_alloc = vmx_vm_alloc
, 因此其实vm_alloc()
调用的是vmx_vm_alloc
,其它kvm_x86_ops
的子方法也可以使用类似的方法找到.
创建vm
kvm_dev_ioctl_create_vm()
-> kvm_create_vm()
-> kvm_arch_alloc_vm()
-> vmx_vm_alloc()
| -> kvm_arch_init_vm()
| -> vmx_vm_init()
因此可以通过调用kvm_dev_ioctl_create_vm()
完成对一个vm
的内存分配和初始化,最终返回的是一个kvm_vmx
结构的结构.
创建vCPU
kvm_vm_ioctl_create_vcpu()
-> kvm_arch_vcpu_create()
-> vmx_create_vcpu()
| -> kvm_arch_vcpu_setup()
-> vmx_vcpu_setup()
| -> create_vcpu_fd
kvm_arch_vcpu_create()
为vcpu_vmx
结构申请空间,初始化vcpu,为guest_msr,vmcs结构申请空间,并利用vmx_vcpu_setup()
将vmcs
设置为实模式状态,利用vmx_vcpu_put()
准备将vcpu切换至host状态.
运行vCPU
kvm_vcpu_ioctl(...,KVM_RUN,...)
-> kvm_arch_vcpu_ioctl_run()
-> vcpu_run()
-> vcpu_enter_guest()
|
-> need_resched()
<-|
vcpu_enter_guest()
使虚拟vcpu进入non-root
操作,退出该函数等效于执行了VM exit
,如果退出该函数时返回1,即代表guest
无法处理本次exit reasion
,需要进入到用户空间(qemu),使用qemu对本次exit reason
进行处理,处理完成之后再进入vcpu_enter_guest()
.
QEMU与KVM的交互
QEMU的ioctl
由于这部分与qemu有交互的部分,因此我提前对qemu进行了学习.
qemu与kvm对应有4大类的ioctl,用于对kvm提供的3个级别的fd进行控制.
- kvm_device_ioctl()
用于对device_fd(/dev/kvm)
进行操作 ---> hypervisor
- kvm_ioctl()
用于对KVMState
结构体中的fd
进行操作 ---> 对应kvm的device
级别
- kvm_vm_ioctl()
用于对KVMState
结构体中vmfd
进行操作 ---> 对应kvm的vm
级别
- kvm_vcpu_ioctl()
用于对CPUState
结构体中的kvm_fd
进行操作 ---> 对应kvm的vcpu
级别
kvm的kvm_vcpu
结构体中含有kvm_run
结构,用于QEMU的用户空间和kvm模块的交互. 例如在VM exit时,为了对虚拟硬件的访问进行模拟,kvm必须返回到QEMU用户空间中,因此kvm将相关信息存储到kvm_run
结构中,留给QEMU获取信息.
【update】 2019.11.22
QEMU配置加速器(kvm)
qemu使用了大量面向对象
的编程方式,并用c语言实现了类
和类的构建、析构函数
等。
qemu将kvm定义为一种加速类型(AccelClass)
,注册到了type_table
中,因此通过初始化对象就可以直接调用对象所属类的方法。
AccelClass
的init_machine()
方法可以获得vm_fd
.
QEMU设置vCPU
与加速器类似,vCPU也被设计为一种CPU类型(x86_vcpu_type)
, 将qemu的main函数中的current_machine->type
指向x86_vcpu_type
,即可调用该类的方法使用vCPU.
x86_vcpu_type
的x86_vcpu_common_class_init()
方法可以获得vCPU的inode
(qemu中称为kvm_fd
).
值得注意的是qemu为每个vCPU申请了一个线程(thread)
,所占空间在qemu本身在host上所占的空间中.
QEMU的main函数中与kvm有关的部分
QEMU的main函数中与kvm有关的部分对应的为配置加速器
和设置vCPU
两部分,以及最后的循环运行vCPU
,主要函数为:
我对qemu-kvm框架整理后,画了以下结构图.
__EOF__

本文链接:https://www.cnblogs.com/haiyonghao/p/14440094.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律