From patchwork Thu Mar 15 20:30:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 131868 Delivered-To: patch@linaro.org Received: by 10.46.84.17 with SMTP id i17csp1579561ljb; Thu, 15 Mar 2018 13:33:40 -0700 (PDT) X-Google-Smtp-Source: AG47ELuLAL8u40uuVWL4Fpv0GvoOlRnMyOaGV2CCXOE0Cfa4G5tb0teNZdpRNWZVT9rGXB3OF9dE X-Received: by 10.36.116.130 with SMTP id o124mr8364306itc.30.1521146019983; Thu, 15 Mar 2018 13:33:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521146019; cv=none; d=google.com; s=arc-20160816; b=Z5BguZEN7D3tYpfjBV4L5OM7CNhkWw9I2xuVTJU1QcHgZGuc8809mCJBSNAvHFnT0g lQfVKA0I6rxtbdlHYEQsy25vb0vE0/vdeIpWgFK6MFOXyAUkU/mhWdavfmEtICH9GHWn JmEV3P2K4rzrvFPqj9hUdeSGXyy2x+Z61jS7CHuY/UWSUyuXkk6Nx9Jx3zFXglP1iaCg PJxQzedLKAnU6RU7AI5GHtpQvwj3v82IpXMMFcdwVnlUKNUcDJ8SafEMKLS/c7QwjeR6 F5vODw0UnZM7qw7LWUVddTpKuHtfoLYgIBJRhCk0oPfp4Lhifb08atax2ZzOcsV3DSYx u+cA== 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 :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:cc:references:in-reply-to:message-id:date:to :from:dkim-signature:arc-authentication-results; bh=8iMV5FnSLUoYqgNdLv/7Wi3fCiGwIIyOzLH//txZhp4=; b=mFG2JJvnwXD6TpbF3yXcidnaIsPf1ujUUDIeGbzmqqAO/CEC7URt3dTiIeEA0270PU IuIPvKSnoUMxgJya4XTzGd7GO+Qo4fC8HTNdAC/T0qGaUbjduLgGV70/bznhohr6QGpX AfhVWon9dfMDLXjHQmFBfIbKSnPvLwB23NMvGFKkD4IaAcQbG2KNos15g4u7aNBAk5sm bLQTDrGqGOI43zXPu/zFbPF3PskzLAIYB++2bJUoNzPC1tI5L077T+pqer4azcvMhlR1 i9kQOCWbdx6dLlI4SHk+G/eb14CZ6ZfsIj4r82gjnGhcSlxa2eLiXMCegLiLp9yq4kEC GrMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=TvRKkqdi; 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 a63si3966596iog.38.2018.03.15.13.33.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 15 Mar 2018 13:33:39 -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=TvRKkqdi; 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.84_2) (envelope-from ) id 1ewZX3-0003L1-0u; Thu, 15 Mar 2018 20:31:25 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ewZX1-0003IZ-T6 for xen-devel@lists.xenproject.org; Thu, 15 Mar 2018 20:31:23 +0000 X-Inumbo-ID: cfa7ff02-288f-11e8-9728-bc764e045a96 Received: from mail-wr0-x241.google.com (unknown [2a00:1450:400c:c0c::241]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id cfa7ff02-288f-11e8-9728-bc764e045a96; Thu, 15 Mar 2018 21:31:17 +0100 (CET) Received: by mail-wr0-x241.google.com with SMTP id h2so9562741wre.12 for ; Thu, 15 Mar 2018 13:31:22 -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=j0JmgH8qTWKZVGx/NoY3dBrICppNCnx3PQXmSeG5ALw=; b=TvRKkqdi1G2bPDVWziX9vZjedYxwRFrdQt/qrjuiYT8MphklyxHbmjf7IR7TSJDTAL TCztNKOewV7NKhjYtPjr41sPSnOVK6HcFSiyNQ6XZyFUHrVG5Rnt6mWTg0VGmb0ngMMh TpEq3bwHMz+1SmTQ3LrVg3tvp2QXGaE4aQZag= 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=j0JmgH8qTWKZVGx/NoY3dBrICppNCnx3PQXmSeG5ALw=; b=G+1b1L6ceeT8nNmJMR+CaPYegtKdPzE9d/qRTZNXcpGoyaGOaa0ytHjRstm63oGppv pbNzIPKivu4EkCcP+BFZWKBIS37kd6JJwPnUEL7RL/ZwhUcbiOQFwmcBlDvmin+2S02v 4o/RMrY5VhBM8XDIjXJLJl/DGIzpwAFSs168waFRgAtxhUDslAWiEI1yCbq3dsUvbT3I QmZK/v+QoPDuJtaXIuQtJP+u2NF8SgCMz/8zirqsYcYKvz9fPlemN8b9M4UkqRG9xv91 whhfWDzhqlgvrPEOsL6fnIF0wtV2spFWh3HT+ac6KFbSn++d2IGWmrenjcpIm9sLdbIL I8XQ== X-Gm-Message-State: AElRT7HzYH4Ai/uPrqTxCa3Na5ONZTFBF1duGF0bzE8q3pfgntEMf5K0 lPaN6/BHAJNyLfS3x3OMh6rtng== X-Received: by 10.223.155.129 with SMTP id d1mr8949385wrc.8.1521145881347; Thu, 15 Mar 2018 13:31:21 -0700 (PDT) Received: from e104803-lin.lan (mail.andrep.de. [217.160.17.100]) by smtp.gmail.com with ESMTPSA id w125sm3217102wmw.20.2018.03.15.13.31.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 15 Mar 2018 13:31:20 -0700 (PDT) From: Andre Przywara To: Stefano Stabellini , Julien Grall Date: Thu, 15 Mar 2018 20:30:20 +0000 Message-Id: <20180315203050.19791-16-andre.przywara@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180315203050.19791-1-andre.przywara@linaro.org> References: <20180315203050.19791-1-andre.przywara@linaro.org> Cc: xen-devel@lists.xenproject.org Subject: [Xen-devel] [PATCH v2 15/45] ARM: new VGIC: Add acccessor to new struct vgic_irq instance X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , 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 --- Changelog v1 ... v2: - reorder header file inclusion xen/arch/arm/vgic/vgic.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++ xen/arch/arm/vgic/vgic.h | 41 ++++++++++++++++ 2 files changed, 165 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..d9d285c361 --- /dev/null +++ b/xen/arch/arm/vgic/vgic.c @@ -0,0 +1,124 @@ +/* + * 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. + */ +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(); +} + +/** + * 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. + */ +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: + */