草庐IT

硬件辅助虚拟化

方晓山 2023-09-28 原文

一、云计算与虚拟化的关系

云计算作为一种新型资源分配和使用模式,为“移动为端,云为中心”的移动互联网业务体系打下了基础,起到了信息化社会发展的中坚作用。

云计算的一个核心思想是在服务器端提供几种的计算资源,同时这些计算资源要独立地服务于不同的用户,也就是在共享计算资源的同时,为每个用户提供隔离、安全、可信的工作环境。

云计算需要支持无数的应用请求,并保证存储和计算的性能。在云计算的SaaS、PaaS和IaaS三个层面中,IaaS承担着底层基础作用,而虚拟化技术又是IaaS技术的核心,它提供资源的多种颗粒度分配、动态可扩展和回收等手段。

二、虚拟化与虚拟机

       虚拟化技术的含义很广泛。将任何一种形式的资源抽象成另一种形式的技术都是虚拟化。在常用的操作系统中就存在某种意义上的“虚拟化技术”,例如虚拟内存空间和进程。如果把内存看作是一个设备,虚拟内存就是将物理内存虚拟成多个内存空间。虚拟内存的容量可以少于或多余物理内存。进程的概念实际是对于物理硬件执行环境的一个抽象,每一个进程都享有一个完整的硬件执行环境,并且与其他进程相隔离。

相对于进程级的虚拟化,虚拟机(VM)是另外一个层面的虚拟化,即系统虚拟化。与虚拟单个进程的执行环所不同,系统级虚拟化所抽象的环境是整个计算机,其抽象出的环境称为虚拟机,包括CPU、内存和I/O。在每个虚拟机都可以运行一个操作系统,在一台计算机上可以虚拟出多个虚拟机。

在虚拟环境中,虚拟机监控器(VMM)抢占了操作系统的位置,对下管理真实的物理硬件,对上层软件则呈现出虚拟的硬件平台。如下图,

VMM对物理资源的虚拟主要包括:处理器虚拟化、内存虚拟化和I/O虚拟化。这篇文章主要介绍硬件辅助虚拟化的内容。

三、硬件辅助虚拟化

硬件辅助虚拟化就是在CPU、芯片组及I/O设备等硬件中加入专门针对虚拟化的支持。并且,硬件虚拟化相比软件虚拟化,可以彻底解决软件虚拟化实现中存在的下面一些问题。软件虚拟化实现非常复杂,比如内存虚拟化的“影子页表”。还有软件虚拟化实现的虚拟化性能不佳,比如I/O设备的虚拟化。

下面以Intel VT(Intel Virtualization Technology)为例,说明一下对硬件辅助虚拟化技术所提供的支持。

在CPU虚拟化方面,Intel VT 提供了VT-x(Intel Virtualization technology)技术;在内存虚拟化方面,Intel VT提供了EPT(Extended Page Table)技术;在I/O设备虚拟化方面,Intel VT提供了VT-d(Intel Virtualization Technology for Direct I/O)等技术。

以下主要讲解下硬件虚拟化中的CPU虚拟化和内存虚拟化两部分。

1、CPU虚拟化

下图是Intel VT技术实现的VMM的典型结构。上面是虚拟机,下面是VMM层。

每一个VM(虚拟机)都可以独立地使用物理平台的资源,比如处理器,内存,I/O等。Intel VT-x有两种操作模式,根操作模式(VMX Root Operation),VMM运行所处的模式;非根模式(VMX Non-Root Operation),VM(虚拟机)运行所处的模式。每种模式都有特权级0~3,VMM可以处于根模式的特权级0或特权级3下,VM也可以处于非根模式的特权级0或特权级3下。

非根模式下,VM执行敏感指令(操作虚拟机的指令)会导致CPU从非根模式进入根模式的VMM,被称为VM Exit。VMM处理完敏感指令,从根模式返回非根模式,被称为VM Entry,如图:

VT-X引入了VMCS(Virtual-Machine Control Structure,虚拟机控制结构体),该结构是一个4Kb对齐且大小不超过4KB的内存块,格式如下:

