- 文章 中说 的中断流程
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