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

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.comSigned-off-by: default avatarSantosh Shukla <Santosh.Shukla@amd.com>
Link: https://lore.kernel.org/r/20230227084016.3368-2-santosh.shukla@amd.comSigned-off-by: default avatarSean Christopherson <seanjc@google.com>
parent d8708b80
...@@ -416,18 +416,17 @@ void nested_sync_control_from_vmcb02(struct vcpu_svm *svm) ...@@ -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. */ /* Only a few fields of int_ctl are written by the processor. */
mask = V_IRQ_MASK | V_TPR_MASK; mask = V_IRQ_MASK | V_TPR_MASK;
if (!(svm->nested.ctl.int_ctl & V_INTR_MASKING_MASK) && /*
svm_is_intercept(svm, INTERCEPT_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
* In order to request an interrupt window, L0 is usurping * has usurped vmcb02's int_ctl. If an interrupt window opens before
* svm->vmcb->control.int_ctl and possibly setting V_IRQ * the next VM-Exit, svm_clear_vintr() will restore vmcb12's int_ctl.
* even if it was clear in L1's VMCB. Restoring it would be * If no window opens, V_IRQ will be correctly preserved in vmcb12's
* wrong. However, in this case V_IRQ will remain true until * int_ctl (because it was never recognized while L2 was running).
* interrupt_window_interception calls svm_clear_vintr and */
* restores int_ctl. We can just leave it aside. if (svm_is_intercept(svm, INTERCEPT_VINTR) &&
*/ !test_bit(INTERCEPT_VINTR, (unsigned long *)svm->nested.ctl.intercepts))
mask &= ~V_IRQ_MASK; mask &= ~V_IRQ_MASK;
}
if (nested_vgif_enabled(svm)) if (nested_vgif_enabled(svm))
mask |= V_GIF_MASK; mask |= V_GIF_MASK;
......
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