diff mbox series

KVM: SVM: allocate AVIC data structures based on kvm_amd moduleparameter

Message ID 1582617278-50338-1-git-send-email-pbonzini@redhat.com (mailing list archive)
State New, archived
Headers show
Series KVM: SVM: allocate AVIC data structures based on kvm_amd moduleparameter | expand

Commit Message

Paolo Bonzini Feb. 25, 2020, 7:54 a.m. UTC
Even if APICv is disabled at startup, the backing page and ir_list need
to be initialized in case they are needed later.  The only case in
which this can be skipped is for userspace irqchip, and that must be
done because avic_init_backing_page dereferences vcpu->arch.apic
(which is NULL for userspace irqchip).

Tested-by: rmuncrief@humanavance.com
Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=206579
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/x86/kvm/svm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Vitaly Kuznetsov Feb. 25, 2020, 1:45 p.m. UTC | #1
Paolo Bonzini <pbonzini@redhat.com> writes:

> Even if APICv is disabled at startup, the backing page and ir_list need
> to be initialized in case they are needed later.  The only case in
> which this can be skipped is for userspace irqchip, and that must be
> done because avic_init_backing_page dereferences vcpu->arch.apic
> (which is NULL for userspace irqchip).
>
> Tested-by: rmuncrief@humanavance.com
> Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=206579
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  arch/x86/kvm/svm.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index ad3f5b178a03..bd02526300ab 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -2194,8 +2194,9 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>  static int avic_init_vcpu(struct vcpu_svm *svm)
>  {
>  	int ret;
> +	struct kvm_vcpu *vcpu = &svm->vcpu;
>  
> -	if (!kvm_vcpu_apicv_active(&svm->vcpu))
> +	if (!avic || !irqchip_in_kernel(vcpu->kvm))
>  		return 0;
>  
>  	ret = avic_init_backing_page(&svm->vcpu);

Out of pure curiosity,

when irqchip_in_kernel() is false, can we still get to .update_pi_irte()
(svm_update_pi_irte()) -> get_pi_vcpu_info() -> "vcpu_info->pi_desc_addr
= __sme_set(page_to_phys((*svm)->avic_backing_page));" -> crash! or is
there anything which make this impossible?

The patch is an improvement anyway, so
Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Paolo Bonzini Feb. 25, 2020, 2:01 p.m. UTC | #2
On 25/02/20 14:45, Vitaly Kuznetsov wrote:
>>  	int ret;
>> +	struct kvm_vcpu *vcpu = &svm->vcpu;
>>  
>> -	if (!kvm_vcpu_apicv_active(&svm->vcpu))
>> +	if (!avic || !irqchip_in_kernel(vcpu->kvm))
>>  		return 0;
>>  
>>  	ret = avic_init_backing_page(&svm->vcpu);
> Out of pure curiosity,
> 
> when irqchip_in_kernel() is false, can we still get to .update_pi_irte()
> (svm_update_pi_irte()) -> get_pi_vcpu_info() -> "vcpu_info->pi_desc_addr
> = __sme_set(page_to_phys((*svm)->avic_backing_page));" -> crash! or is
> there anything which make this impossible?

No, because kvm_arch_irqfd_allowed returns false so you cannot create
any irqfd (svm_update_pi_irte is called when virt/lib/irqbypass.c finds
a match between two eventfds in KVM and VFIO).

Paolo
diff mbox series

Patch

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index ad3f5b178a03..bd02526300ab 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -2194,8 +2194,9 @@  static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
 static int avic_init_vcpu(struct vcpu_svm *svm)
 {
 	int ret;
+	struct kvm_vcpu *vcpu = &svm->vcpu;
 
-	if (!kvm_vcpu_apicv_active(&svm->vcpu))
+	if (!avic || !irqchip_in_kernel(vcpu->kvm))
 		return 0;
 
 	ret = avic_init_backing_page(&svm->vcpu);