https://chengyi818.gitbooks.io/fat-cheng-s-xv6-journey/content/LEC_21/LEC_21.html
https://www.usenix.org/conference/osdi12/technical-sessions/presentation/belay
LEC21: 虚拟机Dune
大纲
- 虚拟机
- x86虚拟机制和VT-x
- Dune
虚拟机
什么是虚拟机?
模拟计算机,以准确运行一个OS
图示
参加paper
为何讨论虚拟机?
- VMM也是某种类型的内核,包含进程调度,进程隔离,资源分配
- 当前的做法是VMM和guest OS协同工作
- 是否可以通过虚拟机来解决某些OS难题
虚拟机的作用
- 在一台物理主机上运行很多guest OS. 1.1 对于云计算企业而言,经常需要为每个服务提供一个独立隔离的运行环境并分配一定的资源. 1.2 如果每个服务都运行在一台独立的物理主机上,将会造成巨大的资源浪费.
- 虚拟机可以提供比进程更好的隔离效果.
- 在一台物理主机上运行不同的操作系统.
- 提供内核开发环境,比如qemu
基于硬件的虚拟化
硬件虚拟化机制
- Intel VT-x, VMX, AMD SVM
- 虚拟机概念的火热推动了Intel和AMD增加了硬件对虚拟化的支持.
- 使得实现VMM(virtual machine monitor)变得更加容易.
VT-x
- 增加了两种模式: root和non-root.
- VMM运行在VT-x的root模式. 2.1 VMM可以修改VT-x的控制数据结构,比如VMCS和EPT
- guest运行在non-root模式 3.1 guest在CPL=0的特权级下,可以直接使用硬件 3.2 此时VT-x会检查guest的某些操作,并使guest返回VMM.
- 为了支持新的两种模式,增加了一些指令. 4.1 VMLAUNCH/VMRESUME: root -> non-root 4.2 VMCALL: non-root -> root 4.3 另外,某些中断和异常也会导致guest返回VMM
- 虚拟机控制数据结构(VM control structure,VMCS) 5.1 包含了在两种模式间转换所需保存和恢复的状态. 5.2 配置信息,比如是否需要在缺页异常时陷入root模式.
pushf/popf 示例
- guest使用硬件标志位 1.1 当CPL=0时,pushf/popf等指令会读写该标志位 1.2 从guest的角度,硬件运行正常
- 当发生硬件设备中断 2.1 通过VMM配置VMCS(virtual machine control structure),来控制每个中断是由guest还是由host响应. 2.2 如果由guest响应: 2.2.1 硬件首先检查guest的可中断标志位 2.2.2 通过guest的IDT获取硬件中断向量 2.2.3 不需要退出guest状态 2.3 如果由host响应 2.3.1 VT-x退出guest状态,返回VMM.VMM处理中断.
VT-x: 页表
- EPT: 第二层地址转换
- EPT由VMM控制
- %cr3寄存器由guest控制
- guest虚拟地址通过cr3转换为guest物理地址,guest物理地址通过EPT转换为host物理地址. 4.1 cr3寄存器保存的是guest物理地址 4.2 EPT保存的是host物理地址.
- EPT对于guest而言,是不可见的.
- 所以: 6.1 guest可以自由读写cr3寄存器,修改PTE. 6.2 VMM通过EPT提供隔离
- 典型设置: 7.1 VMM分配size大小的物理内存供guest使用 7.2 VMM将guest物理内存地址,从0到size映射到EPT中. 7.3 guest使用cr3来配置guest的进程地址空间.
guest和host之间的内存隔离机制
- 通过两次内存地址转换,从而避免了guest访问host中的非法内存
如何处理设备?
- VT-x选择性允许
INB
和OUTB
指令 - 同样需要转换DMA地址. 2.1 当guest需要提供一个DMA缓冲区供设备使用 2.2 VT-x会提供相应的内存映射
- 通常guest使用真实设备并没有什么意义 3.1 guest通常需要和其他guest共享真实设备 3.2 每个guest都需要一部分硬盘 3.3 每个guest都需要使用网卡 3.4 每个guest都有一个独立的x window.
- 通常VMM会模拟一些网卡和硬盘,而不是使用真实的host硬件设备.
- guest可能会运行特定的驱动以跳转到VMM.
Dune
主要思想
- 使用VT-x提供的功能来支持Linux的原生进程,而不是支持guest的OS内核.
- 进程可以更快地访问cr3,IDT等寄存器.
- 通过VT-x,会允许新的分页机制.在Linux中,是不存在的.
- 以上目标和
exokernel
类似.
总体方案
- Dune是Linux中的一个可加载模块.
- 一个普通的进程可以切换为
Dune mode
. - 一个Dune-mode的进程仍然保持进程的特性. 3.1 拥有内存,可以调用Linux系统调用,并且是完全独立隔离的.
- 不同于普通进程的
CPL=3
和页表保护,Dune-mode进程通过VT-x non-root模式隔离. 4.1 通过EPT保护内存,Dune只会在其中插入已分配给进程的内存. 4.2 通过VMCALL使用系统调用,而不是INT
为什么Dune可以通过VT-x可以隔离进程?
- 因为运行在
CPL=0
,进程可以通过修改cr3寄存器,管理其自身的页表. - 将会通过进程自身的IDT,执行快速异常调用,从而避免陷入内核.
- 在
CPL=3
时,运行沙箱代码,从而使得进程类似内核态.
栗子: 沙箱代码的执行
- 为了支持浏览器运行第三方插件,而插件可能包含恶意代码或者漏洞.
- 所以,浏览器需要一种沙箱环境,可以其中执行插件,却限制其使用系统调用或访问内存.
- 假设浏览器以Dune进程的形式运行: 3.1 浏览器运行在CPL=0,插件运行在CPL=3. 3.2 创建一个页表,通过设置PTE_U标志位,允许插件访问部分内存. 3.3 仅浏览器可以访问的内存,则不设置PTE_U标志位. 3.4 将页表地址写入cr3寄存器. 3.5
IRET
指令会跳转到不可信任的代码,会将CPL设置为3. 3.6 通过页表,插件可以访问图片内存. 3.7 插件可以尝试执行系统调用,然后会陷入浏览器,最终由浏览器决定是否允许插件调用系统调用. - 可以在Linux上实现这些功能么? 4.1 在Linux上无法实现这些功能,没有在用户态使用CPL,cr3,或者IDT.
栗子: 垃圾回收
- 基于boehm的
mark-and-sweep
回收器修改. - GC的主要任务是跟踪所有存活的数据 2.1 为每个可达的对象设置标志位 2.2 所有没有设置标志位的对象均可回收
- 因为跟踪对象往往需要100ms以上,所以GC是一个比较耗时的操作.
GC方案
- 在无锁保护的情况下,执行者和跟踪器同时运行.
- 执行者有可能会修改跟踪器已经处理过的一些对象,这会让没有被标记的对象重新可达.
- 停止执行者
- 跟踪器重新扫描执行者修改过的页面中的对象
Dune的作用
- 通过PTE_D比特位,查找被修改过的页面.
- 当GC结束,清除所有PTE_D dirty标志位.
- 因此,程序需要快速读写PTE标志位.
用户态访问虚拟机
与exokernel类似,更好的用户态访问虚拟机会帮助到许多程序.
Dune对性能的影响
- 论文Table2
- 因为VT-x的进出,会导致系统调用消耗增加
- 基于同样的原因,陷入内核也会更慢一些.
- 因为EPT二次地址转换的原因,TLB未命中也会更慢.
- Dune论文中认为,大部分应用性能影响不大.
- 较短的系统调用,受性能影响很小.
- TLB未命中带来的性能损耗也不高于5%
合理使用Dune对性能的提升
- 提供Web Server性能达20%
- GC的收益取决于内存分配的速度 2.1 对于单个应用,比如XML parser并没有什么提升,EPT的消耗抵消了收益 2.2 但是其他真实应用通常会分配更多内存.
Dune是如何实现新功能?
- 通过CPL=3和页表,实现沙箱
- sthreads,每个线程一个页表,而不是每个进程.
- 性能提升让一些想法变得可行,比如GC,DSM
Dune总结
- Dune通过VT-x而不是页表实现进程的隔离机制.
- Dune进程可以使用Linux系统调用和特权硬件设备.
- Dune允许进程快速处理页表和page fault.
- Dune允许进程构建类似kernel的功能. 4.1 比如,每个线程一个独立的页表.或者CPL=3的沙箱. 4.2 普通进程是很难实现这些功能的.