Commit 5faaffab authored by Santosh Shukla's avatar Santosh Shukla Committed by Sean Christopherson
Browse files

KVM: nSVM: Don't sync vmcb02 V_IRQ back to vmcb12 if KVM (L0) is intercepting VINTR



Don't sync vmcb02 V_IRQ back to vmcb12 if KVM (L0) is intercepting
virtual interrupts in order to request an interrupt window, as KVM
has usurped vmcb02's int_ctl.  If an interrupt window opens before
the next VM-Exit, svm_clear_vintr() will restore vmcb12's int_ctl.
If no window opens, V_IRQ will be correctly preserved in vmcb12's
int_ctl (because it was never recognized while L2 was running).

Suggested-by: default avatarSean Christopherson <seanjc@google.com>
Link: https://lkml.kernel.org/r/Y9hybI65So5X2LFg%40google.com


Signed-off-by: default avatarSantosh Shukla <Santosh.Shukla@amd.com>
Link: https://lore.kernel.org/r/20230227084016.3368-2-santosh.shukla@amd.com


Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent d8708b80
Loading
Loading
Loading
Loading
+10 −11
Original line number Diff line number Diff line
@@ -416,18 +416,17 @@ void nested_sync_control_from_vmcb02(struct vcpu_svm *svm)

	/* Only a few fields of int_ctl are written by the processor.  */
	mask = V_IRQ_MASK | V_TPR_MASK;
	if (!(svm->nested.ctl.int_ctl & V_INTR_MASKING_MASK) &&
	    svm_is_intercept(svm, INTERCEPT_VINTR)) {
	/*
		 * In order to request an interrupt window, L0 is usurping
		 * svm->vmcb->control.int_ctl and possibly setting V_IRQ
		 * even if it was clear in L1's VMCB.  Restoring it would be
		 * wrong.  However, in this case V_IRQ will remain true until
		 * interrupt_window_interception calls svm_clear_vintr and
		 * restores int_ctl.  We can just leave it aside.
	 * Don't sync vmcb02 V_IRQ back to vmcb12 if KVM (L0) is intercepting
	 * virtual interrupts in order to request an interrupt window, as KVM
	 * has usurped vmcb02's int_ctl.  If an interrupt window opens before
	 * the next VM-Exit, svm_clear_vintr() will restore vmcb12's int_ctl.
	 * If no window opens, V_IRQ will be correctly preserved in vmcb12's
	 * int_ctl (because it was never recognized while L2 was running).
	 */
	if (svm_is_intercept(svm, INTERCEPT_VINTR) &&
	    !test_bit(INTERCEPT_VINTR, (unsigned long *)svm->nested.ctl.intercepts))
		mask &= ~V_IRQ_MASK;
	}

	if (nested_vgif_enabled(svm))
		mask |= V_GIF_MASK;