Commit 5753743f authored by Haozhong Zhang's avatar Haozhong Zhang Committed by Radim Krčmář

KVM: VMX: remove WARN_ON_ONCE in kvm_vcpu_trigger_posted_interrupt

WARN_ON_ONCE(pi_test_sn(&vmx->pi_desc)) in kvm_vcpu_trigger_posted_interrupt()
intends to detect the violation of invariant that VT-d PI notification
event is not suppressed when vcpu is in the guest mode. Because the
two checks for the target vcpu mode and the target suppress field
cannot be performed atomically, the target vcpu mode may change in
between. If that does happen, WARN_ON_ONCE() here may raise false
alarms.

As the previous patch fixed the real invariant breaker, remove this
WARN_ON_ONCE() to avoid false alarms, and document the allowed cases
instead.
Signed-off-by: default avatarHaozhong Zhang <haozhong.zhang@intel.com>
Reported-by: default avatar"Ramamurthy, Venkatesh" <venkatesh.ramamurthy@intel.com>
Reported-by: default avatarDan Williams <dan.j.williams@intel.com>
Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Fixes: 28b835d6 ("KVM: Update Posted-Interrupts Descriptor when vCPU is preempted")
Signed-off-by: default avatarRadim Krčmář <rkrcmar@redhat.com>
parent dc91f2eb
...@@ -5077,21 +5077,30 @@ static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu, ...@@ -5077,21 +5077,30 @@ static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu,
int pi_vec = nested ? POSTED_INTR_NESTED_VECTOR : POSTED_INTR_VECTOR; int pi_vec = nested ? POSTED_INTR_NESTED_VECTOR : POSTED_INTR_VECTOR;
if (vcpu->mode == IN_GUEST_MODE) { if (vcpu->mode == IN_GUEST_MODE) {
struct vcpu_vmx *vmx = to_vmx(vcpu);
/* /*
* Currently, we don't support urgent interrupt, * The vector of interrupt to be delivered to vcpu had
* all interrupts are recognized as non-urgent * been set in PIR before this function.
* interrupt, so we cannot post interrupts when *
* 'SN' is set. * Following cases will be reached in this block, and
* we always send a notification event in all cases as
* explained below.
*
* Case 1: vcpu keeps in non-root mode. Sending a
* notification event posts the interrupt to vcpu.
*
* Case 2: vcpu exits to root mode and is still
* runnable. PIR will be synced to vIRR before the
* next vcpu entry. Sending a notification event in
* this case has no effect, as vcpu is not in root
* mode.
* *
* If the vcpu is in guest mode, it means it is * Case 3: vcpu exits to root mode and is blocked.
* running instead of being scheduled out and * vcpu_block() has already synced PIR to vIRR and
* waiting in the run queue, and that's the only * never blocks vcpu if vIRR is not cleared. Therefore,
* case when 'SN' is set currently, warning if * a blocked vcpu here does not wait for any requested
* 'SN' is set. * interrupts in PIR, and sending a notification event
* which has no effect is safe here.
*/ */
WARN_ON_ONCE(pi_test_sn(&vmx->pi_desc));
apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), pi_vec); apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), pi_vec);
return true; return true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment