博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux虚拟化:KVM影子页表
阅读量:2031 次
发布时间:2019-04-28

本文共 1022 字,大约阅读时间需要 3 分钟。

影子页表简单来说就是,可以直接把客户端的虚拟地址映射成宿主端的物理地址。

 2019年是崭新的一年,Linux kernel 5.0 低调发布了,给我的感觉就是,牛人不断在飞跃,我们也要策马奔腾赶紧追赶才有些许出路。

内核子系统众多,我发现KVM是个非常有意思的子系统,对cpu,内核,IO的虚拟化玩的太溜了,一些技巧真是令人折服,简直就是一个超级魔法师,也可以成为"骗术”,而且还是里因外和。话不多说,进入主题。

VM虚拟化,对虚拟cpu很好理解,cpu采用两种模式,一种是root模式下的0 – 3特权级,另一种是非root模式下的0 - 3特权级别。在root模式下,cpu有真实的寄存器,一切都是真实,但是在非root模式下,cpu要使用的寄存器都放在与cpu绑定的一块物理内存上,绑定的过程有cpu新增的指令支持,当cpu收到中断,或者访问pio、mmio等会陷入到vmm(虚拟机监控机,在宿主端内核态特权级),,陷入以后vmm可以选择自己处理或者交给应用层处理。(此篇文章针对的是x86平台)

但是对于内存的虚拟化就更麻烦了,一般的思路是,客户端虚拟地址经过客户端的页表转化为客户端的物理地址,然后把客户端的物理地址经过转换,变为宿主端的虚拟地址,kvm中有一个数据结构kvm_memory_slot记录了此映射关系,再经过页表的转换变为真实可用的物理地址。然而这样的转换路径也太长,影响了性能,kvm有了硬件的支持以后提出了影子页表的概念。

影子页表简单来说就是,可以直接把客户端的虚拟地址映射成宿主端的物理地址。客户端想把客户端的页表基地址写入cr3寄存器的时候,由于读写cr3寄存器的指令都是特权指令,在读写 cr3的过程中都会陷入到VMM,VMM会首先截获到此指令。在客户端写cr3寄存器的时候,vmm首先保存好写入的值,然后填入的是主机端针对客户端生成的一张页表(也就是影子页表)的基地址,当客户端读cr3值的时候,vmm会把之前保存的cr3的值返回给客户端。

这样做的目的是,在客户端内核态中虽然有一张页表,但是客户端在访问内存的时候,MMU不会走这张页表,MMU走的是以填入到cr3寄存器上的真实的值为基地址(这个值是vmm写的主机端的物理地址)的影子页表,经过影子页表找到真实的物理地址.影子页表时刻与客户端的页表保持同步。

影子页表也有缺陷,KVM需要对客户端的每一个进程维护一张表,后面又有了EPT页表.暂且不谈。

 

 

转载地址:http://hvvaf.baihongyu.com/

你可能感兴趣的文章
【基础知识】【1】CDN
查看>>
【Oracle】【2】复制表结构及其数据
查看>>
【Oracle】【1】查询距离现在N分钟前的数据
查看>>
【JS】【4】字符串数字比较大小
查看>>
【Mybatis】【1】insert/update 数据后返回关键字段
查看>>
【微信公众号开发】【14】公众号迁移
查看>>
【IDEA】【6】Maven打包
查看>>
【Oracle】【6】去掉字符串中的空格/字符
查看>>
【Navicat】【1】解决 导入保存为txt文件的数据 中文乱码问题
查看>>
【HTML&CSS】【1】让DIV中的文字换行显示
查看>>
【MySQL】【4】数据库时间与实际时间相差8小时
查看>>
【Git】【1】简单介绍
查看>>
【记录】【2】各种在线网址
查看>>
【Mybatis】【4】mybatis Example Criteria like 模糊查询
查看>>
【Java】【12】Double类型精确的加减乘除运算
查看>>
【Oracle】【9】取前N条记录——rownum和row_number() over()的使用
查看>>
【Java】【15】判断url对应的图片是否存在
查看>>
【JS】【14】判断对象是否为{}
查看>>
【Java】【18】去掉字符串的最后一个字符
查看>>
【Java】【22】读写properties文件
查看>>