本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫。

前面 虚拟化技术总览 中从虚拟平台 VMM 的角度,将虚拟化分为 Hypervisor 模型和宿主模型,如果根据虚拟的对象(资源类型)来划分,虚拟化又可以分为计算虚拟化、存储虚拟化和网络虚拟化,再细一些,又有中断虚拟化,内存虚拟化,字符/块设备虚拟化,网络功能虚拟化等。

我会将此作为一个系列来写,本文先看 CPU 虚拟化。在这之前,我们先来笼统看下虚拟化的本质是什么,它到底是如何做到将 Host 的硬件资源虚拟化给 Guest 用,我这里用两个词来定义,interceptvirtualize,中文翻译成截获模拟比较恰当一点,这两个词基本上是虚拟化的终极定义了,带着这两个词去看每一种虚拟化类型,会发现很容易理解和记忆。

CPU 软件虚拟化

基于软件的 CPU 虚拟化,故名思议,就是通过软件的形式来模拟每一条指令。通过前面的文章我们知道常用的软件虚拟化技术有两种:优先级压缩和二进制代码翻译。这两种是通用技术,可以用在所有虚拟化类型中。我们就结合 intercept 和 virtualize 来看看 CPU 软件虚拟化是怎么做的。

首先,一些必须的硬件知识要知道,X86 体系架构为了让上层的软件(操作系统、应用程序)能够访问硬件,提供了四个 CPU 特权级别,Ring 0 是最高级别,Ring 1 次之,Ring 2 更次之,Ring 3 是最低级别。

一般,操作系统由于要直接访问硬件和内存,因此它的代码需要运行在最高级别 Ring 0 上,而应用程序的代码运行在最低级别 Ring 3 上,如果要访问硬件和内存,比如设备访问,写文件等,就要执行相关的系统调用,CPU 的运行级别发生从 Ring 3 到 Ring 0 的切换,当完成之后,再切换回去,我们熟悉的用户态和内核态切换的本质就来自这里。

虚拟化的实现也是基于这个思想,VMM 本质上是个 Host OS,运行在 Ring 0 上,Guest OS 运行在 Ring 1 上,再往上是相应层次的应用程序运行在 Ring 2 和 Ring 3 上。

当 Guest OS 或上层应用在执行相关的特权指令时,就会发生越权访问,触发异常,这个时候 VMM 就截获(intercept)这个指令,然后模拟(virtualize)这个指令,返回给 Guest OS,让其以为自己的特权指令可以正常工作,继续运行。整个过程其实就是优先级压缩和二进制代码翻译的体现。

CPU 硬件虚拟化

上面的这种截获再模拟的纯软件的虚拟化方式,势必是性能非常低的。那怎么样提高性能呢,有一种改进的方式是修改 Guest OS 中关于特权指令的相关操作,将其改为一种函数调用的方式,让 VMM 直接执行,而不是截获和模拟,这样就能在一定程度上提高性能。

但这种方式并不通用,要去改 Guest OS 的代码,只能看作是一种定制。为了能够通用,又能够提高性能,就只能从硬件上去做文章了。所以,后来,以 Intel 的 VT-x 和 AMD 的 AMD-V 为主的硬件辅助的 CPU 虚拟化就被提出来(Intel VT 包括 VT-x (支持 CPU 虚拟化)、EPT(支持内存虚拟化)和 VT-d(支持 I/O 虚拟化))。

CPU 硬件辅助虚拟化在 Ring 模式的基础上引入了一种新的模式,叫 VMX 模式。它包括根操作模式(VMX Root Operation)和非根操作模式(VMX Non-Root Operation)。

这两种模式都有 Ring 0 - Ring 3 的特权级。所以,在描述某个应用程序时,除了描述其属于哪个特权级,还要指明其处于根模式还是非根模式。

引入这种模式的好处就在于,Guest OS 运行在 Ring 0 上,就意味着它的核心指令可以直接下达到硬件层去执行,而特权指令等敏感指令的执行则是由硬件辅助,直接切换到 VMM 执行,这是自动执行的,应用程序是感知不到的,性能自然就提高了。

