From patchwork Tue Feb 6 17:09:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 127063 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp3107919ljc; Tue, 6 Feb 2018 09:11:38 -0800 (PST) X-Google-Smtp-Source: AH8x227i9PDMincV7mqkf8NUMpFyEytvgfA3GvgoFk8eakS6LCEkzdVI1OgA3sjrM48WuPKbK9Lp X-Received: by 10.36.17.208 with SMTP id 199mr3963782itf.103.1517937098516; Tue, 06 Feb 2018 09:11:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517937098; cv=none; d=google.com; s=arc-20160816; b=xjX+k+RCwl1j3wx7YvgnFO3fxWqix/Rq2zPw6PvjI5PDWu5ynX1vcn/AtS9xcIrlg1 ca51ZsSIN44l8hUJijXvVD54P2+xb5MoRtdMR17pZ4VS+VPxJ/opHQ34fm/golI4hXZT 1bfMss7KwhhIrOtaPcfMWj5kzT7FAZQSHsEHQKmGs6VqR8Q6QiLMzaM4SZ20SCCzodqt Z5BwFGCHaSR1SEeH+kSArPjdKCFPmX3O+LzaCJBjm2H6+A3c2QQiWzG3WIfE8NS5gqMp RcsseKzvF/tjXbL47oSurEOcZIfNfigfq4Hos/N+DRsh+A90q91rvEETjBKFuRTy0Kqc LV+w== 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=k7OGHahqTUm7JHm7ZkTkSArW+dpo43MZXAVMVHZq+bA=; b=UJNKhLBrernBw0dYJ3VG4ueWuUE4o90mQHz9h7O3iKZS1NVR8q762Y+ddzCJbHdiiV D01FbWRduwYZ/5lGcGAtBGEGg/4EhKDnvrpJBmwuISUNMq+gtoOg09YIManLDme++jV0 Aen+g69t7CV/QGPTTUa4WzJCBqX/ELFEtew5Tf2WgY5G9+DYQTYubRHzVm/L2IfpZM1I qgAuIZvg8TyC52X4Fo+VtFD9jlKP+8ErOcD+VmpVae3FLPMalm0rrM9HRVCSem48h/VX ro9SigcXHmXqHetfalpFUXLbiU0LUVJ2HXDsdxr5M2b93KOzqeJmz6i7RbqX1y/yvs4f BY9Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=I5u1J7wu; 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 l13si8145016ioc.48.2018.02.06.09.11.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 09:11:38 -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=I5u1J7wu; 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 1ej6kA-0003rO-Gh; Tue, 06 Feb 2018 17:09:18 +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 1ej6k8-0003pm-R5 for xen-devel@lists.xenproject.org; Tue, 06 Feb 2018 17:09:16 +0000 X-Inumbo-ID: 6765e030-0b60-11e8-ba59-bc764e045a96 Received: from mail-wr0-x243.google.com (unknown [2a00:1450:400c:c0c::243]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id 6765e030-0b60-11e8-ba59-bc764e045a96; Tue, 06 Feb 2018 18:08:52 +0100 (CET) Received: by mail-wr0-x243.google.com with SMTP id 35so2717458wrb.13 for ; Tue, 06 Feb 2018 09:09:15 -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=KdUjnUOeF65RItFACjj74TVsUR7Sjblqkkzf+zynHm0=; b=I5u1J7wuPWQf9oPH5KI5jVmw/FakOwvN+w9CV88ZHwQDxDfDEpe96Gd/+ZVOSAYVdR RTCgOSrjy5UqlK/GeGqR8y6/l3iXhrx+yFYvdOE5LDqta4kD7NH3erRHsmoBv906qu4P IoO9b+1/FW+1bwfrDhomPR0n8jhUiU/d91FMg= 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=KdUjnUOeF65RItFACjj74TVsUR7Sjblqkkzf+zynHm0=; b=Zmrzx+BiCf6ITpvfYCNWddwDiRzpz6kEGsI8HHbbk/lByNYRLTswrepu1aNzZNs8+j Atw49DXNZ7yGsFp57b+4Ky001Zbm+YHC9UehIZl2HtPKgg9qT+ceYwBQn1iPCAwA/mGJ /rpOFKwUeOdfxF8LF5W8ipp7M+9q/g8n053EdAqlHPCuWjE4Kzebb164uOXZrPETihg1 SKt9VOEc6F0PuYjRkAyiSJZYuuW72e44oqEvj9VttJUiratMmPAnFpS3ee7ptdmk9f29 XZzIZ2ocBTn8zRfsL6OVlwVZx4tV3ct6hEYQkP5ZviBMmuzE1UqI6qggxvvc8HTCn7jw stEQ== X-Gm-Message-State: APf1xPAOvjgOWA9NdkUyjDPzpyEMx/HKv9TtuRLru25WLlpOPF9dNYjb EB55ywqkRCqXtDRS1tXf6w8GTg== X-Received: by 10.223.193.65 with SMTP id w1mr3201225wre.88.1517936954686; Tue, 06 Feb 2018 09:09:14 -0800 (PST) Received: from e104803-lin.lan (mail.andrep.de. [217.160.17.100]) by smtp.gmail.com with ESMTPSA id n2sm7885819wra.41.2018.02.06.09.09.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 06 Feb 2018 09:09:14 -0800 (PST) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Tue, 6 Feb 2018 17:09:00 +0000 Message-Id: <20180206170903.30637-6-andre.przywara@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180206170903.30637-1-andre.przywara@linaro.org> References: <20180206170903.30637-1-andre.przywara@linaro.org> Cc: xen-devel@lists.xenproject.org Subject: [Xen-devel] [PATCH v5 5/8] ARM: VGIC: factor out vgic_connect_hw_irq() 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" At the moment we happily access VGIC internal data structures like the rank and struct pending_irq in gic.c, which should be VGIC agnostic. Factor out a new function vgic_connect_hw_irq(), which allows a virtual IRQ to be connected to a hardware IRQ (using the hw bit in the LR). This removes said accesses to VGIC data structures and improves abstraction. One thing to note is that this changes the locking scheme slightly: we hold the rank lock for a shorter period of time, not covering some of the later lines, which deal with the "irq_desc" structure only. This should not have any adverse effect, but is a change in locking anyway. Signed-off-by: Andre Przywara Reviewed-by: Julien Grall --- xen/arch/arm/gic-vgic.c | 41 +++++++++++++++++++++++++++++++++++++++++ xen/arch/arm/gic.c | 44 ++++++++++---------------------------------- xen/include/asm-arm/vgic.h | 2 ++ 3 files changed, 53 insertions(+), 34 deletions(-) diff --git a/xen/arch/arm/gic-vgic.c b/xen/arch/arm/gic-vgic.c index 8221ae557c..820e464fc0 100644 --- a/xen/arch/arm/gic-vgic.c +++ b/xen/arch/arm/gic-vgic.c @@ -397,6 +397,47 @@ void gic_dump_vgic_info(struct vcpu *v) printk("Pending irq=%d\n", p->irq); } +int vgic_connect_hw_irq(struct domain *d, struct vcpu *v, unsigned int virq, + struct irq_desc *desc, bool connect) +{ + unsigned long flags; + /* + * Use vcpu0 to retrieve the pending_irq struct. Given that we only + * route SPIs to guests, it doesn't make any difference. + */ + struct vcpu *v_target = vgic_get_target_vcpu(d->vcpu[0], virq); + struct vgic_irq_rank *rank = vgic_rank_irq(v_target, virq); + struct pending_irq *p = irq_to_pending(v_target, virq); + int ret = 0; + + /* "desc" is optional when we disconnect an IRQ. */ + ASSERT(connect && desc); + + /* We are taking to rank lock to prevent parallel connections. */ + vgic_lock_rank(v_target, rank, flags); + + if ( connect ) + { + /* The VIRQ should not be already enabled by the guest */ + if ( !p->desc && + !test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) ) + p->desc = desc; + else + ret = -EBUSY; + } + else + { + if ( desc && p->desc != desc ) + ret = -EINVAL; + else + p->desc = NULL; + } + + vgic_unlock_rank(v_target, rank, flags); + + return ret; +} + /* * Local variables: * mode: C diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 4cb74d449e..968e46fabb 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -128,13 +128,7 @@ void gic_route_irq_to_xen(struct irq_desc *desc, unsigned int priority) int gic_route_irq_to_guest(struct domain *d, unsigned int virq, struct irq_desc *desc, unsigned int priority) { - unsigned long flags; - /* Use vcpu0 to retrieve the pending_irq struct. Given that we only - * route SPIs to guests, it doesn't make any difference. */ - struct vcpu *v_target = vgic_get_target_vcpu(d->vcpu[0], virq); - struct vgic_irq_rank *rank = vgic_rank_irq(v_target, virq); - struct pending_irq *p = irq_to_pending(v_target, virq); - int res = -EBUSY; + int ret; ASSERT(spin_is_locked(&desc->lock)); /* Caller has already checked that the IRQ is an SPI */ @@ -142,12 +136,9 @@ int gic_route_irq_to_guest(struct domain *d, unsigned int virq, ASSERT(virq < vgic_num_irqs(d)); ASSERT(!is_lpi(virq)); - vgic_lock_rank(v_target, rank, flags); - - if ( p->desc || - /* The VIRQ should not be already enabled by the guest */ - test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) ) - goto out; + ret = vgic_connect_hw_irq(d, NULL, virq, desc, true); + if ( ret ) + return ret; desc->handler = gic_hw_ops->gic_guest_irq_type; set_bit(_IRQ_GUEST, &desc->status); @@ -156,31 +147,19 @@ int gic_route_irq_to_guest(struct domain *d, unsigned int virq, gic_set_irq_type(desc, desc->arch.type); gic_set_irq_priority(desc, priority); - p->desc = desc; - res = 0; - -out: - vgic_unlock_rank(v_target, rank, flags); - - return res; + return 0; } /* This function only works with SPIs for now */ int gic_remove_irq_from_guest(struct domain *d, unsigned int virq, struct irq_desc *desc) { - struct vcpu *v_target = vgic_get_target_vcpu(d->vcpu[0], virq); - struct vgic_irq_rank *rank = vgic_rank_irq(v_target, virq); - struct pending_irq *p = irq_to_pending(v_target, virq); - unsigned long flags; + int ret; ASSERT(spin_is_locked(&desc->lock)); ASSERT(test_bit(_IRQ_GUEST, &desc->status)); - ASSERT(p->desc == desc); ASSERT(!is_lpi(virq)); - vgic_lock_rank(v_target, rank, flags); - if ( d->is_dying ) { desc->handler->shutdown(desc); @@ -198,19 +177,16 @@ int gic_remove_irq_from_guest(struct domain *d, unsigned int virq, */ if ( test_bit(_IRQ_INPROGRESS, &desc->status) || !test_bit(_IRQ_DISABLED, &desc->status) ) - { - vgic_unlock_rank(v_target, rank, flags); return -EBUSY; - } } + ret = vgic_connect_hw_irq(d, NULL, virq, desc, false); + if ( ret ) + return ret; + clear_bit(_IRQ_GUEST, &desc->status); desc->handler = &no_irq_type; - p->desc = NULL; - - vgic_unlock_rank(v_target, rank, flags); - return 0; } diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h index 22c8502c95..fda082395b 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -219,6 +219,8 @@ int vgic_v2_init(struct domain *d, int *mmio_count); int vgic_v3_init(struct domain *d, int *mmio_count); bool vgic_evtchn_irq_pending(struct vcpu *v); +int vgic_connect_hw_irq(struct domain *d, struct vcpu *v, unsigned int virq, + struct irq_desc *desc, bool connect); extern int domain_vgic_register(struct domain *d, int *mmio_count); extern int vcpu_vgic_free(struct vcpu *v);