QEMU与KVM基本概述

一些术语

汇总在虚拟化世界里经常会涉及到的术语或缩写等。

术语含义
VMVirtual Machine,虚拟机
VMM在系统虚拟化中,管理全局物理资源的软件叫作虚拟机监控器(Virtual MachineMonitor,VMM),VMM之于虚拟机就如同操作系统之于进程,VMM利用时分复用或者空分复用的办法将硬件资源在各个虚拟机之间进行分配
Xen2001年剑桥大学开发了Xen,早期的开源虚拟化方案,出现在各种硬件虚拟化技术之前。现在远不如KVM
KVM2006年,以色列的初创公司Qumranet利用Intel的硬件虚拟化技术在Linux内核上开发了KVM(Kernel Virtual Machine),是一款非常成功的虚拟化VMM,称为云计算的基石
QEMUQuick Emulator,模拟器
VMXVirtual Machine eXtensions. intel在x86 cpu架构基础上增加VMX架构来实现CPU的硬件虚拟化
VMX架构下有:VMM(虚机监控器) 和 VM(虚机)
CPU支持VT-x技术的标志为vmx,Linux中/proc/cpuinfo可查看
VT-xIntel virtualization,intel虚拟化技术。可在BIOS中设置是否启用VT-x技术
所以可以认为 VMX = VT-x,都是指 intel 硬件虚拟化技术

虚拟化解决方案

虚拟化解决方案
VMware WorkstationVMware最早的产品,至今仍有大量用户使用。VMware Workstation能够很方便地在PC上构建一个虚拟机,用户可以在其上安装各种操作系统,能够非常方便地完成多种任务,比如跨平台的开发测试
VirtualBox最早由一个德国公司开发,后来被甲骨文收购。它的优点是性能不错并且开源,能够很方便地用来实现一些定制需求
HyperV微软提供的虚拟化解决方案,微软用它来构建自己的云计算平台
XenXen作为早期的开源VMM,其诸多思想直到今天也在影响着虚拟化社区

QEMU/KVM架构

VMX operation

VMX架构中,每个VM都是一个虚拟机实例,能够支持操作系统以及各种软件栈和应用程序,VM本身不会意识到其处在虚拟化环境中。每一个VM都相互独立,有自己独立的CPU、内核、中断和设备等,这些资源都是VMM提供的。

VMM需要对各个VM进行管理,包括创建、配置、删除VM实例、为其分配资源、确保各个VM之间的隔离与独立,还需要处理VM对资源的访问、确保公平,所有这些都需要VMM运行的权限高于VM,只有这样,VMM才能够实现对整个系统资源和对VM的管理。但是传统上,操作系统内核已经运行在ring0最高级了,所以为了让CPU支持VMM和VM两种软件,Intel为CPU引入了一种新的模式,叫作VMX operation。

VMM执行的模式叫作VMX root operation模式,VM执行的模式叫作VMX non-root operation模式,这两种模式之间的转换叫作VMX转换。从VMX root转换到VMXnon-root叫作VM Entry,而从VMX non-root转换到VMX root则叫作VM Exit。

在这里插入图片描述

每种模式都有自己的ring0和ring3结构。VMX operation与CPU特权级是正交的。在普通的QEMU/KVM架构中,QEMU等用户态软件以及KVM等宿主机的内核都运行在VMX root模式下,在虚拟机也有自己的ring0和ring3。当然,VM中执行指令的行为肯定不能完全与VMM中相同,否则也用不着VMX架构了。在VMX non-root模式中,各种指令是严格受到限制的,执行一些特殊的指令(如之前所说的影响系统全局的指令)或者发生一些特殊的事件都会导致VM Exit,使VM退出到VMM。

QEMU/KVM架构图

在这里插入图片描述

CPU在运行包括QEMU在内的普通进程和宿主机的操作系统内核时,CPU处在VMX root模式。CPU在运行虚拟机中的用户程序和操作系统代码的时候处于VMX non-root模式。需要注意的是,CPU的运行模式与CPU运行时的特权等级是相互正交的,虚拟机在VMXroot模式和VMX non-root模式下都有ring 0到ring 3四个特权级别。