这种切换 VT-x 定义了一套机制,称为 VM-entry 和 VM-exit。从非根模式切换到根模式,也就是从 Guest 切换到 Host VMM,称为 VM-exit,反之称为 VM-entry。

  • VM-exit : 如果 Guest OS 运行过程中遇到需要 VMM 处理的事件,比如中断或缺页异常,或者主动调用 VMCALL 指令调用 VMM 服务的时候(类似于系统调用),硬件自动挂起 Guest OS,切换到根模式,VMM 开始执行。

  • VM-entry: VMM 通过显示调用 VMLAUNCH 或 VMRESUME 指令切换到非根模式,硬件自动加载 Guest OS 的上下文,Guest OS 开始执行。

KVM CPU 虚拟化

KVM 是一种硬件辅助的虚拟化技术,支持 Intel VT-x 和 AMD-v 技术,怎么知道 CPU 是否支持 KVM 虚拟化呢?可以通过如下命令查看:

# grep -E '(vmx|svm)' /proc/cpuinfo

如果输出是 vmx 或 svm,则表明当前 CPU 支持 KVM,Intel 是 vmx,AMD 是svm。

从本质上看,一个 KVM 虚拟机对应 Host 上的一个 qemu-kvm 进程,它和其他 Linux 进程一样被调度,而 qemu-kvm 进程中的一个线程就对应虚拟机的虚拟 CPU (vCPU),虚拟机中的任务线程就被 vCPU 所调度。

比如下面这个例子,Host 机有两个物理 CPU,上面起了两个虚拟机 VM1 和 VM2,VM1 有两个 vCPU,VM2 有 3 个 vCPU,VM1 和 VM2 分别有 2 个 和 3 个线程在 2 个物理 CPU 上调度。VM1 和 VM2 中又分别有 3 个任务线程在被 vCPU 调度。

所以,这里有两级的 CPU 调度,Guest OS 中的 vCPU 负责一级调度,Host VMM 负责另一级调度,即 vCPU 在物理 CPU 上的调度。

我们也可以看到,vCPU 的个数,可以超过物理 CPU 的个数,这个叫 CPU 「超配」,这正是 CPU 虚拟化的优势所在,这表明了虚拟机能够充分利用 Host 的 CPU 资源,进行相应的业务处理,运维人员也可以据此控制 CPU 资源使用,达到灵活调度。

OK,CPU 虚拟化就到这里,下篇文章将讲述内存虚拟化。觉得写得凑合可以给个赞,谢谢大家的支持。


我的公众号 「Linux云计算网络」(id: cloud_dev) ,号内有 10T 书籍和视频资源,后台回复 「1024」 即可领取,分享的内容包括但不限于 Linux、网络、云计算虚拟化、容器Docker、OpenStack、Kubernetes、工具、SDN、OVS、DPDK、Go、Python、C/C++编程技术等内容,欢迎大家关注。

