分享

x86-64安全虚拟机构架

 panic moon 2012-03-08

x86-64安全虚拟机构架

AMD虚拟化(AMD-V?)构架安全虚拟机(Secure Virtual Machine,SVM)为企业级服务器虚拟软件技术设计,SVM在处理器上提供了硬件资源,允许单个机器更有效地运行多个操作系统,并维护安全和资源相互隔离。

虚拟机监视器(Virtual Machine Monitor,VMM)也称为系统管理程序(Hypervisor),由控制程序软件组成,用于控制在单个物理机器上运行的多个客户操作系统。VMM给 每个客户操作系统提供了完全的计算机系统控制,包括内存、CPU和其他周边设备。

VMM在客户操作系统上以安全的方式拦截和模拟硬件敏感的操作(如:页表切换)。AMD的 SVM提供了硬件支持,以改进虚拟化操作的性能。

SVM硬件概述

SVM处理器提供了一套硬件扩展,用于虚拟化和安全的支持。虚拟化支持包括VMM和客户机之间的快速切换机制、拦截客户机上的指令或事件、用于内存的外部DMA访问保护、中断处理及虚拟中断支持、客户/主机标识的TLB(减少虚拟化开销)。

SVM硬件特征说明如下:

(1)客户机模式

客户机模式(Guest Mode)是一种新的处理器模式,由指令VMRUN进入该模式。在客户机模式中,一些x86指令使得虚拟化更容易。

(2)外部访问保护

客户机可被授权直接访问I/O设备,硬件可以阻止一个客户机的设备访问另一个客户机(或VMM)拥有的内存。

(3)标记的TLB

在SVM模型中,VMM映射到不同于客户机的地址,为了减少切换的开销,TLB用地址空间ID(Address Space Identifier,ASID)进行标识,用来将主机空间条目与客户机空间条目区分开。

(4)中断支持

为了促进更有效的中断虚拟化,在VMCB标识的控制下处理器支持下面的功能:

  • 拦截物理中断分发 VMM可以请求物理中断引起运行的客户机退出,允许VMM处理中断。

  • 虚拟中断 VMM可以抛出虚拟中断给客户机。在VMM的控制下,客户机透明地使用APIC任务优先级寄存器的虚拟拷贝和EFLAGS.IF中断掩码位的虚拟拷贝,而不是使用物理资源。

  • 共享一个物理APIC SVM允许多个客户机共享一个物理APIC,并保护不受恶意或失效客户机的破坏,从而可能留下高优先级中断永远在不可知状态,并因此关闭其他客户机中断。

(5)可重启动的指令

SVM设计为可安全启动,除了任务切换、任何拦截操作后拦截的指令(原子的或等幂的)。

(6)安全认证

指令SKINIT和相关的系统支持(可信平台模块TPM)允许可信软件(如:VMM)基于安全Hash比较进行可验证的启动。

SVM的核心构架包括指令VMRUN和拦截操作。

基于虚拟机运行(Virtual Machine Run,VMRUN)指令VMRUN。

Hypervisor执行VMRUN,引起客户机运行在客户机模式(Guest Mode)。

客户机运行直到它退回到Hypervisor。

Hypervisor在VMRUN指令后恢复运行。

切换方式为:Hypervisor?客户? Hypervisor

X86-64处理器安全 01.png

客户机运行直到:

– 它执行引起退出到主机的动作。

– 它明确执行VMMCALL指令。

客户机的VMCB有设置,用来判断什么动作引起客户机退出到主机。

– 这些拦截能从客户机到客户机改变。

– 两类拦截

    例外&中断拦截

    指令拦截

– 丰富的拦截集允许主机设置定制每个客户机的特权

有关拦截事件的信息在退出时存入到VMCB

新指令集特征

– 处理器模式:客户机模式

– 数据结构:虚拟机控制块(Virtual Machine Control Block,VMCB)等

– 指令:VMRUN, VMLOAD, VMSAVE, VMMCALL等

– 所有指令可重启动的

中断结构变化

– 可选择的拦截

    增加了执行性能,并可以半虚拟化(para-virtualization)

– 事件注入(Event Injection)

     消除了VMM代码仿真x86例外分发的必要。?? 降低了VMM开发时间

分页特征

安全特征:DMA互斥向量, SKINIT等。

SVM分页支持

新的分页特征与支持:

– 影子页表(Shadow Page Tables,SPT)与嵌套页表(Nested Page Tables)

– 新的内存模式:实模式(Real Mode) w/ Paging

"标记的TLB":增加地址空间ID(Address Space ID,ASID)改变(Translation Look-aside Buffer,TLB)执行性能。

– VMRUN设置客户机ASID。

影子分页支持

– 主机拦截客户机CR3的读/写操作。

– 主机监控客户机对客户机页表的编辑,该页表被主机标识为"仅读"。

– 主机用软件构建和管理。

– 客户机从未没有看见"真实的"页表或真实的CR3内容。

嵌套的分页机制(Nested Paging):CPU遍历客户机和主机页表

CPU映射每个Guest_PA到Host_VA,并接着翻译到Host_PA

CPU构建法例的gVA_to_hPA TLB条目(用ASID护卫)

比影子页表有效得多,CPU完成所有的处理。

X86-64处理器安全 02.png

SVM处理器和平台扩展

SVM硬件扩展分为下面几个部分:

  • 状态切换 指令VMRUN、VMSAVE、 VMLOAD,全局中断标识(Global Interrupt flag,GIF)以及处理GIF的指令STGI、CLGI,共同完成状态切换。

  • 拦截 允许VMM拦截客户机上的敏感操作。

  • 中断和APIC支持物理中断拦截,支持虚拟中断、APIC.TPR虚拟化。

  • SMM拦截和支持。

  • 外部的(DMA)访问保护。

  • 两级地址翻译的嵌套分页支持。

  • 安全SKINIT指令。

SVM硬件扩展提供了一套指令。当EFER.SVME设置为1时,指令VMRUN、VMSAVE、 VMLOAD、CLGI、VMMCALL和INVLPGA可用。否则,这些指令产生#UD例外。当EFER.SVME设置为1或ECX.SKINIT位设 置为1时,指令SKINIT和STGI可用,否则,产生#UD例外。

SVM扩展指令的定义列出如下(在linux26/drivers/kvm/svm.h中):

#define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda"#define SVM_VMRUN  ".byte 0x0f, 0x01, 0xd8"#define SVM_VMSAVE ".byte 0x0f, 0x01, 0xdb"#define SVM_CLGI   ".byte 0x0f, 0x01, 0xdd"#define SVM_STGI   ".byte 0x0f, 0x01, 0xdc"#define SVM_INVLPGA ".byte 0x0f, 0x01, 0xdf"

指令VMRUN与虚拟机控制块VMCB

指令VMRUN是SVM的基础,它使用一个参数:一个指向4KB对齐页的物理地址。该物理页描述了执行的虚拟机(客户机),称为虚拟机控制块(Virtual Machine Control Block,VMCB)。VMCB的内容包括:

  • 在客户机上将被拦截的指令或事件(如:写CR3)列表。

  • 各种控制位,用来指定客户机的执行环境或指示运行客户机代码之前的指定动作。

  • 客户机处理器状态(如:控制寄存器等)。

处理器通过物理地址访问VMCB,因此,它将VMCB映射为回写模式(Writeback,WB)内存。

指令VMRUN存储一些主机处理器状态在主机状态存储区,物理地址在 VM_HSAVE_PA MSR中定义,接着,它从VMCB状态存储区装载客户机状态。VMRUN还从VMCB读取附加的控制位,允许VMM刷新客户机TLB、抛出虚拟中断给客户 机等。然后,指令VMRUN检查刚装载的客户机状态,如果装载了不合法的状态,处理器将退出到主机。否则,处理器运行客户机代码直到有一个拦截事件发生, 在拦截点,处理器挂起客户机,并在VMRUN之后的指令恢复主机执行。

指令VMRUN存储或恢复最小量的状态信息,允许VMM在客户机退出后恢复运行。这样,VMM可以快速处理简单的拦截条件。如果VMM必须 存储和恢复附加的客户机状态信息,如:处理更加复杂的拦截操作或切换到不同的客户机,VMM可以使用命令VMSAVE和VMLOAD。