可以按上图中的色框线来理解QEMU/KVM架构,整体可以分为3大部分:

  • VMX root 应用层:宿主机的qemu等普通进程
  • VMX non-root 虚拟机层:虚拟机guest
  • VMX root 内核层:宿主机的内核
VMX root 应用层

从图中可以看出,QEMU的主要任务是模拟芯片组,创建CPU线程来表示虚拟机的CPU执行流,在QEMU虚拟地址空间中分配空间作为虚拟机的物理地址,创建用户指定的虚拟设备等,QEMU通过监听事件的方式来响应KVM转过来的虚拟机请求。

VMX non-root 虚拟机层

虚拟机中本身也有自己的操作系统内核和应用层,虚拟机的一个CPU对应QEMU进程中的一个vCPU线程,可以被host主机正常调度。

虚拟机中的物理内存对应QEMU进程的虚拟内存,VM通过guest os的页表管理系统完成VM虚拟地址到VM物理地址的转换,最终经由KVM的页表完成VM物理地址到host物理地址的转换

VMX root 内核层

Linux内核中的KVM驱动,主要做两件事:

  1. KVM通过 “/dev/kvm” 设备提供ioctl的API接口,QEMU通过该接口可控制虚拟机,比如设定CPU个数、内存布局等;
  2. KVM需要截获虚拟机产生的 VM Exit 事件并响应处理;

QEMU与KVM配合起来共同完成了虚拟机各个组件的虚拟化,比如CPU虚拟化、内存虚拟化、设备虚拟化、中断虚拟化等。

CPU虚拟化

QEMU创建vCPU线程,初始化时就设置好vCPU寄存器的值,然后通过KVM API,运行虚拟机。

KVM需要截获虚拟机中的敏感指令,当虚拟机的代码是敏感指令或者满足一定的退出条件时,CPU从VMX non-root模式退出到KVM(VMX root模式),这叫 VM Exit(类似于用户态陷入内核态)。VMX Exit后首先在KVM中处理,如果KVM无法处理,再转给QEMU处理。当QEMU或KVM处理好VM Exit事件后,又将CPU置于VMX non-root模式,这叫VM Entry。虚拟机就这样不停的VM Exit和VM Entry。

KVM中用一个结构来记录虚拟机的VM Exit和VM Entry状态,叫VMCS

VM Exit 保存VM状态 加载host状态
VM Entry 保存host状态 加载VM状态
虚拟机代码
KVM/QEMU

内存虚拟化

QEMU在初始化的时候会通过mmap系统调用分配虚拟内存空间作为虚拟机的物理内存,QEMU在不断更新内存布局的过程中会持续调用KVM接口通知内核KVM模块虚拟机的内存分布。

VM虚拟地址
VM物理地址
host虚拟地址
host物理地址

在CPU支持EPT(Extended Page Table,扩展页表)之前,虚拟机通过影子页表实现从虚拟机虚拟地址到宿主机物理地址的转换,是一种软件实现。当CPU支持EPT之后,CPU会自动完成虚拟机物理地址到宿主机物理地址的转换。虚拟机在第一次访问内存的时候就会陷入到KVM,KVM会逐渐建立起所谓的EPT页面。这样虚拟机的虚拟CPU在后面访问虚拟机虚拟内存地址的时候,首先会被转换为虚拟机物理地址,接着会查找EPT页表,然后得到宿主机物理地址,整个过程由硬件完成,很高效。

在这里插入图片描述

设备虚拟化

虚拟化的一个烦琐任务就是为虚拟机提供大量的设备支持,如同Linux内核中最多的代码是设备驱动,QEMU最多的代码是设备模拟。

QEMU在初始化过程中会创建好模拟芯片组和必要的模拟设备,包括南北桥芯片、PCI根总线、ISA根总线等总线系统,以及各种PCI设备、ISA设备等。

