CPUID management in QEMU/KVM
本文以QEMU V5.2.0,kernel v5.14的源码,介绍CPUID management,具体细节不会一一介绍,但是会给出函数调用链,读者可以以此为线索,深挖细节。
1. Overview
guest执行cpuid指令肯定会导致VM Exit,然后由KVM处理cpuid指令的模拟。
KVM会执行kvm_emulate_cpuid。
1 | int kvm_emulate_cpuid(struct kvm_vcpu *vcpu) |
比较重要的函数为kvm_find_cpuid_entry,该函数寻找qemu写入到KVM中的CPUID entry(具体细节请参考源码)。
所以比较重要的是这个”entry”,该entry由qemu写入。
大致过程为:
- qemu通过ioctl(KVM_GET_SUPPORTED_CPUID)读取到host支持的CPUID列表
- qemu通过与运算剔除掉qemu(用户通过 -cpu option来指定)不支持的CPUID
- qemu通过ioctl(KVM_SET_CPUID2)将CPUID数据写入到KVM中供guest使用
说白了,就是qemu与KVM协调创建cpuid “entry”,最终,qemu将该“entry”的值写入KVM。接下来,guest执行cpuid指令而发生VM Exit时,KVM就可以cover住,无需qemu的参与。
2. Call chains in QEMU
1 | x86_cpu_realizefn |
KVM_GET_SUPPORTED_CPUID
和KVM_SET_CPUID2
的更多描述,可以参考kvm/api.txt。
1 | /***** Steps involved on loading and filtering CPUID data |
3.How to use
qemu-system-x86_64 -cpu help
增加 pdpe1gb feature (其中Nehalem是我选定的CPU型号, 也可以是别的型号)
qemu-system-x86_64 -cpu Nehalem,+pdpe1gb
增加 pdpe1gb feature, 减去sse feature
qemu-system-x86_64 -cpu Nehalem,+pdpe1gb,-sse
增加x2apic feature
qemu-system-x86_64 -cpu host,x2apic=on
qemu解析cpu feature选项的函数为x86_cpu_parse_featurestr。
4. MISC
1 | /* Compatibily hack to maintain legacy +-feat semantic, |
1 | //CPUID usage for interaction between Hypervisors and Linux |
kvm_cpu_cap_clear
can update guest cpuid.
参考资料: