From patchwork Wed Sep 6 12:26:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 9940551 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0ABB260350 for ; Wed, 6 Sep 2017 12:26:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D300F28BC0 for ; Wed, 6 Sep 2017 12:26:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C7AE428BC3; Wed, 6 Sep 2017 12:26:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 105D528BC0 for ; Wed, 6 Sep 2017 12:26:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753542AbdIFM02 (ORCPT ); Wed, 6 Sep 2017 08:26:28 -0400 Received: from mail-wm0-f53.google.com ([74.125.82.53]:38593 "EHLO mail-wm0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753326AbdIFM00 (ORCPT ); Wed, 6 Sep 2017 08:26:26 -0400 Received: by mail-wm0-f53.google.com with SMTP id 187so30360205wmn.1 for ; Wed, 06 Sep 2017 05:26:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=tLWFowIDT49COxsjJLe0SMUb3CmTF6ZLlwa7WjHZWW4=; b=JIFYlmgYKNefpyOVc62bv/K0jX5BtOg4oKiPqlYKbkq//6kTdofu6v90fKfPVEp2u+ cZBofrR2+MUERnWVzeijeYYUcjtStzeZDi9acYgPPjSLvSKInG9CCe90nI3DeCQtq0k3 7NKlCgNnPZ8omA8TElRhbIDAoJYyt+Ep590a4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=tLWFowIDT49COxsjJLe0SMUb3CmTF6ZLlwa7WjHZWW4=; b=lOqE21D5dOQFVxWAKCzWc/2eluT0DKvweiNQSdN/hhZa5mwybU/wNIwQKKtYbnuA5X cNS9x0RsPgtIlUjPB6R7JnfvBxbE6b6QELHxSnZZwglm48GZTI389Pc2U2GVYD6DFOws v+OtDT45Msj5W9tkr/p34JBNNEJbp5yFStePwqETfuuqO1/2sI8t5Me4KBjsB7r/CIjr MyOG3QwtCE/cRHtyEkKmbwKwgVFxoMvy2tpQUx08PwQ1e0KUxfQb8WRx+tRIS3x99IhU eVWe8jJlx12jT/fQNPdSXp61IvOtBhI7zpNdyS5bdcDucvFZMDNoV6H0ydlF9TfStEHp 0eWg== X-Gm-Message-State: AHPjjUgzaJVwrRE2KKvNwzsfSs0a+XEX+nylqdyK8+QGE5dcArPqDGku Cl6bTnAlbfCaOPgB X-Google-Smtp-Source: ADKCNb73pLLrvDpB056fYMo7Rhr229z6qxWUsnn7Alx0omUhWfHl08GBpX6bvEHm924hh6yo2FL6jg== X-Received: by 10.80.195.91 with SMTP id q27mr5869402edb.144.1504700784507; Wed, 06 Sep 2017 05:26:24 -0700 (PDT) Received: from localhost.localdomain (xd93ddc2d.cust.hiper.dk. [217.61.220.45]) by smtp.gmail.com with ESMTPSA id e12sm1251954edm.85.2017.09.06.05.26.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 06 Sep 2017 05:26:23 -0700 (PDT) From: Christoffer Dall To: kvmarm@lists.cs.columbia.edu, Eric Auger , Marc Zyngier Cc: Andre Przywara , linux-arm-kernel@lists.infradead.org, kvm@vger.kernel.org, Christoffer Dall Subject: [PATCH v3 2/5] KVM: arm/arm64: vgic: restructure kvm_vgic_(un)map_phys_irq Date: Wed, 6 Sep 2017 14:26:09 +0200 Message-Id: <20170906122612.18050-3-cdall@linaro.org> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170906122612.18050-1-cdall@linaro.org> References: <20170906122612.18050-1-cdall@linaro.org> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Auger We want to reuse the core of the map/unmap functions for IRQ forwarding. Let's move the computation of the hwirq in kvm_vgic_map_phys_irq and pass the linux IRQ as parameter. The host_irq is added to struct vgic_irq because it is needed in later patches which manipulate the physical GIC state to support forwarded IRQs. We introduce kvm_vgic_map/unmap_irq which take a struct vgic_irq handle as a parameter. Signed-off-by: Eric Auger Signed-off-by: Christoffer Dall Acked-by: Marc Zyngier --- include/kvm/arm_vgic.h | 8 ++++--- virt/kvm/arm/arch_timer.c | 24 +------------------ virt/kvm/arm/vgic/vgic.c | 60 +++++++++++++++++++++++++++++++++++------------ 3 files changed, 51 insertions(+), 41 deletions(-) diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 34dba51..53f631b 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -116,6 +116,7 @@ struct vgic_irq { bool hw; /* Tied to HW IRQ */ struct kref refcount; /* Used for LPIs */ u32 hwintid; /* HW INTID number */ + unsigned int host_irq; /* linux irq corresponding to hwintid */ union { u8 targets; /* GICv2 target VCPUs mask */ u32 mpidr; /* GICv3 target VCPU */ @@ -307,9 +308,10 @@ void kvm_vgic_init_cpu_hardware(void); int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, bool level, void *owner); -int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, u32 virt_irq, u32 phys_irq); -int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq); -bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq); +int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, + u32 vintid); +int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid); +bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid); int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index 2a5f877..c4fa675 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c @@ -649,9 +649,6 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) { struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); - struct irq_desc *desc; - struct irq_data *data; - int phys_irq; int ret; if (timer->enabled) @@ -669,26 +666,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) return -EINVAL; } - /* - * Find the physical IRQ number corresponding to the host_vtimer_irq - */ - desc = irq_to_desc(host_vtimer_irq); - if (!desc) { - kvm_err("%s: no interrupt descriptor\n", __func__); - return -EINVAL; - } - - data = irq_desc_get_irq_data(desc); - while (data->parent_data) - data = data->parent_data; - - phys_irq = data->hwirq; - - /* - * Tell the VGIC that the virtual interrupt is tied to a - * physical interrupt. We do that once per VCPU. - */ - ret = kvm_vgic_map_phys_irq(vcpu, vtimer->irq.irq, phys_irq); + ret = kvm_vgic_map_phys_irq(vcpu, host_vtimer_irq, vtimer->irq.irq); if (ret) return ret; diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c index fed717e..9d557efd 100644 --- a/virt/kvm/arm/vgic/vgic.c +++ b/virt/kvm/arm/vgic/vgic.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include "vgic.h" @@ -403,38 +405,66 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, return 0; } -int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, u32 virt_irq, u32 phys_irq) +/* @irq->irq_lock must be held */ +static int kvm_vgic_map_irq(struct kvm_vcpu *vcpu, struct vgic_irq *irq, + unsigned int host_irq) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, virt_irq); + struct irq_desc *desc; + struct irq_data *data; - BUG_ON(!irq); - - spin_lock(&irq->irq_lock); + /* + * Find the physical IRQ number corresponding to @host_irq + */ + desc = irq_to_desc(host_irq); + if (!desc) { + kvm_err("%s: no interrupt descriptor\n", __func__); + return -EINVAL; + } + data = irq_desc_get_irq_data(desc); + while (data->parent_data) + data = data->parent_data; irq->hw = true; - irq->hwintid = phys_irq; + irq->host_irq = host_irq; + irq->hwintid = data->hwirq; + return 0; +} + +/* @irq->irq_lock must be held */ +static inline void kvm_vgic_unmap_irq(struct vgic_irq *irq) +{ + irq->hw = false; + irq->hwintid = 0; +} + +int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, + u32 vintid) +{ + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid); + int ret; + BUG_ON(!irq); + + spin_lock(&irq->irq_lock); + ret = kvm_vgic_map_irq(vcpu, irq, host_irq); spin_unlock(&irq->irq_lock); vgic_put_irq(vcpu->kvm, irq); - return 0; + return ret; } -int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int virt_irq) +int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid) { struct vgic_irq *irq; if (!vgic_initialized(vcpu->kvm)) return -EAGAIN; - irq = vgic_get_irq(vcpu->kvm, vcpu, virt_irq); + irq = vgic_get_irq(vcpu->kvm, vcpu, vintid); BUG_ON(!irq); spin_lock(&irq->irq_lock); - - irq->hw = false; - irq->hwintid = 0; - + kvm_vgic_unmap_irq(irq); spin_unlock(&irq->irq_lock); vgic_put_irq(vcpu->kvm, irq); @@ -772,9 +802,9 @@ void vgic_kick_vcpus(struct kvm *kvm) } } -bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq) +bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid) { - struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, virt_irq); + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid); bool map_is_active; spin_lock(&irq->irq_lock);