基本逻辑
虚拟机可以选择性的支持host上的功能,不同功能的集合可以表示不同的CPU类型,QEMU里
把用这样方式定义虚拟机CPU叫做CPU model。QEMU里X86定义了种类繁多的vCPU类型,具体
的说明可以参考这里。
在基于KVM的QEMU上,需要KVM支持vCPU的特性可以被配置,具体逻辑可以参考这里。
QEMU里需要定义不同类型vCPU的具体特性列表,并根据QEMU启动参数传入的CPU model类型
打开或者关闭对应的CPU特性。在基于KVM的QEMU上,打开或者关闭CPU特性是通过KVM的ioctl
KVM_SET_ONE_REG/KVM_GET_ONE_REG。
代码分析
各种vCPU model定义在:static const X86CPUDefinition builtin_x86_defs[]。
如上的每个vCPU类型被依次注册到系统里:
1 | /* target/i386/cpu.c */ |
进一步展开如上的逻辑,可以看到每个vCPU类型被定义成一个class,注册到系统里。需要
注意的是,在QOM里,这里的type_register只是向系统注册一个class的描述,class本身的
创建还需要后续调用class_init回调函数。这里class的name就是定义的vCPU类型的名字,
这种类型的vCPU的父类就是TYPE_X86_CPU,这里类的继承关系是:
1 | CPUClass <--- X86CPUClass <--- 特定vCPU类 |
在特定vCPU类的初始化函数里填充X86CPUClass.model的数据结构,而model(即X86CPUModel)
是在x86_register_cpudef_types中创建的,其中包含有vCPU的具体定义信息。
X86 CPU的实例根据X86CPUClass中的定义被创建出来,在CPU实例初始化的时候把CPU的定义,
主要是支持feature的描述保存到CPU实例的env结构里(env结构描述整个CPU的状态)。
1 | x86_cpu_initfn |
基于KVM的QEMU上,KVM vCPU初始化的时候,依次根据env->features[]中的定义配置vCPU
的各个feature。(todo: 找到具体下配置的点?)
1 | /* target/i386/kvm/kvm.c */ |