Intel VT学习笔记(一)—— 基础知识&支持检测

前言

  1. 本系列主要是记录学习VT虚拟化技术过程中的一些笔记,并通过Intel开发手册和网络资料学习虚拟机体系结构的基础知识,以及支持多软件环境处理器硬件虚拟化的虚拟机扩展(VMX)。
  2. 有关VMX指令的信息,请参阅《英特尔64和IA-32体系结构软件开发人员手册》第2B卷。
  3. 《英特尔64和IA-32体系结构软件开发人员手册》第3B卷的章节介绍了VMX的其他方面和系统编程注意事项。

VT简介

VT,就是虚拟化技术(Virtualization Technology)的缩写。Intel VT就是指Intel的虚拟化技术。这种技术简单来说就是让可以让一个CPU工作起来就像多个CPU并行运行,从而使得在一台电脑内可以同时运行多个操作系统。只有部分Intel的CPU才支持这种技术。——摘自《百度百科》

开启VT后,CPU进入VMX模式,关于VMX的信息会在下文介绍。

VT分类

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寄存器保护
  • 监控控制寄存器/调试寄存器
  • ……

虚拟机架构

描述:虚拟机扩展定义了对IA-32处理器上的虚拟机的处理器级支持,支持Virtual-machine monitors (VMM)Guest software这两类主要的软件。

Virtual-machine monitors (VMM)

描述

  1. VMM充当主机,完全控制处理器和其他平台硬件。
  2. VMM为Guest software提供了虚拟处理器的抽象,并允许它直接在逻辑处理器上执行。
  3. VMM能够保留对处理器资源、物理内存、中断管理和I/O的选择性控制。
  4. 它是负责与虚拟机进行交互的管理器,当虚拟机发出一条指令时,会被VMM捕捉到,然后VMM会模拟执行这条指令,并将结果返回给虚拟机。
  5. 因为VMM需要有执行0环指令的权限,因此VMM需要运行在0环。
  6. 如果用户要在虚拟机中获得使用VT的权限,需要先在设置中开启相关选项。

Guest software

描述

  1. 每个虚拟机(VM)都是一个Guest software环境,由操作系统(OS)和应用软件组成。
  2. 每个虚拟机独立于其他虚拟机运行,并在同一接口上使用物理平台提供的处理器、内存、存储器、图形和I/O。
  3. 软件的行为就像它在没有VMM的平台上运行一样。
  4. 在虚拟机中执行的软件必须以较低的权限运行,以便VMM可以保留对平台资源的控制。

VMX

描述:处理器对虚拟化的支持是通过一种称为VMX操作的处理器操作形式提供的。

VMX操作有两种:

  1. VMX root
  2. VMX non-root

通常,VMM将在VMX root中运行,而Guest software将在VMX non-root中运行。VMX root和VMX non-root之间的转换称为VMX转换。VMX转换有两种。过渡到VMX non-root称为VM entries。从VMX non-root过渡到VMX root称为VM exits。

VMX root

描述:进入VMX root模式后,CPU唯一的区别是能够执行VMX指令,并能够有限地向部分控制寄存器中加载值。

VMX non-root

描述

  1. VMX non-root中的处理器行为受到限制和修改,以促进虚拟化实现。
  2. 某些指令(包括新的VMCALL指令)和事件会导致虚拟机退出,而不是通常的操作。这是由于这些虚拟机出口替换了普通行为,VMX non-root中的软件功能受到限制。正是这个限制允许VMM保留对处理器资源的控制。
  3. 由于不存在标志位表示当前系统是否处于VMX non-root状态,因此没有软件能够以此判断自己是否在虚拟机中。

VT实现

在VMware中为用户开启VT支持的方法:
「虚拟机」-「设置」-「处理器和内存」-「高级选项」- 勾选「在此虚拟机中启用Hypervisor」
在这里插入图片描述
注意:如果无法勾选,需要先在BIOS中开启VT支持。

支持检测

三个因素决定了系统是否支持VT:

  1. cpuid指令的返回值
  2. IA32_FEATURE_CONTROL MSR
  3. Cr0 & Cr4

cpuid

描述:生成 cpuid 适用于 x86 和 x64 的指令。 本指令可查询处理器,以获取有关支持的功能和 CPU 类型的信息。

void __cpuid(
   int cpuInfo[4],		//弄一个包含四个整数的数组,其中包含在 EAX、EBX、ECX 和 EDX 中返回的有关 CPU 支持的功能的信息。
   int function_id		//中指定要检索的信息的代码,传入 EAX。
);

可参考Intel开发手册第3卷第23.6小节:
在这里插入图片描述

简单来说就是:
1)将EAX置1
2)执行cpuid指令
3)查看ecx的下标第5位是否为1(1表示支持,0表示不支持)

注意:cpuid为3环指令,可以在OD中直接执行。
在这里插入图片描述在这里插入图片描述

IA32_FEATURE_CONTROL MSR

描述: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处于禁用状态」。

Cr0 & Cr4

描述:进入VT模式前,需要保证Cr0PE位PG位NE位为1,即保证系统开启了保护模式页保护模式,且启用了x87 协处理器错误的内部报告机制Cr4VMXE位(第13位)是用户可控的,表示系统是否进入VT模式,进入VT模式前需要手动置1,否则会触发保护异常,且退出VT模式前无法更改该标志位。

具体参考Intel开发手册第3卷第23.8小节:
在这里插入图片描述

代码实现

部分代码截取自开源项目VT_Learn:

//vtasm.h
#ifndef VTASM_H
#define 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 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;

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;

void Asm_CPUID(ULONG uFn, PULONG uRet_EAX, PULONG uRet_EBX, PULONG uRet_ECX, PULONG uRet_EDX);

ULONG64 Asm_ReadMsr(ULONG uIndex);

ULONG Asm_GetCr0();
ULONG Asm_GetCr4();

#endif!
.686p
.model flat, stdcall
option casemap:none

.data

.code

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

END
#ifndef VTSYSTEM_H
#define VTSYSTEM_H
#include <ntddk.h>

/*MSR definition*/
#define MSR_IA32_FEATURE_CONTROL 		0x03a

//检查当前处理器是否支持VT
BOOLEAN IsVTEnabled();

#define Log(message,value) {{KdPrint(("[MinVT] %-40s [%p]\n",message,value));}}

#endif
//vtsystem.c
#include "vtsystem.h"
#include "vtasm.h"

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);
    *((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 <ntddk.h>
#include "vtasm.h"
#include "vtsystem.h"

VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
	DbgPrint("Driver unload. \r\n");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path)
{
	DbgPrint("Driver load. \r\n");
	
	IsVTEnabled();

	pDriver->DriverUnload = DriverUnload;

	return STATUS_SUCCESS;
}

运行结果
在这里插入图片描述

参考资料

  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值