問題描述
VirtualMachine 的第一條指令是如何獲取的(在 KVM‑QEMU 中) (How is the first instruction of VirtualMachine is fetched (in KVM‑QEMU))
我是 SO 和 X86 VMX 的新手。我在 X86 上學習 KVM‑QEMU,我想知道如何獲取 VM 的第一條指令的詳細信息,以便 VM 可以開始運行。有 KVM API 可以配置和註冊一組內存作為 VM 的物理內存,然後將 guest_RIP 設置為 AAA(例如)。我不知道何時調用 VMLaunch(使用正確配置的 VMCS),CPU 如何從 VMCS 中的 RIP 獲取指令,是否通過一些地址轉換過程,因此應正確設置 guest_CR3 以指向主機為客人分配的內存?謝謝
參考解法
方法 1:
I will explain this in the context of QEMU and how QEMU operates when the KVM accelerator is enabled.
As you might be knowing, under kvm, virtual machines are created by opening a device node /dev/kvm
. A guest will have its own memory and is usually separate from the userspace process that created it. So basically kvm is structured as a fairly typical Linux character device ‑ you use ioctl()
s to create, run, modify parameters, allocate memory and read and write to the VCPU registers of the virtual machines. Thus, the initial setup will be done via various ioctl()
s that will setup KVM for further use.
In terms of the QEMU code, all execution(whether KVM or non‑KVM) starts from :
The initialization of the KVM architecture happens via the below function ‑‑ (collecting CPU flags from CPUID and setting up frequencies etc.)
Once all the initialization functions are done, the function do_kvm_cpu_synchronize_post_init
will try to synchronize the initial values of the VCPU registers based on the host CPU state. It calls another function, kvm_arch_put_registers
and sets the VCPU to be dirty. Why is the VCPU set to dirty ? Only then will the subsequent functions actually initialize the values of the VCPU registers.
This function kvm_arch_put_registers
is the key to obtaining all the initial values of the VMCS registers. If you see its body, you will realize what is happening :‑
Specifically focus on the functions, kvm_getput_regs
and kvm_put_sregs
‑ the first function will set up the initial values of the GPRs and the EFLAGS as well as the EIP/RIP register, while the second function will set up the initial segment register values.
The guest page table will be rooted to the CR3 register. How does this page table work ?
For this, you need to remember that the mmu in KVM only accounts for one level of virtualization ( guest virtual ‑> guest physical ) but does not account for the second level ( guest physical ‑> host physical ). The initial RIP will account for virtual addresses ‑ it will be appropriately translated to physical addresses in the guest. However, to convert this guest physical address to the host physical address, you need to have a separate page table. This is a shadow page table that will be used in conjunction with the original page table (that converts guest virtual ‑> guest physical) to perform the entire translation.
There is a need for synchronizing the state of the guest page table with the shadow page table and this sometimes tends to be a problem. Whenever the guest will write to its page table, the corresponding changes need to be performed on the shadow page tables as well.
(by wangt13、Arnabjyoti Kalita)