在SIMICS软件里面模拟最新的CPU进行虚拟化测试的时候,先把Dave的kernel patches拿到手,打补丁到v4.1-rc2上,每次启动qemu-kvm的时候,console上就打印了一堆信息,然后panic了,信息简略如下:

先是反汇编内核,看到了出问题的地方,在kvm_cpu_vmxon函数上,它就是汇编执行vmxon指令进入到vmx模式,vmxon也就接受一个参数phys_addr,来自于phys_addr = __pa(per_cpu(vmxarea, cpu)),而vmxarea在hardware_setup上初始化,在最后一句话:alloc_kvm_area,内容是vmcs = alloc_vmcs_cpu(cpu);per_cpu(vmxarea, cpu) = vmcs,怎么看都没发现Dave的patch和vmcs有关联,(去掉Dave的patch就OK了,但他完成的只是kernel部分,virtualization部分归我完成),Dave也认为和simics模拟有关,只好发给simics的Rechistov同事看一下,他让使用“log-level 4”的simics命令配合“break-exception General_Protection_Exception”可以抓取到更多日志,参照抓取日志,果然很不同:

vmxon不支持CR4,这是什么鬼,Rechistov指出去看SDM “23.8 RESTRICTIONS ON VMX OPERATION”,才发现vmxon对cr寄存器有限制:
在SDM “VMXON—Enter VMX Operation”章节中提到IF (CPL > 0) or (in A20M mode) or (the values of CR0 and CR4 are not supported in VMX operation; see Section 23.8) or (bit 0 (lock bit) of IA32_FEATURE_CONTROL MSR is clear) or (in SMX operation11 and bit 1 of IA32_FEATURE_CONTROL MSR is clear) or (outside SMX operation and bit 2 of IA32_FEATURE_CONTROL MSR is clear) THEN #GP(0); 这样就对上号。
而vmxon对cr的限制是:如果vmxon执行是,发现cr0和cr4的格式不满足要求,即某些位的值必须固定,则产生GP,格式要求来自于IA32_VMX_CR0_FIXED0(值为1的位对应到cr0必须为1),IA32_VMX_CR0_FIXED1(值为0的位对应到cr0必须为0),IA32_VMX_CR4_FIXED0(值为1的位对应到cr4必须为1), IA32_VMX_CR4_FIXED1(值为0的位对应到cr4必须为0),而且这些MSR值是(R/O),也就是硬件固定的,但是SDM中没有找到对应的说明。

虽然kernel代码里面有如下的宏:

但实际只有vmx使用这些宏做模拟,另外一个方法就是直接读取一个实际CPU系统的值,IA32_VMX_CR4_FIXED1结果如下:

这样就比较清楚了,Dave的patch更新了cr4的第22位,而simics并没有将22位添加到IA32_VMX_CR4_FIXED1中,这样就GP了。
解决方法:simics> viper.mb.cpu0.core[x][y]->ia32_vmx_cr4_fixed1 = 0x7467FF。

至于IA32_VMX_CR4_FIXED1的其他位有什么要求,可以对照下图看一下:
cpu-cr4-oenhan

 

 


KVM进入vmx模式产生general protection fault来自于OenHan

链接为:http://oenhan.com/kvm-vmxon-gp-error

发表评论