前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >x86 kvm和qemu虚拟化介绍

x86 kvm和qemu虚拟化介绍

作者头像
惠伟
发布2021-02-24 11:23:05
1K0
发布2021-02-24 11:23:05
举报
文章被收录于专栏:虚拟化笔记虚拟化笔记

简单说一下自己对x86平台虚拟化的理解,intel有SDM手册,代码都是公开的,难度比较大,理解起来困难,网上有大量优秀博客讲解虚拟化,引用了大量手册和代码,还是很难看懂。个人觉得理解虚拟化不能一上来就看很详细的手册和代码,虚拟化有点绕,先闭上眼睛想想大的道理,掌握了大的道理,再看手册和代码加深理解,否则很容易迷失,对虚拟化的理解只流于表面。

X86体系结构和OS

要理解虚拟化一定要回顾x86体系结构和OS原理,其实这两门课上大学时就学过,当时理解的很肤浅,随着工作的时间越长,理解的越深刻。计算机运转起来飞快,控制的非常精细,表面上给人很多假象,功能越来越复杂,集成度越来越高,不需要掌握很一个细节,但要能简化出一个最简单模型,通过个模型去深入理解背后的原理,思考时要站在不同的角度看问题,CPU的角度,guest的角度,外设的角度,进程的角度,内核的角度,不同角度看问题能让软件逻辑走通。也要不断提出问题,然后试着查资料解答自己的问题,计算机已经复杂到让一个人已经不可能掌握了所有细节,但要形成自己的抽象,各方面逻辑能成环,能自圆其说,只知道一些概念最不可取。

CPU(一堆寄存器)/Cache/Timer

physical memory map, segment and page,MMU and TLB

pci and device,driver and interrupt

kernel space and user space,context and process scheduler

软件和硬件的边界?

对x86和OS回顾后,那么得问自己一个问题,让自己写一个hypervisor怎么实现?guest是不能动的,linux和windows已经编译好的,还是物理机上跑的那些OS,那么是不是得借鉴物理机,哪个厂商什么型号的主板?什么型号的CPU几个核多少G内存?先构造一套假想的硬件,芯片组是什么型号,连接关系什么样的,就想象出下面这张图,这样guest就可以自动识别出这套硬件。

有那些bus,那些device,之间连接关系怎么表示?device的参数(virtio-net queue数量)等怎么表示?bus和device的状态怎么表示?硬件是主板电路连接好的,qemu怎么统一处理?还能支持hotplug?答案就是qdev和QOM(qemu object model)。

静态的东西已经出来了,guest是要运行的,动态怎么办?

CPU分为ring 0和ring 3不同权限,一条条指令执行,有些指令要在ring 3执行,有些要在ring 0执行,指令中包含的地址是虚拟地址。由于guest是事先编译好的,原来在物理机上怎么运行,现在要在虚拟机中一模一样运行,里面该ring 0还是ring 0,该ring 3还是ring 3,该虚拟地址还是原来的虚拟地址,所以得给guest制造假象,但guest的运行最终要落实到真正的硬件CPU和内存上,guest运行于host ring 3,要落实到真正的硬件qemu得做很多工作,那么qemu干什么呢,简单想象guest ring 3指令只要把guest的虚拟地址替换成host的虚拟地址,ring 0指令由于权限太高,得通过host模拟得出个结果然后把这个结果给了guest,这就是软件翻译,太慢了,intel vt-x技术就登场了。

intel vt-x vmx硬件实现了哪些功能?

VMCS(virtual machine controle structure)

non-root(guest)模式和root(host)模式,增加一个ring给guest,让guest指令直接上物理CPU执行,guest指令直接上物理CPU,那么指令中的地址肯定得用MMU硬件单元直接翻译(shadow page和EPT),当然不是guest的任何一条指令都能顺顺当当执行的,尤其是guest操作它以为的真正硬件的指令,因为是假象,其实是不存在的,所以得拦截和模拟,得vmexit然后再vmentry。qemu是host上的进程,ioctl到kvm内核后会vmentry到guest模式,执行guest代码,特权指令trap住vmexit回host模式模拟执行,然后再vmentry到guest模式

CPU虚拟化

一个vcpu在qemu中是一个线程,qemu通过ioctl调用kvm创建vcpu的资源

host调度这些线程,vcpu线程vcpu_run进入kvm内核,然后load_vcpu进入guest模式执行guest的代码

vcpu进入guest模式时从VMCS加载寄存器等,退出guest模式时把寄存器等保存到VMCS上

vcpu_enter_guest->vmx_vcpu_run->__vmx_vcpu_run调用汇编进入guest模式

vmx_handle_exit根据exit_reason来有不同的处理,kvm搞不定就再退回到qemu

vcpu占用了pcpu,host上其它进程要用pcpu,怎么抢占?

vcpu之间cache怎么同步,尤其是一个vcpu在运行,另一个没有运行?

pcpu进入或者退出guest时cache和TLB要不要做处理?

内存虚拟化

x86上物理内存空间大概是这样的。

x86上物理地址空间是怎么组成的那么qemu就要拿自己的进程虚拟空间的内存拼凑出一个空间仍给guest,让guest当作自己的物理地址空间。

在qemu monitor上可以看

虚拟出一块内存给guest用,GVA(guest virtual address)->GPA(guest physical address)->HVA(host virtual address)->HPA(host physical address)

cpu_exec_init_all–>io_mem_init

-->memory_map_init

pc_init1->pc_memory_init ->memory_region_allocate_system_memory->allocate_system_memory_nonnuma->

memory_region_init_ram_shared_nomigrate->qemu_ram_alloc->qemu_ram_alloc_internal->ram_block_add->

phys_mem_alloc(qemu_anon_ram_alloc)->qemu_ram_mmap->mmap

kvm_init->kvm_memory_listener_register->memory_listener_register->listener_add_address_space->kvm_region_add->kvm_set_phys_mem

memory_region_transaction_begin

memory_region_transaction_commit

AddressSpaceDispatch从GPA转到HVA

guest从IO地址空间的一个port读一个数到内存

kvm_mmu_create创建guest MMU的页表,但内容为空

vcpu_enter_guest => kvm_mmu_reload加载guest的页表到VMCS结构的对应字段

EPT_VOLATION和EPT_MISCONFIG

外设和中断

host上driver和硬件外设有明确的接口,硬件外设是个黑盒子。guest中driver是没有变的,那qemu得保持这些接口不变,否则guest里的driver就跑不起来了,接口后面的功能和动作那qemu就随便实现了,最终的结果一样就行了。guest中driver读寄存器那qemu就给一个结果,guest发起DMA操作,qemu就从guest的物理内存搬东西到自己的虚拟空间。

PIC(8259 chip)/APIC(IOAPIC和LAPIC)

INTx/NMI/SMI/SMI-X

qemu和kvm分别模拟中断芯片,混合模拟(on, off, split)

个人认为中断模拟是最难的,host上中断处理流程已经够复杂的了。PIC给CPU发送一个电信号就给CPU一个中断,APIC直接给一个物理地址写,CPU的LAPIC就收中断了,物理机上中断是由硬件发起的,现在只能由hypervisor发起,硬件的中断路由得hypervisor模拟。中断来了OS是怎么取中断号的?怎么操作LAPIC的?中断处理结束了OS怎么操作中断芯片,有哪些指令,这些指令都得trap住然后模拟。

vcpu正在pcpu上运行,ovs把一个数据包放在virtio ring上,怎么打断vcpu运行?中断到底是怎么注入的?kvm运行在一个pcpu A上,vcpu在另一个pcpu B上,难道pcpu A给pcpu B发送一个IPI打断pcpu B?这个IPI和正常的两个pcpu之间的IPI有什么不同没?

vcpu没有运行时来的中断怎么保存的?(pending_event)处理不及时中断会不会丢失?

enter guest时guest是怎么知道有中断在pending?enter guest时不是延着上次执行的地方继续执行吗?为什么要执行中断服务例程呢?难道是硬件搞的?

中断来了要不要exit?怎么减少exit次数?硬件辅助(vAPIC还是APICv)?

总结

虚拟化水很深,大的方面理解了,再看代码深入理解,最后再解决实际碰到的问题,如windows虚拟机中DPC Latency太高怎么解决,嵌套虚拟化的问题。

抛砖引玉,很多问题是不知道答案的,如果你感兴趣,不防想一想找一下答案,找到了答案那么恭喜你,你对虚拟化的理解又上了一个台阶。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • X86体系结构和OS
  • CPU虚拟化
  • 内存虚拟化
  • 外设和中断
  • 总结
相关产品与服务
轻量应用服务器
轻量应用服务器(TencentCloud Lighthouse)是新一代开箱即用、面向轻量应用场景的云服务器产品,助力中小企业和开发者便捷高效的在云端构建网站、Web应用、小程序/小游戏、游戏服、电商应用、云盘/图床和开发测试环境,相比普通云服务器更加简单易用且更贴近应用,以套餐形式整体售卖云资源并提供高带宽流量包,将热门软件打包实现一键构建应用,提供极简上云体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档