前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >System|隔离|虚拟化

System|隔离|虚拟化

作者头像
朝闻君
发布2021-11-22 11:42:24
4080
发布2021-11-22 11:42:24
举报

ref:CSE,SE,SJTU

虚拟化

我们需要在一个物理机上运行多个不同的OS,从而实现软件上的

  • 隔离 - 如果OS崩了,那不会影响其他的OS
  • 可维护性 - 易部署克隆移植备份(容器化)
  • 安全 - 虚拟机自省

因此,我们在传统的OS的位置放置一个支持虚拟化的系统,称为VMM(VM Monitor) or Host. 每一个其上运行的虚拟机成为一个Guest。(当然也可以在传统OS和VM之间加入一层VMM,但是这样性能会比较差)

VMM具有高优先级,管理多个硬件。但是和传统OS具有不同的抽象,仅负责调度VM。

为了实现虚拟化,需要在三个层面进行隔离

  • CPU - 每个虚拟机各自拥有自己的user/kernel mode
  • Memory - 每个虚拟机各自拥有自己的虚拟MMU
  • IO - 每个虚拟机各自拥有自己的虚拟设备

CPU 虚拟化

尝试I - VM as 进程

对于每个进程而言,CPU似乎都只被自己占有。如果我们直接把VM作为传统的进程,结果会如何?

宿主机作为一般的应用

问题在于,如果按照这样的方式,VM处于user mode,某些特殊的指令(如关中断,change CR3)就无法执行。VM是无法执行高优先级指令的。

尝试II - Trap & Emulation

解决方式显而易见,如果VM无法执行,那么只需要转交给VMM执行即可。

  • Trap - 调用高优先级指令时,由于处于user mode,因此trap到宿主机
  • Emulate - 实现对应的函数,将VM的系统状态存储到VMM的内存,VM并没有操作硬件的CR3,只是修改了宿主机的内存而已。

问题在于,Intel的指令集一开始并不天然支持虚拟化。

如popf,将pop出的内容存到flag寄存器里。对于IF(中断)而言,如果处于kernel mode,那么popf会更新IF,如果处于user mode,popf只会被忽略掉(而不是发生trap)。然而,我们无法区分同样是在user mode运行情况下,VM究竟是在

这类指令共有17条。

SGDT, SIDT, SLDT, SMSW, PUSHF, POPF, LAR, LSL, VERR, VERW, POP, PUSH, CALL, JMP, INT n, RET, STR, MOV

尝试III - 处理特殊指令

1.指令解释器:软件模拟

软件写个CPU模拟器,容易实现,但是性能非常低。(因为所有指令都是在对内存操作)

2.二进制翻译: 翻译为其他指令

每个basic block进行翻译,将这些指令翻译成VMM提供的函数调用,并存在code cache中。

Inline Call

然而问题依然存在,

首先是某些语言如Java会修改源代码(SMC),因此需要一个机制通知cache已经过期,否则执行的就是错误的代码;

其次,这就导致了每次Guest转交整个basic block,如果发生PC同步的中断,只会在边界处发生,而真实机器则可能在每个指令发生。

总结一下,虚拟机的kernel执行这些代码时,发生二进制翻译,而应用程序执行这些代码时则进行Trap&Emulate

3.半虚拟化: 直接在源代码中替换

这要求虚拟机中的程序清楚地意识到自己处于虚拟化运行

修改OS的代码,使得其中的指令直接变成对VMM的函数调用(hypercall)(eg. Xen)

4.硬件支持虚拟化: 改变 CPU(主流)

CPU分为两种模式,Root和非Root,每个模式都从ring-0至ring-3有四个优先级。由CPU本身存储虚拟化所需求的bit。VMM负责处理Exit

内存虚拟化

在虚拟化设计中,存在着三种地址,GVA, GPA,HPA。(G-guest,H-host)

然而对于虚拟机而言,他并不知道哪些HPA是属于自己的。如果设置VM的CR3直接指向GPT的话,很有可能使得VM访问越界。

尝试I-Shadow Page

我们并不让CR3指向属于VM管理的GPT,而是属于VMM管理的SPT(注意,软件模拟虚拟化的时候VM的虚拟CR3也在VMM上)。相当于两表合一,通过SPT直接寻址到宿主机的物理地址

代码语言:javascript
复制
set_cr3 (guest_page_table):
    for GVA in 0 to 220
        if guest_page_table[GVA] & PTE_P:
            GPA = guest_page_table[GVA] >> 12
            HPA = host_page_table[GPA] >> 12
            shadow_page_table[GVA] = (HPA<<12)|PTE_P
        else
            shadow_page_table = 0
     CR3 = PHYSICAL_ADDR(shadow_page_table)

那么,如何同步GPT和SPT呢?答案很简单,就是将GPT设置为只读,如果要写的话,就会触发Page Fault,然后由VMM处理并且同步SPT。

如果Guest上的应用通过SPT访问的话,同时也能访问到Guest的kernel space。所以需要对两种模式分别创建SPT,其中user态缺失了kernel space。

对于每个VM,需要一张HPT,对于每个VM上的进程,又需要一张GPT,并且两张SPT。

尝试II-直接映射

修改guest OS的源代码,让GVA直接映射到HPA。对于页表的修改只能通过hypercall进行,而对于guest OS只读。

但是这样做对guest OS不那么透明,并且guest OS会了解很多HPA相关的信息,可能会导致rowhammer攻击(见下节)

尝试III-硬件支持虚拟化

Intel EPT(extended)和AMD NPT(nested)为每个VM单独创立了一个表,用于将GPA映射到HPA上,由VMM管理。

IO 虚拟化

for OS lecture

尝试I -Device emulation

尝试II-Para-virtualization driver, e.g., virtio

尝试III- Hardware support, e.g., SR-IOV

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 虚拟化
  • CPU 虚拟化
  • 内存虚拟化
  • IO 虚拟化
相关产品与服务
专用宿主机
专用宿主机(CVM Dedicated Host,CDH)提供用户独享的物理服务器资源,满足您资源独享、资源物理隔离、安全、合规需求。专用宿主机搭载了腾讯云虚拟化系统,购买之后,您可在其上灵活创建、管理多个自定义规格的云服务器实例,自主规划物理资源的使用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档