控制块VMCB包括处理器状态和控制位信息,描述VMCB的结构vmcb列出如下(在linux26/drivers/kvm/svm.h中):

struct __attribute__ ((__packed__)) vmcb {
	struct vmcb_control_area control;
	struct vmcb_save_area save;};

结构vmcb_save_area 描述了在操作系统切换时需要保存的处理器状态信息,它包括段寄存器、控制寄存器、状态标识寄存器等信息。该结构列出如下:

struct __attribute__ ((__packed__)) vmcb_save_area {
	struct vmcb_seg es;
	struct vmcb_seg cs;
	struct vmcb_seg ss;
	struct vmcb_seg ds;
	struct vmcb_seg fs;
	struct vmcb_seg gs;
	struct vmcb_seg gdtr;
	struct vmcb_seg ldtr;
	struct vmcb_seg idtr;
	struct vmcb_seg tr;
	u8 reserved_1[43];
	u8 cpl;
	u8 reserved_2[4];
	u64 efer;
	u8 reserved_3[112];
	u64 cr4;
	u64 cr3;
	u64 cr0;
	u64 dr7;
	u64 dr6;
	u64 rflags;
	u64 rip;
	u8 reserved_4[88];
	u64 rsp;
	u8 reserved_5[24];
	u64 rax;
	u64 star;
	u64 lstar;
	u64 cstar;
	u64 sfmask;
	u64 kernel_gs_base;
	u64 sysenter_cs;
	u64 sysenter_esp;
	u64 sysenter_eip;
	u64 cr2;
	u8 reserved_6[32];
	u64 g_pat;
	u64 dbgctl;
	u64 br_from;
	u64 br_to;
	u64 last_excp_from;
	u64 last_excp_to;};

(1)保存主机状态

为了确保在#VMEXIT后主机能恢复操作,指令VMRUN必须存储主机状态信息在新MSR VM_HSAVE_PA指定物理地址所在的VMCB上。这些信息包括:

  • CS.SEL, NEXT_RIP—跟随VMRUN之后指令的CS选择子和rIP。在#VMEXIT后,主机在这个地址恢复运行。

  • RFLAGS, RAX—主机处理器模式和VMRUN使用的寄存器,用于寻址VMCB。

  • SS.SEL, RSP—主机的栈指针。

  • CR0, CR3, CR4, EFER—主机的分页机制/操作模式。

  • IDTR, GDTR—伪描述符,VMRUN不存储或恢复主机LDTR。

  • ES.SEL和DS.SEL

(2)装载客户机状态

在存储主机状态后,VMRUN从VMCB装载随后的客户机状态,客户机状态说明如下:

  • CS和rIP—客户机开始在此地址执行,CS段寄存器的隐藏状态也从VMCB装载。

  • RFLAGS和RAX.

  • SS和RSP—包括SS寄存器的隐藏状态。

  • CR0, CR2, CR3, CR4, EFER—客户机分页方式、写页相关的控制寄存器,VMRUN不刷新TLB,因为切换了地址空间。

  • INTERRUPT_SHADOW—该标识指明客户机当前是否在中断关闭映像(Interrupt Lockout Shadow)中。

  • IDTR, GDTR。

  • ES和DS—包括段寄存器的隐藏状态。

  • DR7和DR6—客户机的断点状态。

  • V_TPR—客户机的虚拟TPR。

  • V_IRQ—该标识指明在客户机上的虚拟中断是否挂起。

  • CPL—如果客户机是实模式,CPL强制为0,如果客户机为v86模式,CPL强制为3,否则,使用存储在VMCB中CPL。

处理器检查装载的客户机状态的一致性。如果在装载客户机状态时,一致性检查失败,处理器执行一个#VMEXIT。

如果客户机按刚装载的寄存器进入PAE分页方式,处理器将还读取由新装载的CR3值所指向的第4级PDPE,在PDPE中设置任何保留位将引起#VMEXIT。

指令VMRUN可能装载客户机代码段限制之外的rIP或者非规范rIP(如果运行在长模式)。如果这种情况发生,处理器将在客户机内发送#GP。在客户机代码段之外的rIP失败不看作非法的客户机状态。

在所有客户机状态已被装载、中断和其他控制位建立后,处理器通过设置GIF为1来再次打开中断。它假定VMM软件以前已清除了GIF。

(3)控制位

指令VMRN除了装载客户机状态外,它还可从VMCB读取各种控制域,这些的大部分不会在#VMEXIT时写回到VMCB,因为在客户机执行时不会改变。控制域说明如下:

  • TSC_OFFSET—当客户机读取TSC(time stamp counter,时间戳计数器)时的加数偏移。客户机写TSC的操作可通过改变偏移地址来拦截或模拟,而不用写物理TSC。当客户机退回到主机时,清除这个偏移。

  • V_INTR_PRIO, V_INTR_VECTOR, V_IGN_TPR—用于描述客户机虚拟中断的域。

  • V_INTR_MASKING—用来控制中断的掩码(EFLAGS.IF和 TPR中)是否虚拟化。

  • 地址空间ID(Address Space ID,ASID) 在运行客户机时使用。

  • 在VMRUN期间控制TLB刷新的域。

  • 用描述客户机已激活拦截的拦截向量。当从客户机退出时,系统清除了内部拦截寄存器,因此,不会拦截主机操作。

在VMCB中,控制域结构vmcb_control_area列出如下(在linux26/drivers/kvm/svm.h中):

struct __attribute__ ((__packed__)) vmcb_control_area {
	u16 intercept_cr_read;       //拦截CR的读操作
	u16 intercept_cr_write;
	u16 intercept_dr_read;
	u16 intercept_dr_write;
	u32 intercept_exceptions;
	u64 intercept;
	u8 reserved_1[44];
	u64 iopm_base_pa;
	u64 msrpm_base_pa;   //SVM MSR许可映射物理基地址
	u64 tsc_offset;
	u32 asid;           // 地址空间ID(Address Space Identifier,ASID)
	u8 tlb_ctl;
	u8 reserved_2[3];
	u32 int_ctl;
	u32 int_vector;    //中断向量
	u32 int_state;      //中断状态
	u8 reserved_3[4];
	u32 exit_code;      //鉴别拦截发生的原因
	u32 exit_code_hi;
	u64 exit_info_1;    //IO拦截触发时描述拦截操作的信息
	u64 exit_info_2;    //存放跟随IN/OUT之后指令的rIP
	u32 exit_int_info;   //客户机通过IDT分发中断或例外时,标志拦截是否发生
	u32 exit_int_info_err;
	u64 nested_ctl;
	u8 reserved_4[16];
	u32 event_inj;       //VMM抛出给客户机的中断或例外(称为事件)
	u32 event_inj_err;
	u64 nested_cr3;
	u64 lbr_ctl;
	u8 reserved_5[832];};

#VMEXIT

当一个拦截操作触发时,处理器执行#VMEXIT操作(如:从客户机退出到主机上下文)。在#VMEXIT操作中,处理器的动作说明如下:

  • 通过清除GIF关闭中断,这样,在#VMEXIT后,VMM软件可以自动完成状态切换。

  • 将当前的客户机状态写回到VMCB—与指令VMRUN装载时一样的处理器状态的子集,包括V_IRQ、V_TPR和INTERRUPT_SHADOW位。

  • 在VMCB的域EXITCODE存储退出客户机的原因,根据拦截操作的情况,在EXITINFO1或 EXITINFO2域存放附加信息。

  • 清除所有的拦截。

  • 重复位当前的ASID寄存器(主机ASID)到0。

  • 清除在处理器内的V_IRQ和V_INTR_MASKING位。

  • 重装载以前指令VMRUN存储的主机状态。处理器重装载主机的CS、SS、DS和ES段寄存器,如果需要,从主机的段描述子表中重读取 描述子。段描述子表必须映射为主机页表可写的。执行VMRUN指令时,软件应该保持主机的段描述子表与段寄存器一致。刚在#VMEXIT之后时,处理器还 含有LDTR的客户机值。因此,对于CS、SS、DS和ES来说,VMM必须仅从全局描述子表中使用段描述子。当重装载主机段时,系统遇到任何例外将引起 关机。

  • 如果主机在PAE模式,处理器从主机CR3所指示的页表中重装载主机的PDPE。如果PDPE含有非法状态,处理器将关机。

  • 强制CR0.PE = 1和RFLAGS.VM = 0。

  • 设置主机CPL到0。

  • 检查重装载主机状态的一致性,任何错误将引起处理器关闭。如果#VMEXIT重装载的主机rIP在主机的代码段限制之外或者是非规范的,在主机内系统分发#GP错误。

拦截操作

客户机中的各种指令和事件(如:例外)可通过VMCB中的控制位拦截。SVM支持的两类主要的拦截为指令拦截和例外拦截。

  • 例外拦截

当正常指令处理必定产生一个例外时,系统检查例外拦截。此检查发生在解决可能的双重出错条件(指在例外中产生了第二个例外的条件)并尝试分发例外(包括压栈例外帧、访问IDT等)之前,

对于某些例外,处理器还写某些例外特定的寄存器,即使此例外被拦截。当一个外部的或虚拟的中断被拦截时,中断将被挂起。

当在客户机用IDT正处理分发非拦截中断或例外,而一个拦截发生时,SVM在#VMEXIT提供附加信息。

  • 指令拦截

指令拦截发生在指令执行完、在指令的结果提交前,指令拦截按与指令例外检查相关的拦截特定优先级排序。通常,指令拦截在简单例外(如:CPL不正常引发的#GP例外)检查之后、但在与内存访问相关的例外(如:页出错)和基于特定操作数值的例外之前进行检查。

拦截操作的机制说明如下:

(1)退出时状态存储

当拦截操作触发时,它写EXITCODE到VMCB,用来鉴别拦截的原因。EXITINTINFO域给出信号,表示当客户机尝试通过IDT 分发中断或例外时是否发生拦截操作。VMM能透明地使用这些信息完成中断或例外的分发。一些拦截操作还在VMCB的EXITINFO1和 EXITINFO2域中提供附加信息。

存储在VMCB中的客户机状态是拦截触发时的处理器状态。在x86构架上,处理器在触发陷阱指令执行之后检测指令陷阱(与出错相反),同样,陷阱拦截发生在指令例外执行之后。存储的客户机状态因此包括指令执行的效果信息。

例如:假定一个客户机指令触发了一个数据断点(#DB)陷阱,该陷阱被依次拦截。VMCB在此指令执行后记录了客户机状态,以便存储的CS:IP指向后续的指令,并且存储的DR7包含了匹配数据断点的结果信息。

(2)在IDT中断分发期间拦截操作

在客户机尝试通过IDT分了一个例外或中断(如:因为VMM分页超出客户机的例外栈产生#PF例外)时,拦截操作可能发生。某些情况下,这 样的拦截可能导致客户机再恢复所需要信息的丢失。例如:在一个外部中断中,处理器已执行中断识别周期,PIC和APIC已获知中断类型和向量,中断因此不 再挂起。

为了从这种情况下恢复,所有拦截指示(在VMCB的EXITINTINFO域)它们是否发生在例外 或中断通过IDT分发期间。这种机制允许VMM完成拦截的中断分发,即使当重创建事件是不再可能的。

(3)指令拦截

指令拦截操作会读写处理器的控制寄存器CRn、调试寄存器DRn、段寄存器等资源的指令,VMM将处理拦截操作。

(4)IOIO拦截

VMM能通过SVM I/O许可映射拦截IOIO指令IN, OUT, INS和OUTS。I/O许可映射(I/O Permissions Map,IOPM)占用12K字节连续的物理内存,表是64K+3位的线性数据结构,并且它在4K字节边界对齐。IOPM的物理基地址在VMCB的 IOPM_BASE_PA域定义,由指令VMRUM装载进处理器。指令VMRUN忽略指定在VMCB中地址的低12位。如果表中最后字节的地址大于或等于 最大支持物理地址,VMCB将被当作不合法的,并引起一个#VMEXIT(VMEXIT_INVALID)。

表中的每一位与一个8位I/O端口对应,第0位对应端口0,第1位对应端口1,等等。每个设置为1的位表示相应的端口被拦截。IOPM通过物理地址访问,它应该以回写方式驻留内存。

如果设置了IOIO_PROT拦截位,表示IOPM表控制端口访问,对于访问多于一个字节的IN/OUT指令来说,检查所有字节的许可位都会被检查,如果任何位设置为1,I/O操作都会被拦截。

与虚拟x86模式、IOPL或TSS位图相关的例外在SVM拦截之前被检查。所有其他的例位在SVM拦截检查之后被检查。

当IOIO拦截触发时,描述拦截操作的信息存放进VMCB的EXITINFO1域中。

(5)MSR拦截

VMM能通过SVM MSR(Model-specific register,MSR模型特定寄存器)许可映射(MSR Permissions Map,MSRPM)拦截REMSR和WRMSR指令。MSR许可位图由许多独立的2K字节位图组成,每个位图覆盖8K MSR的范围。4个这样的位图占据2个物理页(8KB覆盖32K MSR)。

如果MSR_PRO拦截激活,任何尝试读写位图没覆盖的MSR将自动引起一个拦截。系统通过物理地址访问MSRPM,它以回写的方式存放在 内存。MSRPM以4KB边界对齐,在VMCB中的MSRPM_BASE_PA域定义物理基地址,VMRUN指令将MSRPM装载进处理器。

如果在VMCB的拦截向量中的MSR_PROT位被清除,系统不会拦截指令RDMSR/WRMSR。在#VMEXIT时,处理器在VMCB 的EXITINFO1中指示RDMSR (EXITINFO1 = 0) 或WRMSR (EXITINFO1 = 1)是否被拦截。

(6)例外拦截

当拦截定义了一个错误代码的例外(通常错误代码压到例外栈上)时,SVM硬件分发错误代码到VMCB的EXITINFO1域,例外向量号从 EXITCODE派生。存放在VMCB中例外拦截上的CS.SEL和rIP与压向例外栈的相匹配。除了基于中断的指令引起的拦截外,指令的rIP而不是下 一个指令的rIP存放在VMCB。基于中断的指令是INT3(操作码CC)、INTO和BOUND.

外部中断和软件中断(INTn指令)不检查例外拦截,即它们使用0到31范围内的向量。发生在处理更早的例外期间的例外,在联合更早例外(联合成双出错double-fault)之前检查拦截。如果联合例外的结果是双出错或关闭,处理器在尝试分发之前检查拦截的例外。

例如:假定VMM拦截#GP和#DF例外,并且客户机产生(非拦截的)例外#NP,在它还得到#GP(由于不合法的IDT条目)的分发期 间,按x86语法,将导致#DR。这种情况下,#VMEXIT产生拦截#GP而非拦截#DF的信号,并且用#NF出错填充EXITINTINFO。另一方 面,如果仅#DF拦截被激活,#VMEXIT将产生一个拦截#DF的信号。

(7)中断拦截

当外部中断被拦截时,它将引起一个#VMEXIT。中断保持在挂起状态,以便系统最终在VMM中接受中断。例外拦截不应用到外部或软件中断,因此,不能通过例外拦截来拦截一个中断,即使中断发生的0到31范围之内的向量。

(8)其他拦截

SVM构架包括处理任务切换、处理器由于FERR突然停止和关闭操作的拦截。

引起任务切换的任何指令或事件(如:JMP, CALL, 例外, 中断, 软件中断)检查任务切换拦截,拦截在任务切换之前、在TSS和任务门检查正确性之前检查。

指令VMSAVE和VMLOAD

指令VMSAVE和VMLOAD获取在rAX中的物理地址,补充VMRUN指令和#VMEXIT的状态存储/恢复能力。它们提供了对软件不能访问的隐藏处理器状态的访问以及对附加的特权状态访问。

VMSAVE存储下面状态到VMCB:

  • FS, GS, TR, LDTR (包括所有隐藏状态)

  • 内核GS基地址KernelGsBase

  • STAR, LSTAR, CSTAR, SFMASK

  • SYSENTER_CS, SYSENTER_ESP, SYSENTER_EIP

VMLOAD从VMCB装载相应的状态。VMLOAD和VMSAVE仅在CPL-0并且在打开SVM的保护模式下可用。

TLB控制

TLB条目用地址空间ID(Address Space Identifier,ASID)标记,用来区分主机或客户机地址空间。VMM可以选择软件策略,在处理器中保持多个影子页表(Shadow Page Tables,SPT)和多个嵌套的页表,支持嵌套的页更新。这样,可以不刷新TLB切换到客户机中的新进程。例如:新CR3值意味着新SPT或嵌套的页 表。

对每个客户机地址空间,VMM负责建立影子页表或嵌套的页表,映射客户机线性地址到系统物理地址。在影子分页中,VMM应该设置客户机的 VMCB中的CR3域指向该影子页表的系统物理地址。当客户机改变页表或页控制状态时,VMM负责更新影子页表,并且VMM应该更新客户机页表的访问位 (Access Bit)和脏位(Dirty Bit)。

VMRUN指令和#VMEXIT写寄存器CR0, CR3, CR4和EFER,这些写操作不刷新TLB。VMM负责明确地使客户机页翻译机制失效。

当处理器在SVM(安全虚拟机,Security Virtual Machine)打开下运行时,全局的页表条目(Page Table Entrie,PTE)仅在一个ASID内是全局的,不能跨越ASID。

在软件上,当VMM通过改变客户机的VMCB来改变客户机的分页模式时,VMM必须确保客户机的TLB条目从TLB刷新。

TLB刷新操作在SVM打开下起作用,TLB刷新操作必须不影响所有的ASID。如果VMM为任何客户机刷新TLB的动作设置拦截 位,#VMEXIT拦截发生,并且不刷新TLB。VMM负责刷新TLB。处理器不刷新单个ASID的所有页翻译,软件可以有效地刷新客户机的TLB条目, 它给客户机分配新ASID而不再使用旧的ASID,直到整个TLB条目被刷新。

在VMCB中的TLB_CONTROL 有一个命令实现,当VMM设置TLB_CONTROL域为非作歹时,指令VMRUN为所有的ASID、全局和非全局的页刷新TLB。VMRUN指令读取但不修改TLB_CONTROL域的值。

一条新指令INVLPGA允许VMM选择性地使TLB对一个给定虚拟页和给定的ASID映射失效。线性地址存放在隐含寄存器操作数rAX中,ASIC存放在ECX中。

事件抛出

VMM可以通过在执行VMRUN之前设置VMCB的EVENTINJ域抛出例外或中断(统称为事件)到客户机。

当一个事件被抛出时,指令VMRUN引起客户机在执行第一个客户机指令之前无条件地接受指定的例外或中断。客户机将抛出的事件看作象在客户机上正常发生的一样,特别的是,它们记录在EXITINTINFO域。客户机抛出事件有下面一些不同:

  • 抛出的事件不接受拦截检查。但是,如果在拦截事件分发期间发生了第二次例外,这些例外接受例外拦截。

  • 一个抛出的NMI不阻塞更多的NMI的分发。

  • 如果VMM尝试抛出一个客户机上不可能的事件(如:当客户机在64位模式时的#BR例外),事件抛出将失败,客户机不执行任何客户机状态指令,VMRUN将立即退出,产生错误代码VMEXIT_INVALID。

中断和本地APIC支持

SVM硬件确保了有效的中断虚拟化。

(1)在EFLAGS中的物理中断掩码

为了阻止客户机阻塞可掩码中断(INTR),SVM提供了VMCB控制位V_INTR_MASKING,它通过CR8寄存器改变了EFLAGS.IF的操作和对TPR的访问。

当运行V_INTR_MASKING清除为0的客户机时,EFLAGS.IF控制虚拟和物理中断。

当运行V_INTR_MASKING设置为1的客户机时,主机EFLAGS.IF在VMRUN时存储,并在客户机运行时控制物理中断,EFLAGS.IF的客户机值仅控制虚拟中断。

(2)虚拟化APIC.TPR

SVM提供了一个客户机使用的虚拟TPR寄存器V_TPR,VMRUN从VMCB装载它的值,#VMEXIT将它的值写回到VMCB。APIC的TPR总是为物理中断控制任务优先级,V_TPR总控制虚拟中断。

当将V_INTR_MASKING清除为0时运行客户机,对CR8的写操作仅V_TPR寄存器,从CR8的读操作就像没有SCM一样。

当将V_INTR_MASKING设置为1时运行客户机,对CR8的写操作影响APIC的TPR和V_TPR寄存器,从CR8的读操作返回V_TPR。

(3)在32位模式下的TPR访问

为了改进32位模式下TPR访问效率,SVM通过可替换的编码"MOV TO/FROM CR8"使CR8在32位模式可用。为了获得更好的执行效率,32位客户机应该修改为使用该访问方法,代替传统的内存映射TPR。

(4)抛出虚拟中断

虚拟中断允许主机传递一个中断(#INTR)到客户机。在客户机内部,虚拟中断遵循与真实中断一样的规则,虚拟#INTR直到EFLAGS.I设置为1时,才被接受,客户机的TPR在与挂起的虚拟中断同样的优先级下打开中断。

SVM提供了有效的机制,让VMM能抛出虚拟中断给一个客户机:

  • VMM通过打开在VMCB中的INTR拦截,能在客户机正运行时拦截到达的物理中断。

  • VMM能通过设置在VMCB中的V_INTR_MASKING位虚拟化中断掩码逻辑。

  • VMCB的V_IRQ, V_INTR_PRIO和V_INTR_VECTOR指示是否有虚拟中断挂起、如果有挂起,它向量号和优先级是什么,VMRUN指令装载这些信息到相应的片上寄存器。

  • 如果虚拟中断满足下面条件,处理器接受一个虚拟INTR:

- V_IRQ和V_INTR_PRIO指示有一个虚拟中断挂起,它的优先级大于V_TPR的值。

- EFLAGS.IF设置为1,表示中断已打开。

-用GIF打开中断,并且处理器不在中断影子中。

虚拟INTR处理和正常中断处理其他区别是,虚拟中断向量从V_INTR_VECTOR寄存器获取,正常中断到本地APIC运行INTAK周期得到。

  • VMCB的V_IGN_TPR域能设置表示:当前挂起的虚拟中断不服从TPR的掩码。这种情况下,忽略对V_TPR的优先级比较。这种机制用于抛出ExtINT类型中断给客户机。

  • 当处理器分发虚拟中断(通过IDT)时,在检查虚拟中断的拦截后、在访问IDT之前,VMM清除V_IRQ。

  • 在#VMEXIT时,系统写回V_IRQ到VMCB,允许VMM跟踪虚拟中断是否被接受。

  • 物理中断优先级高于虚拟中断,不管是直接还是通过#VMEXIT接受中断。

  • 在#VMEXIT时,处理器清除它内部V_IRQ和V_INTR_MASKING的拷贝,因此,虚拟中断不保留在VMM中的挂起,中断控制转向正常。

(5)中断影子

x86构架定义了中断影子(Interrupt Shadow)的概念:在中断不被识别期间的一个单条指令窗口。例如:在设置EFLAGS.IF(从0设置为1)的STI指令之后的指令,不识别中断或某 个调试陷阱。VMCB的INTERRUPT_SHADOW域指示客户机当前是否在中断映像中,该信息在#VMEXIT时存储,在VMRUN时装载。

(6)虚拟中断拦截

当虚拟化中断处理时,在客户机的新中断到达或产生,并且客户机发生EOI(End-Of-Interrupt,中断结束)情况下,VMM通常仅需要获得控制权。在某些情况下,VMM在客户机打开中断时必须获取控制权,VMM通过打开VINTR拦截实现控制权的获取。

(7)在本地APIC中的中断掩码

当客户机直接访问设备时,到达本地APIC的中断通常被拥有引起中断的设备的客户机删除。为了保护一个客户机锁住其他客户机的中断,VMM可以掩码挂起本地APIC的中断,这样,它们不加入到其他中断的优先级。

SVM引入了下面的APIC特征:

  • 加入一个256位IER(Interrupt Enable Regiser,中断使能寄存器)到本地APIC,该寄存器得到复位到1(打开所有256个向量)。软件能通过内存映射的APIC页读写IER。

  • 仅在IER中打开的向量参与最高优先级挂起中断的APIC计算。

  • VMM能发出指定的中断结束(end-of-interrupt,EOI)命令给本地APIC,允许VMM以任何次序清除挂起的中断,而不是用最高优先级设置中断。

(8)INIT支持

INIT发信号在下一个指令边界中断处理器,并引起一个非条件控制转移。INIT用类似RESET#的方式重初始化控制寄存器、段寄存器和 GP寄存器,但不改变大多数MSR、Cache或数据协处理器(x87或SSE)状态,并接着转移控制给与RESET#同一指令地址(物理地址 FFFFFFF0h)。不像RESET#,INIT不想对内存控制器可见,因此,不会触发通过内存控制器硬件对可信内存页的自动清除。

为了维持这些页的安全,VMM能请求将INIT重定向,并通过设置VM_CR MSR的R_INIT位转换成#SX例外。这允许请求INIT时VMM获取控制权。VMM可以因此关闭INIT的重定向,并接着引起平台重声明INIT, 处理器将以正常方式对INIT作出响应。

(9)NMI支持

VMM能用VMCB控制位拦截非屏蔽中断(non-maskable interrupt,NMI),在拦截时,NMI引起系统从客户机退出并保持挂起状态。

SMM支持

SMM(System Management Mode,系统管理模式)对处理器的虚拟化提供了支持。

(1)SMI的源

各种事件可能引起系统管理中断(system management interrupt,SMI)的声明,这些事件分为三类,分别说明如下:

  • 内部的、同步的(也称为I/O陷阱)—在CPU中产生陷阱的处理器构架特定IOIO或配置空间,对IN或OUT指令的响应总是同步的。系统通过MSR建立I/O陷阱,并通过拦截客户机对这些MSR的访问将I/O陷阱放在VMM的控制下。

  • 外部的、同步的—对IN或OUT指令响应产生IOIO陷阱,但该陷阱由外部代理(通常是南桥)产生。

  • 外部的、异步的—对外部的物理事件(如:合上笔记本电脑、温度传感器触发等)响应产生IOIO陷阱。

(2)对SMI作出的响应

通过拦截SMI,VMM可以在处理器进入SMM之前获取控制。

(3)包装平台SMM

在某些使用场景,VMM可以不信任平台SMM代码或可以确保SMM不在某客户机或系统管理程序下操作。在这种情况下,SVM提供了包装SMM代码的能力等 ,用代替VMM的完全保护机制在客户机内运行SMM。其他情况下,VMM不能在SMM之上实行控制。

VMM通过3种方法控制SMM处理程序:

  • 最简单的解决方法是不拦截SMI信号。从客户机上下文内部提取上下文时,系统会遇到SMI ,这时,SMM处理程序不接受任何VMM建立的拦截,并随后运行在虚拟控制之外。SMM处理程序所见的状态(存放在SMM状态存储区)反映了客户机正运行 在遇到SMI时的状态。当SMM处理程序执行了RSM指令,处理器返回到在客户机上下文运行,并且SMM处理程序对SMM状态存储区所做的任何修改反映在 客户机状态中。

  • 一个系统管理程序(Hypervisor)可能想为一个客户模拟所有基于SMI的I/O拦截,并接受在系统管理程序上下文中的信号。 Hypervisor应该设置所有的IOIO拦截位和客户机的SMI拦截位,确保运行客户机时不遇到同步的SMI信号。遇到的任 何#VMEXIT(SMI)是由外部的、异步的SMI引起的。Hypervisor通过执行STGI指令对#VMEXIT(SMI)作出反映,该命令引起 立即接受挂起的SMI。当由于I/O指令挂起产生的SMI时,在Hypervisor中执行STGI的结果是不确定的。为了处理由于I/O指令引起的挂起 的SMI,Hypervisor必须包装SMM或不拦截SMI。

  • 最复杂的解决方法是包装SMM,把它放到客户机中。包装或以让VMM完全控制SMM处理程序能访问的状态。

VMM可以包装SMM,VMM创建它自己的可信的SMM Hypervisor,并在包装中使用该SMM处理程序运行平台SMM代码。SMM Hypervisor可以与VMM本身同样代码,或者可以是完全不同的代码。可信的SMM Hypervisor建立客户机上下文,以客户机运行平台SMM。客户机上下文由一个VMCB、相关的状态和客户机(真实或虚拟的)SMM存储区组成。 SMM Hypervisor仿真SMM条目,包括SMM存储区的建立和在SMM操作结束时仿真RSM。客户机代替地用合适的SVM拦截在分页的实模式中执行平台 SMM代码,这样,确保了安全。

为了完成工作,VMM可能需要写SMM_BASE MSR和相关的SMM控制寄存器。作为仿真SMM条目和RSM的一部分,VMM需要访问SMM_CTL MSR。但与任何BIOS相冲突的动作将锁住SMM控制寄存器。

VMM能通过检查在HWCR MSR中的SMMLOCK位,判断它是否与合适的BIOS一起运行。如果该位设置为1,表示BIOS已锁住SMM控制寄存器,并且VMM不能删除它们或插入它自己的SMM Hypervisor。

当处理器物理上进入SMM,它重映射SMRAM区域。VMM设计必须确保当SMRAM区域映射或取消映射时,没有VMM的代码或数据丢失。 还应注意SMRAM的ASEG区域与视频内存部分重叠,因此,SMM Hypervisor不应尝试写诊断消息到屏幕。客户机尝试重定义SMRAM的任何区域(通过MSR写)必须被拦截,以阻止恶意SMM代码干扰VMM操 作。

如果BIOS已锁住了SMM控制寄存器,对SMM_CTL MSR的写引起例外#GP。

上次分支记录的虚拟化

AMD64调试控制MSR(DebugCtl)提供了控制传输记录和其他调试任务的处理器控制。软件设置上次分支记录(last-branch record,LBR)位DebugCtl.LBR为1时,引起处理器在一个调试例外之前记录上次控制传输使用的源地址和目标地址。记录信息存在4个 MSR(模型特定寄存器)中,分别说明如下:

  • LastBranchFromIP—存放源指令指针(rIP)的段偏移。

  • LastBranchToIP—存放目标rIP的段偏移。

  • LastExceptionFromIP—在中断和例外期间用LastBranchFromIP以前的值更新,除了调试断点和ICEBP引起的#DB例外。

  • LastExceptionToIP—在中断和例外期间用LastBranchToIP以前的值更新,除了调试断点和ICEBP引起的#DB例外。

在SVM下,控制传输记录MSR的内容必须在主机和客户机跟踪的值之间交换。这可通过打开在客户机VMCB控制域中的LBR虚拟化来实现。

(1)打开LBR虚拟化

设置VMCB控制域的LBR_VIRTUALIZATION_ENABLE位为1,可以打开LBR虚拟化。当LBR虚拟化打开时,VMM存放DebugCtl MSR的映像,并且每个指针存放在VMCB存储区4个域的控制传输记录MSR中。

DBGCTL—持有DebugCTL MSR的客户机值。

BR_FROM—持有LastBranchFromIP MSR 的客户机值。

BR_TO—持有LastBranchToIP MSR的客户机值。

LASTEXCPFROM—持有LastExceptionToIP MSR的客户机值。

LASTEXCPTO—持有LastExceptionFromIP MSR的客户机值。

(2)主机和客户机LBR虚拟化

当设置了VMCB.LBR_VIRTUALIZATION_ENABLE[0]时,VMRUN存储所有5个主机控制传输MSR到主机存储 域,并接着从VMCB装载客户机的同样的5个MSR。类似地,#VMEXIT存放客户机的MSR到相应的存储区,并且从相应的存储区装载主机的MSR。

(3)LBR虚拟化CPUID特征检测

当CPUID函数8000_000Ah返回EDX的第1位,它在AMD64处理器上报告LBR虚拟化特征。

外部访问检测

通过确保虚拟地址转换机制,VMM限制客户机CPU访问内存。但是,客户机应该可以直接访问有DMA能力的设备,这需要附加的保护机制。SVM提供 了多个保护域,这些域能基于每页限制设备访问物理内存。这通过北桥的主机桥的控制逻辑完成,北桥的主机桥监管任何外部访问端口(如:PCI等)。

北桥的主机桥提供了大量的保护域。每个保护域有一个与它相关的设备独占向量(Device Exclusion Vector,DEV),DEV指定了域中设备的每页访问权限。HyperTransport?总线/ unitID(设备ID)鉴别设备,并且主机桥俼固定尺寸的查找表,用来映射保护域的设备ID。

一个DEV是一个物理内存中连续的数组位,DEV中的每个位(小位字节序)与物理内存中的一个4K字节页相对应。DEV的基物理地址必须是 4K字节对齐,并存放在一个DEVBASE寄存器中,在主机桥的DEVCTL PCI配置空间功能块中,系统通过一个间接机制访问DEVBASE寄存器。DEV保护硬件通过设置在DEV控制寄存器中的控制位(也在DEVCTL功能块 中)来打开。

访问检查说明如下:

(1)内存空间访问

当系统在一个外部主机桥上接收到一个内存空间读写请求,主机桥映射HyperTransport总线设备ID到一个保护域号,保护域号依次 选择定义设备访问许可的DEV。主机桥接着对DEV内容检查内存地址,用地址(39-12位)PFN端口索引到DEV。在DEV内PFN用作位索引。如果 从DEV读出的位为1,主机桥通过对读请求的数据返回全1来禁止访问,或者在写请求时,禁止存储操作。一个Master Abort错误响应将返回给请求的设备。

路由到主机桥的对等内存访问也需要接受对DEV的检查,可以不检查发生在桥之后的对等传输。

(2)I/O空间访问

主机桥能通过设备DEV_CR控制寄存器的IOSPE位,配置为拒绝所有来自设备的I/O空间访问。系统不检查在桥之后的I/O空间对等传输。

(3)配置空间访问

系统通过访问PCI配置空间的控制寄存器配置主机桥功能的主要方面。因为通过设备对等传输它是潜在可访问的,因此,主机桥总是阻塞非CPU的设备对这个空间的访问。

嵌套的分页

可选的SVM嵌套分页(Nested Paging)特征提供了两级地址翻译,这样,消除了VMM需要维护影子页表(shadow page table)的需要。

(1)传统分页与嵌套分页的比较

图2显示了显示了在传统(单级)地址翻译中线性地址空间的一页如何映射到物理地址空间的一页,控制寄存器CR3含有页表(page table,PT)基地址的物理地址,它控制着地址翻译。

X86-64处理器安全 03.png

图2 传统分页下的地址翻译

当嵌套分页机制打开时,系统使用2级地址翻译,嵌套分页机制如图3所示。

X86-64处理器安全 04.png

图3 嵌套分页下的地址翻译

图3中的嵌套分页机制说明如下:

客户机和主机有它们自己的CR3的拷贝,分别称为gCR3和nCR3。

客户机的页表(称为Guest page tables,gPT)映射客户机线性地址到客户机物理地址。客户机页表在客户机gCR3所指向的物理内存中。

嵌套页表(Nested page tables,nPT)映射客户机物理地址到系统物理地址,嵌套的页表在nCR3所指向的系统物理内存中。

最近使用的从客户机线性地址到系统物理地址的翻译用高速缓存存在TLB中,并被随后的客户机访问。

值得注意的是,gCR3和客户机页表条目含有客户机物理地址,而不是系统物理地址。因此,在访问客户机页表条目之前,表查询者(table walker)先翻译条目的客户机物理地址到系统物理地址。

VMM可以给每个客户机一个不同的ASID,以便来自不同的客户机的TLB条目共存在TLB中。ASID值0保留给主机用。如果VMM尝试执行客户机ASID为0的VMRUN,结果将是#VMEXIT(VMEXIT_INVALID)。

(2)复制的状态

大多数影响分页的处理器状态复制为主机和客户机的状态,包括分页寄存器CR0, CR3, CR4, EFER 和PAT。CR2不被复制但由VMRUN装载,系统不复制MTRR。

当嵌套分页机制打开时,x86代码(如:MOV to/from CRn等)对所有(客户机)分页机制寄存器的状态的引用,读和写寄存器客户机的拷贝,寄存器的VMM的版本是不可改动的,并继续控制从客户机物理地址到系 统物理地址的第二级翻译。与之相对,当嵌套分页机制关闭时,VMM的分页控制寄存器被存放在主机存储区,并且来自客户机VMCB的分页控制寄存器是这些寄 存器中仅激活的版本。

(3)打开嵌套分页机制

当在VMCB中的NP_ENABLE位设置为1时,指令VMRUN开启嵌套分页机制。VMCB含有页表的hCR3值,用于额外翻译。当额外翻译执行最近的VMRUN时,它使用与VMM一样的分页模式。#VMEXIT自动关闭嵌套的分页机制。

仅当主机打开分页机制时,系统才允许嵌套的分页机制。CPUID功能8000_000A.EDX[0]指明嵌套的分页机制是否可用。如果将 hCR0.PG清除到0,并且NP_ENABLE设置为1运行VMRUN,则VMRUN用#VMEXIT(VMEXIT_INVALID)终止执行。

(4)嵌套分页机制和VMRUN/#VMEXIT

当VMRUN运行在嵌套分页机制打开(NP_ENABLE = 1)时,分页寄存器受到的影响说明如下:

VMRUN存储所有VMM的CR3在主机存储区。

VMRUN从客户机VMCB装载客户机分页状态到客户机寄存器(如:VMRUN将VMCB CR3域装进CR3)。在VMCB的G_PAT域装进客户机PAT寄存器。

VMRUN装载nCR3,它是嵌套分页客户机运行的CR3的版本,来自VMCB的N_CR3域。其他主机分页控制位(如:hCR4.PAE)保持它们在VMM中VMRUN执行时同样的值。

当VMRUN在嵌套页机制打开(NP_ENABLE = 1)运行时,下面任何一种条件都被认为是非法的(它们也用于规范化和一致性检查):

设置了nCR3的任何MBZ位。

任何 G_PAT.PA域有不支持的类型编码或在G_PAT中任何保留域为非0值。

当在嵌套分页机制下的#VMEXIT发生时,#VMEXIT的操作说明如下:

#VMEXIT将客户机分页状态(如:gCR3, gCR0)写回到VMCB。nCR3不存回到VMCB。

#VMEXIT不需要重装载任何主机分页状态,除了CR3外,不需要从主机存储区装载任何主机分页状态。

(5)嵌套表遍历

当客户机在嵌套分页打开运行时,TLB失靶引起几个嵌套页表遍历(Nested Table Walk):

客户机页表—寄存器gCR3指定客户机物理地址,就象客户机页表条目一样。这些客户机物理地址必须使用嵌套页表翻译成系统物理地址。当进行包括由于在嵌套页表中访问设置和脏位引起的写出错时,嵌套页表级出错发生。

最后的客户机物理页(Final Guest-Physical Page)—一旦客户机对客户机物理映射线性化,系统可以检查客户机许可。如果客户机页表允许访问,系统遍历在嵌套页表中的客户机物理地址,找到对应的系统物理地址。

客户机页表的表遍历总是看作用户对嵌套页表级的写操作。因此,页的一些特殊要求说明如下:

在嵌套页表级,页对用户应是可写的,否则,将产生#VMEXIT(NPF)。

嵌套页表条目的脏和访问位应被设置,在为客户机页表条目进行的嵌套页表遍历期间,脏和访问位会被改动。

(6)嵌套页与客户机页出错、出错排序

在嵌套分页机制中,页出错可能在客户机或嵌套页表级产生。嵌套的遍历将按下面次序进行,也在同样次序产生出错:

1)在嵌套的页表中遍历客户机页表条目,需要时,设置在嵌套页表中的脏/访问位。任何嵌套页表出错将导致产生#VMEXIT(NPF)。

2)当客户机页表遍历从页表顶部到最后条目进行时,在客户机遍历的每级中,客户机页表条目里任何不出现(notpresent)条目或保留位将引起在客户机中引起#PF。在遍历期间,需要时在客户机页表中设置客户机脏和访问位。穿过的每级客户机页表重复第1和第2步骤。

3)一旦客户机访问的客户机物理地址已确定,系统检查客户机许可,任何出错将在客户机中引起#PF。

4)用嵌套页表执行从客户机物理地址到系统物理地址的翻译工作,在翻译期间的任何出错将导致产生#VMEXIT(NPF)。

嵌套页出错是嵌套页表和VMM处理器模式的一个功能。嵌套出错对VMM引起#VMEXIT(NPF)。出错的客户机物理地址存入VMCB的EXITINFO2域,EXITINFO1分发一个类似于#PF的错误代码,错误代码说明如下:

位0 (P)—如果嵌套页不出现,清除为0,否则,设置为1。

位1 (RW)—如果嵌套页表级访问是一个写操作,设置为1.注意:为客户机页表进行的主机页表遍历总是看作数据写操作。

位2 (US)—总是为1,因为在嵌套级中所有客户机访问看作用户访问。

位3 (RSV)—如果在相应的嵌套页表系上中的保留位被设置,该位设置为1。

位4 (ID)—如果嵌套页表级访问是一个代码读,该位设置为1.注意:客户机页表的嵌套表遍历总是看作数据写,即使访问本身是一个代码读。

客户机出错是客户机页表和处理器模式的一个功能,它们在没有任何VMM干预下作为正常的#PF例外被分发,除非VMM正在拦截客户机#PF。

(7)将嵌套和客户机属性联合

任何对客户机物理内存的访问都需要通过在嵌套页表中检查客户机物理地址的映射来检查许可。

仅在客户机和嵌套页表级中页标识为可写的,系统才认为该页是可写的。注意:客户机的gCR0.WP仅影响客户机页表条目的解释,如果在嵌套 页表中,页标识为仅读,在客户机上设置gCR0.WP不能使用任何CPL级的页变为可写。在嵌套分页机制下,系统忽略主机hCR0.WP位。

仅在客户机和嵌套页表级中页标识为可执行的,系统才认为该页是可执行的。如果系统为客户机清除了EFER.NXE位,在客户机级上,所有的客户机页是可执行的。相似地,如果系统为主机清除了EFER.NXE位,在嵌套级以下所有映射的嵌套页表是可执行的。

系统仅从客户机页表和操作模式采用上属性。仅当在客户机页表中页标识为全局的,系统才在客户机内认为页是全局的,嵌套的页表条目和主机的hCR4.PGE是不相关的。全局的页仅在它们的ASID内是全局的。

仅当在客户机级页标识为用户页时,系统认为页是用户页。在嵌套页表中的页应该标识为用户页,以允许任何客户机可以访问。

(8)将内存类型和MTRR联合

处理器联合客户机和嵌套页表内存类型,影响内存类型的寄存器列出如下:

在嵌套和客户机页表条目中的PCD/PWT/PATi位。

在嵌套CR3和客户机CR3寄存器中的PCD/PWT位。

客户机PAT类型(通过索引gPAT寄存器获取)。

主机PAT类型(通过索引主机的PAT寄存器获取)。

MTRR(仅基于系统物理地址引用它们)。

gCR0.CD和hCR0.CD。

注意没有硬件支持客户机MTRR,VMM通过改变在嵌套页表中的内存类型来仿真它们的作用。注意:MTRR仅应用于系统物理内存。

当构建客户机TLB条目时,联合内存类型的规则说明如下:

嵌套的和客户机PAT类型按照表3的规则联合,产生一个"联合的PAT类型"。

表3 联合客户机和主机PAT类型

X86-64处理器安全 05.png

联合的PAT类型再与MTRR类型按表4的规则进一步联合,系统物理地址决定相关的MTRR。

表4 联合PAT和MTRR类型

X86-64处理器安全 06.png

gCR0.CD或hCR0.CD可以关闭高速缓存。

内存一致性问题 因为客户机使用格外的区域决定内存类型,与客户机相比,VMM可使用不同的内存类型访问给定的内存块。如果一块是可高速缓存而其他块不是,VMM和客户机 能观察不同的内存映像,这不是理想的办法,因为当VMM期望迁移一个虚拟处理器从一个物理处理器到另外一个时,多处理器系统对这个问题较敏感。

为了解决这个问题,x86-64使用了下面的机制:

VMRUN和#VMEXIT刷新写联合者。这确保所有对WC内存的写操作,不管内存类型如何,客户机对主机是可见的。这不能保证一个代码的WC读或写能观察到另一个代理可高速缓存的写操作。

引进了一个新内存类型WC+。WC+是一个非高速缓存的内存类型,并且像WC一样在写联合缓冲区中进行写操作。不像WC(但像CD内存类型),对WC+内 存访问也探查所有处理器上的高速缓存(包括发出请求处理器的自探查高速缓存),维护内存的一致性。这确保WC+访问可观察到可高速缓存的写操作。

当联合了与高速缓存不相适应的嵌套和客户机内存类型时,系统使用WC类型替换使用的WC+内存类型。表3显示了客户机和主机PAT类型联合成一个有效的PAT类型。表4显示了PAT类型如何与物理MTRR联合。

(9)页裂变

当客户机和有不同页尺寸的嵌套页表条目映射一个地址时,创建的TLB条目匹配较小页的尺寸。

(10)传统PAE模式

在嵌套分页的客户机中,PAE模式的行为稍微与传统PAE模式(仅在主机)有些不同,那就是在写CR3时,客户机的4个PDPE不装进处理器。代替 的方法是,系统按要求将PDPE作为一个表遍历的部分进行访问。这有副作用,当错误PDPE作为表遍历的一部分被访问时,在PDPE中不合法的位联合在写 CR3时不会被标识出来。这意味着当内存中的PDPE不同于处理器中的拷贝时,操作系统不能依赖于CR3中的位联合。

(11)A20掩码

没有规定应用于客户机物理地址的A20掩码,VMM可以通过改变嵌套页映射来仿真A20掩码。

(12)检测嵌套分页支持

嵌套分页是SVM的一个可选支持,CPUID指令可用来检测处理器是否支持嵌套分页。

安全

SVM为促进可信软件的构建提供了附加硬件支持。SVM提供了指令SKINIT和安全例外两种方式协助构建可信系统。指令SKINIT 和相关系统支持(如:可信平台模块)允许可信软件(如:VMM)启动时基于安全Hash比较的认证;安全例外(Security Exception,#SX)用于发出某一安全关键事件的信号。这两种分别说明如下:

(1)指令SKINIT

指令SKINIT用于创建可信根,用于启动初始不可信的操作模式。它再次初始化处理器,为称为安全装载器(Secure Loader,SL)的软件构件建立一个可信执行环境,并以不可打扰的方式开始SL的执行。指令SKINIT还拷贝SL执行映像到外部设备,例如:可信平 台模块,为了使用惟一的总线事务验证而拷贝SL,避免SKINT操作以TPM不易检测的方式被软件仿真。

在第一次认证软件的身份后,SL通常初始化SVM硬件和相关的数据结构,并初始化可信软件部分的执行,如:VMM。系统启动并运行在非可信模式下后,SKINIT给SVM提供了可靠保护,而不需要改变通常的x86平台启动过程。

安全装载器映像含有安全装载器的所有代码和数据部分。这些代码和初始的数据用于以完全安全的方式初始化和启动安全内核(Security Kernel),包括建立SL和SK使用内存的DEV保护。SL映像装载到称为安全装载块(Secure Loader Block, SLB)的内存区域,一般不大于64K字节。SL映像在SLB的字节偏移0处启动。

指令SKINIT在VMM获取控制之前使用。它获取SLB的物理基地址,输入操作数放在EAX中,并按下面的步骤执行操作:

1)用与INIT信号相同的方式再次初始化处理器,接着,进入关闭分页的扁平32位保护模式。

CS选择子设置为8h,CS设置为仅读方式。SS选择子设置为10h,并且SS是可读写和扩展的。CS和SS基地址清除为0,并限制设置为 4G。DS, ES, FS和GS为16实模式段,并且SL必须以保护模式选择子再装载它们,选择子在使用前必须有合适的GDT条目。

系统可以使用SS段重载前缀引用在SLB中的已初始化的数据,直到系统再装载DS。除了EZX外,系统清除其他的通用寄存器,EAX指向安 全装载器的开始处,EDX含有模型、处理器簇和步进信息,ESP含有安全装载器的初始栈指针。高速缓存内容保持为原封未动,与x87和SSE控制寄存器一 样。

除了可能SVM保护的MSR外,其他大多数MSR还保留它们的值。EFER MSR清除为0,在寄存器VM_CR中的DPD, R_INIT和DIS_A20M标识无条件设置为1.

2)通过清除EAX的15-0位形成SLB的基地址,并打开SL_DEV保护机制保护物理内存的64K字节区域,阻止任何设备访问。