三种设备虚拟化技术方案:

  1. 最开始的QEMU只有纯软件模拟,虚拟机内核不用做任何修改,每一次对设备的寄存器读写都会陷入到KVM,进而到QEMU,QEMU再对这些请求进行处理并模拟硬件行为,如图a所示,很显然,软件模拟会导致非常多的QEMU/KVM介入,效率不高。

在这里插入图片描述

  1. 为了提高虚拟设备的性能,社区提出了virtio设备方案。virtio设备是一类特殊的设备,并没有对应的物理设备,所以需要虚拟机内部操作系统安装特殊的virtio驱动,如图b所示。virtio设备将QEMU变成了半虚拟化方案,因为其本质上修改了虚拟机操作系统内核,与之相对的完全不用修改虚拟机操作系统的方案叫作完全虚拟化
  2. virtio仍然不能完全满足一些高性能的场景,于是又有了设备直通方案,也就是将物理硬件设备直接挂到虚拟机上,虚拟机直接与物理设备交互,尽可能在I/O路径上减少QEMU/KVM的参与,如图c所示。与设备直通经常一起使用的有设备的硬件虚拟化支持技术SRIOV(Single RootI/O Virtualization,单根输入/输出虚拟化),SRIOV能够将单个的物理硬件高效地虚拟出多个虚拟硬件。

中断虚拟化

操作系统通过写设备的I/O端口或者MMIO地址来与设备交互,设备通过发送中断来通知虚操作系统事件。如下图所示。QEMU在初始化主板芯片的时候初始化中断控制器。QEMU支持单CPU的Intel 8259中断控制器以及SMP的I/O APIC(I/O Advanced Programmable Interrupt Controller)和LAPIC(Local Advanced Programmable Interrupt Controller)中断控制器。传统上,如果虚拟外设通过QEMU向虚拟机注入中断,需要先陷入到KVM,然后由KVM向虚拟机注入中断,这是一个非常费时的操作,为了提高虚拟机的效率,KVM自己也实现了中断控制器Intel 8259、I/O APIC以及LAPIC。用户可以有选择地让QEMU或者KVM模拟全部中断控制器,也可以让QEMU模拟Intel 8259中断控制器和I/O APIC,让KVM模拟LAPIC。QEMU/KVM一方面需要完成这项中断设备的模拟,另一方面需要模拟中断的请求。中断请求的形式大体上包括传统ISA设备连接Intel 8259中断控制器产生的中断请求,PCI设备的INTx中断请求以及MSI和MSIX中断请求。

在这里插入图片描述

QEMU的事件循环机制

/*vl.c,qemu主循环函数简化版*/
void qemu_main_loop(void)
{while (!main_loop_should_exit()) {main_loop_wait(false);}
}

QEMU线程模型

QEMU-KVM架构中,一个QEMU进程代表一个虚拟机。QEMU会有若干个线程,其中对于每个CPU会创建一个线程,还有其他的线程,如VNC线程、I/O线程、热迁移线程。

在这里插入图片描述

QEMU主事件循环所在的线程由于会不断监听各种I/O事件,所以被称为I/O线程。现在的I/O线程通常是指块设备层面的单独用来处理I/O事件的线程。每一个CPU都会有一个线程,通常叫作VCPU线程,其主要的执行函数是kvm_cpu_exec。QEMU为了完成其他功能还会有一些辅助线程,如热迁移时候的migration线程、支持远程连接的VNC和SPICE线程等

线程模型通常使用QEMU大锁进行同步,获取锁的函数为 qemu_mutex_lock_iothread,解锁函数为 qemu_mutex_unlock_iothread。cpus.c中的static变量qemu_global_mutex是BQL用于main loop的锁。

VCPU线程

x86架构中,qemu-kvm架构创建vcpu线程大体流程如下,kvm_init_vcpu()函数中通过KVM_CREATE_VCPU字段ioctl下发给内核kvm创建vcpu线程,kvm_cpu_exec()函数通过ioctl下发KVM_RUN字段给内核kvm模块进行vcpu run运行。

