Skip to content

Commit 06a5524

Browse files
Wincy Vanbonzini
authored andcommitted
KVM: nVMX: Fix posted intr delivery when vcpu is in guest mode
The PI vector for L0 and L1 must be different. If dest vcpu0 is in guest mode while vcpu1 is delivering a non-nested PI to vcpu0, there wont't be any vmexit so that the non-nested interrupt will be delayed. Signed-off-by: Wincy Van <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 210f84b commit 06a5524

File tree

1 file changed

+11
-11
lines changed

1 file changed

+11
-11
lines changed

arch/x86/kvm/vmx.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4987,9 +4987,12 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
49874987
}
49884988
}
49894989

4990-
static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu)
4990+
static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu,
4991+
bool nested)
49914992
{
49924993
#ifdef CONFIG_SMP
4994+
int pi_vec = nested ? POSTED_INTR_NESTED_VECTOR : POSTED_INTR_VECTOR;
4995+
49934996
if (vcpu->mode == IN_GUEST_MODE) {
49944997
struct vcpu_vmx *vmx = to_vmx(vcpu);
49954998

@@ -5007,8 +5010,7 @@ static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu)
50075010
*/
50085011
WARN_ON_ONCE(pi_test_sn(&vmx->pi_desc));
50095012

5010-
apic->send_IPI_mask(get_cpu_mask(vcpu->cpu),
5011-
POSTED_INTR_VECTOR);
5013+
apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), pi_vec);
50125014
return true;
50135015
}
50145016
#endif
@@ -5023,7 +5025,7 @@ static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu,
50235025
if (is_guest_mode(vcpu) &&
50245026
vector == vmx->nested.posted_intr_nv) {
50255027
/* the PIR and ON have been set by L1. */
5026-
kvm_vcpu_trigger_posted_interrupt(vcpu);
5028+
kvm_vcpu_trigger_posted_interrupt(vcpu, true);
50275029
/*
50285030
* If a posted intr is not recognized by hardware,
50295031
* we will accomplish it in the next vmentry.
@@ -5057,7 +5059,7 @@ static void vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector)
50575059
if (pi_test_and_set_on(&vmx->pi_desc))
50585060
return;
50595061

5060-
if (!kvm_vcpu_trigger_posted_interrupt(vcpu))
5062+
if (!kvm_vcpu_trigger_posted_interrupt(vcpu, false))
50615063
kvm_vcpu_kick(vcpu);
50625064
}
50635065

@@ -10064,13 +10066,9 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
1006410066

1006510067
/* Posted interrupts setting is only taken from vmcs12. */
1006610068
if (nested_cpu_has_posted_intr(vmcs12)) {
10067-
/*
10068-
* Note that we use L0's vector here and in
10069-
* vmx_deliver_nested_posted_interrupt.
10070-
*/
1007110069
vmx->nested.posted_intr_nv = vmcs12->posted_intr_nv;
1007210070
vmx->nested.pi_pending = false;
10073-
vmcs_write16(POSTED_INTR_NV, POSTED_INTR_VECTOR);
10071+
vmcs_write16(POSTED_INTR_NV, POSTED_INTR_NESTED_VECTOR);
1007410072
} else {
1007510073
exec_control &= ~PIN_BASED_POSTED_INTR;
1007610074
}
@@ -10941,7 +10939,9 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
1094110939
*/
1094210940
vmx_flush_tlb(vcpu);
1094310941
}
10944-
10942+
/* Restore posted intr vector. */
10943+
if (nested_cpu_has_posted_intr(vmcs12))
10944+
vmcs_write16(POSTED_INTR_NV, POSTED_INTR_VECTOR);
1094510945

1094610946
vmcs_write32(GUEST_SYSENTER_CS, vmcs12->host_ia32_sysenter_cs);
1094710947
vmcs_writel(GUEST_SYSENTER_ESP, vmcs12->host_ia32_sysenter_esp);

0 commit comments

Comments
 (0)