From patchwork Wed Mar 21 16:32:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 132243 Delivered-To: patch@linaro.org Received: by 10.46.84.29 with SMTP id i29csp2357908ljb; Wed, 21 Mar 2018 09:36:41 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/0c4eSPiwMnHa+EnVmSJejYdL7I0Ook0thBYSKkJin3Hsxa0+8wHXIpkpFmwcwudGlati7 X-Received: by 2002:a24:f246:: with SMTP id j67-v6mr4894686ith.90.1521650107345; Wed, 21 Mar 2018 09:35:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521650107; cv=none; d=google.com; s=arc-20160816; b=oHPrJsm/lQH55viUEbyDTcTsQPVh64ZucL2CqXICYmieD/b4fpjb2lVS4/ibqzDBjQ 9Lr4fz7Xmx8YxESgWwHPZ92kbrsxnjn9PnDsm6+PugNeqm6pGgSXGHJuRSihNTNn91Dh VAHoXAn/rd2PajK5bUrAdaLNY7EXlRUH/xDWHRS6l1sxfYzNlklsxmrrh69j5fuZ10XE 2SLhEU1n9t5GtAcKdewZsKdMVxU5JA2UHokPvtAS7oI2/S2TNodR1mXtwluUW3tlgO3c mtih2jDfUx8eLB1RBoSPL2UWAvREgx+q7My374MxTCZQyFhpT/2F2YZYDR02IEA7WTPe 0TTA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:references:in-reply-to:message-id:date:to:from :dkim-signature:arc-authentication-results; bh=4ebOFkyQq5nFSB15PJg4KFJJ2zIj/FGQtUajA7ukrL0=; b=tmUvP0EJu1DMRogUkMH2doSZDISxe7ylsWT/QNpd8/zcb+4QNcVvzPxatO8WLXsNE3 jsXvvtbrVoilQuugMUVJZVtuz2AAFTQP4XnBus3nTY/b0+eCHBx7wQFZRqm5Bk+D6ldi zo1e6SdKZoJ1Ed2X4fn64B49xjWAV6bM2fe/PI6lEpKwQihxtpWtv6vyQ1S8ZwC6t3sF V/1DfjI6Vk2dZajZTFs1KRBltINOWXJonnJXf0XMLUWNs56ZUsLeutCdUhLYOpbVaQiA pjthb2CpxOTBdzln4NYmyKesKhYyuE1NXwE5AUdSirYzaspTMH54v0rLksEQZyEy0P/5 1JcA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=HFxOAzZr; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id p187-v6si3496810itp.51.2018.03.21.09.35.07 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 21 Mar 2018 09:35:07 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=HFxOAzZr; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1eygfd-00027y-21; Wed, 21 Mar 2018 16:33:01 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1eygfc-00026o-7S for xen-devel@lists.xenproject.org; Wed, 21 Mar 2018 16:33:00 +0000 X-Inumbo-ID: 7adf377d-2d25-11e8-9728-bc764e045a96 Received: from mail-wm0-x243.google.com (unknown [2a00:1450:400c:c09::243]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id 7adf377d-2d25-11e8-9728-bc764e045a96; Wed, 21 Mar 2018 17:32:44 +0100 (CET) Received: by mail-wm0-x243.google.com with SMTP id t6so11002355wmt.5 for ; Wed, 21 Mar 2018 09:32:58 -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=pb+lFVnLmibx8iRrLO0D4BtbZS8Rty6LQ+4Pq/SfDk0=; b=HFxOAzZrXUIgauG1KkKScWrtkkH+soXEYzdPLCdO+KCu0LU4UxgZ86sTVezYHuSXzN aP8M9nsQJorl82y2gncBvfM7iIB6YEllPGkIbqDrwpDe4oqLnrHC8UyRftaP3QzeHyPt NnW9SCGflOhPR3irDHkETJI6apR4D8hZ1Zczo= 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=pb+lFVnLmibx8iRrLO0D4BtbZS8Rty6LQ+4Pq/SfDk0=; b=HhTs7Xtc72QNCCS1B3zXidIu25chbHoF+tIN8TtSe3QmbLauN6Ebz2yJB60N+p4QkO raitxuMJtIlk7e6d3/2QmMtilfX4KX7yw1Z5rmxBYxFrvrvi2wPuxw9sG/bpUR6DIaEr zJ4MnMGLPO6TM3nWAaXHQY82YLbCEKv9jjBqjqoFVmACB/5h3GrRzYLSXfSz0tTpkdY4 fc9lfZzrEGabmJvwBAidVexSbqcRS8Er1+NoP3mK0ACmuPyA9hBRioHSb097MiZPaSmz ScEQbdZ9JfzfulUm6ejJeXxlgDD/Jx7Df8ZWwt4uZInS+365U5fgJDfbCIIVvs4OlCJc mQog== X-Gm-Message-State: AElRT7FvsuDWELkD42PIs+PAPYessrgJKylC8ORf1gU8OCtyyH55UNXi Asn4838+iPv+QgMedLYL/kg26w== X-Received: by 10.28.190.19 with SMTP id o19mr3190985wmf.53.1521649977448; Wed, 21 Mar 2018 09:32:57 -0700 (PDT) Received: from e104803-lin.lan (mail.andrep.de. [217.160.17.100]) by smtp.gmail.com with ESMTPSA id n64sm4423724wmd.11.2018.03.21.09.32.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 21 Mar 2018 09:32:56 -0700 (PDT) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Wed, 21 Mar 2018 16:32:05 +0000 Message-Id: <20180321163235.12529-10-andre.przywara@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180321163235.12529-1-andre.przywara@linaro.org> References: <20180321163235.12529-1-andre.przywara@linaro.org> Subject: [Xen-devel] [PATCH v3 09/39] ARM: new VGIC: Add accessor to new struct vgic_irq instance X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: xen-devel@lists.xenproject.org, Andre Przywara MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" The new VGIC implementation centers around a struct vgic_irq instance per virtual IRQ. Provide a function to retrieve the right instance for a given IRQ number and (in case of private interrupts) the right VCPU. This also includes the corresponding put function, which does nothing for private interrupts and SPIs, but handles the ref-counting for LPIs. This is based on Linux commit 64a959d66e47, written by Christoffer Dall. Signed-off-by: Andre Przywara Acked-by: Julien Grall Acked-by: Stefano Stabellini --- Changelog v2 ... v3: - extend comments to note preliminary nature of vgic_get_lpi() Changelog v1 ... v2: - reorder header file inclusion xen/arch/arm/vgic/vgic.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++ xen/arch/arm/vgic/vgic.h | 41 +++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 xen/arch/arm/vgic/vgic.c create mode 100644 xen/arch/arm/vgic/vgic.h diff --git a/xen/arch/arm/vgic/vgic.c b/xen/arch/arm/vgic/vgic.c new file mode 100644 index 0000000000..a818e382b1 --- /dev/null +++ b/xen/arch/arm/vgic/vgic.c @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2015, 2016 ARM Ltd. + * Imported from Linux ("new" KVM VGIC) and heavily adapted to Xen. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "vgic.h" + +/* + * Iterate over the VM's list of mapped LPIs to find the one with a + * matching interrupt ID and return a reference to the IRQ structure. + * + * TODO: This is more documentation of how it should be done. A list is + * not a good data structure for Dom0's LPIs, it merely serves as an + * example here how to properly do the locking, allocation and refcounting. + * So lpi_list_head should be replaced with something more appropriate. + */ +static struct vgic_irq *vgic_get_lpi(struct domain *d, u32 intid) +{ + struct vgic_dist *dist = &d->arch.vgic; + struct vgic_irq *irq = NULL; + + spin_lock(&dist->lpi_list_lock); + + list_for_each_entry( irq, &dist->lpi_list_head, lpi_list ) + { + if ( irq->intid != intid ) + continue; + + /* + * This increases the refcount, the caller is expected to + * call vgic_put_irq() later once it's finished with the IRQ. + */ + vgic_get_irq_kref(irq); + goto out_unlock; + } + irq = NULL; + +out_unlock: + spin_unlock(&dist->lpi_list_lock); + + return irq; +} + +/** + * vgic_get_irq() - obtain a reference to a virtual IRQ + * @d: The domain the virtual IRQ belongs to. + * @vcpu: For private IRQs (SGIs, PPIs) the virtual CPU this IRQ + * is associated with. Will be ignored for SPIs and LPIs. + * @intid: The virtual IRQ number. + * + * This looks up the virtual interrupt ID to get the corresponding + * struct vgic_irq. It also increases the refcount, so any caller is expected + * to call vgic_put_irq() once it's finished with this IRQ. + * + * Return: The pointer to the requested struct vgic_irq. + */ +struct vgic_irq *vgic_get_irq(struct domain *d, struct vcpu *vcpu, + u32 intid) +{ + /* SGIs and PPIs */ + if ( intid <= VGIC_MAX_PRIVATE ) + return &vcpu->arch.vgic.private_irqs[intid]; + + /* SPIs */ + if ( intid <= VGIC_MAX_SPI ) + return &d->arch.vgic.spis[intid - VGIC_NR_PRIVATE_IRQS]; + + /* LPIs */ + if ( intid >= VGIC_MIN_LPI ) + return vgic_get_lpi(d, intid); + + ASSERT_UNREACHABLE(); + + return NULL; +} + +/** + * vgic_put_irq() - drop the reference to a virtual IRQ + * @d: The domain the virtual IRQ belongs to. + * @irq: The pointer to struct vgic_irq, as obtained from vgic_get_irq(). + * + * This drops the reference to a virtual IRQ. It decreases the refcount + * of the pointer, so dynamic IRQs can be freed when no longer needed. + * This should always be called after a vgic_get_irq(), though the reference + * can be deliberately held for longer periods, if needed. + * + * TODO: A linked list is not a good data structure for LPIs in Dom0. + * Replace this with proper data structure once we get proper LPI support. + */ +void vgic_put_irq(struct domain *d, struct vgic_irq *irq) +{ + struct vgic_dist *dist = &d->arch.vgic; + + if ( irq->intid < VGIC_MIN_LPI ) + return; + + spin_lock(&dist->lpi_list_lock); + if ( !atomic_dec_and_test(&irq->refcount) ) + { + spin_unlock(&dist->lpi_list_lock); + return; + }; + + list_del(&irq->lpi_list); + dist->lpi_list_count--; + spin_unlock(&dist->lpi_list_lock); + + xfree(irq); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/arm/vgic/vgic.h b/xen/arch/arm/vgic/vgic.h new file mode 100644 index 0000000000..a3befd386b --- /dev/null +++ b/xen/arch/arm/vgic/vgic.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015, 2016 ARM Ltd. + * Imported from Linux ("new" KVM VGIC) and heavily adapted to Xen. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __XEN_ARM_VGIC_VGIC_H__ +#define __XEN_ARM_VGIC_VGIC_H__ + +struct vgic_irq *vgic_get_irq(struct domain *d, struct vcpu *vcpu, + u32 intid); +void vgic_put_irq(struct domain *d, struct vgic_irq *irq); + +static inline void vgic_get_irq_kref(struct vgic_irq *irq) +{ + if ( irq->intid < VGIC_MIN_LPI ) + return; + + atomic_inc(&irq->refcount); +} + +#endif + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */