虚拟化(6):kvm+kernel All CPU(s) started at EL2
上文中,还有个跟KVM有关的内容是All CPU(s) started at EL2
https://elixir.bootlin.com/linux/v6.6/source/arch/arm64/kernel/smp.c#L419
一般情况下,我们的都是执行424行,在没有kvm的情况下,我们CPU都是工作在EL1,这个函数都是跟多CPU相关,比如CPU的启动与初始化,通信,SMP系统全局初始化,CPU负载均衡和调度支持。
捋一下调度关系:
kernel_init->kernel_init_freeable->smp_init->smp_cpus_done->hyp_mode_check
1.is_hyp_mode_available
https://elixir.bootlin.com/linux/v6.6/source/arch/arm64/include/asm/virt.h#L86
判断hyp模式是否可用,第一个判断走的是pkvm, 如果OK的话,我们可以判断开启的是pkvm,但是走的是下面那个return话,只能判断是常规KVM模式(VHE是常规的一种)
同样is_hyp_mode_available处于也出现在上一节的kvm_arm_init函数
https://elixir.bootlin.com/linux/v6.6/source/arch/arm64/kvm/arm.c#L2402
先确定hyp是否能用,然后再敲定hyp mode
2.如何敲定CPU是在EL2上
换句话说,如何确定hyp是pkvm或者vhe等其他普通KVM模式,可以通过__boot_cpu_mode来判断,来捋一下逻辑
这里就要切换到汇编代码了
https://elixir.bootlin.com/linux/v6.6/source/arch/arm64/kernel/head.S#L696
可以看到将__boot_cpu_mode中的内容放到了x1中,那么__boot_cpu_mode的函数来自于哪里
https://elixir.bootlin.com/linux/v6.6/source/arch/arm64/kernel/head.S#L490
__boot_cpu_mode<-set_cpu_boot_mode_flag<-__primary_switched<-__primary_switch<-primary_entry
转到这个函数之后,就已经有init_kernel_el这个函数了,然后就到了最关键的地方
这个CurrentEL是armv8的一个寄存器
qemu+kernel

