【问题标题】:QEMU-KVM: Is Guest Physical Address(GBA) same as QEMU-KVM's Virtual Address on the host?QEMU-KVM:Guest Physical Address(GBA) 是否与 QEMU-KVM 在主机上的虚拟地址相同?
【发布时间】:2021-05-31 12:56:27
【问题描述】:

例如,如果来宾上的一个进程在 0x8000(如来宾虚拟内存中)分配了数据,并且已映射到来宾物理内存地址空间中的 0x4000,则数据位于虚拟内存地址中的 0x4000主机端 QEMU-KVM 的(子)进程(每个 VM)的空间?换句话说,如果我在QEMU的源代码中编写新代码(这样我可以使用QEMU-KVM的页表),编译并运行它,那么我可以直接访问guest进程的数据,只需与guest的物理内存地址匹配到来宾虚拟内存地址?

【问题讨论】:

    标签: memory-management virtual-machine qemu virtual-memory kvm


    【解决方案1】:

    不,用于用户空间 QEMU 进程的页表映射与客户本身用于客户虚拟 -> 客户物理地址映射的页表或 KVM 内核代码使用的页表无关用于来宾物理地址 -> 用于 RAM 的主机物理地址映射。

    当您在 QEMU 中编写需要访问客户内存的代码时,您应该使用 QEMU 提供的 API 来执行此操作,这些 API 处理将客户地址转换为 RAM 的主机虚拟地址,并处理客户地址具有模拟设备而不是 RAM 的情况。 QEMU 开发者内部文档有a section on APIs for loads and stores,函数也记录在头文件的doc cmets 中。

    通常最好的建议是“在 QEMU 中找到一些与您正在尝试做的事情基本相同的现有代码,并以此为例”。

    【讨论】:

      【解决方案2】:

      我假设您的问题是关于 x86 平台的。 QEMU+KVM 使用扩展页表 (EPT) 将主机虚拟地址 (HVA) 映射到客户物理地址 (GPA)。要找到GPA对应的HVA,你应该遍历你的客人的EPT。

      当你需要从你的客户机读取一个虚拟地址时,你可以使用 QEMU 源码中的 GDB 函数。此 sn-p 将在您的 guest 的当前执行进程中读取 virtualAddress 的 4 个字节:

        uint8_t instr[4];
        if( cpu_memory_rw_debug( cpu, virtualAddress, (uint8_t *)instr, sizeof( instr ), 0 ) )
        {
          printf( "Failed to read instr!\n" );
          return;
        }
      

      cpu 是您客人的 CPU 的 CPUState*。

      当你想在你的guest中读取一个具体进程的地址时,你应该设置env->cr[3]到CR3这个进程的值(env是一个CPUX86State*)。看完后别忘了恢复原值。当然,只有在您的客人未执行时才读取内存,否则可能会出现竞争。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-24
        • 1970-01-01
        • 2018-04-19
        • 2016-05-10
        • 2016-09-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多