-
-
分享一下对vt-x中VPID和TLB的理解
-
发表于:
2021-9-10 14:36
18359
-
先说明几个问题,
环境是win10 1809 + intel vt-x。
不管是指令TLB还是数据TLB都统称TLB。
TLB在虚拟化上跟VPID和EPTP字段有关,但基本上同一个虚拟机(VM)中的不同vCpu(VMCS.VPID相同)的EPTP是一样的,所以其实TLB可以看作只跟VPID或EPTP有关,因为VPID和EPTP其实就标志着是哪个VM的问题,并且起到了内存隔离的作用。
图片是HyperPlateForm代码、VirtualBox代码或intel手册。
正文:
virtualbox的实现就几个vCpu,创建几个线程,windows下就是_beginthreadex,linux下是kthread_run,但linux下创建的是内核线程,windows下是用户线程,这里我不太明白为什么要创建内核线程(不太懂linux),总之就是用线程模拟核心。如果支持超线程的话,vCpu就是hyper thread,每个核有2个hyper thread。
其实我对vm-exit和vm-entry刷新tlb加上各种帖子的分析我也不是很明白,如果flush掉了,那么vm-exit之后再vm-entry,原来TLB还是没了,那么VPID有什么用?
但是结合intel手册,我是这样理解的,应该是比较合理的:
原始架构的vt-x确实会刷TLB,但是有VPID之后,每次vm-exit,他不会刷新tlb,但是也不会去用这部分tlb,只是保存下来,因为host的vpid是0,肯定跟原来的guest的vpid不一样了,导致用不了。再次vm-entry的时候,恢复了vpid为vmcs中的vpid,cpu还可以继续使用原来这部分的TLB。vpid还有一个好处,如果是同一个VM中的不同vCpu接连调度到一个物理核心,那么两者的vpid也相同,也可以使用同样的tlb cache。
guest的vmcs的vpid是不能等于0的,不然vm-entry的时候报错,就算进去了,guest的vpid等于host的vpid,那么tlb在vm-exit和vm-entry的时候共用了,那么访问同一个线性地址得到的内存是相同的,那ept起不到内存隔离的作用了啊。
虚拟化原理:每个VM(虚拟机)对应一个vmcs,每次模拟核心的线程运行的时候,通过系统调用到内核然后call vmptrld将vmcs置为当前物理核心的vmcs,如果其他VM的vCpu切换到这个物理核心,再把那个VM的vmcs切换,切换vmcs相当于切换VPID。
hyperplatform对vpid的设置
hyperbone的设置
我觉得都是一样的(当然只是我觉得)。而且单纯基于tlb的变化不管是hyperbone/platform还是virtualbox、vmware都是能检测到的。
以上全是个人观点,我也不是很明白虚拟化。
2021.9.11 11.51
误导人了兄弟们。
我用代码测试了一下,
因为hyperplatform用vpid的缘故,导致tlb不刷新了,就算强制vm-exit,回来的时候tlb正常用,导致检测不到。
但是vmware是能检测到的,我估计他是没用vpid?因为每个vm肯定eptp不同啊,就算没有vpid也可以内存隔离,不是很清楚。
检测代码在附件里。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2021-9-11 11:57
被ookkaa编辑
,原因: