现在我在qemu-kvm和linux任务调度程序上做一个项目。我知道每个VCPU都是qemu为linux操作系统创建的正常任务。然后我尝试执行qemu命令以查看任务是如何创建的。我使用strace来跟踪所有系统调用。没有像“fork”或“pthreadcreate”这样的东西。但我看到了这个:
open("/dev/kvm", O_RDWR|O_LARGEFILE) = 3
ioctl(3, KVM_GET_API_VERSION, 0) = 12
ioctl(3, KVM_CHECK_EXTENSION, 0x19) = 0
ioctl(3, KVM_CREATE_VM, 0) = 4
ioctl(3, KVM_CHECK_EXTENSION, 0x4) = 1
ioctl(3, KVM_CHECK_EXTENSION, 0x4) = 1
ioctl(4, KVM_SET_TSS_ADDR, 0xfffbd000) = 0
ioctl(3, KVM_CHECK_EXTENSION, 0x25) = 0
ioctl(3, KVM_CHECK_EXTENSION, 0xb) = 1
ioctl(4, KVM_CREATE_PIT, 0xb) = 0
ioctl(3, KVM_CHECK_EXTENSION, 0xf) = 2
ioctl(3, KVM_CHECK_EXTENSION, 0x3) = 1
ioctl(3, KVM_CHECK_EXTENSION, 0) = 1
ioctl(4, KVM_CREATE_IRQCHIP, 0) = 0
ioctl(3, KVM_CHECK_EXTENSION, 0x1a) = 0
所以看起来它打开了设备/ dev / kvm并做了一些ioctl系统调用。我相信这是实际创建VM线程的地方。对?我是操作系统的新手,如果有人能给我一些线索,我将不胜感激:>感谢
答案 0 :(得分:3)
VCPU既不是OS线程也不是进程。要了解VCPU的工作原理,首先我们应该弄清楚客户操作系统如何在Intel VT-x
架构上运行。
Intel VT-x
提出了一种新模式方法,它有两种模式:VMX root mode
和VMX non-root mode
,分别用于运行主机VMM和来宾。 Intel VT-x
还包含一个新结构:VMCS
,可以保存主机和客户所需的所有信息。 VMCS
是每位客人一个。
KVM是一个硬件辅助虚拟机管理程序,可以利用Intel VT-x
。主机Linux KVM正在VMX root mode
中运行。当KVM决定切换CPU模式以运行guest虚拟机时,KVM会将所有当前上下文转储到VMCS
并执行“VMLAUNCH”指令。 “VMLAUNCH”将CPU从VMX root mode
传输到VMX non-root mode
,并从VMCS加载访客上下文,然后开始或继续执行访客代码。
总之,访客代码直接在VMX non-root mode
的CPU上运行。不需要VCPU的软件仿真层。这就是为什么KVM具有更好的性能,并且没有针对guest的特定线程。
/dev/kvm
由kvm.ko
创建,strace
只是QEMU的KVM界面。您的fork
输出显示了QEMU如何与KVM交互并控制底层访客。您永远无法在KVM中找到clone
或arch/x86/kvm/vmx.c
系统调用。
有关更多KVM详细信息(尤其是VCPU),您可以在Intel VT-x
中读取KVM代码,以获取基于{{1}}的更多VCPU实现详细信息。
答案 1 :(得分:2)
即使VCPU是与线程或进程不同的OS对象,并且使用KVM_CREATE_VCPU ioctl创建VCPU对象,QEMU确实为每个VCPU创建一个线程。当QEMU从该线程执行KVM_RUN时,guest虚拟机运行(物理CPU进入VMX非root模式)。 KVM_CREATE_VCPU返回一个新的文件描述符,这就是你在KVM_RUN ioctl中看到的fd。
您的strace中可能缺少VCPU线程,因为您没有使用-ff
选项。 -ff
要求strace跟踪除初始线程之外的其他线程。