3)在多处理器操作时,执行处理器间握手。

4)从内存中读取SL映像,并将它以不能被软件仿真的方式传输到TPM。

5)发信号给TPM,完成Hash运算,并验证签名。如果其间发生任何错误,TPM将断定没有启动有效的SL。

6)清除全局的中断标识,这将关闭所有的中断,包括NMI, SMI和INIT,并确保原子地执行随后的代码。如果处理器在GIF清除时进入关闭状态(如:由于三态错误),系统仅可通过RESET重新启动。

7)更新指向在SLB结束处(SLB基地址+65536)的第一字节的ESP寄存器,以便SL压入栈的第一个条目将在SLB的顶部。

8)从SLB加无符号16位入口点偏移值到SLB基地址,形成SL入口点地址,并跳转到该地址。

(2)安全例外

当执行VMM时,安全例外(Security Exception,#SX)出错发出安全敏感事件信号,以例外的形式发信号是为了VMM可以采取合适的行动,VMM会拦截客户机上敏感事件。

SVM相关的MSR

不管EFER.SVME位是否打开,SVM的MSR(模型特定寄存器)都是可用。SVM使用的MSR说明如下:

(1)VM_CR MSR (C001_0114h)

寄存器VM_CR控制SVM的全局属性。VM_CR寄存器如图2所示:

X86-64处理器安全 07.png

图2 VM_CR模型特定寄存器(C001_0114h)

寄存器VM_CR各个域说明如下:

DPD—位0 如果设置为1,关半HDT和某些内部调试特征。

R_INIT—位1 如果设置为1,非拦截的INIT信号将被转换成#SX信号。

DIS_A20M—位2 如果设置,关闭A20掩码。

LOCK—位3 当设置为1时,对LOCK和SVMDIS的写将被悄悄的忽略。当清除此位时,系统可以写VM_CR的第3和第4位。一旦该位设置为1,系统仅能使用SVM_KEY MSR清除LOCK。INIT或SKINIT不会影响该位。

SVMDIS—位4 当设置为1睦,对EFER的写操作将SVME位当作MBZ。当清除该位时,系统可正常写EFER.SVME。该不会阻止CPUID报告SVM可用状态。当 EFER.SVME为1时,设置SVMDIS时,系统产生#GP错误,而不管VM_CR.LOCK的当前状态。SKINIT不影响该位。当LOCK清除为 0时,INIT清除该位,否则,该位不受影响。

(2)IGNNE MSR (C001_0115h)

可读写的IGNNE MSR用于直接设置处理器内部的IGNNE信号的状态。它仅在HW_CR MSR 中的IGNNE仿真开启时有用。位0定义了IGNNE的当前值,所有其他位为MBZ。

(3)SMM_CTL MSR (C001_0116h)

仅写的SMM_CTL MSR提供了对SMM信号的软件控制。该寄存器的结构如图3所示。

X86-64处理器安全 08.png

图3 SMM_CTL MSR (C001_0116h)

系统写SMM_CTL MSR的每位,将引起下面的操作:

DISMISS—位0 清除处理器内部的"SMI正挂起"标识。

ENTER—位1 进入SMM:映射SMRAM内存区域,记录NMI是否当前被阻塞,并且阻塞更多的的NMI和SMI中断。

SMI_CYCLE—位2 发送SMI特殊周期。

EXIT—位3 退出SMM:去掉SMRAM内存区域映射,恢复NMI以前的掩码状态,并无条件地再次打开SMI。

RSM_CYCLE—位4 发送RSM特殊周期。

如果BIOS通过设置HWCR[SMMLOCK]已锁住SMM控制寄存器,对SMM_CTL MSR的写操作将引起#GP。

虽然下面的位联合操作可在在一个写操作中完成,但位操作顺序一般应是:ENTER, SMI_CYCLE, DISMISS, RSM_CYCLE,EXIT。其他的位联合操作将引起非定义的行为:

ENTER + SMI_CYCLE

DISMISS + ENTER

DISMISS + ENTER + SMI_CYCLE

EXIT + RSM_CYCLE

VMM必须确保ENTER和EXIT操作匹配,而不能嵌套,否则,处理器将执行非定义的行为。

(4)VM_HSAVE_PA MSR (C001_0117h)

64位读/写VM_SAVE_PA MSR持有一个内存块的物理地址,在该内存块上,VMRUN存储主机状态,并且#VMEXIT从它再装载主机状态。VMM软件在发出第一个VMRUN指令之前,应建立该寄存器。软件不能直接尝试读写主机存储状态区域。

如果发生下面的任何一种情况时,写VM_HSAVE_PA MSR将引起#GP:

在写入地址低12位中,任一位非0。

写入的地址大于或等于处理器最大支持的物理地址。

SVM-Lock

SVM-Lock特征允许软件阻止系统设置EFER.SVME、无条件地或者用64位密钥重打开SVM功能。

CPUID函数8000_000Ah返回EDX的第2位,指示系统是否支持SVM-Lock。在支持SVM-Lock的处理器上,即使EFER.SVME=0,系统也能执行SKINIT和STGI。

当SVM-Lock特征不可用时,Hypervisors可以用仅读的VM_CR.SVMDIS位检查SVM。

  • SVM_KEY MSR (C001_0118h)

仅写的SVM_KEY MSR用于创建密码保护来清除VM_CR.LOCK。当VM_CR.LOCK为0时,对SVM_KEY MSR的写操作设置64位SVM密钥值。当VM_CR.LOCK为1时,对SVM_KEY MSR的写操作将写入的值与SVM密钥值进行比较,如果值相匹配且非0,系统清除VM_CR.LOCK位;如果不匹配或SVM密钥值为0,系统忽略对 SVM_KEY的写操作,并且SVM_KEY为不可修改的。

软件应该在写SVM_KEY后读取VM_CR.LOCK,判定解锁是否成功。如果当VM_CR.LOCK为1时SVM密钥为0,处理器仅能通过复位清除VM_CR.LOCK。为了SVM密钥的安全,对SVM_KEY MSR的读操作总是返回0。

SMM-Lock

SMM-Lock特征允许软件阻止系统管理中断(System Management Interrupts,SMI)在SVM中被拦截,位SmmLock在HWCR MSR寄存器中。

(1)SmmLock位— HWCR[0]

SmmLock位(第0位)位于HWCR MSR (C001_0015h),当SmmLock位清除时,它可被设置为1。一旦设置为1时,软件不能清除该位,系统忽略对它的写操作。系统仅能通过 SMM_KEY MSR或复位清除SmmLock。INIT 和SKINIT不影响该位。当SmmLock被设置时,其他SMM配置寄存器不可写。

(2)SMM_KEY MSR (C001_0119h)

仅写的SMM_KEY MSR用于创建密码保护机制来清除SmmLock。

当SmmLock为0时,对SMM_KEY MSR的写操作设置64位SMM密钥值。

当SmmLock为1时,对SMM_KEY MSR的写操作将已写入的值与SMM密钥值相比较,如果值匹配且不为0,系统清除SmmLock位。如果值不匹配或SMM密钥值为0,系统忽略对 SMM_KEY的写操作,并且SmmLock是不可修改的。软件应该在写SMM_KEY之后读取SmmLock,判断解锁是否成功。

如果SmmLock为1时SMM_Key MSR为0,系统仅能通过复位清除SmmLock。

为了保护SMM密钥的安全,对SMM_KEY MSR的读操作总是返回0。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多