KVM MMU EPT内存管理

2023-11-13

转载请注明:【转载自博客xelatex KVM】,并附本文链接。谢谢。
 
【注】文章中采用的版本:
Linux-3.11,https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.11.tar.gz
qemu-kvm,git clone http://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git, 
          git checkout 4d9367b76f71c6d938cf8201392abe4bfb1136cb
 
先说几个英文缩写:
  • GVA - Guest Virtual Address,虚拟机的虚拟地址
  • GPA - Guest Physical Address,虚拟机的虚拟地址
  • GFN - Guest Frame Number,虚拟机的页框号
  • HVA - Host Virtual Address,宿主机虚拟地址,也就是对应Qemu中申请的地址
  • HPA - Host Physical Address,宿主机物理地址
  • HFN - Host Frame Number,宿主机的页框号
KVM中目前一般采用硬件虚拟化来对内存的MMU进行虚拟化,以提高访存的效率。在比较老的虚拟化技术中,一般采用SPT(Shadow Page Table)来实现MMU虚拟化,所以在KVM代码中有很多地方依然采用类似的命名方式。本文主要针对Intel体系架构Intel VT-x中EPT在KVM中的应用进行说明。
 
一、内存槽(slot)的注册和管理
 
上文中我提到KVM只提供机制,不提供策略。为了实现对内存区域的管理,采用了kvm_memory_slot结构来对应Qemu中的AddressSpace。Qemu将虚拟机的线性地址(物理地址)在KVM中注册为多个内存槽,如BIOS、MMIO、GPU、RAW。
Qemu的内存模型请参考官方文档 https://github.com/qemu/qemu/blob/master/docs/memory.txt
 
KVM中memory slot的数据结构:
<include/linux/kvm_host.h>
struct kvm_memory_slot {
    gfn_t base_gfn; // 该slot对应虚拟机页框的起点
    unsigned long npages; // 该slot中有多少个页
    unsigned long *dirty_bitmap; // 脏页的bitmap
    struct kvm_arch_memory_slot arch; // 体系结构相关的结构
    unsigned long userspace_addr; // 对应HVA的地址
    u32 flags; // slot的flag
    short id; // slot识别id
};
<arch/x86/include/asm/kvm_host.h>
struct kvm_arch_memory_slot {
    unsigned long *rmap[KVM_NR_PAGE_SIZES]; // 反向映射结构(reverse map)
    struct kvm_lpage_info *lpage_info[KVM_NR_PAGE_SIZES - 1]; // Large page结构(如2MB、1GB大小页面)
}; 

KVM数据结构中与内存槽相关的结构,注意KVM对每个虚拟机都会建立和维护一个struct kvm结构。
<include/linux/kvm_host.h>
struct kvm {
	spinlock_t mmu_lock; // MMU最大的锁
	struct mutex slots_lock; // 内存槽操作锁
	struct mm_struct *mm; /* userspace tied to this vm,指向虚拟机内部的页存储结构 */
	struct kvm_memslots *memslots; // 存储该KVM所有的memslot
...
};

struct kvm_memslots {
	u64 generation;
	struct kvm_memory_slot memslots[KVM_MEM_SLOTS_NUM];
	/* The mapping table from slot id to the index in memslots[]. */
	short id_to_index[KVM_MEM_SLOTS_NUM];
};

kvm->memslots结构在创建虚拟机时被创建,代码见:
<virt/kvm/kvm_main.c>
static struct kvm *kvm_create_vm(unsigned long type)
{
...
    kvm->memslots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
    if (!kvm->memslots)
        goto out_err_nosrcu;
    kvm_init_memslots_id(kvm);
...
}

内存槽的注册入口在 kvm_vm_ioctl函数中 case KVM_SET_USER_MEMORY_REGION部分,最终调用函数 __kvm_set_memory_region在KVM中建立与Qemu相对应的内存槽结构。 __kvm_set_memory_region函数主要做了如下几件事情:
  1. 数据检查
  2. 调用id_to_memslot来获得kvm->memslots中对应的memslot指针
  3. 设置memslot的base_gfn、npages等域
  4. 处理和已经存在的memslots的重叠
  5. 调用install_new_memslots装载新的memslot
虚拟机线性地址被分成若干个memslot,每个memslot是不能重叠的,也就是说每一段内存区间都必须有独立的作用。一般来说Qemu会对RAM、IO memory、High memory等分别注册若干个memslot
二、KVM MMU创建和初始化流程
2.1 KVM MMU的创建
KVM在vcpu创建时创建和初始化MMU,所以说KVM的MMU是每个VCPU独有的(但是有一些是共享的内容,后面会说到)。创建VCPU的代码起点是函数 kvm_vm_ioctl_create_vcpu
<virt/kvm/kvm_main.c>
static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
{
...
    vcpu = kvm_arch_vcpu_create(kvm, id);
...
    r = kvm_arch_vcpu_setup(vcpu);
...
}

该函数中首先调用 kvm_arch_vcpu_create创建vcpu,然后调用 kvm_arch_vcpu_setup初始化vcpu。在x86架构中,kvm_arch_vcpu_create最终调用vmx_create_vcpu函数进行VCPU的创建工作。MMU的创建在 vmx_create_vcpu => kvm_vcpu_init => kvm_arch_vcpu_init => kvm_mmu_create 中,如下:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

KVM MMU EPT内存管理 的相关文章

  • KVM下Ubuntu18.04打开设置注销问题

    问题描述 xff1a 在KVM中创建Ubuntu18 04 xff0c 打开系统设置 xff0c 发现直接注销 xff08 不是锁屏 xff0c 因为所有程序都退出 xff09 解决思路 在google上搜索发现大多数都是指向显卡问题 xf
  • Ubuntu20 + KVM虚拟机

    1 命令汇总 span class token comment 查看一下linux是32位还是64位 xff1a span span class token function file span bin ls span class toke
  • KVM虚拟机创建功能详细讲解

    KVM虚拟机创建功能详细讲解 一 KVM虚拟机创建的用户操作 对于用户或者管理员来说 xff0c 虚拟机的创建有着很多的方法 xff0c 例如 xff1a kvm自带命令行工 具 使用virsh命令来创建 使用具有图形界面的virt man
  • KVM interface passthrough

    nbsp nbsp nbsp nbsp kvm passthrouth sr iov nbsp nbsp https blog csdn net yzy1103203312 article details 81092647 nbsp nbs
  • kvm的快照功能 (二、基于libvirt的快照)

    实例二 利用libvirt使用快照 virsh snapshot create domain name 一 创建虚机快照 名字自动生成 可在开机 关机 suspend等各种状态下做 virsh snapshot create test Do
  • kvm常见故障及解决

    一 启动虚拟机Connection reset by peer virsh start vmhost1error Failed to start domain vmhost1error Unable to read from monitor
  • kvm qemu内幕介绍

    kvm qemu内幕介绍 标签 虚拟化io数据结构linux内核优化磁盘 2012 09 14 11 10 6923人阅读 评论 4 收藏 举报 分类 linux 56 版权声明 本文为博主原创文章 未经博主允许不得转载 目录 1 硬件虚拟
  • Linux上启用kvm嵌套虚拟化功能

    kvm支持嵌套虚拟化 即可以在虚拟机中创建虚拟机 本文主要介绍如何在使用Intel处理器的CentOS7中开启KVM的嵌套虚拟化功能 kvm主要是通过内核模块来实现的 因此我们查看系统是否开启了kvm嵌套虚拟化 只需要 cat sys mo
  • 如何在 Ubuntu 18.04 上安装 Kvm

    KVM 基于内核的虚拟机 是内置于 Linux 内核中的开源虚拟化技术 它允许您运行多个基于 Linux 或 Windows 的隔离来宾虚拟机 每个来宾都有自己的操作系统和专用虚拟硬件 例如 CPU 内存 网络接口和存储 本指南介绍如何在
  • Proxmox VE(PVE) 进行网卡直通

    文章目录 我的设备 介绍 添加CPU支持 开启iommu 查询网卡信息 Intel CPU AMD CPU 新增所需模块 添加PCI设备 命令模式添加 web页面模式添加 验证IOMMU有效 IOMMU中断重映射 查看中断重映射 启用中断重
  • 再论KVM超量使用

    转载自 http www sohu com a 111248295 251444 KVM超量使用一直是热门话题 前段时间发的文章 群讨论 虚拟机能否使用32个CPU 又引去了群友的激烈讨论 本文为群友根据自己的经验总结投稿 感谢这位热心的群
  • KVM——迁移KVM虚拟机

    一 KVM虚拟机迁移的方式 KVM平台中的KVM虚拟机迁移分为以下两种 1 冷迁移 静态迁移 我们存放虚拟机磁盘的目录都是挂在的一个nfs文件系统的磁盘 进行冷迁移时 只要在目标主机上挂载这个nfs文件系统 就可以看到要迁移的那个虚拟机的磁
  • KVM-6、virsh 命令及功能详解

    1 虚拟机管理操作 attach device 从XML文件附加设备 attach disk 附加磁盘设备 attach interface 连接网络接口 autostart 自动启动一个域 blkdeviotune 设置或查询块设备I O
  • ovirt-node和ovirt-engine相连遇到的问题解决办法

    1 Host 192 168 70 7 does not comply with the cluster Default emulated machines The Hosts emulated machines are
  • kvm虚拟机vnc和spice配置

    一 简介 通过vnc或spice方式访问虚拟主机上的KVM虚拟机 可以直接通过图形化界面virt manager来设置 但此处通过xml配置文件修改 二 详解 1 VNC方式访问 vnc方式访问虚拟机不是在kvm虚拟机安装配置vnc服务器
  • 是否可以在 Azure 上运行 KVM

    Azure Fabric 似乎运行在 Hyper V 的定制版本上 是否可以在 Azure 上运行 KVM 虚拟化实例 使用嵌套虚拟化 我有一个基于 Debian 的自定义 VHD 比如说 根据本文档https learn microsof
  • Linux x86-64 上的物理内存中的用户空间和内核之间是否存在明确的划分?

    也就是说 给定一个物理地址 我可以判断这个地址是否来自用户空间吗 据我所知 在虚拟地址空间中 内核将使用 上半部分和用户空间将使用下半部分 但是关于 在物理地址空间 让问题变得复杂的是我想检查KVM中的客户物理地址 这意味着我无法调用客户操
  • x86 PIC,QEMU 在所有 CPU 上引发中断是否正确?

    我最近不得不解决 x86 PIC 的专有操作系统问题 其中操作系统预期定时器中断仅在 CPU0 上 我启用了 IO APIC 来解决这个问题并进行了 CPU 控制 因此中断仅到达 CPU0 问题解决了 有人告诉我 我们的硬件已经损坏 无法做
  • Xen、QEMU 和 KVM 之间有什么区别?

    我知道Xen使用QEMU 而KVM是QEMU的一个分支 那么 KVM 包括 Xen 添加到 QEMU 中吗 是什么名字 Thanks QEMU 是一个功能强大的模拟器 这意味着它可以模拟多种处理器类型 Xen 使用 QEMUHVM http
  • Android 模拟器和 OpenGL ES3:EGL_BAD_CONFIG

    我正在运行一个Android 虚拟设备 https developer android com studio run managing avds html在我的 Ubuntu 主机上 它使用 CPU ABI Intel Atom x86 我

随机推荐

  • mysql开启和关闭远程访问权限

    文章目录 说明 用的是 navicat 连接工具 1 mysql开启远程访问权限 1 1 改表法 1 2 语句更改 2 mysql关闭远程访问权限 2 1 改表法 2 2 语句更改 说明 用的是 navicat 连接工具 先来看下mysql
  • Unity3D实践系列07,组件的启用或禁用开关,物体的的可见或不可见开关,以及相应事件...

    创建一个Unity项目 在 Project 窗口中 在 Asserts 中 添加 MyScene 文件夹 点击 File 中的 Save Scene 给Scene命名 并保存到 MyScene 文件夹 创建一个类型为 Plane 的Game
  • jsp的基本认识与理解

    简介 JSP全称是JavaServer Pages 它和servlet技术一样 都是SUN公司定义的一种用于开发动态web资源的技术 JSP这门技术的最大的特点在于 写jsp就像在写html 但 它相比html而言 html只能为用户提供静
  • 阿里云Windows Server 利用Subversion和TortoiseSVN部署SVN服务器

    SVN 全称为 SubVersion 是一个开源的版本控制系统 管理着随时间而改变更新的数据 这些数据都放置在一个中央资料档案库 repository 中 它类似于一个普通的文件服务器 可以记录每一次文件的更 新变动 这样就可以把档案恢复到
  • rabbitmq取消自动重连_RabbitMQ Java客户端自动重新连接

    When my application looses connection to RabbitMQ I have its connection factory set to automatically try and reconnect C
  • 小白也能弄懂的目标检测之YOLO系列 - 第一期

    大家好 上期分享了电脑端几个免费无广告且实用的录屏软件 这期想给大家来讲解YOLO这个算法 从零基础学起 并最终学会YOLOV3的Pytorch实现 并学会自己制作数据集进行模型训练 然后用自己训练好的模型进行预测 话不多说 先上我用Vis
  • windows命令行文件中获取bat文件所在目录相关路径

    批处理命令获取当前盘符和当前目录 d0 是当前盘符 cd 是当前目录 可以用echo cd 进行打印测试 以下例子是命令行编译Visual Studio编写的程序 echo off set b cd 将当前目录保存到参数b中 等号前后不要有
  • qrcode 生成二维码的代码

  • CentOs7.5安装JDK1.8详细步骤

    1 先检查系统中有没有自带的JDK 有就卸载 查询命令 rpm qa grep jdk color 卸载命令 rpm e nodeps 软件名称 再次查询检查是否成功 rpm qa grep jdk color 没有提示也没有报错就是操作成
  • 大厂测试工程师面试题总结-三面(附参考答案)

    三面 1 指针常量 常量指针 指针常量 1 指针常量的本质是一个常量 并且使用指针来修饰它 2 通过对const定义 我们可以简单理解为这个指针是个常量 它不可以被修改 即它只能指向开始时我们给赋值的变量 不可以被修改从而再指向其他的变量
  • 安装mmdetection(windows下)

    windows环境安装mmdetection 创建pytorch环境 最终安装的版本信息 安装过程 step1 安装mmcv full step2 安装mmdetection 安装mmdet报错 Could not build wheels
  • Linux进程间通信--msgsnd函数的作用

    msgsnd函数用于将消息发送到消息队列中 它的原型如下 int msgsnd int msqid const void msgp size t msgsz int msgflg 参数解释 msqid 消息队列标识符 由msgget函数返回
  • windows系统查看进程端口号的命令

    查看进程端口号 1 查看windows所有端口进程 netstat ano 命令提示符窗口 2 查询指定的端口占用 netstat aon findstr 端口 显示列表中的PID 然后根据PID在电脑的任务管理器中查看对应的占用程序 根据
  • Python 生成当前项目依赖包 requirements

    Python 生成当前项目依赖包 requirements 1 安装 pipreqs pip install pipreqs 2 执行命令 在当前工程目录生成 pipreqs encoding utf8 force 3 使用requirem
  • CentOS下ELK 7.2生产安全部署

    01 架构说明 在需要采集日志的服务器上部署Filebeat服务 它将采集到的日志数据推送到Kafka集群 Logstash服务通过input插件读取Kafka集群对应主题的数据 期间可以使用filter插件对数据做自定义过滤解析处理 然后
  • Android Studio 4.x 返回上一次编辑的地方

    Android Studio 升级到 4 x 后 返回上一次编辑的地方的快捷键变成了 Alt Shift 左箭头 了
  • JUC之ReentrantReadWriteLock

    JUC之ReentrantReadWriteLock 1 背景 由于ReentrantLock是独占可重入锁 因此在进行操作的时候 不能够满足多线程同时操作数据 为了满足并发场景下的临界资源的数据共享 出现了ReentrantReadWri
  • web上传图片到七牛云服务器

    本文通过java web的使用 把要上传的图片通过浏览器上传到服务器上面 文本仅供参考 可能出现很多不合理 1 创建对应的jsp页面 下面是jsp下面的对应的from表单 上传文件用的那么ImgFiles的属性名称 同样你可以使用其他的 或
  • 零基础开发NBIOT

    前言 shineblink core 开发板 简称Core 的库函数支持NBIOT通信功能 所以只用几行代码即可实现基于M5311 NB模块的联网通信 TCP UDP MQTT 功能 这里我们主要介绍通过TCP实现联网通信的功能 更多关于T
  • KVM MMU EPT内存管理

    转载请注明 转载自博客xelatex KVM 并附本文链接 谢谢 注 文章中采用的版本 Linux 3 11 https www kernel org pub linux kernel v3 x linux 3 11 tar gz qemu