On Thu, Mar 10, 2022, Maciej S. Szmigiero wrote: > From: "Maciej S. Szmigiero" <maciej.szmigiero@xxxxxxxxxx> > > In SVM synthetic software interrupts or INT3 or INTO exception that L1 > wants to inject into its L2 guest are forgotten if there is an intervening > L0 VMEXIT during their delivery. > > They are re-injected correctly with VMX, however. > > This is because there is an assumption in SVM that such exceptions will be > re-delivered by simply re-executing the current instruction. > Which might not be true if this is a synthetic exception injected by L1, > since in this case the re-executed instruction will be one already in L2, > not the VMRUN instruction in L1 that attempted the injection. > > Leave the pending L1 -> L2 event in svm->nested.ctl.event_inj{,err} until > it is either re-injected successfully or returned to L1 upon a nested > VMEXIT. > Make sure to always re-queue such event if returned in EXITINTINFO. > > The handling of L0 -> {L1, L2} event re-injection is left as-is to avoid > unforeseen regressions. > > Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@xxxxxxxxxx> > --- ... > @@ -3627,6 +3632,14 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu) > if (!(exitintinfo & SVM_EXITINTINFO_VALID)) > return; > > + /* L1 -> L2 event re-injection needs a different handling */ > + if (is_guest_mode(vcpu) && > + exit_during_event_injection(svm, svm->nested.ctl.event_inj, > + svm->nested.ctl.event_inj_err)) { > + nested_svm_maybe_reinject(vcpu); Why is this manually re-injecting? More specifically, why does the below (out of sight in the diff) code that re-queues the exception/interrupt not work? The re-queued event should be picked up by nested_save_pending_event_to_vmcb12() and propagatred to vmcb12.