From patchwork Tue Apr 22 12:58:43 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 28788 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pb0-f70.google.com (mail-pb0-f70.google.com [209.85.160.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id D55A5203AC for ; Tue, 22 Apr 2014 13:04:45 +0000 (UTC) Received: by mail-pb0-f70.google.com with SMTP id rp16sf24033670pbb.5 for ; Tue, 22 Apr 2014 06:04:45 -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=hgJmZJ4cE0nt6CTV6Paf+W1Lvas3dgWTZhYkRlEyu5I=; b=ZgGXz1mcOeTUmCqqPORNbPWFFTl1oPJVSzKMOIXTtG0wVBf68Q3bfHEE3QANV+W9ws khVbWAE0GzxMYqHY7M/AA6SLhbcw8zt57vZhUAHBR3JCfKKRg3egtbDjMHu3C8LA3aSc j8lDhGH1XNxBX72nu6nk7ANepfhJ09dqgC2Zjioq2A38mxT6tyQbMRwH5JzkQkfUOxVz Rm7hvC08SIg75tCJnftT/BlnPm9xfQUhlpVHUS1RVAnZl/wd7uKguf1Zb6J4ybe/GRe0 kCdn9oGUc2rIIWtjUVUawvbg4R17Ovt++F1qzsc9feOGDrYNX5SG95Nn99jBbD2WeDsb /H1A== X-Gm-Message-State: ALoCoQlwcqjl4Z3X+xS5k4oQ8VVewBd45zGEgRjJ+BI2Ql68jj7i5cGolweIZ/Cw8hmCkf55wf8d X-Received: by 10.66.66.35 with SMTP id c3mr21855430pat.7.1398171885093; Tue, 22 Apr 2014 06:04:45 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.38.133 with SMTP id t5ls74805qgt.43.gmail; Tue, 22 Apr 2014 06:04:44 -0700 (PDT) X-Received: by 10.58.134.101 with SMTP id pj5mr272908veb.38.1398171884810; Tue, 22 Apr 2014 06:04:44 -0700 (PDT) Received: from mail-vc0-f171.google.com (mail-vc0-f171.google.com [209.85.220.171]) by mx.google.com with ESMTPS id s10si6892386vco.56.2014.04.22.06.04.44 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 22 Apr 2014 06:04:44 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.171 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.171; Received: by mail-vc0-f171.google.com with SMTP id lg15so2575161vcb.30 for ; Tue, 22 Apr 2014 06:04:44 -0700 (PDT) X-Received: by 10.220.161.8 with SMTP id p8mr36540273vcx.4.1398171884697; Tue, 22 Apr 2014 06:04:44 -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.220.221.72 with SMTP id ib8csp22904vcb; Tue, 22 Apr 2014 06:04:44 -0700 (PDT) X-Received: by 10.224.22.65 with SMTP id m1mr2740730qab.103.1398171884023; Tue, 22 Apr 2014 06:04:44 -0700 (PDT) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id 100si16978903qgv.154.2014.04.22.06.04.43 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 22 Apr 2014 06:04:44 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of xen-devel-bounces@lists.xen.org designates 50.57.142.19 as permitted sender) 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 1WcaJc-000204-Rl; Tue, 22 Apr 2014 13:00:48 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1WcaI6-0001h8-D8 for xen-devel@lists.xenproject.org; Tue, 22 Apr 2014 12:59:44 +0000 Received: from [85.158.139.211:51628] by server-7.bemta-5.messagelabs.com id F0/D7-20531-1A766535; Tue, 22 Apr 2014 12:59:13 +0000 X-Env-Sender: julien.grall@linaro.org X-Msg-Ref: server-16.tower-206.messagelabs.com!1398171552!8736950!1 X-Originating-IP: [74.125.83.50] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 6.11.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 17306 invoked from network); 22 Apr 2014 12:59:12 -0000 Received: from mail-ee0-f50.google.com (HELO mail-ee0-f50.google.com) (74.125.83.50) by server-16.tower-206.messagelabs.com with RC4-SHA encrypted SMTP; 22 Apr 2014 12:59:12 -0000 Received: by mail-ee0-f50.google.com with SMTP id c13so4548023eek.23 for ; Tue, 22 Apr 2014 05:59:12 -0700 (PDT) X-Received: by 10.14.69.201 with SMTP id n49mr2126454eed.106.1398171552410; Tue, 22 Apr 2014 05:59:12 -0700 (PDT) Received: from belegaer.uk.xensource.com ([185.25.64.249]) by mx.google.com with ESMTPSA id x45sm112862825eef.15.2014.04.22.05.59.10 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 Apr 2014 05:59:11 -0700 (PDT) From: Julien Grall To: xen-devel@lists.xenproject.org Date: Tue, 22 Apr 2014 13:58:43 +0100 Message-Id: <1398171530-27391-12-git-send-email-julien.grall@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1398171530-27391-1-git-send-email-julien.grall@linaro.org> References: <1398171530-27391-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 11/18] xen/arm: IRQ: Defer routing IRQ to Xen until setup_irq() call 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=neutral (google.com: 209.85.220.171 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) 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: When an IRQ is handling by Xen, setup is done in 2 steps: - Route the IRQ to the current CPU and set priorities - Set up the handler For PPIs, these steps are called on every cpu. For SPIs, they are only called on the boot CPU. Dividing the setup in two step complicates the code when a new driver is added to Xen (for instance a SMMU driver). Xen can safely route the IRQ when the driver sets up the interrupt handler. Signed-off-by: Julien Grall Acked-by: Ian Campbell --- Changes in v3: - Don't need to initialiase disabled - Typoes and update commit message Changes in v2: - Fix typo in commit message - s/SGI/SPI/ in comments - Rename gic_route_dt_irq into gic_route_irq_to_xen which is taking a desc now - Call setup_irq before initializing the GIC IRQ as the first one can fail. --- xen/arch/arm/gic.c | 63 +++++++------------------------------------- xen/arch/arm/irq.c | 24 ++++++++++++++++- xen/arch/arm/setup.c | 2 -- xen/arch/arm/smpboot.c | 2 -- xen/arch/arm/time.c | 11 -------- xen/include/asm-arm/gic.h | 10 +++---- xen/include/asm-arm/time.h | 3 --- 7 files changed, 36 insertions(+), 79 deletions(-) diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 29ecb49..577d85b 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -249,30 +249,20 @@ static void gic_set_irq_properties(unsigned int irq, bool_t level, spin_unlock(&gic.lock); } -/* Program the GIC to route an interrupt */ -static int gic_route_irq(unsigned int irq, bool_t level, - const cpumask_t *cpu_mask, unsigned int priority) +/* Program the GIC to route an interrupt to the host (i.e. Xen) + * - needs to be called with desc.lock held + */ +void gic_route_irq_to_xen(struct irq_desc *desc, bool_t level, + const cpumask_t *cpu_mask, unsigned int priority) { - struct irq_desc *desc = irq_to_desc(irq); - unsigned long flags; - ASSERT(priority <= 0xff); /* Only 8 bits of priority */ - ASSERT(irq < gic.lines); /* Can't route interrupts that don't exist */ - - if ( desc->action != NULL ) - return -EBUSY; - - spin_lock_irqsave(&desc->lock, flags); - - /* Disable interrupt */ - desc->handler->shutdown(desc); + ASSERT(desc->irq < gic.lines);/* Can't route interrupts that don't exist */ + ASSERT(desc->status & IRQ_DISABLED); + ASSERT(spin_is_locked(&desc->lock)); desc->handler = &gic_host_irq_type; - gic_set_irq_properties(irq, level, cpu_mask, priority); - - spin_unlock_irqrestore(&desc->lock, flags); - return 0; + gic_set_irq_properties(desc->irq, level, cpu_mask, priority); } /* Program the GIC to route an interrupt to a guest @@ -296,17 +286,6 @@ void gic_route_irq_to_guest(struct domain *d, struct irq_desc *desc, p->desc = desc; } -/* Program the GIC to route an interrupt with a dt_irq */ -void gic_route_dt_irq(const struct dt_irq *irq, const cpumask_t *cpu_mask, - unsigned int priority) -{ - bool_t level; - - level = dt_irq_is_level_triggered(irq); - - gic_route_irq(irq->irq, level, cpu_mask, priority); -} - static void __init gic_dist_init(void) { uint32_t type; @@ -560,30 +539,6 @@ void gic_disable_cpu(void) spin_unlock(&gic.lock); } -void gic_route_ppis(void) -{ - /* GIC maintenance */ - gic_route_dt_irq(&gic.maintenance, cpumask_of(smp_processor_id()), - GIC_PRI_IRQ); - /* Route timer interrupt */ - route_timer_interrupt(); -} - -void gic_route_spis(void) -{ - int seridx; - const struct dt_irq *irq; - - for ( seridx = 0; seridx <= SERHND_IDX; seridx++ ) - { - if ( (irq = serial_dt_irq(seridx)) == NULL ) - continue; - - gic_route_dt_irq(irq, cpumask_of(smp_processor_id()), - GIC_PRI_IRQ); - } -} - static inline void gic_set_lr(int lr, struct pending_irq *p, unsigned int state) { diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c index b6dd9de..9f1ca40 100644 --- a/xen/arch/arm/irq.c +++ b/xen/arch/arm/irq.c @@ -250,15 +250,37 @@ int setup_dt_irq(const struct dt_irq *irq, struct irqaction *new) int rc; unsigned long flags; struct irq_desc *desc; + bool_t disabled; desc = irq_to_desc(irq->irq); spin_lock_irqsave(&desc->lock, flags); + + disabled = (desc->action == NULL); + rc = __setup_irq(desc, new); + if ( rc ) + goto err; - if ( !rc ) + /* First time the IRQ is setup */ + if ( disabled ) + { + bool_t level; + + level = dt_irq_is_level_triggered(irq); + /* It's fine to use smp_processor_id() because: + * For PPI: irq_desc is banked + * For SPI: we don't care for now which CPU will receive the + * interrupt + * TODO: Handle case where SPI is setup on different CPU than + * the targeted CPU and the priority. + */ + gic_route_irq_to_xen(desc, level, cpumask_of(smp_processor_id()), + GIC_PRI_IRQ); desc->handler->startup(desc); + } +err: spin_unlock_irqrestore(&desc->lock, flags); return rc; diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 6b77a4c..dec5950 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -719,8 +719,6 @@ void __init start_xen(unsigned long boot_phys_offset, init_IRQ(); - gic_route_ppis(); - gic_route_spis(); xsm_dt_init(); init_maintenance_interrupt(); diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c index 7f28b68..cf149da 100644 --- a/xen/arch/arm/smpboot.c +++ b/xen/arch/arm/smpboot.c @@ -287,8 +287,6 @@ void __cpuinit start_secondary(unsigned long boot_phys_offset, init_secondary_IRQ(); - gic_route_ppis(); - init_maintenance_interrupt(); init_timer_interrupt(); diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c index 7cad888..ce96337 100644 --- a/xen/arch/arm/time.c +++ b/xen/arch/arm/time.c @@ -218,17 +218,6 @@ static void vtimer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs) vgic_vcpu_inject_irq(current, current->arch.virt_timer.irq, 1); } -/* Route timer's IRQ on this CPU */ -void __cpuinit route_timer_interrupt(void) -{ - gic_route_dt_irq(&timer_irq[TIMER_PHYS_NONSECURE_PPI], - cpumask_of(smp_processor_id()), GIC_PRI_IRQ); - gic_route_dt_irq(&timer_irq[TIMER_HYP_PPI], - cpumask_of(smp_processor_id()), GIC_PRI_IRQ); - gic_route_dt_irq(&timer_irq[TIMER_VIRT_PPI], - cpumask_of(smp_processor_id()), GIC_PRI_IRQ); -} - /* Set up the timer interrupt on this CPU */ void __cpuinit init_timer_interrupt(void) { diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 0e6e325..b750b17 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -167,15 +167,13 @@ extern void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq,int virtual); extern void vgic_clear_pending_irqs(struct vcpu *v); extern struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq); -/* Program the GIC to route an interrupt with a dt_irq */ -extern void gic_route_dt_irq(const struct dt_irq *irq, - const cpumask_t *cpu_mask, - unsigned int priority); +/* Program the GIC to route an interrupt */ +extern void gic_route_irq_to_xen(struct irq_desc *desc, bool_t level, + const cpumask_t *cpu_mask, + unsigned int priority); extern void gic_route_irq_to_guest(struct domain *, struct irq_desc *desc, bool_t level, const cpumask_t *cpu_mask, unsigned int priority); -extern void gic_route_ppis(void); -extern void gic_route_spis(void); extern void gic_inject(void); extern void gic_clear_pending_irqs(struct vcpu *v); diff --git a/xen/include/asm-arm/time.h b/xen/include/asm-arm/time.h index 9bbab0b..d544b5b 100644 --- a/xen/include/asm-arm/time.h +++ b/xen/include/asm-arm/time.h @@ -25,9 +25,6 @@ enum timer_ppi /* Get one of the timer IRQ number */ unsigned int timer_get_irq(enum timer_ppi ppi); -/* Route timer's IRQ on this CPU */ -extern void __cpuinit route_timer_interrupt(void); - /* Set up the timer interrupt on this CPU */ extern void __cpuinit init_timer_interrupt(void);