From patchwork Thu Jul 31 15:00:40 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 34655 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wg0-f70.google.com (mail-wg0-f70.google.com [74.125.82.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 2FBA720540 for ; Thu, 31 Jul 2014 15:02:22 +0000 (UTC) Received: by mail-wg0-f70.google.com with SMTP id l18sf1887966wgh.9 for ; Thu, 31 Jul 2014 08:02:21 -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:sender:errors-to :x-original-sender:x-original-authentication-results:mailing-list :list-archive:content-type:content-transfer-encoding; bh=s8MKrWP4egKElKkB3eLuPwclF6qwRgYaE4t0Wr0wCKY=; b=FKUNdO+haha5fJzysZvhViCDKokf1Fa2yncGtk3M2iTbiiUdOBfCsKseCa51ReHpn6 Or5sIzJBNA2U+4wDYOigkXuPe15vRzJeG8FkggYfC/UZdnSzbOFSOgELJ4rsfSL3ImJx SSeObqxqTZvafLjrhu6gBdSFhmojW52RRxTwvdd+BKyA7lywZnhYHuHT59yNYHu03bzI ChQQMMIv6MeTQrMonwGXn/bbuSOMRkIQznIMbR+Fhn0cHjyvYfTv5S4iWLt5gJqMjAt7 80wahsvC/ZPnn/waZo9yeVIQHX42sDUiRhd9NOlpRBoz9YLb/QIhXPg9eXq18wt4uUOn fQWA== X-Gm-Message-State: ALoCoQnKqpqrRfWcIy/RrZb/tl8y+nitqBU1twPaO2f+3Nv1mYPNywH4Me90ajmPqqEPXgUjX/YG X-Received: by 10.112.42.229 with SMTP id r5mr1140857lbl.23.1406818940918; Thu, 31 Jul 2014 08:02:20 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.24.184 with SMTP id 53ls1068108qgr.70.gmail; Thu, 31 Jul 2014 08:02:20 -0700 (PDT) X-Received: by 10.220.172.8 with SMTP id j8mr13613908vcz.32.1406818940747; Thu, 31 Jul 2014 08:02:20 -0700 (PDT) Received: from mail-vc0-f172.google.com (mail-vc0-f172.google.com [209.85.220.172]) by mx.google.com with ESMTPS id sg10si4609641vec.88.2014.07.31.08.02.20 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 31 Jul 2014 08:02:20 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.172 as permitted sender) client-ip=209.85.220.172; Received: by mail-vc0-f172.google.com with SMTP id im17so4399035vcb.31 for ; Thu, 31 Jul 2014 08:02:20 -0700 (PDT) X-Received: by 10.220.50.8 with SMTP id x8mr13653148vcf.18.1406818940269; Thu, 31 Jul 2014 08:02:20 -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.221.37.5 with SMTP id tc5csp25063vcb; Thu, 31 Jul 2014 08:02:19 -0700 (PDT) X-Received: by 10.43.64.77 with SMTP id xh13mr15743809icb.68.1406818938959; Thu, 31 Jul 2014 08:02:18 -0700 (PDT) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id wc16si14917163icb.20.2014.07.31.08.02.18 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 31 Jul 2014 08:02:18 -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 1XCrr3-0000cR-EO; Thu, 31 Jul 2014 15:01:17 +0000 Received: from mail6.bemta4.messagelabs.com ([85.158.143.247]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1XCrr2-0000b5-6F for xen-devel@lists.xenproject.org; Thu, 31 Jul 2014 15:01:16 +0000 Received: from [85.158.143.35:39546] by server-2.bemta-4.messagelabs.com id 23/0A-04525-B3A5AD35; Thu, 31 Jul 2014 15:01:15 +0000 X-Env-Sender: julien.grall@linaro.org X-Msg-Ref: server-12.tower-21.messagelabs.com!1406818874!12691602!1 X-Originating-IP: [74.125.82.41] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 6.11.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 12995 invoked from network); 31 Jul 2014 15:01:14 -0000 Received: from mail-wg0-f41.google.com (HELO mail-wg0-f41.google.com) (74.125.82.41) by server-12.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 31 Jul 2014 15:01:14 -0000 Received: by mail-wg0-f41.google.com with SMTP id z12so2884705wgg.12 for ; Thu, 31 Jul 2014 08:01:14 -0700 (PDT) X-Received: by 10.180.208.13 with SMTP id ma13mr16942583wic.45.1406818873155; Thu, 31 Jul 2014 08:01:13 -0700 (PDT) Received: from belegaer.uk.xensource.com ([185.25.64.249]) by mx.google.com with ESMTPSA id r20sm67128337wik.0.2014.07.31.08.01.11 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 31 Jul 2014 08:01:12 -0700 (PDT) From: Julien Grall To: xen-devel@lists.xenproject.org Date: Thu, 31 Jul 2014 16:00:40 +0100 Message-Id: <1406818852-31856-10-git-send-email-julien.grall@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1406818852-31856-1-git-send-email-julien.grall@linaro.org> References: <1406818852-31856-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 v2 09/21] 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.220.172 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 v2: - Drop the desc->handler = &no_irq_type in release_irq as it's buggy the IRQ is routed to Xen - Add release_guest_irq and gic_remove_guest_irq --- xen/arch/arm/gic.c | 36 ++++++++++++++++++++++++++++++++++ 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, 106 insertions(+) diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 8ef8764..22f331a 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -144,6 +144,42 @@ void gic_route_irq_to_guest(struct domain *d, unsigned int virq, p->desc = desc; } +/* 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 pending_irq *p = irq_to_pending(d->vcpu[0], virq); + + ASSERT(spin_is_locked(&desc->lock)); + ASSERT(test_bit(_IRQ_GUEST, &desc->status)); + ASSERT(p->desc == desc); + + /* 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: + desc->handler = &no_irq_type; + p->desc = NULL; + + 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 7eeb8dd..ba33571 100644 --- a/xen/arch/arm/irq.c +++ b/xen/arch/arm/irq.c @@ -292,6 +292,7 @@ void release_irq(unsigned int irq, const void *dev_id) if ( !desc->action ) { desc->handler->shutdown(desc); + clear_bit(_IRQ_GUEST, &desc->status); } @@ -479,6 +480,53 @@ out: 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; + + if ( 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 a037ecc..2a5fc18 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -118,6 +118,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); } diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 89816cd..46d7fd6 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -201,6 +201,10 @@ extern void gic_route_irq_to_guest(struct domain *, unsigned int virq, const cpumask_t *cpu_mask, 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 a7174f3..d25e1a1 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 */