|
@@ -4987,9 +4987,12 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu)
|
|
|
+static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu,
|
|
|
+ bool nested)
|
|
|
{
|
|
|
#ifdef CONFIG_SMP
|
|
|
+ int pi_vec = nested ? POSTED_INTR_NESTED_VECTOR : POSTED_INTR_VECTOR;
|
|
|
+
|
|
|
if (vcpu->mode == IN_GUEST_MODE) {
|
|
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
|
|
@@ -5007,8 +5010,7 @@ static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu)
|
|
|
*/
|
|
|
WARN_ON_ONCE(pi_test_sn(&vmx->pi_desc));
|
|
|
|
|
|
- apic->send_IPI_mask(get_cpu_mask(vcpu->cpu),
|
|
|
- POSTED_INTR_VECTOR);
|
|
|
+ apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), pi_vec);
|
|
|
return true;
|
|
|
}
|
|
|
#endif
|
|
@@ -5023,7 +5025,7 @@ static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu,
|
|
|
if (is_guest_mode(vcpu) &&
|
|
|
vector == vmx->nested.posted_intr_nv) {
|
|
|
/* the PIR and ON have been set by L1. */
|
|
|
- kvm_vcpu_trigger_posted_interrupt(vcpu);
|
|
|
+ kvm_vcpu_trigger_posted_interrupt(vcpu, true);
|
|
|
/*
|
|
|
* If a posted intr is not recognized by hardware,
|
|
|
* we will accomplish it in the next vmentry.
|
|
@@ -5057,7 +5059,7 @@ static void vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector)
|
|
|
if (pi_test_and_set_on(&vmx->pi_desc))
|
|
|
return;
|
|
|
|
|
|
- if (!kvm_vcpu_trigger_posted_interrupt(vcpu))
|
|
|
+ if (!kvm_vcpu_trigger_posted_interrupt(vcpu, false))
|
|
|
kvm_vcpu_kick(vcpu);
|
|
|
}
|
|
|
|
|
@@ -10064,13 +10066,9 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
|
|
|
|
|
|
/* Posted interrupts setting is only taken from vmcs12. */
|
|
|
if (nested_cpu_has_posted_intr(vmcs12)) {
|
|
|
- /*
|
|
|
- * Note that we use L0's vector here and in
|
|
|
- * vmx_deliver_nested_posted_interrupt.
|
|
|
- */
|
|
|
vmx->nested.posted_intr_nv = vmcs12->posted_intr_nv;
|
|
|
vmx->nested.pi_pending = false;
|
|
|
- vmcs_write16(POSTED_INTR_NV, POSTED_INTR_VECTOR);
|
|
|
+ vmcs_write16(POSTED_INTR_NV, POSTED_INTR_NESTED_VECTOR);
|
|
|
} else {
|
|
|
exec_control &= ~PIN_BASED_POSTED_INTR;
|
|
|
}
|
|
@@ -10941,7 +10939,9 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
|
|
|
*/
|
|
|
vmx_flush_tlb(vcpu);
|
|
|
}
|
|
|
-
|
|
|
+ /* Restore posted intr vector. */
|
|
|
+ if (nested_cpu_has_posted_intr(vmcs12))
|
|
|
+ vmcs_write16(POSTED_INTR_NV, POSTED_INTR_VECTOR);
|
|
|
|
|
|
vmcs_write32(GUEST_SYSENTER_CS, vmcs12->host_ia32_sysenter_cs);
|
|
|
vmcs_writel(GUEST_SYSENTER_ESP, vmcs12->host_ia32_sysenter_esp);
|