CPU 虚拟化的更多相关文章

  1. [原] KVM 虚拟化原理探究(3)— CPU 虚拟化

    KVM 虚拟化原理探究(3)- CPU 虚拟化 标签(空格分隔): KVM [TOC] CPU 虚拟化简介 上一篇文章笼统的介绍了一个虚拟机的诞生过程,从demo中也可以看到,运行一个虚拟机再也不需要 ...

  2. CPU虚拟化的常见技术

    关键词:cpu虚拟化,KVM,Host-PassThrough,Nested,CGroup,NUMA,热添加 云计算虚拟化技术主要包括三个领域:计算.存储.网络 本文主要总结了计算虚拟化领域中的CPU ...

  3. CPU虚拟化技术(留坑)

    留坑~~~ 不知道这个是这么实现的 CPU虚拟化技术就是单CPU模拟多CPU并行,允许一个平台同时运行多个操作系统,并且应用程序都可以在相互独立的空间内运行而互不影响,从而显著提高计算机的工作效率.虚 ...

  4. 第六讲:CPU虚拟化

    虚拟化技术的分类主要有服务器虚拟化.存储虚拟化.网络虚拟化.应用虚拟化. 服务器虚拟化技术按照虚拟对象来分,可分为:CPU虚拟化.内存虚拟化.I/O虚拟化: 按照虚拟化程度可分为:全虚拟化.半虚拟化. ...

  5. CPU虚拟化

    1. 为什么需要 CPU 虚拟化 X86 操作系统是设计在直接运行在裸硬件设备上的,因此它们自动认为它们完全占有计算机硬件.x86 架构提供四个特权级别给操作系统和应用程序来访问硬件.  Ring 是 ...

  6. KVM之CPU虚拟化

    1.1 为什么要虚拟化CPU 虚拟化技术是指在x86的系统中,一个或以上的客操作系统(Guest Operating System,简称:Guest OS)在一个主操作系统(Host Operatin ...

  7. 技嘉主板+AMD CPU开启CPU虚拟化方法

    硬件环境:技嘉AB350+AMD Ryzen 5 1600X 由于安装虚拟机的需要,所以要开启CPU的虚拟化. 首先进入BIOS. 然后如图:(M.I.T-高级频率设定-CPU超频进阶设置-SVM M ...

  8. 虚拟化技术实现 — KVM 的 CPU 虚拟化

    目录 文章目录 目录 前文列表 x86 体系结构的虚拟化 硬件辅助的 CPU 虚拟化 由 VMX 切换支撑的 CPU 虚拟化技术 KVM 的 CPU 虚拟化实现 vCPU 的调度方式 客户机 CPU ...

  9. 烂泥:查看服务器的BIOS是否开启CPU虚拟化

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 有关CPU是否支持虚拟化,我们可以通过相关的命令和软件进行查看. 在windows系统下,我们可以使用CPU-Z这个软件,如下图: 在linux系统下, ...

随机推荐

  1. Java并发编程之原子变量

    原子变量最主要的一个特点就是所有的操作都是原子的,synchronized关键字也可以做到对变量的原子操作.只是synchronized的成本相对较高,需要获取锁对象,释放锁对象,如果不能获取到锁,还 ...

  2. 【JAVA零基础入门系列】Day9 Java中的那个大数值

    什么是大数值?用脚趾头想也知道,当然是"大"的数值(233).Java中有两个用于表示大数值的类,BigInteger和BigDecimal,那到底能表示多大的数值呢?理论上,可以 ...

  3. python第三课

    本节内容 1.列表 2.购物车设计思路 3.字典 1.列表 不可变类型:整型.字符串.元组tuple 可变类型:列表list.字典dict 2.购物车 3.字典

  4. dubbo的架构

    dubbo架构图如下所示: 节点角色说明: Provider: 暴露服务的服务提供方. Consumer: 调用远程服务的服务消费方. Registry: 服务注册与发现的注册中心. Monitor: ...

  5. Msys2配置总结

    一.MSYS2的MirrorList配置 1.修改msys2安装目录下的/etc/pacman.d文件夹里面的3个mirrorlist.*文件 [mirrorlist.mingw32] #中国科学技术 ...

  6. Python 由__dict__和dir()引发的一些思考

    关于__dict__和dir()的区别和作用请参考这篇文章:http://blog.csdn.net/lis_12/article/details/53521554 说下我当时遇到的问题: class ...

  7. N厂劳力士黑水鬼V7出了1年,如今依旧被追捧,供不应求

    今天和大家一起来谈谈,风靡复刻界的潜航者,国人眼中的一劳永逸,何为一劳永逸,即(用这个腕表能省很多事)真的有这么牛?其实不然只要是机械腕表都会有或多或少的问题,一劳永逸更多的是指腕表的质量给力,所谓潜 ...

  8. hibernate的操作Blob和Clob类型数据(笔记)

  9. 使用jQuery判断元素是否在可视区域

    $("#app").offset().top; offset().top表示 绝对偏移值,比如说有一个很长的页面,#app这个元素 在最底下,  $("#app" ...

  10. HDFS--笔记

    HDFS的简介 分布式的文件系统,基于流数据模式访问和处理超大文件的分布式文件系统 Hadoop Distributed File System HDFS的优点 处理超大文件 流数据访问 运行廉价的商 ...