偏移0处存放VMCS的版本标识,表示VMCS数据格式的版本号;

偏移4处存放中止标识,VM Exit执行不成功时产生VMX中止,CPU会把中止的原因存储在这里。

偏移8处存放VMCS的数据域,该数据域的格式与具体CPU的型号有关。

VMCS在使用时需要与物理CPU绑定。在任意时刻,VMCS与物理CPU是一对一的绑定关系,但在不同时刻,VMCS可以绑定到不同的CPU,即和一个CPU解绑,并重绑定到另一个CPU上,这个过程称为“迁移“”。使用指令VMPTRLD完成VMCS与物理CPU绑定,指令VMCLEAR用于VMCS与物理CPU解绑定。可以给一个VM配置多个VCPU,并通过调度器让它们共享一个物理CPU分时执行或分散到多个物理CPU同时执行。

CPU在发生VM Exit和VM Entry时,会自动更新和查询VMCS。Intel提供专门的指令来配置VMCS,如VMWrite和VMRead用于读写VMCS保存的虚拟寄存器等信息。

2、内存虚拟化

内存虚拟化是实现地址空间的虚拟化,内存虚拟化通过两次地址转换来支持地址空间的虚拟化。VM的虚拟地址GVA转换为VM的物理地址GPA,再转换为VMM的物理地址HPA。其中,GVA到GPA的转换由VM内的操作系统完成,通常依靠VMCS中VM的CR3完成;GPA到HPA的转换依靠VMM的EPT(Extended Page Table)完成。

CPU查询VMCS里的CR3寄存器,CR3寄存器存放的是GPA,需要通过EPT页表找到对应的HPA。首先CPU会查看EPT TLB,如果在缓存中没有找到对应的HPA,CPU 会继续在EPT内查找,仍然没有找到,CPU抛出EPT Violation异常交由VMM来处理。CPU从VM non-Root Operation模式切换到VM Root Operation,即触发一次VM Exit。找到GPA对应的HPA,则从VM Root Operation模式切换会VM non-Root Operation模式,即VM Entry。

以4级页表为例,CPU完成一次地址转换的过程如下:

一个GPA地址被分成5部分,L4,L3,L2,L1,L0。每一部分作为一个索引,Index4,Index3,Index2,Index1,Offset。从EPTP取出PML4 Table的基地址,加上Index4*4找到PML4 Entry;并取出PML4 Entry中存放的PDP Table的基地址,加上Index3*4找到PDP Entry;取出PDP Entry中存放的PD Table的基地址,加上Index2*4找到PD Entry;取出PD Entry中存放的PT Table的基地址,加上Index1*4找到物理页帧号PFN;PFN 加上Offset就是最终的物理内存。

参考资料《系统虚拟化——原理与实现》

              《虚拟化技术原理与实现》

              《Intel手册卷3》

              《虚拟化与云计算》

              《Windows Internals Seventh Edition Part 2》

