前言
Proxmox对于CPU Type为host情况下Windows虚拟机的性能低下问题由来已久,本实验用于寻找其原因和缓解方法
测试环境&指标
测试环境:
- CPU:2 * E5 2667 v2
- 内存:128G 1866Mhz DDR3 ECC 8*16G 1 Memory Per Channel
- CPU(Windows虚拟机):2插槽8核心,启用NUMA
- 内存(Windows虚拟机):32G
测试指标
- AIDA64 Extreme 7.60.7300 Cache and Memory Benchmark 三次
- CPU-Z 2.14.0 x64 基准17.01.64 三次
- Windows在开机进入桌面后至少5分钟才开始进行测试以确保系统完全加载
获取基线信息
获取虚拟机初始CPU Flags
- host(E5 2667v2)
fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 cx16 pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm cpuid_fault pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust smep erms xsaveopt arat umip md_clear flush_l1d arch_capabilities
- x86_64-v2-AES
fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx lm constant_tsc nopl xtopology cpuid tsc_known_freq pni ssse3 cx16 sse4_1 sse4_2 x2apic popcnt aes hypervisor lahf_lm cpuid_fault pti
- Ivybridge-IBRS
fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm cpuid_fault pti ibrs ibpb fsgsbase smep erms xsaveopt arat
经过实测,在Ivybridge-IBRS\x86_64-v2-AES这两种CPU Type下,Windows使用没有性能问题,而在host下,Windows降速明显
测试数据
IvyBridge-IBRS AIDA64第一次
Read | Write | Copy | Latency | |
Memory | 51400MB/s | 26738MB/s | 37879MB/s | 155ns |
L1 Cache | 476.46GB/s | 305.52GB/s | 454.48GB/s | 1.2ns |
L2 Cache | 67626MB/s | 29715MB/s | 45322MB/s | 7.7ns |
L3 Cache | 306.64GB/s | 245.73GB/s | 246GB/s | 7.7ns |
IvyBridge-IBRS AIDA64第二次
Read | Write | Copy | Latency | |
Memory | 53210MB/s | 29658MB/s | 37697MB/s | 156.1ns |
L1 Cache | 501.62GB/s | 293.04GB/s | 777.15GB/s | 1.2ns |
L2 Cache | 67104MB/s | 25346MB/s | 45168MB/s | 8.7ns |
L3 Cache | 423.89GB/s | 372.61GB/s | 316.3GB/s | 7.7ns |
IvyBridge-IBRS AIDA64第三次
Read | Write | Copy | Latency | |
Memory | 51400MB/s | 26738MB/s | 37879MB/s | 155ns |
L1 Cache | 476.46GB/s | 305.52GB/s | 454.48GB/s | 1.2ns |
L2 Cache | 67626MB/s | 29715MB/s | 45322MB/s | 7.7ns |
L3 Cache | 306.64GB/s | 245.73GB/s | 246GB/s | 7.7ns |
IvyBridge-IBRS CPU-Z第一次
单线程 | 多线程 |
368.2 | 5351.8 |
IvyBridge-IBRS CPU-Z第二次
单线程 | 多线程 |
344.1 | 5057.5 |
IvyBridge-IBRS CPU-Z第三次
单线程 | 多线程 |
375.8 | 5267.4 |
x86_64-v2-AES AIDA64第一次
| Read | Write | Copy | Latency |
Memory | 52365MB/s | 30861MB/s | 38087MB/s | 183.2ns |
L1 Cache | 504.63GB/s | 0GB/s | 1641.7GB/s | 1.2ns |
L2 Cache | 84364MB/s | 28117MB/s | 61839MB/s | 3.3ns |
L3 Cache | N/A | N/A | N/A | N/A |
x86_64-v2-AES AIDA64第二次
Read | Write | Copy | Latency | |
Memory | 51669MB/s | 29632MB/s | 37988MB/s | 80.4ns |
L1 Cache | 510.87GB/s | 0GB/s | 779.98GB/s | 1.3ns |
L2 Cache | 99525MB/s | 29955MB/s | 58421MB/s | 3.6ns |
L3 Cache | N/A | N/A | N/A | N/A |
x86_64-v2-AES AIDA64第三次
Read | Write | Copy | Latency | |
Memory | 51172MB/s | 28918MB/s | 38097MB/s | 167.8ns |
L1 Cache | 495.93GB/s | 290.82GB/s | 1633.5GB/s | 1.4ns |
L2 Cache | 93406MB/s | 30235MB/s | 62859MB/s | 3.5ns |
L3 Cache | N/A | N/A | N/A | N/A |
x86_64-v2-AES CPU-Z第一次
单线程 | 多线程 |
384.2 | 5380.1 |
x86_64-v2-AES CPU-Z第二次
单线程 | 多线程 |
380.4 | 5306.4 |
x86_64-v2-AES CPU-Z第三次
单线程 | 多线程 |
321.8 | 5444.1 |
host AIDA64第一次
Read | Write | Copy | Latency | |
Memory | 3028MB/s | 1635MB/s | 2276MB/s | 2567.7ns |
L1 Cache | 30462MB/s | 0MB/s | 25126GB/s | 21.5ns |
L2 Cache | 4422MB/s | 1771MB/s | 2608MB/s | 109ns |
L3 Cache | 18641MB/s | 14449MB/s | 13169MB/s | 146.1ns |
host AIDA64第二次
Read | Write | Copy | Latency | |
Memory | 3656MB/s | 2219MB/s | 2751MB/s | 2118.9ns |
L1 Cache | 124.7GB/s | 63744MB/s | 118.15GB/s | 17.1ns |
L2 Cache | 5175MB/s | 3169MB/s | 3115MB/s | 96.6ns |
L3 Cache | 23482MB/s | 19499MB/s | 16528MB/s | 112ns |
host AIDA64第三次
Read | Write | Copy | Latency | |
Memory | 3467MB/s | 1932MB/s | 2440MB/s | 989.5ns |
L1 Cache | 33783MB/s | 58091MB/s | 33791MB/s | 18.6ns |
L2 Cache | 4915MB/s | 2012MB/s | 2645MB/s | 107.8ns |
L3 Cache | 16003MB/s | 12353MB/s | 14985MB/s | 141.7ns |
host CPU-Z第一次
单线程 | 多线程 |
342.1 | 5461.1 |
host CPU-Z第二次
单线程 | 多线程 |
382.8 | 5538.0 |
host CPU-Z第三次
单线程 | 多线程 |
329.5 | 5398.1 |
测试可得,在三种不同的CPU Type中,CPU的运行速度并没有太大区别,但是内存访问方面区别巨大,在86_64-v2-AES和Ivybridge中,内存延迟和CPU缓存延迟都比较正常,但是在host中,内存的延迟可以达到2ms的水平
由于CPU Type只是改变了直通到虚拟机的ISA和CPU Flag,因此可以通过测试直通的CPU Flag进行测试,由于x86_64-v2-AES是Ivybridge的子集,因此对这两种CPU Type Flags取Ivybridge对于host的补集
arch_capabilities ss ept ssbd stibp pdpe1gb flush_l1d flexpriority tsc_adjust pdcm arch_perfmon tpr_shadow md_clear vmx vnmi vpid umip pcid
并根据作用对其进行分类
作用类别 | CPU Flags |
---|---|
虚拟化 | vmx ept vpid tpr_shadow vnmi flexpriority |
安全性 | arch_capabilities ssbd stibp flush_l1d md_clear umip |
内存管理 | pdpe1gb pcid ss |
性能优化 | arch_perfmon pdcm tsc_adjust |
基于此,通过使用host CPU Type并在此基础上裁剪不同组的flags,可以找到是哪一类CPU Flags导致了Windows性能下降
验证问题范围
通过在Linux中进行host和IvyBridge-IBRS的内存延迟测试,证明性能问题存在于Windows操作系统本身而不是KVM程序
- host
root@Dev:/usr/lib/lmbench/bin/x86_64-linux-gnu# ./lat_mem_rd 128M 128 "stride=128 0.00049 0.988 0.00098 0.982 0.00195 0.987 0.00293 0.880 0.00391 0.987 0.00586 0.936 0.00781 0.983 0.01172 0.988 0.01562 0.980 0.02344 0.988 0.03125 0.989 0.04688 1.007 0.06250 1.811 0.09375 2.319 0.12500 1.750 0.18750 1.513 0.25000 1.391 0.37500 1.347 0.50000 1.310 0.75000 1.225 1.00000 1.170 1.50000 1.297 2.00000 1.671 3.00000 2.203 4.00000 2.368 6.00000 2.391 8.00000 2.528 12.00000 2.391 16.00000 2.356 24.00000 2.568 32.00000 3.454 48.00000 4.722 64.00000 5.663 96.00000 6.359 128.00000 6.531
- IvyBridge-IBRS
root@Dev:/usr/lib/lmbench/bin/x86_64-linux-gnu# ./lat_mem_rd 128M 128 "stride=128 0.00049 0.988 0.00098 0.985 0.00195 0.987 0.00293 0.987 0.00391 0.988 0.00586 0.982 0.00781 0.988 0.01172 0.976 0.01562 0.988 0.02344 0.988 0.03125 0.988 0.04688 1.049 0.06250 1.444 0.09375 1.307 0.12500 1.275 0.18750 1.340 0.25000 1.243 0.37500 1.173 0.50000 1.223 0.75000 1.183 1.00000 1.200 1.50000 1.297 2.00000 1.686 3.00000 2.205 4.00000 2.405 6.00000 2.386 8.00000 2.389 12.00000 2.380 16.00000 2.372 24.00000 2.520 32.00000 3.073 48.00000 4.552 64.00000 5.528 96.00000 6.059 128.00000 6.347
由此可见得,在host和IvyBridge-IBRS中,内存延迟基本一致,并符合L1、L2、L3、DRAM缓存的延迟递增,因此可确定问题在于Windows操作系统本身而非KVM虚拟化程序
对比实验
修改传入的Flags
禁用虚拟化Flags(args: -cpu host,-vmx,-vnmi)(ept,vpid,tpr_shadow,flexpriority无法通过args显式禁用)
AIDA64
| Read | Write | Copy | Latency |
Memory | 5664MB/s | 2177MB/s | 2989MB/s | 2284.3ns |
L1 Cache | 52324MB/s | 50705MB/s | 94914MB/s | 23.2ns |
L2 Cache | 7500MB/s | 3440MB/s | 3573MB/s | 191.6ns |
L3 Cache | 16531MB/s | 11405MB/s | 17375MB/s | 191.3ns |
CPU-Z
单线程 | 多线程 |
276.9 | 4694.9 |
禁用安全性Flags(args: -cpu host,-ssbd,-stibp,-umip)(arch_capabilities,flush_l1d,md_clear无法通过args显式禁用)
AIDA64
Read | Write | Copy | Latency | |
Memory | 3102MB/s | 1834MB/s | 2324MB/s | 1353.2ns |
L1 Cache | 97632MB/s | 51292MB/s | 26084MB/s | 23.7ns |
L2 Cache | 4699MB/s | 1795MB/s | 2985MB/s | 153ns |
L3 Cache | 15573MB/s | 18908MB/s | 17607MB/s | 187ns |
CPU-Z
单线程 | 多线程 |
282.9 | 4651.6 |
IvyBridge启用虚拟化Flags(args: -cpu IvyBridge-IBRS,+vmx,+vnmi)
AIDA64
Read | Write | Copy | Latency | |
Memory | 81440MB/s | 43509MB/s | 48711MB/s | 158.3ns |
L1 Cache | 463.39GB/s | 302.49GB/s | 446.9GB/s | 1.9ns |
L2 Cache | 114.05GB/s | 40022MB/s | 65063MB/s | 9.4ns |
L3 Cache | 249.69GB/s | 222.34GB/s | 252.59GB/s | 12.5ns |
CPU-Z
单线程 | 多线程 |
279.5 | 4678.2 |
能禁用的全部禁用(args: -cpu host,-ss,-ssbd,-stibp,-pdpe1gb,-tsc_adjust,-pdcm,-vmx,-vnmi,-umip,-pcid)(arch_capabilities,ept,flush_l1d,flexpriority,arch_perfmon,tpr_shadow,md_clear无法通过args显式禁用)
AIDA64
Read | Write | Copy | Latency | |
Memory | 3015MB/s | 1813MB/s | 2283MB/s | 2461.5ns |
L1 Cache | 103.06GB/s | 54991MB/s | 101648MB/s | 22.8ns |
L2 Cache | 4520MB/s | 1609MB/s | 2731MB/s | 188.2ns |
L3 Cache | 17269GB/s | 12200MB/s | 14918MB/s | 151.3ns |
CPU-Z
单线程 | 多线程 |
283.5 | 4758.5 |
能启用的全启用(args: -cpu IvyBridge-IBRS,+ss,+ssbd,+stibp,+pdpe1gb,+tsc_adjust,+pdcm,+vmx,+vnmi,+umip,+pcid)
AIDA64
Read | Write | Copy | Latency | |
Memory | 52361MB/s | 27803MB/s | 35670MB/s | 166.9ns |
L1 Cache | 476.62GB/s | 0MB/s | 452.45GB/s | 1.7ns |
L2 Cache | 70509MB/s | 30976MB/s | 48923MB/s | 11.8ns |
L3 Cache | 239.61GB/s | 222.75GB/s | 364.06GB/s | 12.3ns |
CPU-Z
单线程 | 多线程 |
272.4 | 4646.6 |
由此可初见端倪,即使在args中把所有的能禁用的Flags都禁用了,内存延迟仍然居高不下,但是启用了能启用的Flags后,Windows又表现正常,那么回到Linux中,查看在IvyBridge-IBRS并且能启用的都启用后,传入的Flags是什么
fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm cpuid_fault pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust smep erms xsaveopt arat umip
对其取host的补集可得
arch_capabilities arch_perfmon flush_l1d md_clear pdcm
那么可推断问题就出在给Windows虚拟机传入了arch_capabilities arch_perfmon flush_l1d md_clear pdcm
这些Flags上
排除VBS机制影响
考虑Win10引入了VBS机制,于是安装了一台Win8.1主机并使用host类型进行测试
| Read | Write | Copy | Latency |
Memory | 3419MB/s | 1674MB/s | 2198MB/s | 1531.5ns |
L1 Cache | 55263MB/s | 27151MB/s | 51860GB/s | 23.6ns |
L2 Cache | 11501MB/s | 11834MB/s | 13189MB/s | 133.5ns |
L3 Cache | 17099MB/s | 9850MB/s | 13780MB/s | 143.6ns |
可见不是Win10的VBS原因,因为Win8.1不可能会有VBS
结论
Proxmox/KVM中Windows性能低下的主要原因是PVE传入了不合适的CPU Flags,可能触发了Windows中不同的CPU漏洞缓解措施或其他数据路径,性能下降是二者共同造成的结果,推翻了网上常流传的主要原因是Windows 10的Hyper-V虚拟化启动(bcdedit /set hypervisorlaunchtype off)和VBS的原因
为了实现发挥最大CPU能力的目的,可通过手动筛选CPU Flags,并通过args参数或者PVE自定义CPU类型,在使用最接近的CPU Type中额外启用这些Flags来模拟使用host来发挥CPU最大性能,以避免PVE直接使用host同时传入不合适的Flag
vim /etc/pve/virtual-guest/cpu-models.conf
cpu-model: windows-host
flags +ss;+ssbd;+stibp;+pdpe1gb;+tsc_adjust;+pdcm;+vmx;+umip;+pcid
phys-bits host
hidden 0
hv-vendor-id proxmox
reported-model IvyBridge-IBRS
好消息是,并不是虚拟化导致的性能下降,通过这种方法,可以在不使用host的情况下在windows中也进行嵌套虚拟化
后续
md-clear在args中无法禁用,但是可以在cpu参数中直接禁用,在使用host并禁用md-clear后,相比直接使用host,性能有了巨大提升,延迟降低了一半,但是性能仍然比不过自定义host,而md-clear和flush_l1d同为防止CPU漏洞攻击的指令集,因此可以确定,Windows性能下降的罪魁祸首就是md-clear和flush_l1d,可惜KVM无法直接禁用flush_l1d(至少我没成功),否则则可以直接禁用这两个Flags而无需寻找最接近的CPU类型和手动启用其他Flag就可以解决问题,当前的最佳解决方案仍然是自定义CPU类型
解决方案
(请注意,此解决方案仅适用于个人PC、Homelab等安全性要求不高的情况下,禁用md_clear和flush_l1d会导致CPU存在meltdown侧信道攻击可能,不要在企业级上使用此解决方案)
此解决方案旨在作为host的替代品,在不使用host的情况下经可能的发挥出您的CPU最大性能
首先您需要准备一台Linux KVM虚拟机,并使用CPU Type = host启动它,查看/proc/cpuinfo以获取您作为host直通到虚拟机的Flags,您将获得类似fpu vme de pse tsc ...
这样的Flag列表,我们称为host_flags
然后您需要选择一个适合您CPU的预置非host的CPU类型,比如PVE8默认的x86_64-v2-AES,或者Icelake,这一步是为了降低您手动启用的Flag数量,同时为了让您的任务管理器更加好看,您需要查阅qemu官方文档 并进行一些适当的穷举来寻找最佳的CPU型号,然后使用此型号再次启动你的Linux KVM虚拟机查看存在的Flags,得到当前CPU Type直通到虚拟机的列表,我们称为selected_cpu_flags
最后,通过下面的一个简单的python代码,您可以得到selected_cpu_flags对于host_flags的补集
def find_complement(host_flags, selected_cpu_type_flags, kvm_recognized_flag):
host_set = set(host_flags.split())
selected_cpu_type_set = set(selected_cpu_type_flags.split())
kvm_recognized_set = set(kvm_recognized_flag.split())
complement = host_set - selected_cpu_type_set
result = [flag for flag in complement if flag in kvm_recognized_set]
return result
kvm_recognized_flag = """
3dnow 3dnowext 3dnowprefetch abm ace2 ace2-en acpi adx aes amd-no-ssb amd-psfd amd-ssbd amd-stibp amx-bf16 amx-complex amx-fp16 amx-int8 amx-tile apic arat arch-capabilities arch-lbr auto-ibrs avic avx avx-ifma avx-ne-convert avx-vnni avx-vnni-int8 avx2 avx512-4fmaps avx512-4vnniw avx512-bf16 avx512-fp16 avx512-vp2intersect avx512-vpopcntdq avx512bitalg avx512bw avx512cd avx512dq avx512er avx512f avx512ifma avx512pf avx512vbmi avx512vbmi2 avx512vl avx512vnni bmi1 bmi2 bus-lock-detect cid cldemote clflush clflushopt clwb clzero cmov cmp-legacy cmpccxadd core-capability cr8legacy cx16 cx8 dca de decodeassists ds ds-cpl dtes64 erms est extapic f16c fb-clear fbsdp-no flush-l1d flushbyasid fma fma4 fpu fsgsbase fsrc fsrm fsrs full-width-write fxsr fxsr-opt fzrm gds-no gfni hle ht hypervisor ia64 ibpb ibrs ibrs-all ibs intel-pt intel-pt-lip invpcid invtsc kvm-asyncpf kvm-asyncpf-int kvm-asyncpf-vmexit kvm-hint-dedicated kvm-mmu kvm-msi-ext-dest-id kvm-nopiodelay kvm-poll-control kvm-pv-eoi kvm-pv-ipi kvm-pv-sched-yield kvm-pv-tlb-flush kvm-pv-unhalt kvm-steal-time kvmclock kvmclock kvmclock-stable-bit la57 lahf-lm lbrv lfence-always-serializing lm lwp mca mcdt-no mce md-clear mds-no misalignsse mmx mmxext monitor movbe movdir64b movdiri mpx msr mtrr no-nested-data-bp nodeid-msr npt nrip-save null-sel-clr-base nx osvw pae pat pause-filter pbe pbrsb-no pcid pclmulqdq pcommit pdcm pdpe1gb perfctr-core perfctr-nb pfthreshold pge phe phe-en pks pku pmm pmm-en pn pni popcnt prefetchiti pschange-mc-no psdp-no pse pse36 rdctl-no rdpid rdrand rdseed rdtscp rsba rtm sbdr-ssdp-no sep serialize sgx sgx-aex-notify sgx-debug sgx-edeccssa sgx-exinfo sgx-kss sgx-mode64 sgx-provisionkey sgx-tokenkey sgx1 sgx2 sgxlc sha-ni skinit skip-l1dfl-vmentry smap smep smx spec-ctrl split-lock-detect ss ssb-no ssbd sse sse2 sse4.1 sse4.2 sse4a ssse3 stibp stibp-always-on svm svm-lock svme-addr-chk syscall taa-no tbm tce tm tm2 topoext tsc tsc-adjust tsc-deadline tsc-scale tsx-ctrl tsx-ldtrk umip v-vmsave-vmload vaes vgif virt-ssbd vmcb-clean vme vmx vmx-activity-hlt vmx-activity-shutdown vmx-activity-wait-sipi vmx-any-errcode vmx-apicv-register vmx-apicv-vid vmx-apicv-x2apic vmx-apicv-xapic vmx-cr3-load-noexit vmx-cr3-store-noexit vmx-cr8-load-exit vmx-cr8-store-exit vmx-desc-exit vmx-enable-user-wait-pause vmx-encls-exit vmx-entry-ia32e-mode vmx-entry-load-bndcfgs vmx-entry-load-efer vmx-entry-load-pat vmx-entry-load-perf-global-ctrl vmx-entry-load-pkrs vmx-entry-load-rtit-ctl vmx-entry-noload-debugctl vmx-ept vmx-ept-1gb vmx-ept-2mb vmx-ept-advanced-exitinfo vmx-ept-execonly vmx-eptad vmx-eptp-switching vmx-exit-ack-intr vmx-exit-clear-bndcfgs vmx-exit-clear-rtit-ctl vmx-exit-load-efer vmx-exit-load-pat vmx-exit-load-perf-global-ctrl vmx-exit-load-pkrs vmx-exit-nosave-debugctl vmx-exit-save-efer vmx-exit-save-pat vmx-exit-save-preemption-timer vmx-flexpriority vmx-hlt-exit vmx-ins-outs vmx-intr-exit vmx-invept vmx-invept-all-context vmx-invept-single-context vmx-invept-single-context vmx-invept-single-context-noglobals vmx-invlpg-exit vmx-invpcid-exit vmx-invvpid vmx-invvpid-all-context vmx-invvpid-single-addr vmx-io-bitmap vmx-io-exit vmx-monitor-exit vmx-movdr-exit vmx-msr-bitmap vmx-mtf vmx-mwait-exit vmx-nmi-exit vmx-page-walk-4 vmx-page-walk-5 vmx-pause-exit vmx-ple vmx-pml vmx-posted-intr vmx-preemption-timer vmx-rdpmc-exit vmx-rdrand-exit vmx-rdseed-exit vmx-rdtsc-exit vmx-rdtscp-exit vmx-secondary-ctls vmx-shadow-vmcs vmx-store-lma vmx-true-ctls vmx-tsc-offset vmx-tsc-scaling vmx-unrestricted-guest vmx-vintr-pending vmx-vmfunc vmx-vmwrite-vmexit-fields vmx-vnmi vmx-vnmi-pending vmx-vpid vmx-wbinvd-exit vmx-xsaves vmx-zero-len-inject vnmi vpclmulqdq waitpkg wbnoinvd wdt x2apic xcrypt xcrypt-en xfd xgetbv1 xop xsave xsavec xsaveerptr xsaveopt xsaves xstore xstore-en xtpr
"""
host_flags = """
"""
selected_cpu_flags = """
"""
complement = find_complement(host_flags, selected_cpu_flags, kvm_recognized_flag)
for flag in sorted(complement):
print(flag, end=' ')
print("")
请将您得到的两组flags填入对应的位置,其中kvm_recognized_flag是当前qemu/kvm程序能够识别的flag,基于9.0.2版本,您可以自行调整,您应该可以得到如下格式的补集Flags
pcid pdcm pdpe1gb ss ssbd stibp umip vmx vnmi
然后将这些Flags转换为类似下面的格式并添加到您的Linux KVM中进行测试
args: -cpu IvyBridge-IBRS,+pcid,+pdcm,+pdpe1gb,+ss,+ssbd,+stibp,+umip,+vmx,+vnmi
您可能会遇到KVM无法启动或出现Warning的情况,这是正常的,并非所有Flag都可以在args中进行启用或关闭,您只需要把这些Flag从args中删除
当您能没有报错的启动Linux KVM后,您可以查看/proc/cpuinfo并将其与使用host启动的/proc/cpuinfo进行比较,您应该只损失md_clear\flush_l1d\arch_*等一些很少的Flag
接下来您可以将args复制到您需要的conf中,或者制作一个自定义的CPU类型!
Comments | NOTHING