一次kvm嵌套虚拟化踩坑经历

 2023-09-15 阅读 16 评论 0

摘要:女主宣言嵌套虚拟化就是虚拟化环境里再次进行虚拟化,简单的说就是虚拟机里运行虚拟机,听起来有点递归的感觉。那是不是可以无限嵌套下去呢?递归有终结条件,否则无限递归下去资源耗尽,嵌套虚拟化嵌套层次越深复杂度越高性能也越差越容易出

女主宣言

嵌套虚拟化就是虚拟化环境里再次进行虚拟化,简单的说就是虚拟机里运行虚拟机,听起来有点递归的感觉。那是不是可以无限嵌套下去呢?递归有终结条件,否则无限递归下去资源耗尽,嵌套虚拟化嵌套层次越深复杂度越高性能也越差越容易出问题。本文讲述了嵌套虚拟化的一次踩坑经历,希望对遇到类似问题的同学有所帮助。

PS:丰富的一线技术、多元化的表现形式,尽在“360云计算”,点关注哦!

1

引言

公司很多业务部门有这样的需求:一台windows虚拟机运行android模拟器,qemu嵌套qemu,会出现android模拟器图形窗口不显示一直黑屏。这次要说的问题是kvm上运行windows 10虚拟机,windows 10里通过vmware workstation pro再运行linux虚拟机。对于一名linux开发人员来说,windows不开源,没资料没代码,处理windows问题非常有挑战性。

2

小坑

屋漏偏逢连夜雨,怕什么来什么,vmware workstation一打开就报错。

host上kvm是一种hypervisor,guest里vmware workstation也是一种hypervisor,windows hyper-v也是一种hypervisor,看样子是vmware workstation和windows hyper-v冲突了,在windows 10里禁用hyper-v role还是无法解决问题。

虚拟化刚开始是全翻译的,hypervisor对guest的指令一条条做翻译,guest是不知道自己运行在虚拟机里的,这样性能是很差的。

硬件厂商实现了一些硬件加速的虚拟化方案,典型的如intel的vt-x技术,vt-x实现了non-root态,运行guest指令时,CPU进入non-root态,只有碰到敏感指令CPU才会从non-root退回到root,叫做vm-exit,相反叫做vm-entry,然后在root态做敏感指令的模拟,然后再vm-entry。那么肯定是vm-exit的次数越少虚拟机性能越好,为了这个目标,硬件和kvm做了很多努力,但有些特性是需要guest配合才能实现。linux是开源的好说,直接修改linux的代码就能搞定,但windows就比较难了,没有代码没法修改。好在windows有hypervisor hyper-v,windows为了配合hyper-v是做过修改的。hyper-v有公开的文档定义了一些接口,那么kvm实现hyper-v的接口就能和windows里的修改配合到一起了。按我理解vmware workstation可能和windows里为了配合hyper-v所做的这些修改有冲突,所以windows中为hypervisor做过配合的这些代码不能运行,kvm就得关闭这些增强功能,问题到此大致清晰。

从qemu参数找libvirt的问题,再从libvirt找nova-compute的问题,再从nova-compute找到image的元数据,删除os_type,vmware workstation能打开了。

3

大坑

运行vmware workstation里的虚拟机,太惊喜了,windows 10直接蓝屏。

望文生义,vmx86.sys中有vmx。我们知道查看intel cpu是否支持硬件加速的虚拟化得看cpu是否支持vmx特性,这个错误大概率和vmx和cpu的特性有关系。目前云平台为了性能,cpu模型用了host-passthrough。尝试修改qemu参数,传递不同的cpu型号和加减cpu的特性。尝试的结果是参数是-cpu qemu64,+vmx时里面的虚拟机可以正常运行,能运行但性能不理想。我们还是希望用host-passthrough模型,只能求助windows大牛。进入qemu monitor,用dump-guest-memory命令导出蓝屏时windows的内存,发给大牛分析下引起蓝屏的原因,是rdmsr引起的。

找到intel手册查看rdmsr的说明:

“Returns the microcode update signature following the execution of CPUID.01H”看指令是相符的,虽然不知道microcode update signature是干什么的,但“A processor may prevent writing to this MSR when loading guest states on VM entries or saving guest states on VM exits”这句话就难以理解了,似乎说是的wrmsr,难道不能写所以不能读。但前面指令已经wrmsr过,这个非常奇怪。突然想到会不会是kvm的问题,rdmsr指令触发了vm-exit然后由kvm模拟。查看kvm log发现报有unhandled rdmsrc。

查看linux-3.10.0-1127.el7内核代码,打log后return 1,如果打开ignore_msrs就不打log,最终return 0。

host上执行echo 1  > /sys/module/kvm/parameters/ignore_msrs,奇迹发生,不再蓝屏。

4

后续思考

虽然最终问题通过简单的办法解决了,但还有不少疑问。window 10蓝屏时执行的指令rdmsr地址是8BH,但kvm log显示没有处理的rdmsr地址是CEH,这条指令到底是第一层guest执行的还是第二层guest执行的?kvm嵌套虚拟化有VMCS01和VMCS12,然后形成了VMCS02,直接硬件支撑了第二层虚拟机的运行,在第一层guest中CPU已经处于non-root态了。如果第一层guest要VMLAUCH第二层guest,需要先vm-exit出来,然后加载形成的VMCS02运行第二层guest,如果第二层guest vm-exit,到底是第一层hypervisor处理还是第二层hypervisor处理,需要依情况定。由于vmware workstation不开源,很多答案不明。那么三层嵌套虚拟化怎么处理,会有哪些问题,都需要后面继续探索和解决。

360云计算

由360云平台团队打造的技术分享公众号,内容涉及数据库、大数据、微服务、容器、AIOps、IoT等众多技术领域,通过夯实的技术积累和丰富的一线实战经验,为你带来最有料的技术分享

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/57605.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息