From patchwork Tue Jan 13 14:25:21 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 42997 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f198.google.com (mail-lb0-f198.google.com [209.85.217.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id EA75320DE8 for ; Tue, 13 Jan 2015 14:27:55 +0000 (UTC) Received: by mail-lb0-f198.google.com with SMTP id p9sf1871955lbv.1 for ; Tue, 13 Jan 2015 06:27:55 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:cc:subject:precedence:list-id:list-unsubscribe:list-post :list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:sender:errors-to:x-original-sender :x-original-authentication-results:mailing-list:list-archive; bh=kmXDTMcl+qiSsA0oo/jsvtPvNm4NaQ4xai2UOQwMpdo=; b=TkgezBUyA37WP3uM6Gb6OfM4ZB8+YUwtjvaj3JMpmLphQOu+XBada8X1/BpEptK9Aq 3HdfExrAcBf00hOkF1r7SR+ucw/BJDve3PfAeUb7Tp0Qha2G7IRGN+MMaau9g9ZLuxrF HEShgzTHGXV5UqNLp8999pSm2f00wzoadN79CFziSbAB02rt8a501KF/7d+Ur1shUC4w mTsFFL1iBLWKIwmi1Cir5X3axk3Lf05UOCYzBk1mc3cDbK9L73AR/8L/3BCk+ai0aQxR IstrtQmycxX3dGUfMprPTN6shXJva6YNlTtJ3YkSug34ojazBYfKC52VbBZk3MNsk14j gF3A== X-Gm-Message-State: ALoCoQmk5z/HX3tCoBiJymhjaXOMr3GDn58gVPmiNMQy7sJU7Ntcn40w7A0aLxX9j1Qjzm3QW8Rw X-Received: by 10.152.37.193 with SMTP id a1mr2134824lak.3.1421159274972; Tue, 13 Jan 2015 06:27:54 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.21.201 with SMTP id x9ls851903lae.89.gmail; Tue, 13 Jan 2015 06:27:54 -0800 (PST) X-Received: by 10.152.5.132 with SMTP id s4mr42563687las.39.1421159274757; Tue, 13 Jan 2015 06:27:54 -0800 (PST) Received: from mail-la0-f44.google.com (mail-la0-f44.google.com. [209.85.215.44]) by mx.google.com with ESMTPS id v20si3134324laz.0.2015.01.13.06.27.54 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 13 Jan 2015 06:27:54 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.44 as permitted sender) client-ip=209.85.215.44; Received: by mail-la0-f44.google.com with SMTP id gd6so2902380lab.3 for ; Tue, 13 Jan 2015 06:27:54 -0800 (PST) X-Received: by 10.152.7.229 with SMTP id m5mr43024092laa.80.1421159274307; Tue, 13 Jan 2015 06:27:54 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.9.200 with SMTP id c8csp1398766lbb; Tue, 13 Jan 2015 06:27:53 -0800 (PST) X-Received: by 10.224.21.133 with SMTP id j5mr60067490qab.83.1421159267689; Tue, 13 Jan 2015 06:27:47 -0800 (PST) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id g6si26969950qga.61.2015.01.13.06.27.47 (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 13 Jan 2015 06:27:47 -0800 (PST) Received-SPF: none (google.com: xen-devel-bounces@lists.xen.org does not designate permitted sender hosts) client-ip=50.57.142.19; Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YB2Qf-0001KN-L7; Tue, 13 Jan 2015 14:26:45 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YB2Qe-0001Ih-IJ for xen-devel@lists.xenproject.org; Tue, 13 Jan 2015 14:26:44 +0000 Received: from [85.158.137.68] by server-13.bemta-3.messagelabs.com id A3/F5-27623-32B25B45; Tue, 13 Jan 2015 14:26:43 +0000 X-Env-Sender: julien.grall@linaro.org X-Msg-Ref: server-3.tower-31.messagelabs.com!1421159202!19301976!1 X-Originating-IP: [74.125.82.182] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 6.12.5; banners=-,-,- X-VirusChecked: Checked Received: (qmail 12044 invoked from network); 13 Jan 2015 14:26:43 -0000 Received: from mail-we0-f182.google.com (HELO mail-we0-f182.google.com) (74.125.82.182) by server-3.tower-31.messagelabs.com with RC4-SHA encrypted SMTP; 13 Jan 2015 14:26:43 -0000 Received: by mail-we0-f182.google.com with SMTP id w62so3164531wes.13 for ; Tue, 13 Jan 2015 06:26:42 -0800 (PST) X-Received: by 10.180.98.162 with SMTP id ej2mr3749659wib.39.1421159201283; Tue, 13 Jan 2015 06:26:41 -0800 (PST) Received: from chilopoda.uk.xensource.com. ([185.25.64.249]) by mx.google.com with ESMTPSA id ni15sm14513482wic.18.2015.01.13.06.26.39 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 13 Jan 2015 06:26:40 -0800 (PST) From: Julien Grall To: xen-devel@lists.xenproject.org Date: Tue, 13 Jan 2015 14:25:21 +0000 Message-Id: <1421159133-31526-13-git-send-email-julien.grall@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1421159133-31526-1-git-send-email-julien.grall@linaro.org> References: <1421159133-31526-1-git-send-email-julien.grall@linaro.org> Cc: stefano.stabellini@citrix.com, Julien Grall , tim@xen.org, ian.campbell@citrix.com Subject: [Xen-devel] [PATCH v3 12/24] xen/arm: Release IRQ routed to a domain when it's destroying X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: julien.grall@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.44 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Archive: Xen has to release IRQ routed to a domain in order to reuse later. Currently only SPIs can be routed to the guest so we only need to browse SPIs for a specific domain. Futhermore, a guest can crash and let the IRQ in an incorrect state (i.e has not being EOIed). Xen will have to reset the IRQ in order to be able to reuse the IRQ later. Introduce 2 new functions for release an IRQ routed to a domain: - release_guest_irq: upper level to retrieve the IRQ, call the GIC code and release the action - gic_remove_guest_irq: Check if we can remove the IRQ, and reset it if necessary Signed-off-by: Julien Grall --- Changes in v3: - Take the vgic rank lock to protect p->desc - Correctly check if the IRQ is disabled - Extend the check on the virq in release_guest_irq - Use vgic_get_target_vcpu to get the target vCPU - Remove spurious change Changes in v2: - Drop the desc->handler = &no_irq_type in release_irq as it's buggy if the IRQ is routed to Xen - Add release_guest_irq and gic_remove_guest_irq --- xen/arch/arm/gic.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ xen/arch/arm/irq.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ xen/arch/arm/vgic.c | 16 ++++++++++++++++ xen/include/asm-arm/gic.h | 4 ++++ xen/include/asm-arm/irq.h | 2 ++ 5 files changed, 116 insertions(+) diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 240870f..bb298e9 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -162,6 +162,52 @@ out: return res; } +/* 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; + + ASSERT(spin_is_locked(&desc->lock)); + ASSERT(test_bit(_IRQ_GUEST, &desc->status)); + ASSERT(p->desc == desc); + + vgic_lock_rank(v_target, rank, flags); + + /* If the IRQ is removed when the domain is dying, we only need to + * EOI the IRQ if it has not been done by the guest + */ + if ( d->is_dying ) + { + desc->handler->shutdown(desc); + if ( test_bit(_IRQ_INPROGRESS, &desc->status) ) + gic_hw_ops->deactivate_irq(desc); + clear_bit(_IRQ_INPROGRESS, &desc->status); + goto end; + } + + /* TODO: Handle eviction from LRs. For now, deny remove if the IRQ + * is inflight and not disabled. + */ + if ( test_bit(_IRQ_INPROGRESS, &desc->status) || + !test_bit(_IRQ_DISABLED, &desc->status) ) + return -EBUSY; + +end: + clear_bit(_IRQ_GUEST, &desc->status); + desc->handler = &no_irq_type; + + p->desc = NULL; + + vgic_unlock_rank(v_target, rank, flags); + + + return 0; +} + int gic_irq_xlate(const u32 *intspec, unsigned int intsize, unsigned int *out_hwirq, unsigned int *out_type) diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c index 0072347..ce5ae1a 100644 --- a/xen/arch/arm/irq.c +++ b/xen/arch/arm/irq.c @@ -504,6 +504,54 @@ free_info: return retval; } +int release_guest_irq(struct domain *d, unsigned int virq) +{ + struct irq_desc *desc; + struct irq_guest *info; + unsigned long flags; + struct pending_irq *p; + int ret; + + /* Only SPIs are supported */ + if ( virq < 32 || virq >= vgic_num_irqs(d) ) + return -EINVAL; + + p = irq_to_pending(d->vcpu[0], virq); + if ( !p->desc ) + return -EINVAL; + + desc = p->desc; + + spin_lock_irqsave(&desc->lock, flags); + + ret = -EINVAL; + if ( !test_bit(_IRQ_GUEST, &desc->status) ) + goto unlock; + + ret = -EINVAL; + + info = irq_get_guest_info(desc); + if ( d != info->d ) + goto unlock; + + ret = gic_remove_irq_from_guest(d, virq, desc); + + spin_unlock_irqrestore(&desc->lock, flags); + + if ( !ret ) + { + release_irq(desc->irq, info); + xfree(info); + } + + return ret; + +unlock: + spin_unlock_irqrestore(&desc->lock, flags); + + return ret; +} + /* * pirq event channels. We don't use these on ARM, instead we use the * features of the GIC to inject virtualised normal interrupts. diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c index fc8a270..4ddfd73 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -133,6 +133,22 @@ void register_vgic_ops(struct domain *d, const struct vgic_ops *ops) void domain_vgic_free(struct domain *d) { + int i; + int ret; + + for ( i = 0; i < (d->arch.vgic.nr_spis); i++ ) + { + struct pending_irq *p = &d->arch.vgic.pending_irqs[i]; + + if ( p->desc ) + { + ret = release_guest_irq(d, p->irq); + if ( ret ) + dprintk(XENLOG_G_WARNING, "d%u: Failed to release virq %u ret = %d\n", + d->domain_id, p->irq, ret); + } + } + xfree(d->arch.vgic.shared_irqs); xfree(d->arch.vgic.pending_irqs); xfree(d->arch.vgic.allocated_irqs); diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index a8ac294..5571189 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -217,6 +217,10 @@ extern int gic_route_irq_to_guest(struct domain *, unsigned int virq, struct irq_desc *desc, unsigned int priority); +/* Remove an IRQ passthrough to a guest */ +int gic_remove_irq_from_guest(struct domain *d, unsigned int virq, + struct irq_desc *desc); + extern void gic_inject(void); extern void gic_clear_pending_irqs(struct vcpu *v); extern int gic_events_need_delivery(void); diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h index 71b39e7..34b492b 100644 --- a/xen/include/asm-arm/irq.h +++ b/xen/include/asm-arm/irq.h @@ -44,6 +44,8 @@ void init_secondary_IRQ(void); int route_irq_to_guest(struct domain *d, unsigned int virq, unsigned int irq, const char *devname); +int release_guest_irq(struct domain *d, unsigned int irq); + void arch_move_irqs(struct vcpu *v); /* Set IRQ type for an SPI */