From patchwork Thu Mar 19 19:29:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 46089 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f197.google.com (mail-lb0-f197.google.com [209.85.217.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 4602421515 for ; Thu, 19 Mar 2015 19:32:02 +0000 (UTC) Received: by lbvp9 with SMTP id p9sf14261863lbv.0 for ; Thu, 19 Mar 2015 12:32:01 -0700 (PDT) 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=sfrQgsgf1jTfCqnjpsn8qlmmcvA8Jcl1C2jv5lLKkmQ=; b=nAiOLBlUv6is3hhLBRFqpKO/b6lXZF9koYD+LW2te1rdtmRz48N3XZQSQGcpzr0cZu BrKmRaND5RnZXu0Hf//r3KJq77ZZRhNWLexrrlt29kVJcvWlnBInwSiKrwo3A86Ltsqn iWl2KUWjo3Q3MY8HBCvyWJjBJxpVP7PCVZgWc7dcFTMA/ccF8qqbhyTVf+i5VvLbBbCh W/Dt2iRK3LY+2JscJ8HdPKk8hrEJ+QwtgPiLEoBM9X1jqBaYG8aYQoHeEBqx4t15zNs0 1gQaCcolqZcMhlGoMfxyHONN91uFYcz1MWDTcw/axFvnPgK4nqUeK1JaUtWElCiub45i T5nw== X-Gm-Message-State: ALoCoQlsYh52emPx4tdlveF035h7ZBrkPpxtsz7RI/1vsH15FEevZtZzA8h6gVH7ktvQ/fisaGML X-Received: by 10.180.210.132 with SMTP id mu4mr1143860wic.5.1426793521229; Thu, 19 Mar 2015 12:32:01 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.4.131 with SMTP id k3ls343070lak.21.gmail; Thu, 19 Mar 2015 12:32:01 -0700 (PDT) X-Received: by 10.112.199.36 with SMTP id jh4mr34776981lbc.49.1426793521062; Thu, 19 Mar 2015 12:32:01 -0700 (PDT) Received: from mail-lb0-f176.google.com (mail-lb0-f176.google.com. [209.85.217.176]) by mx.google.com with ESMTPS id t9si1659088lal.77.2015.03.19.12.32.01 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Mar 2015 12:32:01 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.176 as permitted sender) client-ip=209.85.217.176; Received: by lbblx11 with SMTP id lx11so38280412lbb.3 for ; Thu, 19 Mar 2015 12:32:01 -0700 (PDT) X-Received: by 10.112.211.200 with SMTP id ne8mr69192696lbc.73.1426793520951; Thu, 19 Mar 2015 12:32:00 -0700 (PDT) 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.35.133 with SMTP id h5csp597347lbj; Thu, 19 Mar 2015 12:32:00 -0700 (PDT) X-Received: by 10.52.230.2 with SMTP id su2mr15715307vdc.4.1426793519065; Thu, 19 Mar 2015 12:31:59 -0700 (PDT) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id s6si1931045vdc.100.2015.03.19.12.31.58 (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 19 Mar 2015 12:31:59 -0700 (PDT) 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 1YYg9s-0004lK-Qx; Thu, 19 Mar 2015 19:31:08 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YYg9r-0004h3-1b for xen-devel@lists.xenproject.org; Thu, 19 Mar 2015 19:31:07 +0000 Received: from [85.158.139.211] by server-16.bemta-5.messagelabs.com id 4B/8D-13528-AF32B055; Thu, 19 Mar 2015 19:31:06 +0000 X-Env-Sender: julien.grall@linaro.org X-Msg-Ref: server-16.tower-206.messagelabs.com!1426793465!9089281!1 X-Originating-IP: [209.85.212.173] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 6.13.4; banners=-,-,- X-VirusChecked: Checked Received: (qmail 7637 invoked from network); 19 Mar 2015 19:31:05 -0000 Received: from mail-wi0-f173.google.com (HELO mail-wi0-f173.google.com) (209.85.212.173) by server-16.tower-206.messagelabs.com with RC4-SHA encrypted SMTP; 19 Mar 2015 19:31:05 -0000 Received: by wibg7 with SMTP id g7so15061444wib.1 for ; Thu, 19 Mar 2015 12:31:05 -0700 (PDT) X-Received: by 10.180.182.67 with SMTP id ec3mr19024594wic.32.1426793465136; Thu, 19 Mar 2015 12:31:05 -0700 (PDT) Received: from chilopoda.uk.xensource.com. ([185.25.64.249]) by mx.google.com with ESMTPSA id hl8sm3203005wjb.38.2015.03.19.12.31.03 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 19 Mar 2015 12:31:04 -0700 (PDT) From: Julien Grall To: xen-devel@lists.xenproject.org Date: Thu, 19 Mar 2015 19:29:44 +0000 Message-Id: <1426793399-6283-19-git-send-email-julien.grall@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1426793399-6283-1-git-send-email-julien.grall@linaro.org> References: <1426793399-6283-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 v4 18/33] 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.217.176 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. Furthermore, 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 v4: - Reorder the code flow - Typoes and coding style - Use the newly helper spi_to_pending 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 | 45 +++++++++++++++++++++++++++++++++++++++++++++ xen/arch/arm/irq.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ xen/arch/arm/vgic.c | 16 ++++++++++++++++ xen/include/asm-arm/gic.h | 4 ++++ xen/include/asm-arm/irq.h | 2 ++ 5 files changed, 113 insertions(+) diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 5f34997..f023e4f 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -163,6 +163,51 @@ 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 ( d->is_dying ) + { + desc->handler->shutdown(desc); + + /* EOI the IRQ it it has not been done by the guest */ + if ( test_bit(_IRQ_INPROGRESS, &desc->status) ) + gic_hw_ops->deactivate_irq(desc); + clear_bit(_IRQ_INPROGRESS, &desc->status); + } + else + { + /* + * TODO: Handle eviction from LRs For now, deny + * remove if the IRQ is inflight or not disabled. + */ + if ( test_bit(_IRQ_INPROGRESS, &desc->status) || + !test_bit(_IRQ_DISABLED, &desc->status) ) + return -EBUSY; + } + + 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 b2ddf6b..376c9f2 100644 --- a/xen/arch/arm/irq.c +++ b/xen/arch/arm/irq.c @@ -513,6 +513,52 @@ 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 < NR_LOCAL_IRQS || virq >= vgic_num_irqs(d) ) + return -EINVAL; + + p = spi_to_pending(d, 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; + + info = irq_get_guest_info(desc); + ret = -EINVAL; + if ( d != info->d ) + goto unlock; + + ret = gic_remove_irq_from_guest(d, virq, desc); + if ( ret ) + goto unlock; + + spin_unlock_irqrestore(&desc->lock, flags); + + release_irq(desc->irq, info); + xfree(info); + + return 0; + +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 fc283ec..93d0139 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -135,6 +135,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 = spi_to_pending(d, i + 32); + + 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 ef4bf9a..9e2acb7 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -220,6 +220,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 */