The following code is an excerpt of function int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) (every function that I mention is linked to a hyperlink, but this is not visible from the mobile version!) and it shows what happens when the main vcpu is going to run guest code (context: kvm, arm):
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) {
//other code
preempt_disable();
kvm_timer_flush_hwstate(vcpu);
kvm_vgic_flush_hwstate(vcpu);
local_irq_disable();
// other code
kvm_arm_setup_debug(vcpu);
/**************************************************************
* Enter the guest
*/
trace_kvm_entry(*vcpu_pc(vcpu));
__kvm_guest_enter();
vcpu->mode = IN_GUEST_MODE;
ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
vcpu->mode = OUTSIDE_GUEST_MODE;
/*
* Back from guest
************************************************************
*/
//other code
local_irq_enable();
//rest of the function
}
I would like to let you focus on function local_irq_disable(): while we are in hypervisor mode (so executing the guest), we don't want to take HOST interrupts, so local_irq_disable() function lets all the HOST interrupts PENDING while we execute the guest.
What I need to figure out is that how the GuestOS can come back to HostOS when an interrupt happens.
I did track that GuestOS comes back to HostOS upon a __kvm_vcpu_return. __kvm_vcpu_return is in turn called by el1_trap or by el1_irq. What I can't figure out is how such interrupts are taken into account if we called local_irq_disable() function before entering in the guest (namely, before invoking __kvm_guest_enter()). Theoretically, EL1 interrupts shall be disabled, not?