x86_cpu_realizefn
qemu_init_vcpu
qemu_kvm_start_vcpu
qemu_thread_create
pthread_create
qemu_kvm_cpu_thread_fn
kvm_init_vcpu
kvm_cpu_exec
qemu_kvm_destroy_vcpu
VNC线程

vnc_init_func对VNC模块进行初始化,经过vnc_display_init->vnc_start_worker_thread的调用最终创建VNC线程,VNC线程用来与VNC客户端进行交互。

qemu_ini
vnc_init_func
vnc_display_init
vnc_start_worker_thread
qemu_thread_create
pthread_create
vnc_worker_thread
vnc_worker_thread_loop
I/O线程

设备模拟过程中可能会占用QEMU的大锁,所以如果是用磁盘类设备进行读写,会导致占用该锁较长时间。为了提高性能,会将这类操作单独放到一个线程中去。QEMU抽象出了一个新的类型TYPE_IOTHREAD,可以用来进行I/O线程的创建。

QEMU还会有其他线程,比如说热迁移线程以及一些设备模拟自己创建的线程。

如同Linux内核中的大锁,BQL会对QEMU虚拟机的性能造成很大影响。早期的QEMU代码在握有BQL时做的事情很多,QEMU多线程的主要动力是减少QEMU主线程的运行时间,QEMU在进行一些设备模拟的时候,VCPU线程会退出到QEMU,抢占QEMU大锁,如果这个时候有其他线程占据大锁,再做长时间的工作就会导致VCPU被挂起比较长的时间,所以将一些没有必要占据QEMU大锁的任务放到单独线程进行处理就能够增加VCPU的运行时间,这也是QEMU社区在多线程方向的努力方向,即尽量将任务从QEMU大锁中拿出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/630389.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从DETR到Mask2former(2): 损失函数loss function

DETR的损失函数包括几个部分,如果只看论文或者代码,比较难理解,最好是可以打断点调试,对照着论文看。但是现在DETR模型都已经被集成进各种框架中,很难进入内部打断掉调试。与此同时,数据的label的前处理也比…

《动手学深度学习》学习笔记 第8章 循环神经网络

本系列为《动手学深度学习》学习笔记 书籍链接:动手学深度学习 笔记是从第四章开始,前面三章为基础知识,有需要的可以自己去看看 关于本系列笔记: 书里为了让读者更好的理解,有大篇幅的描述性的文字,内容很…

Vue3中动态组件使用

一&#xff0c;动态组件使用&#xff1a; 应用场景&#xff1a;动态绑定或切换组件 应用Vue3碎片&#xff1a; is 1.使用 a.组件A <div class"layout-base"><Button>红茶</Button> </div>a.组件B <div class"layout-base"&g…

【MATLAB】SVMD_LSTM神经网络时序预测算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 SVMD-LSTM神经网络时序预测算法是一种结合了单变量经验模态分解&#xff08;Singular Value Decomposition&#xff0c;SVD&#xff09;和长短期记忆神经网络&#xff08;LSTM&#xff09…

第二百七十二回

文章目录 1. 概念介绍2. 方法与类型2.1 使用方法2.2 常见类型 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何加载本地图片"相关的内容&#xff0c;本章回中将介绍如何获取文件类型.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在本章回…

23.实战演练--个人主页

<?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"><applicationandroid:allowBackup"true"an…

【项目实战】Postgresql数据库中出现锁表如何解决

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 系列专栏目录 [Java项目…

Unity之触发器

目录 &#x1f4d5;一、触发器概念 &#x1f4d5;二、碰撞与触发的区别 &#x1f4d5;三、触发器小实例 一、触发器概念 第一次玩侠盗猎车手是在小学&#xff0c;从那以后就开启了我的五星好市民之路。 下面是小编在小破站截的图&#xff0c;这是罪恶都市最开始的地方&a…

MCU和MPU有什么区别

大家好&#xff0c;今天给大家介绍MCU和MPU有什么区别&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 MCU&#xff08;Microcontroller Unit&#xff09;和MPU&#xff08;Micro…

蓝桥杯备赛 day 2 —— 二分算法(C/C++,零基础,配图)

目录 &#x1f308;前言&#xff1a; &#x1f4c1; 二分的概念 &#x1f4c1; 整数二分 &#x1f4c1; 二分的模板 &#x1f4c1; 习题 &#x1f4c1; 总结 &#x1f308;前言&#xff1a; 这篇文章主要是准备蓝桥杯竞赛同学所写&#xff0c;为你更好准备蓝桥杯比赛涉及…

从0到1:实验室设备借用小程序开发笔记

概论 实验室设备借用小程序&#xff0c;适合各大高校&#xff0c;科技园区&#xff0c;大型企业集团的实验室设备借用流程, 通过数字化的手段进一步提升相关单位设备保障水平&#xff0c;规范实验室和设备管理&#xff0c;用户通过手机小程序扫描设备的二维码&#xff0c;可以…

深入解析:如何使用Java、SpringBoot、Vue.js和MySQL构建课表管理系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

VS代码生成工具ReSharper v2023.3正式发布——支持C# 12

实质上&#xff0c;ReSharper特征可用于C#&#xff0c;VB.net&#xff0c;XML&#xff0c;Asp.net&#xff0c;XAML&#xff0c;和构建脚本。 使用ReSharper&#xff0c;你可以进行深度代码分析&#xff0c;智能代码协助&#xff0c;实时错误代码高亮显示&#xff0c;解决方案范…

JavaScript基础(27)_内联样式的获取和修改、获取元素当前显示的样式

内联样式的获取和修改 获取元素的内联样式&#xff1a; 语法&#xff1a;元素.style.样式名 注意&#xff1a;通过style属性设置和读取的都是内联样式&#xff0c;无法读取样式表中的样式。 修改元素的内联样式&#xff1a; 语法&#xff1a;元素.style.样式名 样式值比如…

并发编程之深入理解AQS

目录 什么是AQS&#xff1f; AQS的特性 AQS总结 什么是AQS&#xff1f; java.util.concurrent包中的大多数同步器实现都是围绕着共同的基础行为&#xff0c;比如等待队列、条件队列、独占获取、共享获取等&#xff0c;而这些行为的抽象就是基于AbstractQueuedSynchronizer&a…

WordPress后台仪表盘自定义添加删除概览项目插件Glance That

成功搭建WordPress站点&#xff0c;登录后台后可以在“仪表盘 – 概览”中看到包括多少篇文章、多少个页面、多少条评论和当前WordPress版本号及所使用的主题。具体如下图所示&#xff1a; 但是如果我们的WordPress站点还有自定义文章类型&#xff0c;也想在概览中显示出来应该…

【经验分享】美赛报名以及注册方法-以2024年美赛为例

1 进入美赛官网 首先点击COMAP的官网链接&#xff1a; https://www.comap.com/然后选择Contests目录下的MCM/ICM 选择 Learn More and Register 然后选择 register for contest 接下来开始注册环节&#xff0c;注册分为两个步骤&#xff1a;顾问&#xff08;指导教师&#xf…

Jsqlparser简单学习

文章目录 学习链接模块访问者模式parser模块statement模块Expression模块deparser模块 测试TestDropTestSelectTestSelectVisitor 学习链接 java设计模式&#xff1a;访问者模式 github使用示例参考 测试 JSqlParser使用示例 JSqlParse&#xff08;一&#xff09;基本增删改…

GitHub API使用--获取GitHub topic

目录标题 技术简介申请token简单使用使用Java调用获取GitHub topic总结 技术简介 GitHub API是一个功能强大的工具&#xff0c;为开发者提供了访问和操作GitHub平台上资源的途径。无论是构建个人工具&#xff0c;集成自动化流程&#xff0c;还是开发应用程序&#xff0c;GitHu…

【Git】任何位置查看git日志

需求 现需要查看指定项目中的某个文件的 Git 日志。如有 项目代码 jflowable &#xff0c;需要查看其下文件 D:\z_workspace\jflowable\src\main\java\com\xzbd\jflowable\controller\TestController.java 的日志。 分析 一般的思路是&#xff0c;进入 jflowable 项目&#…