little-qemu&guest 中的 虚拟机CPU角度分析 - 进行中

之前在 文章 中描述了 7个ioctl,现在着重分析 其中5个,这5个与虚拟机CPU相关

KVM_CREATE_VM
KVM_CREATE_VCPU
KVM_ARM_VCPU_INIT
KVM_SET_ONE_REG
KVM_RUN
	vm entry
	vm exit


KVM_RUN

  • VM entry 的流程
kvm_vcpu_ioctl
kvm_arch_vcpu_ioctl_run
-1.kvm_call_hyp_ret(__kvm_vcpu_run_nvhe, vcpu); //kvm_call_hyp_ret即__kvm_call_hyp
0. __kvm_call_hyp 中的 hvc	#0
1. arch/arm/kvm/hyp/hyp-entry.S 中的 __kvm_hyp_vector_ic_inv 中的 W(add)  sp, sp, #1      /* HVC            2 */
2. b       decode_vectors
3. vect_br 0, hyp_fiq 和 vect_br 1, hyp_irq 和 vect_br 2, hyp_hvc
4. hyp_hvc
5. blx     lr                      @ Call the HYP function
6. __kvm_vcpu_run_nvhe
7. __guest_enter
8. eret // 进入 guest
  • VM exit 的流程

1. 虚拟机执行敏感指令
2. __kvm_hyp_vector_ic_inv 中的 W(add)  sp, sp, #1      /* HVC            2 */
3. b       decode_vectors
4. vect_br 0, hyp_fiq 和 vect_br 1, hyp_irq 和 vect_br 2, hyp_hvc
5. hyp_hvc
6. bne     guest_trap              @ Not HVC instr.
7. mov     r1, #ARM_EXCEPTION_HVC 和 b       __guest_exit
8. abort_guest_exit_end: bx      lr
9. arch/arm/kvm/hyp/switch.c 中的 __populate_fault_info 中的 u32 hsr = read_sysreg(HSR); // ???
10. if (exit_code == ARM_EXCEPTION_HVC && !__populate_fault_info(vcpu)) goto again;

切换

  • host PL2 与 host PL1 的切换

关注
	1. host PL1 mode 	陷入 	host PL2mode
		主动调用 指令(hvc)
			virt/kvm/arm/vgic/vgic-init.c:477:          kvm_call_hyp(__vgic_v3_init_lrs);
			virt/kvm/arm/vgic/vgic-v3.c:661:            kvm_call_hyp(__vgic_v3_write_vmcr, cpu_if->vgic_vmcr);
			virt/kvm/arm/vgic/vgic-v3.c:663:     		kvm_call_hyp(__vgic_v3_restore_aprs, vcpu);
			virt/kvm/arm/vgic/vgic-v3.c:685:     		kvm_call_hyp(__vgic_v3_save_aprs, vcpu);
			virt/kvm/arm/mmu.c:58:       				kvm_call_hyp(__kvm_tlb_flush_vmid, kvm);
			virt/kvm/arm/mmu.c:63:       				kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, kvm, ipa);
			virt/kvm/arm/arm.c:348:              		kvm_call_hyp(__kvm_tlb_flush_local_vmid, vcpu);
			virt/kvm/arm/arm.c:507:              		kvm_call_hyp(__kvm_flush_vm_context);
			virt/kvm/arm/arch_timer.c:464:       		kvm_call_hyp(__kvm_timer_set_cntvoff, low, high);
			arch/arm/include/asm/kvm_host.h				kvm_call_hyp(__init_stage2_translation);
			
			virt/kvm/arm/vgic/vgic-v3.c:584:        	u32 ich_vtr_el2 = kvm_call_hyp_ret(__vgic_v3_get_ich_vtr_el2);
			virt/kvm/arm/vgic/vgic-v3.c:676:            cpu_if->vgic_vmcr = kvm_call_hyp_ret(__vgic_v3_read_vmcr);
			virt/kvm/arm/arm.c:747:                 	ret = kvm_call_hyp_ret(__kvm_vcpu_run_nvhe, vcpu);
		中断(来自外设,模拟外设) 	   // 哪些中断会进入host PL2 mode,可配置决定

	2. host PL2 mode 	退出到 	host PL1 mode
		指令 : eret
  • host os 与 guest os 的切换
	1. host PL2 mode 	陷入 	guest
		__kvm_vcpu_run_nvhe -> __guest_enter -> eret(该指令执行后进入 guest)
	2. guest 			退出到 	host PL2 mode
		3.1 敏感指令(包括ipi指令)   // 哪些指令会退出,可配置决定
		3.2 中断(来自外设,模拟外设) // 哪些中断会进入host PL2 mode,可配置决定

Guess you like

Origin blog.csdn.net/u011011827/article/details/120864012