little-qemu&guest 中的 虚拟机中断角度 之 异常向量表

  • 文章 中说 的中断流程
1 2 3 三种都要经过
A.中断发生流程
B.guest退出到host hyp2(host PL2)
C.host hyp2 退出到 host PL1 
D.host PL1 执行 guest 退出(动作B)的对应处理函数
E.host PL1 执行 中断注入
F.host PL1 陷入 host PL2 并执行 guest entry

异常向量表

B.guest退出到host hyp2(host PL2) // PL2 的异常向量表
F.host PL1 陷入 host PL2 并执行 guest entry // PL2 的 异常向量表
两个过程都和异常向量表(__kvm_hyp_vector_ic_inv)有关系

可 在 https://blog.csdn.net/u011011827/article/details/120864012 中的 "VM exit 的流程" 查看 过程B
可 在 https://blog.csdn.net/u011011827/article/details/120864037 中的 "hyp 异常陷入总览" 查看过程F

arch/arm/kvm/hyp/hyp-entry.S:65:__kvm_hyp_vector_ic_inv:
    .align 5                                                                        
__kvm_hyp_vector_ic_inv:                                                            
    .global __kvm_hyp_vector_ic_inv                                                 
                                                                                    
    /*                                                                              
     * We encode the exception entry in the bottom 3 bits of                        
     * SP, and we have to guarantee to be 8 bytes aligned.                          
     */                                                                             
    W(add)  sp, sp, #1  /* Reset      7 */                                          
    W(add)  sp, sp, #1  /* Undef      6 */                                          
    W(add)  sp, sp, #1  /* Syscall    5 */                                          
    W(add)  sp, sp, #1  /* Prefetch abort 4 */                                      
    W(add)  sp, sp, #1  /* Data abort     3 */                                      
    W(add)  sp, sp, #1  /* HVC        2 */                                          
    W(add)  sp, sp, #1  /* IRQ        1 */                                          
    W(nop)          /* FIQ        0 */                                              
                                                                                    
    mcr p15, 0, r0, c7, c5, 0   /* ICIALLU */                                       
    isb                                                                             
                                                                                    
    b   decode_vectors
    	后面分发到几个流程中
    		guest_trap 			// VM exit 会走到这里 ,最终会调用 __guest_exit
    		guest_hvc_trap
    		blx lr          @ Call the HYP function // kvm_call_hyp(__init_stage2_translation); 会走到这里,此时调用  __init_stage2_translation

异常向量表的初始化

  • host 中的 PL2
// 异常向量表的位置经过了 三次 初始化,最终用的是 __kvm_hyp_vector_ic_inv
应该有三个过程,
	第一个过程在异常向量表位置建立了__hyp_stub_vectors,异常中处理HVC_SET_VECTORS
	第二个过程在异常向量表位置销毁了__hyp_stub_vectors,建立了 __kvm_hyp_init ,异常中处理
	第二个过程在异常向量表位置销毁了__kvm_hyp_init, 	建立了 __kvm_hyp_vector_ic_inv

	过程一
		

	过程二
		kvm_mmu_init
			hyp_idmap_vector = kvm_virt_to_phys(__kvm_hyp_init);
		cpu_hyp_reinit
			cpu_init_hyp_mode
				/* Switch from the HYP stub to our own HYP init vector */
				__hyp_set_vectors(kvm_get_idmap_vector()); // 进入入口__hyp_stub_vectors
	过程三
		kvm_get_hyp_vector
			return kvm_ksym_ref(__kvm_hyp_vector_ic_inv);
		cpu_hyp_reinit
			cpu_init_hyp_mode
				vector_ptr = (unsigned long)kvm_get_hyp_vector();
				__cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr, vector_ptr); //  进入入口 __kvm_hyp_init

					__kvm_hyp_init // 
						@ Hyp-mode exception vector
						W(b)    __do_hyp_init
					
					__do_hyp_init
						// 将 r1 中的值 填充到 协处理器寄存器
						@ Set HVBAR to point to the HYP vectors
						mcr p15, 4, r1, c12, c0, 0  @ HVBAR
						
						// 将 r2 r3 中的值 填充到 协处理器寄存器
						@ Set the HTTBR to point to the hypervisor PGD pointer passed
						mcrr    p15, 4, rr_lo_hi(r2, r3), c2
  • host 中的 PL1 : __vectors_start
  • guest 中的 PL1 : __vectors_start

Guess you like

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