最近在测试 Arm 架构嵌套虚拟化。由于我没有真正的 Armv8.4 CPU,因此我使用 QEMU-9.0.0-rc2 来模拟 Arm 芯片。根据 QEMU 更新日志,QEMU-9.0.0 中已添加对 FEAT_ECV、FEAT_NV 和 FEAT_NV2 的支持。此外,我使用 linux-6.8.4 的 KVM 作为 Hypervisor。下面是我用来启动外部 QEMU 的命令:
./qemu-9.0.0-rc2/bin/qemu-system-aarch64 -nographic -machine virt-9.0,secure=on,virtualization=on,gic_version=3 \
-cpu max \
-smp 4 -m 4G \
-bios ./trusted-firmware-a/build/qemu/debug/bl1.bin \
-semihosting-config enable=on,target=native \
-kernel ./linux-6.8.4/arch/arm64/boot/Image \
-initrd ./buildroot-kvm/output/images/rootfs.cpio \
-append "kvm-arm.mode=nested" \
这能够正常启动进入系统并打印:
[ 0.000000] CPU features: detected: Virtualization Host Extensions
[ 0.190843] CPU features: detected: Enhanced Counter Virtualization
[ 0.191057] CPU features: detected: Enhanced Counter Virtualization (CNTPOFF)
[ 0.191520] CPU features: detected: Enhanced Virtualization Traps
[ 0.193408] CPU features: detected: Nested Virtualization Support
[ 1.271492] kvm [1]: nv: 477 coarse grained trap handlers
[ 1.281075] kvm [1]: nv: 668 fine grained trap handlers
[ 1.281840] kvm [1]: IPA Size Limit: 52 bits
[ 1.283506] kvm [1]: GICv3: no GICV resource entry
[ 1.284258] kvm [1]: disabling GICv2 emulation
[ 1.285290] kvm [1]: GIC system register CPU interface enabled
[ 1.287004] kvm [1]: vgic interrupt IRQ9
[ 1.288348] kvm [1]: VHE mode initialized successfully
然后,我尝试使用以下命令,使用带有 KVM 加速的 QEMU 启动虚拟机:
qemu-system-aarch64 -M virt -accel kvm -cpu host -smp 1 -kernel tiny_Image_6.8.4 -initrd tiny_rootfs.cpio -nographic
这导致了异常[ 197.871251] Internal error: Oops - Undefined instruction: 0000000002000000 [#1] PREEMPT SMP
。我发现错误发生在timer_restore_state
中的函数中arch/arm64/kvm/arch_timer.c
,其中set_cntpoff
函数试图将值写入寄存器CNTPOFF_EL2
,但我不确定为什么会发生这种情况。
-cpu neoverse_n2
此外,当我用或替换启动外部 QEMU 的命令时-cpu neoverse_v1
,它仅打印:
[ 0.000000] CPU features: detected: Virtualization Host Extensions
[ 0.189302] CPU features: detected: Enhanced Virtualization Traps
[ 0.190418] CPU features: detected: Nested Virtualization Support
[ 1.272526] kvm [1]: nv: 477 coarse grained trap handlers
[ 1.273213] kvm [1]: IPA Size Limit: 48 bits
[ 1.275016] kvm [1]: GICv3: no GICV resource entry
[ 1.275717] kvm [1]: disabling GICv2 emulation
[ 1.276642] kvm [1]: GIC system register CPU interface enabled
[ 1.278780] kvm [1]: vgic interrupt IRQ9
[ 1.280100] kvm [1]: VHE mode initialized successfully
然后我又尝试在里面启动一个虚拟机,可以正常启动到第二级虚拟机。但是 KVM 没有初始化,显示[ 14.130576] kvm [1]: HYP mode not available
。我认为这是因为 VCPU 没有从 EL2 启动。我该如何让 VCPU 从 EL2 启动?
最后我发现该system_supported_vcpu_features
函数使用了KVM_VCPU_VALID_FEATURES
宏,其中
#define KVM_VCPU_MAX_FEATURES 7
#define KVM_VCPU_VALID_FEATURES (BIT(KVM_VCPU_MAX_FEATURES) - 1)
#define KVM_ARM_VCPU_HAS_EL2 7 /* Support nested virtualization */
这里KVM_VCPU_VALID_FEATURES
无法覆盖新增的KVM_VCPU_VALID_FEATURES
功能,这是BUG吗?