From patchwork Mon Mar 5 16:03:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 130671 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp2853780lja; Mon, 5 Mar 2018 08:07:10 -0800 (PST) X-Google-Smtp-Source: AG47ELvJ3f+h/vT+PLPa/DyrkAJgF2edLsfgsnwfJfK5XZzoTK7KIPIZ7a8yH6SsU+LI+jE3LY93 X-Received: by 10.107.82.1 with SMTP id g1mr18730192iob.203.1520266029904; Mon, 05 Mar 2018 08:07:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520266029; cv=none; d=google.com; s=arc-20160816; b=bvj1uzbIXa7yH3rzVsvKA+s8mPK7HeOOJtMfnRBUb5VHrIWnvrSbvpsI8boJa/POdP Qxa6rl2dU57yCim1Xb28aMklErASlTMGXQ1YiWoPt5rAJfexLobelN9syPneV1l+HwPX v3oNNvNWpt0Z1+BoDR5gHWdcAZ+6SpdpfXqsr/KpoA+gMKhAfw01h5Q5CIgHChVOE5jb xpL0LbNLvlOiDl0IOalt3vv60pRO6TxbgVMnDVHY0soVLj3RsOpcMGW9gLtt0OborXXL Cc6NcqUn4foQjWcVIlyFD5v7RhdnUsrivZ54nynGVvx6GSSSO9iep/GSFguAGX7OwWjf dX1w== 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=pdkuV7armqpSaYl7PlDZxdzHqnRWCcvWbNPd8yOlGAM=; b=FXWhDkuz6RiizalxKR9dhmQmhmvwKWEMuI8r6rArQJ6H3qvmfcuNWv+NL9Q+ZOyQ1f bkiqXH6jzDig7EURyvynaN+5qtGhFYTZ/90a/G5yy9VZ/k0wHLlbuslb0sy6PU7JKalq RIFX4jbnqlom3kqPWTu4xYs3yQ3HN4urSenpBeGPj81marO0zn0rgsfpwVt2YDeNZ1ps CVz33oubeYXc/tSDhcmoZfIlx1oQFp59hhN5BOKbG66wa4V0+ekAfpmzXFspulKn6NWF kPJd5aba+RQEM3BsJeP2YmgU/dkigPeBhuaFBitdmAT8mkStOOTkJlc0GbRnYcNmJ7Mc ZrFg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=MOw37BmV; 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 x6si5905924itd.47.2018.03.05.08.07.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 05 Mar 2018 08:07:09 -0800 (PST) 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=MOw37BmV; 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 1essbd-0007sQ-N6; Mon, 05 Mar 2018 16:04:53 +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 1essbc-0007p3-Mt for xen-devel@lists.xenproject.org; Mon, 05 Mar 2018 16:04:52 +0000 X-Inumbo-ID: c8646aab-208e-11e8-ba59-bc764e045a96 Received: from mail-wm0-x244.google.com (unknown [2a00:1450:400c:c09::244]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id c8646aab-208e-11e8-ba59-bc764e045a96; Mon, 05 Mar 2018 17:03:46 +0100 (CET) Received: by mail-wm0-x244.google.com with SMTP id t6so16611086wmt.5 for ; Mon, 05 Mar 2018 08:04:51 -0800 (PST) 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=iTLdDXuTZ7Vjb1HbZpqUqqrhF8EHtuny5yz+yCtcYgs=; b=MOw37BmV0CVH1ZhK4ywjZbBAcUs1eK5X1l1tt71VzJmPKrRjAeM95nKr7pGnhXErQN tkaIwIeF6iwQQnGd22UmuaBRdfEnYyf4fau7lTb/jIaDhgaT9yXbhdorC88Ut3U4BMZ5 ySoDFJJcYyf4V+zLzaC58ZWOiuBqjdNA8NvM0= 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=iTLdDXuTZ7Vjb1HbZpqUqqrhF8EHtuny5yz+yCtcYgs=; b=qnnkAhD0E0YfkKxVIQCotDnMGx1PnxbSHokoxu1QHKTBighqsT6XSDng555nuswz7q n4k5VRDAjHxnNDQbHvhI2Bm+GxR/cccGmu74Le76E2i4+qBqLQwjYICd13NR777UbmaQ ie3SWBdpFq99WKQ0WNhmtjKv4jayVovBlXuxPEd02YBb8RGyZNVh2rt0AN6Aa5Ln91t+ kZOB/I7zzG3nQALI+Fm8ti73C+dPpvFw5TuR17GNsAL2+hRaI+rVjggF6xXHmGLL9IXV 2Szln/lvj3tDniEknT3MReXaAR6f8gEt9OkPtRVjxzr70kskmRVe8aa60IJ9qJ0SScUW xrXg== X-Gm-Message-State: AElRT7GL1VV0UIgjarmTMftY6HXx7LG6uuALVzUzFJrL0Rq2I9qVOwrH WZjEMGIeJk6rmTxVSCOpsNeHew== X-Received: by 10.28.135.142 with SMTP id j136mr9220374wmd.33.1520265890569; Mon, 05 Mar 2018 08:04:50 -0800 (PST) Received: from e104803-lin.lan (mail.andrep.de. [217.160.17.100]) by smtp.gmail.com with ESMTPSA id y6sm6574381wmy.14.2018.03.05.08.04.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 05 Mar 2018 08:04:50 -0800 (PST) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Mon, 5 Mar 2018 16:03:46 +0000 Message-Id: <20180305160415.16760-29-andre.przywara@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180305160415.16760-1-andre.przywara@linaro.org> References: <20180305160415.16760-1-andre.przywara@linaro.org> Cc: xen-devel@lists.xenproject.org Subject: [Xen-devel] [PATCH 28/57] 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 RFC ... v1: - add kernel-doc comments to exported functions - adapt to previous changes (new_vgic.h, arch_vcpu member name) - use ASSERT_UNREACHABLE 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..ace30f78d0 --- /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: + */