前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >qemu-kvm中vcpu虚拟化到底是咋整的?

qemu-kvm中vcpu虚拟化到底是咋整的?

作者头像
腾讯云TStack
发布2018-03-22 14:21:50
4.5K0
发布2018-03-22 14:21:50
举报

一句话总结

实例化一个vcpu就是在hostOS中创建了一个线程,线程里有个while循环,循环里不停的调用kvm_cpu_exec方法,kvm_cpu_exec方法调用通过kvm_vcpu_ioctl(cpu, KVM_RUN, 0)使得kvm切换为no-root模式。在no-root模式下处理特权指令的时候,会退回root模式,然后一步步返回到kvm_cpu_exec中根据不同原因,处理返回异常。

如此一个轮回结束,周而复始,vcpu。

再补充说一点,内存中申请一块内存,根模式和非根模式切换的时候,先把当前寄存器值放到这块内存中,然后设置物理cpu使得进入对应模式,这块内存叫vmcs。

背景

vcpu初始化的时候(qemu_init_vcpu)是启动了一个线程,也就是说vcpu其实就是一个线程.线程运行方法是qemu_kvm_cpu_thread_fn

kvm_init_vcpu调用KVM_CREATE_VCPU创建了vcpu返回vm_fdvcpu的运行是在kvm_cpu_exec里面的,这里调用如下命令进入kvm

代码语言:javascript
复制
run_ret = kvm_vcpu_ioctl(cpu, KVM_RUN, 0);

进入KVM后,KVM会切入Guest OS,假如Guest OS运行运行,需要访问IO等也就是说要访问physical device,那么Qemu与KVM就要进行emulate。如果是KVM emulate的则由KVM emulate,然后切回Guest OS。如果是Qemu emulate的,则从KVM中进入Qemu,等Qemu中的device model执行完emulate之后,再次在Qemu中调用kvm_vcpu_ioctl(vcpu_fd, KVM_RUN, xxx)进入KVM运行,然后再切回Guest OS

vm-entrykvm_vcpu_ioctl(kvm_main.c)-->kvm_arch_vcpu_ioctl_run(kvm/x86.c)-->vcpu_run(kvm/x86.c)-->vcpu_enter_guest(kvm/x86.c)在qemu中kvm_vcpu_ioctl(cpu, KVM_RUN, 0)调用kvm后代码层层调用最终核心实现的方法是vcpu_enter_guest

vcpu->requests 处理

上次VM-Exit时可能调用kvm_make_request设置不同的request下次准备VM-Entry时需要处理这些request.

prepare_guest_switch

代码语言:javascript
复制
 (vmx.c)
.prepare_guest_switch = vmx_save_host_state,
  1. 保存host的fs和gs的断选择子(segment selector)到vmcs
  2. kvm_set_shared_msr设置host对应的msr寄存器 MSR 总体来是为了设置CPU 的工作环境和标示CPU 的工作状态,包括温度控制,性能监控等guest的msr在handle_wrmsr 最终是在vmx_set_msr中更新
  3. 判断当前是否满足vm-entry vcpu的mode不对,有requests请求,需要重新调度,有pending的信号有异常任何情况,不进入vm_entry开中断,开抢占(在此之前已经关抢占,关中断)

4.kvm_x86_ops->run(vcpu)-->vmx_vcpu_run(vmx.c)更新vmcs中的GUEST_RSP和 GUEST_RIP刷新vmcs中的HOST_CR4字段(其他寄存器在 kvm_arch_vcpu_ioctl_set_regs时设置)(段寄存器在vmx_vcpu_reset时设置)下面调用汇编代码,保存host相关内容,然后加载vmcs中的guest的寄存器值,跳转至guest中代码

vm-exit

前半部分我们知道了如何vm-entry此时进入no-root非根模式执行guest的指令当指令访问特权指令如访问io访问设备的时候会vm-exit

1.vmx_vcpu_run后半段

代码语言:javascript
复制
vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
vmx->loaded_vmcs->launched = 1;
vmx->exit_reason = vmcs_read32(VM_EXIT_REASON);

2.加入vm-exit是由于EXIT_REASON_MCE_DURING_VMENTRY或者EXIT_REASON_EXCEPTION_NMI导致的在vmx_complete_atomic_exit方法中需要进行特殊处理(kvm_machine_check)(kvm_before_handle_nmi和kvm_after_handle_nmi)

  1. 如果有事件模拟的virtual nmi中断,则用vmx_recover_nmi_blocking处理
  2. 获取与预处理导致的中断由vmx_complete_interrupts-->__vmx_complete_interrupts处理

(至此退出vmx_vcpu_run重返vmx_vcpu_run)

kvm_x86_ops->handle_exit-->vmx_handle_exit根据不同情况处理异常

至此从kvm中返回到用户态qemu中kvm_cpu_exec方法

根据不同退出原因,处理异常然后退出到线程方法qemu_kvm_cpu_thread_fn继续执行下一次循环

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-03-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 TStack 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • vcpu->requests 处理
  • vm-exit
相关产品与服务
应用性能监控
应用性能监控(Application Performance Management,APM)是一款应用性能管理平台,基于实时多语言应用探针全量采集技术,为您提供分布式性能分析和故障自检能力。APM 协助您在复杂的业务系统里快速定位性能问题,降低 MTTR(平均故障恢复时间),实时了解并追踪应用性能,提升用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档