【发布时间】:2021-03-21 07:35:42
【问题描述】:
我一直在玩 VMX 和 KVM,并且有一些更一般和更精确的问题。
- 我使用虚拟管理器创建了一个 VM,因为我认为(根据我在网上阅读的内容)它是让来宾运行 Ubuntu 18.04(在我的情况下)或者通常是整个操作系统的最简单方法。这会从 KVM/qemu 实现中添加/更改任何内容,还是只是一个接口?
- 据我所知,在 KVM 中(当插入内核模块(kvm 和 kvm_intel)时),内核确实起到了管理程序的作用。它是否正确?在这个假设下,我假设一个新的内核模块将成为管理程序的一部分。在一个基本内核模块中,我使用 VMREAD 从 VMCS 中读取了一些值。其中一个值是 GUEST_IDTR_BASE(在 vmx.h 中定义),用于读取来宾的 IDTR。出于某种原因, HOST_IDTR 和 GUEST_IDTR 具有相同的值?它是否正确?如果是,其背后的原因是什么,如果不是,我不明白什么?
- 我尝试更改 vmx.c 中的 handle_monitor_trap,仅添加一些打印语句以了解是否发生了什么以及何时调用并重新编译 kvm_intel 模块。然后,当我在一个单独的模块中更改 MTF 位(按照英特尔手册,它应该是 CPU_BASED_VM_EXEC_CONTROL 中的第 27 位) 与
__asm__ __volatile__ ("vmwrite %[value], %[encoding]; setna %[ret]"
: [ret]"=rm"(ret)
: [value]"rm"(value), [encoding]"r"(encoding) : "cc", "memory");
其中 value 是我从 CPU_BASED_VM_EXEC_CONTROL OR 0x8000000 读取的旧值,编码只是 CPU_BASED_VM_EXEC_CONTROL。当我将模块插入内核时(当然只有在虚拟机运行时),我修改的处理程序被调用。问题:
- 在很短的一段时间后,它就停止了(并且该位再次为 0)。有什么东西会重置位吗?这是怎么发生的? qemu 是否也以某种方式参与其中?
- 例如,当打印出 Rip 时,在客户机中执行循环时,正在打印的 Rip 每一步都会增加,并且永远不会返回。 vm在执行什么?我什至退出了正确的 VM,还是在 KVM 或 qemu 中存在我不知道的其他结构?
我禁用了除一个 cpu 之外的所有 cpu,以确保我会更改“正确”的 VMCS,因为如果我从手册中正确理解它,不同的内核上可能会有不同的 VMCS。
总的来说,如果您能给予我任何帮助,我将不胜感激。如果您也有任何关于更好地浏览源代码的提示,我将非常感谢,因为我的经验很少。
【问题讨论】:
-
关于 Q2,如果您在主机和来宾中运行相同的操作系统,那么它们在此类事情上可能具有相同的价值也就不足为奇了。
-
关于 Q3,我的管理程序在非常特殊的情况下启用了 MTF,并且总是在下一个 VM 条目时禁用它,除非导致它启用的条件仍然存在。我不知道 qemu,但也许它是相似的。我希望 qemu 不会期望另一个模块来操纵执行控制。
-
每个 CPU 始终有一个单独的 VMCS。
-
既然你有guest RIP值,如果它是内核地址的话,应该很容易在guest内核的链接映射中查找它。如果是用户地址,那就更难了。
-
谢谢@prl!是的,当然是0x8000000。我不确定我昨天在写这个问题时在想什么。在我的代码中,我设置了正确的位,否则我认为不会调用 handle_monitor_trap。 Q2。这就说得通了!谢谢你。那么翻译发生在哪里?还是他们共享同一个IDT?但是当向 IDT 添加一个新向量并尝试从来宾调用它时,它没有找到自定义处理程序,而我的主机却找到了。
标签: linux-kernel virtual-machine x86-64 qemu kvm