qemu到kvm的处理,再到vm的运行
1、QEMU创建虚拟机发起:kvm_ioctl(s, KVM_CREATE_VM, type);
KVM中kvm_dev_ioctl判断参数-》kvm_dev_ioctl_create_vm-》kvm_create_vm该函数中创建并初始化了对应qemu模拟的内存条模型kvm->memslots【kvm结构体】
2、QEMU创建vcpu发起:kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)kvm_arch_vcpu_id(cpu));
KVM中kvm_vm_ioctl判断参数-》kvm_vm_ioctl_create_vcpu-》
(1)kvm_arch_vcpu_create借助kvm_x86_ops->vcpu_create即vmx_create_vcpu完成任务:(1.1)kvm_vcpu_init初始化,主要是填充结构体【kvm_vcpu】,注意vcpu->run分派了一页内存,该函数继续kvm_arch_vcpu_init负责填充x86 CPU结构体【kvm_vcpu_arch】,该函数还kvm_mmu_create则是初始化MMU的函数,每个MMU都是vcpu独有。(1.2)分配一页给vmcs(执行vm entry的时候将vmm状态保存到vmcs的host area,并加载对应vm的vmcs guest area信息到CPU中,vm exit的时候则反之,vmcs具体结构分配由硬件实现,程序员只需要通过VMWRITE和VMREAD指令去访问)(1.3)vmx_vcpu_load加载VCPU的信息,切换到指定cpu,进入到vmx模式,将loaded_vmcs的vmcs和当前cpu的vmcs绑定到一起(1.4)vmx_vcpu_setup则是初始化vmcs内容,主要是赋值计算
(2)kvm_arch_vcpu_setup-》kvm_x86_ops->vcpu_load(vcpu, cpu)即vmx_vcpu_load,就是进入vcpu模式下准备工作。
(3)create_vcpu_fd为proc创建控制fd,让qemu使用
3、QEMU要运行vcpu发起:kvm_vcpu_ioctl(cpu, KVM_RUN, 0);
KVM中kvm_vcpu_ioctl判断参数-》kvm_arch_vcpu_ioctl_run-》__vcpu_run-》
(1)在while循环里面调用vcpu_enter_guest进入guest模式,该函数(1.1)首先处理vcpu->requests,对应的request做处理,kvm_mmu_reload加载mmu,通过kvm_x86_ops->prepare_guest_switch(vcpu)准备陷入到guest,prepare_guest_switch实现是vmx_save_host_state,顾名思义,就是保存host的当前状态(1.2)然后加载guest的寄存器等信息,fpu,xcr0,将vcpu模式设置为guest状态,屏蔽中断响应,准备进入guest。但仍进行一次检查,vcpu->mode和vcpu->requests等,如果有问题,则恢复host状态。(1.3)kvm_guest_enter做了两件事:account_system_vtime计算虚拟机系统时间;rcu_virt_note_context_switch对rcu锁数据进行保护,完成上下文切换。(1.4)准备工作搞定,kvm_x86_ops->run(vcpu),开始运行guest,由vmx_vcpu_run实现,该函数主要是内联汇编。(1.5)vmx_vcpu_run退出后返回到vcpu_enter_guest通过hw_breakpoint_restore恢复硬件断点(1.6)走到kvm_x86_ops->handle_exit(vcpu);即vmx_handle_exit处理虚拟机的退出:主要设置vcpu->run->exit_reason,让外部感知退出原因,并对应handle_exit函数集处理(有handle_task_switch进行任务切换,handle_io处理qemu的外部模拟IO等)。
(2)退回到__vcpu_run函数,在while (r > 0)中,循环受vcpu_enter_guest返回值控制,只有运行异常的时候才退出循环,否则通过kvm_resched一直运行下去。
(3)再退就到了kvm_arch_vcpu_ioctl_run函数,return到kvm_vcpu_ioctl,就ioctl返回到qemu的kvm_cpu_exec中,此时kvm run的执行也结束。
4、QEMU初始化虚拟机内存发起:kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
KVM中kvm_vm_ioctl把参数copy_from_user复制后-》kvm_vm_ioctl_set_memory_region逐层调用到__kvm_set_memory_region在KVM中建立与QEMU相对应的内存槽结构-》
(1)id_to_memslot根据qemu的内存槽号得到kvm结构下的内存槽号 kvm_memory_slot,转换关系来自id_to_index数组(在kvm_create_vm虚拟机创建过程中,kvm_init_memslots_id初始化对应关系slots->id_to_index[i] = slots->memslots[i].id = i)。
(2)根据slot中的值和要设置的值,决定要操作的类别KVM_MR_CREATE/DELETE/MOVE/_FLAGS_ONLY。如果是CREATE则kvm_arch_create_memslot函数,里面主要是一个循环做了一个3级软件页表;无论删除还是移动, 先申请一个slots,把kvm->memslots暂存到这里,通过id_to_memslot获取kvm_memory_slot,并将应标记为KVM_MEMSLOT_INVALID,然后是install_new_memslots,其实就是更新了一下slots->generation的值(也就是把刚新申请的slots装载到kvm->memslots)(这里为何先不用原来slot而是申请新的slot “如果添加的section的属性变了,如从RAM变成了ROM,那么重新进行添加也是必要的”并不理解https://blog.csdn.net/leoufung/article/details/48781185 )。
qemu到kvm的处理,再到vm的运行的更多相关文章
- Linux 桌面玩家指南:07. Linux 中的 Qemu、KVM、VirtualBox、Xen 虚拟机体验
特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...
- Qemu,KVM,Virsh傻傻的分不清
当你安装了一台Linux,想启动一个KVM虚拟机的时候,你会发现需要安装不同的软件,启动虚拟机的时候,有多种方法: virsh start kvm命令 qemu命令 qemu-kvm命令 qemu-s ...
- Qemu创建KVM虚拟机内存初始化流程
转载请注明:[转载自博客xelatex KVM],并附本文链接.谢谢. [注]文章中采用的版本: Linux-3.11,https://www.kernel.org/pub/linux/kernel/ ...
- QEMU和KVM的关系
首先KVM(Kernel Virtual Machine)是Linux的一个内核驱动模块,它能够让Linux主机成为一个Hypervisor(虚拟机监控器).在支持VMX(Virtual Machin ...
- 014-通过JDB调试,通过HSDB来查看HotSpot VM的运行时数据
一.JDB调试 在预发环境下进行debug时,时常因为工具和环境的限制,导致debug体验非常差,那么有什么方法能够简化我们进行debug的体验吗?JDB就是一种. JDB ...
- 【记录】尝试用QEMU模拟ARM开发板去加载并运行Uboot,kernel,rootfs【转】
转自:https://www.crifan.com/try_use_qemu_emulate_arm_board_to_load_and_run_uboot_kernel_rootfs/ [背景] 手 ...
- kvm初体验之五:vm连接网络的两种方式:bridge和nat
1. 在安装vm时指定网络连接方式 1)bridge virt-install --name vm1 --ram=1024 --vcpus=1 --disk path=/vm-images/vm1,s ...
- kvm初体验之三:vm的安装及管理
Host: CentOS release 6.4 (Final) Guest: CentOS release 6.6 (Final) 全程以root身份操作 1. host上创建桥br0 参考< ...
- Qemu/Limbo/KVM镜像:Ubuntu Mate 22.04+Wine 7.8
链接: https://pan.baidu.com/s/1cf2c_ylu7-SUaYl8ddztog 提取码: b9mi 密码 空格 手机推荐使用termux里面的Qemu运行,速度最快. 镜像特征 ...
随机推荐
- python 生成器generator
关于生成器,主要有以下几个 关键点的内容 一.什么是generator ,为什么要有generator? 二.两种创建生成器方式 三.yield关键字 四.generator 两个调用方法 next( ...
- 团队项目-课程MS需求分析心得
我们的课程管理项目需求讲道理其实应该是比较简单的,但是在经过几次和老师讨论过后,项目需求已经多得让人脑门疼,后来继续跟老师聊,老师嘴上说着减减减,但是每次讨论下来需求还是会变得更多,以致于个人已经不再 ...
- 3. Scala运算符
3.1 运算符介绍 运算符是一种特殊的符号,用以表示数据的运算.赋值和比较等 1) 算术运算符 2) 赋值运算符 3) 比较运算符(关系运算符) 4) 逻辑运算符 5) 位运算符 3.2 算术运算符 ...
- delphi 自动获取串口
delphi 自动获取串口 https://blog.csdn.net/Nevermore_anger/article/details/79012875 版权声明:本文为博主原创文章,未经博 ...
- loj2083 优秀的拆分 [NOI2016] SA
正解:SA 解题报告: 我永远喜欢loj! 显然$AABB$串相当于是由两个$AA$串拼起来的,所以可以先考虑如果求出来了所有$AA$串怎么求答案? 就假如能统计出$st[i]$表示所有以$i$为开头 ...
- JavaScript实现预览本地上传图片
<html> <head> <title> www.jb51.net图片上传预览 </title> <script> function Pr ...
- 【记录tomcat报错解决办法】tomcat请求组件没有找到的问题
报错原因: An incompatible version 1.1.14 of APR based Apache Tomcat Native library is installed, while T ...
- C# linq语句学习
using System; using System.Linq; namespace ConsoleApp1 { class Program { static void Main(string[] a ...
- DOS特殊字符转义方法
http://www.robvanderwoude.com/escapechars.php 期望得到的字符 转义后字符 说明 % %% May not always be required in do ...
- Oracle 11g R2性能优化 10046 event
作为SQL Trace的扩展功能,Oracle 10046 event(10046事件)是一个重要的调试事件,也可以说是系统性能分析时最重要的一个事件,它包含比SQL Trace更多的信息.但可惜的是 ...