From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755881AbdKGVnV (ORCPT ); Tue, 7 Nov 2017 16:43:21 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34366 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755818AbdKGVnT (ORCPT ); Tue, 7 Nov 2017 16:43:19 -0500 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 840F7267D8 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=eric.auger@redhat.com Subject: Re: [PATCH v5 19/26] KVM: arm/arm64: GICv4: Add doorbell interrupt handling To: Marc Zyngier , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, linux-kernel@vger.kernel.org References: <20171027142855.21584-1-marc.zyngier@arm.com> <20171027142855.21584-20-marc.zyngier@arm.com> Cc: Mark Rutland , Andre Przywara , Shameerali Kolothum Thodi , Christoffer Dall , Shanker Donthineni From: Auger Eric Message-ID: <3b39afd2-f035-a138-2a3b-10ac10b55c22@redhat.com> Date: Tue, 7 Nov 2017 22:43:14 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 In-Reply-To: <20171027142855.21584-20-marc.zyngier@arm.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Tue, 07 Nov 2017 21:43:19 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, On 27/10/2017 16:28, Marc Zyngier wrote: > When a vPE is not running, a VLPI being made pending results in a > doorbell interrupt being delivered. Let's handle this interrupt > and update the pending_last flag that indicates that VLPIs are > pending. The corresponding vcpu is also kicked into action. > > Special care is taken to prevent the doorbell from being enabled > at request time (this is controlled separately), and to make > the disabling on the interrupt non-lazy. > > Reviewed-by: Christoffer Dall > Signed-off-by: Marc Zyngier Reviewed-by: Eric Auger Thanks Eric > --- > virt/kvm/arm/vgic/vgic-v4.c | 48 +++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 48 insertions(+) > > diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c > index 01a2889b7b7c..ea898af1a7a9 100644 > --- a/virt/kvm/arm/vgic/vgic-v4.c > +++ b/virt/kvm/arm/vgic/vgic-v4.c > @@ -16,12 +16,24 @@ > */ > > #include > +#include > #include > #include > #include > > #include "vgic.h" > > +static irqreturn_t vgic_v4_doorbell_handler(int irq, void *info) > +{ > + struct kvm_vcpu *vcpu = info; > + > + vcpu->arch.vgic_cpu.vgic_v3.its_vpe.pending_last = true; > + kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu); > + kvm_vcpu_kick(vcpu); > + > + return IRQ_HANDLED; > +} > + > /** > * vgic_v4_init - Initialize the GICv4 data structures > * @kvm: Pointer to the VM being initialized > @@ -61,6 +73,33 @@ int vgic_v4_init(struct kvm *kvm) > return ret; > } > > + kvm_for_each_vcpu(i, vcpu, kvm) { > + int irq = dist->its_vm.vpes[i]->irq; > + > + /* > + * Don't automatically enable the doorbell, as we're > + * flipping it back and forth when the vcpu gets > + * blocked. Also disable the lazy disabling, as the > + * doorbell could kick us out of the guest too > + * early... > + */ > + irq_set_status_flags(irq, IRQ_NOAUTOEN | IRQ_DISABLE_UNLAZY); > + ret = request_irq(irq, vgic_v4_doorbell_handler, > + 0, "vcpu", vcpu); > + if (ret) { > + kvm_err("failed to allocate vcpu IRQ%d\n", irq); > + /* > + * Trick: adjust the number of vpes so we know > + * how many to nuke on teardown... > + */ > + dist->its_vm.nr_vpes = i; > + break; > + } > + } > + > + if (ret) > + vgic_v4_teardown(kvm); > + > return ret; > } > > @@ -73,10 +112,19 @@ int vgic_v4_init(struct kvm *kvm) > void vgic_v4_teardown(struct kvm *kvm) > { > struct its_vm *its_vm = &kvm->arch.vgic.its_vm; > + int i; > > if (!its_vm->vpes) > return; > > + for (i = 0; i < its_vm->nr_vpes; i++) { > + struct kvm_vcpu *vcpu = kvm_get_vcpu(kvm, i); > + int irq = its_vm->vpes[i]->irq; > + > + irq_clear_status_flags(irq, IRQ_NOAUTOEN | IRQ_DISABLE_UNLAZY); > + free_irq(irq, vcpu); > + } > + > its_free_vcpu_irqs(its_vm); > kfree(its_vm->vpes); > its_vm->nr_vpes = 0; >