On 23/11/20 20:22, Oliver Upton wrote:
The pi_pending bit works rather well as it is only a hint to KVM that it
may owe the guest a posted-interrupt completion. However, if we were to
set the guest's nested PINV as pending in the L1 IRR it'd be challenging
to infer whether or not it should actually be injected in L1 or result
in posted-interrupt processing for L2.
Stupid question: why does it matter? The behavior when the PINV is
delivered does not depend on the time it enters the IRR, only on the
time that it enters ISR. If that happens while the vCPU while in L2, it
would trigger posted interrupt processing; if PINV moves to ISR while in
L1, it would be delivered normally as an interrupt.
There are various special cases but they should fall in place. For
example, if PINV is delivered during L1 vmentry (with IF=0), it would be
delivered at the next inject_pending_event when the VMRUN vmexit is
processed and interrupts are unmasked.
The tricky case is when L0 tries to deliver the PINV to L1 as a posted
interrupt, i.e. in vmx_deliver_nested_posted_interrupt. Then the
if (!kvm_vcpu_trigger_posted_interrupt(vcpu, true))
kvm_vcpu_kick(vcpu);
needs a tweak to fall back to setting the PINV in L1's IRR:
if (!kvm_vcpu_trigger_posted_interrupt(vcpu, true)) {
/* set PINV in L1's IRR */
kvm_vcpu_kick(vcpu);
}
but you also have to do the same *in the PINV handler*
sysvec_kvm_posted_intr_nested_ipi too, to handle the case where the
L2->L0 vmexit races against sending the IPI.
What am I missing?
Paolo