有关硬件辅助虚拟化的更多相关文章

  1. ruby-on-rails - 如何使辅助方法在 Rails 集成测试中可用? - 2

    我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel

  2. 在VMware16虚拟机安装Ubuntu详细教程 - 2

    在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主

  3. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  4. ruby-on-rails - Controller 中的 Rails 辅助模块 - 2

    我有一个Controller,我想为这个Controller创建一个助手,我可以在不包含它的情况下使用它。我尝试像这样创建一个与Controller同名的助手classCars::EnginesController我创建的助手是moduleCars::EnginesHelperdefcheck_fuellogger.debug("chekingfuel")endend我得到的错误是undefinedlocalvariableormethod`check_fuel'for#有没有我遗漏的约定? 最佳答案 如果你真的想在Controll

  5. ruby-on-rails - 为什么 Rails 使用像 link_to 这样的辅助方法而不是 <a href...>? - 2

    我正在学习Rails,我注意到Rails不断地使用诸如link_to之类的辅助方法,而不是仅仅使用普通的html。现在我可以理解为什么他们会使用他们会使用一些辅助方法,但我不明白为什么他们更喜欢辅助方法而不是直接编码html。为什么Rails更喜欢辅助方法而不是您必须手动编写html?为什么Rails团队做出这样的设计选择? 最佳答案 在Rails应用程序中,通常使用URL方法和内容方法生成链接,例如这绝对比将它们放入中更易于管理手动标记。">(您正在使用路由器生成这些URL,对吗?如果您硬编码/users/1并决定稍后将其设为/u

  6. ruby-on-rails - Rails 验证虚拟属性 - 2

    我这个模型:classBunny每当我提交一个表单来创建这个模型时,我都会收到以下错误:#的未定义方法“number_before_type_cast” 最佳答案 我通过将此方法添加到我的Bunny模型中解决了这个问题:defnumber_before_type_castnumberend我不喜欢它,但我想在有人发布更好的解决方案之前它会起作用。 关于ruby-on-rails-Rails验证虚拟属性,我们在StackOverflow上找到一个类似的问题: h

  7. 【云计算】私有云在VMware下虚拟机的创建与配置(图文教程) - 2

    【适用平台】私有云   说明:完成私有云部分是需要两台虚拟机的,分别为controller、compute两个节点,但我们只需配置一台,然后克隆就方便多啦!需要用到的映射文件:关于vm的安装我就不介绍的,毕竟挺简单的,下面让我们看看基于私有云模块中,虚拟机的搭建吧。1、创建新的虚拟机,这里一般我会选择自定义,毕竟后面的配置都要根据私有云相关来进行搭建,会比较复杂。(如果是基础的可以选择典型,典型的满足一般虚拟机的配置) 2、选择稍后安装操作系统会比较方便后续的选择,这里你也可以自己选择自己的映像文件(但不建议)  3、我们是基于Linux下操作的,所以选择Linux客户机操作系统,版本选择自己

  8. VMware虚拟机与本地主机进行磁盘共享(详解) - 2

    VMware虚拟机与本地主机进行磁盘共享前提虚拟机版本为Windows10(专业版,不是可能有问题)本地主机为家庭版或学生版(此版本会有问题,但有替代方式)最好是专业版VMware操作1.关闭防火墙,全部关闭。2.打开电脑属性3.点击共享-》高级共享-》权限4.如果没有everyone,就添加权限选择完全控制,然后应用确定。5.打开cmd输入lusrmgr.msc(只有专业版可以打开)如果不是专业版,可以跳过这一步。点击用户-》administrator密码要复杂密码,否则不行。推荐admaiN@1234类型的密码。设置完密码,点击属性,将禁用解开。6.如果虚拟机的windows不是专业版,可

  9. 虚拟机上进行java项目部署 - 2

    🚀🚀🚀🚀🚀🚀🚀🚀🚀🚀虚拟机上进行java项目部署,自己的一点总结,一起学习,一起进步,一起成长!🛸🛸🛸🛸🛸🛸🛸🛸🛸🛸目录文章目录虚拟机上进行java项目部署1.JDK安装2.TOMCAT安装3.DOCKER1、YUM安装2、docker部署java4、最后 【yzh2022.9】1.JDK安装1、我们安装VM的时候,使用命令java-version查看 java-version这里显示JDK的信息是openjdkversion"1.8.0_262",我们会发现这个JDK是VM自带的当然你也可以通过命令rpm-qa|grepjava来查看相关的java信息 rpm-qa|grepjava【如果不

  10. ruby-on-rails - 从 Virtus.model 动态扩展时使用 boolean 属性辅助方法 - 2

    假设我有一个带有boolean属性active的Virtus模型User:classUserincludeVirtus.modelattribute:active,Boolean,default:false,lazy:trueend然后我可以使用辅助方法active?:User.new.active?#=>falseUser.new(active:true).active?#=>true但是当我尝试从Virtus.model中扩展并动态定义一个boolean属性时:classUser;enduser=User.newuser.extend(Virtus.model)user.attri

随机推荐