• Sean Christopherson's avatar
    KVM: VMX: Handle PI descriptor updates during vcpu_put/load · d76fb406
    Sean Christopherson authored
    Move the posted interrupt pre/post_block logic into vcpu_put/load
    respectively, using the kvm_vcpu_is_blocking() to determining whether or
    not the wakeup handler needs to be set (and unset).  This avoids updating
    the PI descriptor if halt-polling is successful, reduces the number of
    touchpoints for updating the descriptor, and eliminates the confusing
    behavior of intentionally leaving a "stale" PI.NDST when a blocking vCPU
    is scheduled back in after preemption.
    
    The downside is that KVM will do the PID update twice if the vCPU is
    preempted after prepare_to_rcuwait() but before schedule(), but that's a
    rare case (and non-existent on !PREEMPT kernels).
    
    The notable wart is the need to send a self-IPI on the wakeup vector if
    an outstanding notification is pending after configuring the wakeup
    vector.  Ideally, KVM would just do a kvm_vcpu_wake_up() in this case,
    but the scheduler doesn't support waking a task from its preemption
    notifier callback, i.e. while the task is right in the middle of
    being scheduled out.
    
    Note, setting the wakeup vector before halt-polling is not necessary:
    once the pending IRQ will be recorded in the PIR, kvm_vcpu_has_events()
    will detect this (via kvm_cpu_get_interrupt(), kvm_apic_get_interrupt(),
    apic_has_interrupt_for_ppr() and finally vmx_sync_pir_to_irr()) and
    terminate the polling.
    Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
    Reviewed-by: default avatarMaxim Levitsky <mlevitsk@redhat.com>
    Message-Id: <20211208015236.1616697-5-seanjc@google.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    d76fb406
vmx.c 229 KB