安全虚拟化SEV简单介绍


安全虚拟化SEV简单介绍

  • 什么是SEV
    • 什么是SVM
    • SME介绍
    • SEV介绍
    • 总结
  • 写在文末

什么是SEV

SEV是由AMD提出的安全虚拟化Secure Encrypted Virtualization技术的英文首字母的缩写。简单来说就是主内存控制器具备了加密功能可以对虚拟机内存数据进行保护。在真正介绍SEV之前,我们首先要弄清楚两个关键的基本概念:SVM、SME。下面先简单了解一下SVM和SME。

什么是SVM

SVM即AMD Secure Virtual Machine的缩写。这是由AMD提供的虚拟化技术,用来X86上支持基于硬件的虚拟化技术,通过硬件提供的辅助加速功能,可以有效提高虚拟化性能。Intel也提供了与之对应的虚拟机技术及VT-x。
为了支持虚拟化技术,AMD虚拟机框架做了以下设计:

  1. 提供VMM(即Hypervisor)和Guest(即虚拟机)之间的快速切换机制。
  2. 拦截虚拟机中特定指令和事件的能力。
  3. 对内存提供外部(DMA)访保护。
  4. 辅助中断处理和虚拟中断(Virtual Interrupt)支持。
  5. 对属于Guest和Host(宿主机)的TLB使用标签来减少虚拟化的开销。

关于SVM技术的更多细节本文不展开介绍,有兴趣的同学可以查看AMD APM卷二的第15章。这里对上面列出的五项内容稍微说明一下:

  1. 硬件虚拟化,简单点说就是虚拟机的代码指令能够在宿主机上运行直接运行,无需进行软件转换或者翻译。但是,硬件(主要是CPU)需要维护Hypervisor和Guest的运行上下文环境,确保互相不产生影响。因此,AMD提供了一组虚拟化相关的指令(如VMRUN、VMSAVE、VMLOAD等等),以及定义了描述运行上下文环境的数据结构VMCB(Virtual Machine Control Block)以及VMSA(Virtual Machine Save Area)。其中VMCB供VMM配置,用来控制虚拟机的运行,包括启动那些硬件特性、拦截那些事件或指令等等;而VMSA用来保存虚拟机运行态相关的寄存器,包括GPR、System Register等。有了这些基础,CPU在运行虚拟机的代码指令时就可以做到快速切换,互不影响。CPU在运行虚拟机代码指令时会进入Guest Mode,而运行宿主机代码时切换到Host Mode。通过模式切换,CPU内部可以很好地区分当前的运行环境,然后做出对应的处理。
  2. 宿主机CPU可以直接运行虚拟机代码指令,但并不是任意指令都可以执行,例如IO指令(IN、OUT等),因为没有真实硬件的支持,所以在CPU执行某些类型的指令时,需要Hypervisor介入,进行模拟或处理。此外,还有些情况需要Guest告知Hypervisor状态进行了转换,由Hypervisor跟踪以及维护虚拟机的状态,例如系统寄存器的读写等。由于这些原因,需要Hypervisor可以有选择地拦截一些指令以及事件。
  3. 主要是防止Guest或者Host通过设备访问彼此的内容,这里是处于安全考虑,不做过多描述。
  4. 由于Guest Mode下虚拟机缺少真正的APIC组件,因此需要支持。虚拟中断用于向虚拟机注入中断事件,模拟真实的中断流程。
  5. 引入了ASID(Address Space Identifier)的概念,用来对属于Host和Guest的TLB进行区分,从而减少开销。对于Shadow Paging或者Nested Paging来说,Guest中切换进程时可以不用Flush TLB,即使CR3发生改变,从而减少Host和Guest的模式切换。

这里着重提及一下Nested Paging,因为这是实现SEV所需要的基础之一。Nested Paging即使用两级页表转换,一级是从GVA(Guest Virtual Address)到GPA(Guest Physical Address)的转换,标记为gCR3,一级是从GPA到HPA(Host Physical Address)的转换,标记为nCR3。Host和Guest各自维护自己的CR3,gCR3由Guest自己维护,通过Guest内的#PF异常处理并更新,nCR3由Host维护,通过Host内的#NPF异常处理并更新。Nested Paging如下图所示:

在这里插入图片描述

SME介绍

SME是Secure Memory Encryption的缩写。AMD在DRAM的控制器中添加了加解密模块,用来控制内内存数据的加密和解密,如下图所示:
在这里插入图片描述

OS和Hypervisor通过页表来控制对内存页的加密解密。一旦SME使能,物理地址的47 bit(也称C-bit,即enCrypted)用来标记对应内存页是否通过加解密保护。内存页在页表PTE中的C-bit置1,则表示该页面被加密。访问该内存页时,加密和解密过程有内存控制器自动完成,具体过程如下图所示:
Address Mapping

有了上面的基础,我们来简单了解一下SEV的工作原理。

SEV介绍

SEV主要的思想是为虚拟机内存进行加密保护,而且不同虚拟机之间以及宿主机不能直接读取或者窃取到虚拟机内存数据。SEV提供的虚拟机内存数据的加密功能,可以保护虚拟机内存免受物理攻击,跨虚拟机和来自Hypervisor的攻击。SEV功能使能后,物理地址的43 bit至47 bit分别用来标志ASID和C-bit,在通过页表访问虚拟机内存时,虚拟机的物理地址回携带与虚拟机对应的ASID的Tag,用来判断是访问哪个虚拟机的数据,或者是操作哪个虚拟机的数据。虚拟机的ASID在页表遍历时使用,用来区分TLB。在缓存(Cache)中,C-bit和ASID用来区分Cache Line。内存控制器中ASID用来区分虚拟机加密密钥(VEK),由于物理地址中的ASID是由硬件自动添加,软件无法直接修改,因此,从内存中读取的数据由内存控制器使用与之对应的VEK进行加解密。SEV模型如下图所示:
SEV Model

开启SEV功能的同时,要求Host使能SME功能,且虚拟机的VMCB中开启NPT功能,这是为了保证Nest Paging的工作过程中C-bit的控制不被软件干扰。由于有两级页表,因此会存在两级页表中PTE的C-bit组合,决定如何对最终的虚拟机内存页如何进行加解密,过程如下图所示:
在这里插入图片描述

虽然虚拟机内容数据被内存控制器自动加解密,但是启动虚拟机会存在虚拟机第一条指令是如何启动的问题,这里就需要提到SEV的另外一个关键组件PSP,即AMD Platform Secure Processor,一个32 bit的微控制器(Arm? Cortex?-A5),被集成到SOC内部。PSP主要完成的关键操作如下:

  1. 用来管理和维护SEV虚拟机状态以及安全信息相关的上下文,并提供一系列API。
  2. 为SEV虚拟机配置VEK,并映射到具体的ASID。
  3. 可以加密SEV虚拟机内存数据进行加解密,以支持对Guest BIOS等启动代码的初始加密操作。

总结

SEV是在SVM、SME的基础上对虚拟机进行保护提供的安全增加功能,主要完成对虚拟机内存数据的保护,其主要安全组件设计PSP和内存控制器等,更具体的细节建议查看官方白皮书以及SPEC。

参考:
1: AMD SEV官网.
2: AMD64 Architecture Programmer’s Manual Volume 2.

写在文末

本文难免会有错误,如有错误,欢迎指出。转载请标明出处。
作者:
Artie Ding
邮箱:
[email protected]