VMX,SVM编程指北——检查系统是否支持 VMX

VMX,SVM编程指北——目录
https://www.cnblogs.com/FE-FR-SH/p/contents.html

VMX 这技术已经出现好多年了,市面上的CPU大多都支持了,那还有必要检查系统是否支持VMX吗?考虑一下还是要检查的,就算市面上的CPU都支持了,但各家的BIOS/UEFI有别,VMX可能会被禁用,所以你的软件应该进行检查,如果发现VMX被禁用,应该恰当的提示用户。

现在让我们来过一遍流程:
1,确认当前的CPU是不是intel的,毕竟这里讨论的都是VMX; 使用指令CPUID.0,返回值按照ebx,edx,ecx排列,就是GenuineIntel,知道就好,写代码的时候没必要抠这种细节,去排这个序。示例代码如下:(注意:代码默认使用WDK风格,如int 默认长度为 32个bit,此类问题以后不再赘述)

点击查看代码
#define BASIC_INTEL_STR "GenuntelineI"

int cpuInfo[4] = {0};//eax, ebx, ecx, edx

__cpuid(cpuInfo, 0);
if (3*sizeof(int) != RtlCompareMemory(BASIC_INTEL_STR, cpuInfo+1, 3*sizeof(int))) {
//not match
}

2,检查CPU是否支持VMX,使用CPUID.1:ECX.VMX[bit 5]来判断,示例代码如下:

点击查看代码
#define CUPID_ECX_VMX (1 << 5)

int cpuInfo[4] = {0};//eax, ebx, ecx, edx

__cpuid(cpuInfo, 1);
if(cpuInfo[2] & CUPID_ECX_VMX)
{
//OK,cpu support vmx
}

3,检查BIOS/UEFI是否禁用了VMX,前面两个步骤中使用的 CPUID 可以在user mode中使用,但从这里开始 你将不得不写一些驱动代码。(若有人需要《驱动编程指北》,我可以另开一个章节) 示例代码如下:

点击查看代码
#define IA32_FEATURE_CONTROL_MSR 0x3a
#define IA32_FEATURE_CONTROL_LOCKED (1 << 0)
#define IA32_FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX (1 << 1)
#define IA32_FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1 << 2)

__int64 featureInfo = 0;
	
featureInfo = __rdmsr( IA32_FEATURE_CONTROL_MSR);
if(!(featureInfo & IA32_FEATURE_CONTROL_LOCKED))
{
//your BIOS/UEFI code maybe not strong. It's time to buy a new one.
//if the bit is clear, VMXON will causes a exception.
}

if(featureInfo & IA32_FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX)
{
//
}

if(featureInfo & IA32_FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX)
{
//
}

SMX 指 Safer Mode Extension, 所以IA32_FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX 和 IA32_FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX,就是判断 VMXON 能否在SMX内和外 执行。
IA32_FEATURE_CONTROL_LOCKED 一个powercycle只能写一次,通常由BIOS/UEFI填写,当然也有可能遇到没有填的,也就是说这个bit处于clear状态,那么我们也可以自己填写这部分,使用指令__wrmsr()按需设置IA32_FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX,IA32_FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX和IA32_FEATURE_CONTROL_LOCKED。

posted @ 2021-10-29 20:59  FE&FR&SH  阅读(538)  评论(2编辑  收藏  举报