mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
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: Sean Christopherson <seanjc@google.com> Link: https://lkml.kernel.org/r/Y9hybI65So5X2LFg%40google.com Signed-off-by: Santosh Shukla <Santosh.Shukla@amd.com> Link: https://lore.kernel.org/r/20230227084016.3368-2-santosh.shukla@amd.com Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
committed by
Sean Christopherson
parent
d8708b80fa
commit
5faaffab5b
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user