aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>2019-01-22 05:25:13 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2019-01-25 13:11:34 -0500
commitbb218fbcfaaa3b115d4cd7a43c0ca164f3a96e57 (patch)
tree057e73c9199a2435309d479dab871a1b49cbcf85
parent37ef0c4414c9743ba7f1af4392f0a27a99649f2a (diff)
svm: Fix AVIC incomplete IPI emulation
In case of incomplete IPI with invalid interrupt type, the current SVM driver does not properly emulate the IPI, and fails to boot FreeBSD guests with multiple vcpus when enabling AVIC. Fix this by update APIC ICR high/low registers, which also emulate sending the IPI. Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/svm.c19
1 files changed, 4 insertions, 15 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 2aff835a65ed..8a0c9a1f6ac8 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -4504,25 +4504,14 @@ static int avic_incomplete_ipi_interception(struct vcpu_svm *svm)
4504 kvm_lapic_reg_write(apic, APIC_ICR, icrl); 4504 kvm_lapic_reg_write(apic, APIC_ICR, icrl);
4505 break; 4505 break;
4506 case AVIC_IPI_FAILURE_TARGET_NOT_RUNNING: { 4506 case AVIC_IPI_FAILURE_TARGET_NOT_RUNNING: {
4507 int i;
4508 struct kvm_vcpu *vcpu;
4509 struct kvm *kvm = svm->vcpu.kvm;
4510 struct kvm_lapic *apic = svm->vcpu.arch.apic; 4507 struct kvm_lapic *apic = svm->vcpu.arch.apic;
4511 4508
4512 /* 4509 /*
4513 * At this point, we expect that the AVIC HW has already 4510 * Update ICR high and low, then emulate sending IPI,
4514 * set the appropriate IRR bits on the valid target 4511 * which is handled when writing APIC_ICR.
4515 * vcpus. So, we just need to kick the appropriate vcpu.
4516 */ 4512 */
4517 kvm_for_each_vcpu(i, vcpu, kvm) { 4513 kvm_lapic_reg_write(apic, APIC_ICR2, icrh);
4518 bool m = kvm_apic_match_dest(vcpu, apic, 4514 kvm_lapic_reg_write(apic, APIC_ICR, icrl);
4519 icrl & KVM_APIC_SHORT_MASK,
4520 GET_APIC_DEST_FIELD(icrh),
4521 icrl & KVM_APIC_DEST_MASK);
4522
4523 if (m && !avic_vcpu_is_running(vcpu))
4524 kvm_vcpu_wake_up(vcpu);
4525 }
4526 break; 4515 break;
4527 } 4516 }
4528 case AVIC_IPI_FAILURE_INVALID_TARGET: 4517 case AVIC_IPI_FAILURE_INVALID_TARGET: