| From e3228fcba101988e5d61ed85eca023bfec00cdf6 Mon Sep 17 00:00:00 2001 |
| From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> |
| Date: Tue, 22 Jan 2019 10:25:13 +0000 |
| Subject: svm: Fix AVIC incomplete IPI emulation |
| |
| [ Upstream commit bb218fbcfaaa3b115d4cd7a43c0ca164f3a96e57 ] |
| |
| 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> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| arch/x86/kvm/svm.c | 19 ++++--------------- |
| 1 file changed, 4 insertions(+), 15 deletions(-) |
| |
| diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c |
| index 656ac12f54392..a94beaecd3e02 100644 |
| --- a/arch/x86/kvm/svm.c |
| +++ b/arch/x86/kvm/svm.c |
| @@ -4006,25 +4006,14 @@ static int avic_incomplete_ipi_interception(struct vcpu_svm *svm) |
| kvm_lapic_reg_write(apic, APIC_ICR, icrl); |
| break; |
| 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; |
| |
| /* |
| - * At this point, we expect that the AVIC HW has already |
| - * set the appropriate IRR bits on the valid target |
| - * vcpus. So, we just need to kick the appropriate vcpu. |
| + * Update ICR high and low, then emulate sending IPI, |
| + * which is handled when writing APIC_ICR. |
| */ |
| - kvm_for_each_vcpu(i, vcpu, kvm) { |
| - bool m = kvm_apic_match_dest(vcpu, apic, |
| - 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); |
| - } |
| + kvm_lapic_reg_write(apic, APIC_ICR2, icrh); |
| + kvm_lapic_reg_write(apic, APIC_ICR, icrl); |
| break; |
| } |
| case AVIC_IPI_FAILURE_INVALID_TARGET: |
| -- |
| 2.19.1 |
| |