IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> The differences EPT handle MMIO RAM -> 正文阅读

[系统运维]The differences EPT handle MMIO RAM

在 Guest系统中IO访问可能分三种:

1,guest 内部执行PMIO指令,guest 会触发VM_EXIT,退出状态是KVM_EXIT_IO;

2,guest内部执行对MMIO空间(如virtio设备的feature协商空间、NOTIFY、设备特有配置空间等)的访问,guest 会触发VM_EXIT,退出状态将是KVM_EXIT_MMIO;

3,guest 内部对ram物理内存的访问,会通过EPT硬件(x86)转化为HPA,进而完成对物理内存的读写(但如果是第一次访问由于EPT页表不存在,会发生EPT_VIOLATION,触发VM_EXIT进而建立EPT表项);

MMIO是将设备I/O映射到 guest 地址空间内,它的实现需要利用EPT机制,guest物理内存(GPA)的虚拟化也是通过EPT机制来完成的。那么VM_EXIT后,KVM需要区分是对MMIO地址的访问还是对ram物理地址的访问,即KVM怎么识别MMIO的pagefault与ram 物理内存的pagefault?是通过EPT页表项的页表项的reserved bits区分。

EPT pagefault:
static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
        [EXIT_REASON_EPT_VIOLATION]           = handle_ept_violation, //EPT_VIOLATION表示的是对应的物理页不存在,类似“page not present” pagefault;
        [EXIT_REASON_EPT_MISCONFIG]           = handle_ept_misconfig, //EPT_MISCONFIG表示EPT页表中有reserved域被设置(KVM就是通过设置EPT页表中的reserved 
														//bits 来表示该页表代表MMO regions),类似“reserved bit set” pagefault;

intel 手册:
An EPT misconfiguration occurs if the entry is present and a reserved bit is set.
EPT misconfigurations result when an EPT paging-structure entry is configured with settings reserved for future functionality.

EPT页表的reserved bits怎么设置的?

对于ram 普通内存,QEMU/KVMTOOL 会调用 ioctl(kvm->vm_fd, KVM_SET_USER_MEMORY_REGION, &mem) 对其进行注册(即将ram内存的HVA和GPA的关系注册到KVM,并分配SLOT), 而对于 MMIO 内存空间,不会调KVM_SET_USER_MEMORY_REGION 注册。

当 guest 第一次访问MMIO地址时发现它对应的GPA在EPT页表中不存在,将导致EPT_VIOLATION触发VM_EXIT而退回到KVM,KVM检查GPA时发现它的PFN不存在(因为QEMU/KVMTOOL不会调用KVM_SET_USER_MEMORY_REGION对MMIO地址空间进行注册),认为这是个MMIO地址,KVM会设置PFN为KVM_PFN_NOSLOT(eg, try_async_pf()),然后set_mmio_spte函数调用is_noslot_pfn(pfn)判断PFN是NOSLOT,就调用mark_mmio_spte()来标志它的spte是一个MMIO region。后面再次访问这个MMIO空间的GPA地址时,发现GPA对应的EPT页表的reserved bits被置位,就会产生ept misconfiguration异常(EPT_MISCONFIG),进而调用handle_ept_misconfig -> handle_mmio_page_fault -> x86_emulate_instruction 来处理所有的MMIO操作了。

try_async_pf() :
        /* Don't expose private memslots to L2. */
        if (is_guest_mode(vcpu) && !kvm_is_visible_memslot(slot)) {
                *pfn = KVM_PFN_NOSLOT;
                *writable = false;
                return false;
        }

/* noslot pfn indicates that the gfn is not in slot. */
static inline bool is_noslot_pfn(kvm_pfn_t pfn)
{
      	  return pfn == KVM_PFN_NOSLOT;
}
 
static bool set_mmio_spte(struct kvm_vcpu *vcpu, u64 *sptep, gfn_t gfn,
                          kvm_pfn_t pfn, unsigned int access)
{
        if (unlikely(is_noslot_pfn(pfn))) {
                mark_mmio_spte(vcpu, sptep, gfn, access); //MMIO空间是KVM通过设置spte的保留位来标志的
                return true;
        }
                
        return false;
}

mark_mmio_spte() -> make_mmio_spte(vcpu, gfn):
	u64 gpa = gfn << PAGE_SHIFT;
	mask |= shadow_mmio_value | access;
	mask |= gpa | shadow_nonpresent_or_rsvd_mask;

mark_mmio_spte() -> mmu_spte_set(sptep, mask):
	__set_spte(sptep, mask); //真正设置MMIO EPT页表项


static void ept_set_mmio_spte_mask(void)
{
        /*
         * EPT Misconfigurations can be generated if the value of bits 2:0
         * of an EPT paging-structure entry is 110b (write/execute).
         */
        kvm_mmu_set_mmio_spte_mask(VMX_EPT_MISCONFIG_WX_VALUE, 0); // 设置shadow_mmio_value = 110b | SPTE_MMIO_MASK

 	// shadow_mmio_value(mask)就是要向 MMIO 的 EPT页表项中要写入的值,
	// shadow_mmio_value = 110b | SPTE_MMIO_MASK =  110b | (3ULL << 52);
	// 110b表示该页可读可写但是还未分配或者不存在,这显然是一个错误的EPT页表项;
	// 3ULL << 52 设置reserved bits 用于标识为MMIO spte.
	// 如果判断EPT页表项spte时(is_mmio_spte(spte)):spte&shadow_mmio_mask == shadow_mmio_mask,就会触发ept_msconfig;
}

reference

MMIO内存模拟原理_享乐主的博客-CSDN博客

MMIO Emulation

MMIO Emulation · kernelgo

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 21:35:42  更:2022-03-21 21:36:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 0:51:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码