kvm feautres
CPUID 40000000:00 = 40000001 4b4d564b 564b4d56 0000004d | ...@KVMKVMKVM...
CPUID 40000001:00 = 01007afb 00000000 00000000 00000000 | .z..............
在 tools/testing/selftests/kvm/include/x86_64/processor.h 可以找到:
/* This CPUID returns two feature bitmaps in eax, edx. Before enabling
* a particular paravirtualization, the appropriate feature bit should
* be checked in eax. The performance hint feature bit should be checked
* in edx.
*/
#define KVM_CPUID_FEATURES 0x40000001
#define KVM_FEATURE_CLOCKSOURCE 0
#define KVM_FEATURE_NOP_IO_DELAY 1
#define KVM_FEATURE_MMU_OP 2
/* This indicates that the new set of kvmclock msrs
* are available. The use of 0x11 and 0x12 is deprecated
*/
#define KVM_FEATURE_CLOCKSOURCE2 3
#define KVM_FEATURE_ASYNC_PF 4
#define KVM_FEATURE_STEAL_TIME 5
#define KVM_FEATURE_PV_EOI 6
#define KVM_FEATURE_PV_UNHALT 7
#define KVM_FEATURE_PV_TLB_FLUSH 9
#define KVM_FEATURE_ASYNC_PF_VMEXIT 10
#define KVM_FEATURE_PV_SEND_IPI 11
#define KVM_FEATURE_POLL_CONTROL 12
#define KVM_FEATURE_PV_SCHED_YIELD 13
#define KVM_FEATURE_ASYNC_PF_INT 14
#define KVM_FEATURE_MSI_EXT_DEST_ID 15
#define KVM_FEATURE_HC_MAP_GPA_RANGE 16
#define KVM_FEATURE_MIGRATION_CONTROL 17
在虚拟机中执行 cpuid
hypervisor features (0x40000001/eax):
kvmclock available at MSR 0x11 = true
delays unnecessary for PIO ops = true
mmu_op = false
kvmclock available at MSR 0x4b564d00 = true
async pf enable available by MSR = true
steal clock supported = true
guest EOI optimization enabled = true
guest spinlock optimization enabled = true
guest TLB flush optimization enabled = true
async PF VM exit enable available by MSR = true
guest send IPI optimization enabled = true
host HLT poll disable at MSR 0x4b564d05 = true
guest sched yield optimization enabled = true
guest uses intrs for page ready APF evs = true
extended destination ID = false
map gpa range hypercall supported = false
MSR_KVM_MIGRATION_CONTROL supported = false
stable: no guest per-cpu warps expected = true
hypervisor features (0x40000001/edx):
realtime hint: no unbound preemption = false
hypervisor_id (0x40000100) = "\0\0\0\0\0\0\0\0\0\0\0\0"
qemu 的支持
在 qemu 的定义:
target/i386/cpu.c
[FEAT_KVM] = {
.type = CPUID_FEATURE_WORD,
.feat_names = {
"kvmclock", "kvm-nopiodelay", "kvm-mmu", "kvmclock",
"kvm-asyncpf", "kvm-steal-time", "kvm-pv-eoi", "kvm-pv-unhalt",
NULL, "kvm-pv-tlb-flush", "kvm-asyncpf-vmexit", "kvm-pv-ipi",
"kvm-poll-control", "kvm-pv-sched-yield", "kvm-asyncpf-int", "kvm-msi-ext-dest-id",
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
"kvmclock-stable-bit", NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
},
.cpuid = { .eax = KVM_CPUID_FEATURES, .reg = R_EAX, },
.tcg_features = TCG_KVM_FEATURES,
},
kvm_emulate_hypercall -> __kvm_emulate_hypercall
KVM_HC_KICK_CPU
好几个 kvm_sched_yield 是看
- directed_yield_attempted
- directed_yield_successful
每一个都是需要仔细看看的:
case KVM_HC_KICK_CPU:
if (!guest_pv_has(vcpu, KVM_FEATURE_PV_UNHALT))
break;
kvm_pv_kick_cpu_op(vcpu->kvm, a1);
kvm_sched_yield(vcpu, a1);
ret = 0;
break;
#ifdef CONFIG_X86_64
case KVM_HC_CLOCK_PAIRING:
ret = kvm_pv_clock_pairing(vcpu, a0, a1);
break;
#endif
case KVM_HC_SEND_IPI:
if (!guest_pv_has(vcpu, KVM_FEATURE_PV_SEND_IPI))
break;
ret = kvm_pv_send_ipi(vcpu->kvm, a0, a1, a2, a3, op_64_bit);
break;
case KVM_HC_SCHED_YIELD:
if (!guest_pv_has(vcpu, KVM_FEATURE_PV_SCHED_YIELD))
break;
kvm_sched_yield(vcpu, a0);
ret = 0;
break;
vcpu stall detector
内核中存在 : drivers/misc/vcpu_stall_detector.c
对应的公开实现在 crosvm:devices/src/vmwdt.rs (https://chromium.googlesource.com/crosvm/crosvm/+/refs/heads/main/devices/src/vmwdt.rs)。
-
impl BusDevice for Vmwdt → write():接收 guest 的 MMIO 写操作,处理启停、频率配置和喂狗。寄存器偏移 0x00/0x04/0x08/0x0c、每个 vCPU 占 0x10 字节,都与 Linux 驱动一致。
-
vmwdt_worker_thread():等待各 vCPU 的定时器,判断是否超时;首次超时触发 guest 中断,后续仍未恢复则发送 WatchdogReset。
-
get_guest_time_ms():读取 /proc/
/task/ /stat 的 guest_time,获取 vCPU 实际执行 guest 的时间。
设备创建和 MMIO/IRQ 注册在 aarch64/src/lib.rs (https://android.googlesource.com/platform/external/crosvm/+/refs/heads/master/aarch64/src/lib.rs) 的 add_arch_devs(),搜索 Vmwdt::new 即可。
本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。