VT简介VT分类VT作用HypervisorVT实现支持检测
cpuidIA32_FEATURE_ConTROL MSRCr0 & Cr4代码实现 参考资料
VT简介VT,就是虚拟化技术(Virtualization Technology)的缩写。Intel VT就是指Intel的虚拟化技术。这种技术简单来说就是让可以让一个CPU工作起来就像多个CPU并行运行,从而使得在一台电脑内可以同时运行多个操作系统。只有部分Intel的CPU才支持这种技术。——摘自《百度百科》
开启VT后,CPU进入VMX模式,这种模式下的CPU有两种状态:
VMX root状态VMX non-root状态
处于VMX root状态的监控器能够控制VMX non-root状态CPU的关键共享资源(从0环到3环)。
以VMware虚拟机来说,VMware处于VMX root状态,在VMware当中安装的操作系统和操作系统中的应用程序处于VMX non-root状态,由VMware负责管理它们。
Intel VT技术,主要由三部分技术组成:VTx、VTd和VTc。
VTx是处理器技术,提供内存以及虚拟机的硬件隔离,所涉及的技术有页表管理以及地址空间的保护。
VTd是处理有关芯片组的技术,它提供一些针对虚拟机的特殊应用,如支持某些特定的虚拟机应用跨过处理器I/O管理程序,直接调用I/O资源,从而提高效率,通过直接连接I/O带来近乎完美的I/O性能。
VTc是针对网络提供的管理,它可以在一个物理网卡上,建立针对虚拟机的设备队列。
在这一系列的笔记中,主要是学习Intel VTx技术。
VT作用在VT诞生之初,主要是为了便于虚拟机的管理,随着掌握VT技术的人不断增加,VT的用途也越来越广泛,例如目前一些游戏厂商就是使用VT技术来对游戏内存进行保护。
VT能做到的事情例如:
重定向中断MSR寄存器保护监控控制寄存器/调试寄存器…… Hypervisor
描述:
Hypervisor,又称虚拟机监视器(英语:virtual machine monitor,缩写为 VMM),是用来建立与执行虚拟机器的软件、固件或硬件。——摘自《百度百科》
它是负责与虚拟机进行交互的管理器,当虚拟机发出一条指令时,会被VMM捕捉到,然后VMM会模拟执行这条指令,并将结果返回给虚拟机。因为VMM需要有执行0环指令的权限,因此VMM需要运行在0环。如果用户要在虚拟机中获得使用VT的权限,需要先在设置中开启相关选项。
在VMware中为用户开启VT支持的方法:
「虚拟机」-「设置」-「处理器和内存」-「高级选项」- 勾选「在此虚拟机中启用Hypervisor」
注意:如果无法勾选,需要先在BIOS中开启VT支持。
进入虚拟机模式前:
检测系统是否支持VT为VMXON区域和VMCS控制块分配内存设置CR4的VMXE标志填充VMXON结构版本信息
进入虚拟机模式后:
VMXONVMXCLEAR & VMXPTRLD填充VMCS控制块VMXLAUNCH 支持检测
三个因素决定了系统是否支持VT:
- cpuid指令的返回值IA32_FEATURE_ConTROL MSRCr0 & Cr4
描述:生成 cpuid 适用于 x86 和 x64 的指令。 本指令可查询处理器,以获取有关支持的功能和 CPU 类型的信息。
void __cpuid( int cpuInfo[4], //弄一个包含四个整数的数组,其中包含在 EAX、EBX、ECX 和 EDX 中返回的有关 CPU 支持的功能的信息。 int function_id //中指定要检索的信息的代码,传入 EAX。 );
VT相关部分参考Intel开发手册第3卷第23.6小节:
简单来说就是:
1)将EAX置1
2)执行cpuid指令
3)查看ECX二进制的下标第5位是否为1(1表示支持,0表示不支持)
注意:cpuid为3环指令,可以在OD中直接检测。
描述:MSR(Model Specific Register)是x86架构中的概念,指的是在x86架构处理器中,一系列用于控制CPU运行、功能开关、调试、跟踪程序执行、监测CPU性能等方面的寄存器,IA32_FEATURE_ConTROL MSR位于地址3AH位置。
VT相关部分参考Intel开发手册第3卷第23.7小节:
简单来说就是,IA32_FEATURE_ConTROL MSR的第0位为锁定位,如果为0,即使cpu支持VT,也无法启用,此时,尝试在虚拟机设置中勾选VT时,会显示「此主机支持Intel VT-x,但Intel VT-x处于禁用状态」。
描述:进入VT模式前,需要保证Cr0的PE位、PG位和NE位为1,即保证系统开启了保护模式和页保护模式,且启用了x87 协处理器错误的内部报告机制;Cr4的VMXE位(第13位)是用户可控的,表示系统是否进入VT模式,进入VT模式前需要手动置1,否则会触发保护异常,且退出VT模式前无法更改该标志位。
具体参考Intel开发手册第3卷第23.8小节:
部分代码截取自开源项目VT_Learn:
//vtasm.asm
Asm_CPUID Proc uses ebx esi edi fn:dword, ret_eax:dword, ret_ebx:dword, ret_ecx:dword, ret_edx:dword
mov eax, fn
cpuid
mov esi, ret_eax
mov dword ptr [esi], eax
mov esi, ret_ebx
mov dword ptr [esi], ebx
mov esi, ret_ecx
mov dword ptr [esi], ecx
mov esi, ret_edx
mov dword ptr [esi], edx
ret
Asm_CPUID Endp
Asm_ReadMsr Proc Index:dword
mov ecx,Index
rdmsr
ret
Asm_ReadMsr Endp
Asm_GetCr0 Proc
mov eax, cr0
ret
Asm_GetCr0 Endp
Asm_GetCr4 Proc
mov eax, cr4
ret
Asm_GetCr4 Endp
//vtasm.h
typedef union
{
struct
{
unsigned SSE3:1;
unsigned PCLMULQDQ:1;
unsigned DTES64:1;
unsigned MONITOR:1;
unsigned DS_CPL:1;
unsigned VMX:1;
unsigned SMX:1;
unsigned EIST:1;
unsigned TM2:1;
unsigned SSSE3:1;
unsigned Reserved:22;
};
}_CPUID_ECX;
typedef union
{
struct
{
unsigned PE:1;
unsigned MP:1;
unsigned EM:1;
unsigned TS:1;
unsigned ET:1;
unsigned NE:1;
unsigned Reserved_1:10;
unsigned WP:1;
unsigned Reserved_2:1;
unsigned AM:1;
unsigned Reserved_3:10;
unsigned NW:1;
unsigned CD:1;
unsigned PG:1;
//unsigned Reserved_64:32;
};
}_CR0;
typedef union
{
struct{
unsigned VME:1;
unsigned PVI:1;
unsigned TSD:1;
unsigned DE:1;
unsigned PSE:1;
unsigned PAE:1;
unsigned MCE:1;
unsigned PGE:1;
unsigned PCE:1;
unsigned OSFXSR:1;
unsigned PSXMMEXCPT:1;
unsigned UNKONOWN_1:1; //These are zero
unsigned UNKONOWN_2:1; //These are zero
unsigned VMXE:1; //It's zero in normal
unsigned Reserved:18; //These are zero
//unsigned Reserved_64:32;
};
}_CR4;
typedef struct _IA32_FEATURE_CONTROL_MSR
{
unsigned Lock :1; // Bit 0 is the lock bit - cannot be modified once lock is set
unsigned Reserved1 :1; // Undefined
unsigned EnableVmxon :1; // Bit 2. If this bit is clear, VMXON causes a general protection exception
unsigned Reserved2 :29; // Undefined
unsigned Reserved3 :32; // Undefined
} IA32_FEATURE_CONTROL_MSR;
//vtsystem.c
BOOLEAN IsVTEnabled()
{
ULONG uRet_EAX, uRet_ECX, uRet_EDX, uRet_EBX;
_CPUID_ECX uCPUID;
_CR0 uCr0;
_CR4 uCr4;
IA32_FEATURE_CONTROL_MSR msr;
//1. CPUID
Asm_CPUID(1, &uRet_EAX, &uRet_EBX, &uRet_ECX, &uRet_EDX); //接收cpuid返回值
*((PULONG)&uCPUID) = uRet_ECX;
if (uCPUID.VMX != 1)
{
Log("ERROR: 这个CPU不支持VT!",0);
return FALSE;
}
// 2. MSR
*((PULONG)&msr) = (ULONG)Asm_ReadMsr(MSR_IA32_FEATURE_CONTROL);
if (msr.Lock != 1)
{
Log("ERROR:VT指令未被锁定!", 0);
return FALSE;
}
// 3. CR0 CR4
*((PULONG)&uCr0) = Asm_GetCr0();
*((PULONG)&uCr4) = Asm_GetCr4();
if (uCr0.PE != 1 || uCr0.PG!=1 || uCr0.NE!=1)
{
Log("ERROR:这个CPU没有开启VT!",0);
return FALSE;
}
if (uCr4.VMXE == 1)
{
Log("ERROR:这个CPU已经开启了VT!",0);
Log("可能是别的驱动已经占用了VT,你必须关闭它后才能开启。",0);
return FALSE;
}
Log("SUCCESS:这个CPU支持VT!",0);
return TRUE;
}
//driver.c #include#include "vtasm.h" #include "vtsystem.h" VOID DriverUnload(PDRIVER_OBJECT pDriver) { DbgPrint("Driver unload. rn"); } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path) { DbgPrint("Driver load. rn"); IsVTEnabled(); pDriver->DriverUnload = DriverUnload; return STATUS_SUCCESS; }
运行结果:
VT虚拟化架构编写视频教程①~⑥课周壑《VT技术入门》系列视频教程github项目:VT_Learngithub项目: HyperPlatformIntel开发手册 卷3:Chapter 23 ~ Chapter 33x86内部函数列表



