Commit bb218fbc authored by Suravee Suthikulpanit's avatar Suravee Suthikulpanit Committed by Paolo Bonzini

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: default avatarSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 37ef0c44
...@@ -4504,25 +4504,14 @@ static int avic_incomplete_ipi_interception(struct vcpu_svm *svm) ...@@ -4504,25 +4504,14 @@ static int avic_incomplete_ipi_interception(struct vcpu_svm *svm)
kvm_lapic_reg_write(apic, APIC_ICR, icrl); kvm_lapic_reg_write(apic, APIC_ICR, icrl);
break; break;
case AVIC_IPI_FAILURE_TARGET_NOT_RUNNING: { case AVIC_IPI_FAILURE_TARGET_NOT_RUNNING: {
int i;
struct kvm_vcpu *vcpu;
struct kvm *kvm = svm->vcpu.kvm;
struct kvm_lapic *apic = svm->vcpu.arch.apic; struct kvm_lapic *apic = svm->vcpu.arch.apic;
/* /*
* At this point, we expect that the AVIC HW has already * Update ICR high and low, then emulate sending IPI,
* set the appropriate IRR bits on the valid target * which is handled when writing APIC_ICR.
* vcpus. So, we just need to kick the appropriate vcpu.
*/ */
kvm_for_each_vcpu(i, vcpu, kvm) { kvm_lapic_reg_write(apic, APIC_ICR2, icrh);
bool m = kvm_apic_match_dest(vcpu, apic, kvm_lapic_reg_write(apic, APIC_ICR, icrl);
icrl & KVM_APIC_SHORT_MASK,
GET_APIC_DEST_FIELD(icrh),
icrl & KVM_APIC_DEST_MASK);
if (m && !avic_vcpu_is_running(vcpu))
kvm_vcpu_wake_up(vcpu);
}
break; break;
} }
case AVIC_IPI_FAILURE_INVALID_TARGET: case AVIC_IPI_FAILURE_INVALID_TARGET:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment