Skip to content

Commit 7334ede

Browse files
sashukla1sean-jc
authored andcommitted
KVM: nSVM: Disable intercept of VINTR if saved L1 host RFLAGS.IF is 0
Disable intercept of virtual interrupts (used to detect interrupt windows) if the saved host (L1) RFLAGS.IF is '0', as the effective RFLAGS.IF for L1 interrupts will never be set while L2 is running (L2's RFLAGS.IF doesn't affect L1 IRQs when virtual interrupts are enabled). 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-3-santosh.shukla@amd.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 5faaffa commit 7334ede

2 files changed

Lines changed: 20 additions & 5 deletions

File tree

arch/x86/kvm/svm/nested.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,18 @@ void recalc_intercepts(struct vcpu_svm *svm)
139139

140140
if (g->int_ctl & V_INTR_MASKING_MASK) {
141141
/*
142-
* Once running L2 with HF_VINTR_MASK, EFLAGS.IF and CR8
143-
* does not affect any interrupt we may want to inject;
144-
* therefore, writes to CR8 are irrelevant to L0, as are
145-
* interrupt window vmexits.
142+
* If L2 is active and V_INTR_MASKING is enabled in vmcb12,
143+
* disable intercept of CR8 writes as L2's CR8 does not affect
144+
* any interrupt KVM may want to inject.
145+
*
146+
* Similarly, disable intercept of virtual interrupts (used to
147+
* detect interrupt windows) if the saved RFLAGS.IF is '0', as
148+
* the effective RFLAGS.IF for L1 interrupts will never be set
149+
* while L2 is running (L2's RFLAGS.IF doesn't affect L1 IRQs).
146150
*/
147151
vmcb_clr_intercept(c, INTERCEPT_CR8_WRITE);
148-
vmcb_clr_intercept(c, INTERCEPT_VINTR);
152+
if (!(svm->vmcb01.ptr->save.rflags & X86_EFLAGS_IF))
153+
vmcb_clr_intercept(c, INTERCEPT_VINTR);
149154
}
150155

151156
/*

arch/x86/kvm/svm/svm.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1583,6 +1583,16 @@ static void svm_set_vintr(struct vcpu_svm *svm)
15831583

15841584
svm_set_intercept(svm, INTERCEPT_VINTR);
15851585

1586+
/*
1587+
* Recalculating intercepts may have cleared the VINTR intercept. If
1588+
* V_INTR_MASKING is enabled in vmcb12, then the effective RFLAGS.IF
1589+
* for L1 physical interrupts is L1's RFLAGS.IF at the time of VMRUN.
1590+
* Requesting an interrupt window if save.RFLAGS.IF=0 is pointless as
1591+
* interrupts will never be unblocked while L2 is running.
1592+
*/
1593+
if (!svm_is_intercept(svm, INTERCEPT_VINTR))
1594+
return;
1595+
15861596
/*
15871597
* This is just a dummy VINTR to actually cause a vmexit to happen.
15881598
* Actual injection of virtual interrupts happens through EVENTINJ.

0 commit comments

Comments
 (0)