qemu-kvm如何在内部创建VM线程?

Hao*_*hen 4 linux kvm qemu

现在我正在做一个关于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
Run Code Online (Sandbox Code Playgroud)

所以看起来它打开了设备 /dev/kvm 并执行了一些 ioctl 系统调用。我相信这是虚拟机线程实际创建的地方。正确的?我是操作系统的新手,如果有人能给我一些线索,我将不胜感激:>谢谢

Pao*_*ini 6

尽管 VCPU 是不同于线程或进程的操作系统对象,并且 VCPU 对象是使用 KVM_CREATE_VCPU ioctl 创建的,但 QEMU 确实为每个 VCPU 创建一个线程。当 QEMU 从该线程执行 KVM_RUN 时,来宾运行(物理 CPU 进入 VMX 非根模式)。KVM_CREATE_VCPU 返回一个新的文件描述符,这就是您将在 KVM_RUN ioctl 中看到的 fd。

由于您没有使用该-ff选项,您的 strace 中可能会缺少 VCPU 线程。-ff要求 strace 还跟踪除初始线程之外的其他线程。


Way*_*yne 5

VCPU 既不是操作系统线程也不是进程。要了解 VCPU 的工作原理,首先我们应该弄清楚 guest OS 是如何在Intel VT-x架构上运行的。

Intel VT-x提出了一种新的模式方法,具有两种模式:VMX root modeVMX 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 modeVMX non-root mode,并从VMCS加载客户上下文,然后启动或继续执行客户代码。

总之,来宾代码直接在VMX non-root mode. 不需要 VCPU 的软件模拟层。这就是为什么KVM具有更好的性能,并且没有针对guest的特定线程。

/dev/kvm由 创建kvm.ko,它只是 QEMU 的 KVM 接口。您的strace输出显示了 QEMU 如何与 KVM 交互并控制底层来宾。在 KVM 中你永远找不到forkclone系统调用。

有关更多 KVM 详细信息,尤其是 VCPU,您可以阅读 KVM 代码,arch/x86/kvm/vmx.c了解更多基于 的 VCPU 实现细节Intel VT-x