From patchwork Tue Jan 13 14:25:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 43012 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ee0-f70.google.com (mail-ee0-f70.google.com [74.125.83.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id A99E420DE8 for ; Tue, 13 Jan 2015 14:28:40 +0000 (UTC) Received: by mail-ee0-f70.google.com with SMTP id b57sf2097535eek.1 for ; Tue, 13 Jan 2015 06:28:39 -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=hCeDxtxwV3vUY+rEPLhH7gUYDUFqBgajjlsiDnwMzVA=; b=EtcrALEqqF54dqwrM7wPrdjysDo/Q5R5/tpF94ofoJlvml4wW5txkmBybJvrIpzGqo fYf3EMYcXFSl0xt/nLvDlv4F9Nfi2NgRXJ6q4qF5iDAF3E+tPIeZtpQ/7NprEJDtJvuk 9iKTrN8n1gs5JWDoiLr2D10coVAAq/P0zNg62r5ppQdqKj0yTsJcEua+bZhsxhOZt59f woQPMwNoYAXpE1+2JlIq04mSkUWo1D4xFdUeAd293M2nMqUibNS2TU+P2gC3m5Sd8p0P 9xjHOep2XyyIopV0/lDBaGyye7j3rEOowfJtXq+0EnFjLvgzIsnJ2zCOjl9U/pnkDXxq W0Dg== X-Gm-Message-State: ALoCoQmHrfmaKjgwjo9fcfOTlyA81Av5JLiI0asbOWl5qxh+IS47Zc4cb7p75iLLeJzyICNSJds1 X-Received: by 10.112.148.198 with SMTP id tu6mr4493911lbb.3.1421159319886; Tue, 13 Jan 2015 06:28:39 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.5.229 with SMTP id v5ls3564lav.11.gmail; Tue, 13 Jan 2015 06:28:39 -0800 (PST) X-Received: by 10.112.198.1 with SMTP id iy1mr42240089lbc.13.1421159319665; Tue, 13 Jan 2015 06:28:39 -0800 (PST) Received: from mail-lb0-f176.google.com (mail-lb0-f176.google.com. [209.85.217.176]) by mx.google.com with ESMTPS id v20si3136136laz.0.2015.01.13.06.28.39 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 13 Jan 2015 06:28:39 -0800 (PST) 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 mail-lb0-f176.google.com with SMTP id p9so2821669lbv.7 for ; Tue, 13 Jan 2015 06:28:39 -0800 (PST) X-Received: by 10.152.87.12 with SMTP id t12mr42527750laz.31.1421159319576; Tue, 13 Jan 2015 06:28:39 -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 c8csp1398952lbb; Tue, 13 Jan 2015 06:28:38 -0800 (PST) X-Received: by 10.180.96.33 with SMTP id dp1mr40901160wib.13.1421159293072; Tue, 13 Jan 2015 06:28:13 -0800 (PST) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id wq5si41907743wjc.172.2015.01.13.06.28.12 (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 13 Jan 2015 06:28:13 -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 1YB2QZ-0001CU-El; Tue, 13 Jan 2015 14:26:39 +0000 Received: from mail6.bemta4.messagelabs.com ([85.158.143.247]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YB2QX-0001A1-2l for xen-devel@lists.xenproject.org; Tue, 13 Jan 2015 14:26:37 +0000 Received: from [85.158.143.35] by server-3.bemta-4.messagelabs.com id 79/3D-15461-C1B25B45; Tue, 13 Jan 2015 14:26:36 +0000 X-Env-Sender: julien.grall@linaro.org X-Msg-Ref: server-15.tower-21.messagelabs.com!1421159195!21135713!1 X-Originating-IP: [74.125.82.52] 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 9549 invoked from network); 13 Jan 2015 14:26:35 -0000 Received: from mail-wg0-f52.google.com (HELO mail-wg0-f52.google.com) (74.125.82.52) by server-15.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 13 Jan 2015 14:26:35 -0000 Received: by mail-wg0-f52.google.com with SMTP id x12so3222303wgg.11 for ; Tue, 13 Jan 2015 06:26:35 -0800 (PST) X-Received: by 10.180.19.193 with SMTP id h1mr6128099wie.10.1421159194760; Tue, 13 Jan 2015 06:26:34 -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.33 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 13 Jan 2015 06:26:33 -0800 (PST) From: Julien Grall To: xen-devel@lists.xenproject.org Date: Tue, 13 Jan 2015 14:25:17 +0000 Message-Id: <1421159133-31526-9-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 08/24] xen/arm: Allow virq != irq 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: Actually Xen is assuming that the virtual IRQ will always be the same as IRQ. Modify route_guest_irq to take the virtual IRQ in parameter and let Xen assign a different IRQ number. Also store the vIRQ in the desc action to easily retrieve easily the IRQ target when we need to inject the interrupt. As DOM0 will get most the devices, the vIRQ is equal to the IRQ in that case. At the same time modify the behavior of irq_get_domain. The function now assumes that the irq_desc belongs to an IRQ assigned to a guest. Signed-off-by: Julien Grall --- Changes in v3 - Spelling/grammar nits - Fix compilation on ARM64. Forgot to update route_irq_to_guest call for xgene platform. - Add a word about irq_get_domain behavior change - More s/irq/virq/ because of the rebasing on the latest staging Changes in v2: - Patch added --- xen/arch/arm/domain_build.c | 2 +- xen/arch/arm/gic.c | 5 ++-- xen/arch/arm/irq.c | 47 ++++++++++++++++++++++++++---------- xen/arch/arm/platforms/xgene-storm.c | 2 +- xen/arch/arm/vgic.c | 20 +++++++-------- xen/include/asm-arm/gic.h | 3 ++- xen/include/asm-arm/irq.h | 4 +-- xen/include/asm-arm/vgic.h | 4 +-- 8 files changed, 55 insertions(+), 32 deletions(-) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index b48b5d0..06c1dec 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -1029,7 +1029,7 @@ static int handle_device(struct domain *d, struct dt_device_node *dev) * twice the IRQ. This can happen if the IRQ is shared */ vgic_reserve_virq(d, irq); - res = route_irq_to_guest(d, irq, dt_node_name(dev)); + res = route_irq_to_guest(d, irq, irq, dt_node_name(dev)); if ( res ) { printk(XENLOG_ERR "Unable to route IRQ %u to domain %u\n", diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index eb0c5d6..15de283 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -126,7 +126,8 @@ void gic_route_irq_to_xen(struct irq_desc *desc, const cpumask_t *cpu_mask, /* Program the GIC to route an interrupt to a guest * - desc.lock must be held */ -void gic_route_irq_to_guest(struct domain *d, struct irq_desc *desc, +void gic_route_irq_to_guest(struct domain *d, unsigned int virq, + struct irq_desc *desc, const cpumask_t *cpu_mask, unsigned int priority) { struct pending_irq *p; @@ -139,7 +140,7 @@ void gic_route_irq_to_guest(struct domain *d, struct irq_desc *desc, /* Use vcpu0 to retrieve the pending_irq struct. Given that we only * route SPIs to guests, it doesn't make any difference. */ - p = irq_to_pending(d->vcpu[0], desc->irq); + p = irq_to_pending(d->vcpu[0], virq); p->desc = desc; } diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c index 25ecf1d..830832c 100644 --- a/xen/arch/arm/irq.c +++ b/xen/arch/arm/irq.c @@ -31,6 +31,13 @@ static unsigned int local_irqs_type[NR_LOCAL_IRQS]; static DEFINE_SPINLOCK(local_irqs_type_lock); +/* Describe an IRQ assigned to a guest */ +struct irq_guest +{ + struct domain *d; + unsigned int virq; +}; + static void ack_none(struct irq_desc *irq) { printk("unexpected IRQ trap at irq %02x\n", irq->irq); @@ -122,18 +129,20 @@ void __cpuinit init_secondary_IRQ(void) BUG_ON(init_local_irq_data() < 0); } -static inline struct domain *irq_get_domain(struct irq_desc *desc) +static inline struct irq_guest *irq_get_guest_info(struct irq_desc *desc) { ASSERT(spin_is_locked(&desc->lock)); - - if ( !test_bit(_IRQ_GUEST, &desc->status) ) - return dom_xen; - + ASSERT(test_bit(_IRQ_GUEST, &desc->status)); ASSERT(desc->action != NULL); return desc->action->dev_id; } +static inline struct domain *irq_get_domain(struct irq_desc *desc) +{ + return irq_get_guest_info(desc)->d; +} + void irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask) { if ( desc != NULL ) @@ -197,7 +206,7 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq) if ( test_bit(_IRQ_GUEST, &desc->status) ) { - struct domain *d = irq_get_domain(desc); + struct irq_guest *info = irq_get_guest_info(desc); desc->handler->end(desc); @@ -206,7 +215,7 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq) /* the irq cannot be a PPI, we only support delivery of SPIs to * guests */ - vgic_vcpu_inject_spi(d, irq); + vgic_vcpu_inject_spi(info->d, info->virq); goto out_no_end; } @@ -370,19 +379,30 @@ err: return rc; } -int route_irq_to_guest(struct domain *d, unsigned int irq, - const char * devname) +int route_irq_to_guest(struct domain *d, unsigned int virq, + unsigned int irq, const char * devname) { struct irqaction *action; - struct irq_desc *desc = irq_to_desc(irq); + struct irq_guest *info; + struct irq_desc *desc; unsigned long flags; int retval = 0; action = xmalloc(struct irqaction); - if (!action) + if ( !action ) + return -ENOMEM; + + info = xmalloc(struct irq_guest); + if ( !info ) + { + xfree(action); return -ENOMEM; + } + + info->d = d; + info->virq = virq; - action->dev_id = d; + action->dev_id = info; action->name = devname; action->free_on_release = 1; @@ -413,7 +433,7 @@ int route_irq_to_guest(struct domain *d, unsigned int irq, if ( retval ) goto out; - gic_route_irq_to_guest(d, desc, cpumask_of(smp_processor_id()), + gic_route_irq_to_guest(d, virq, desc, cpumask_of(smp_processor_id()), GIC_PRI_IRQ); spin_unlock_irqrestore(&desc->lock, flags); return 0; @@ -421,6 +441,7 @@ int route_irq_to_guest(struct domain *d, unsigned int irq, out: spin_unlock_irqrestore(&desc->lock, flags); xfree(action); + xfree(info); return retval; } diff --git a/xen/arch/arm/platforms/xgene-storm.c b/xen/arch/arm/platforms/xgene-storm.c index b0808b8..e2f8b89 100644 --- a/xen/arch/arm/platforms/xgene-storm.c +++ b/xen/arch/arm/platforms/xgene-storm.c @@ -75,7 +75,7 @@ static int map_one_spi(struct domain *d, const char *what, printk("Failed to reserve the vIRQ %u on dom%d\n", irq, d->domain_id); - ret = route_irq_to_guest(d, irq, what); + ret = route_irq_to_guest(d, irq, irq, what); if ( ret ) printk("Failed to route %s to dom%d\n", what, d->domain_id); diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c index 38216f7..c915670 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -380,16 +380,16 @@ void vgic_clear_pending_irqs(struct vcpu *v) spin_unlock_irqrestore(&v->arch.vgic.lock, flags); } -void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq) +void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int virq) { uint8_t priority; - struct vgic_irq_rank *rank = vgic_rank_irq(v, irq); - struct pending_irq *iter, *n = irq_to_pending(v, irq); + struct vgic_irq_rank *rank = vgic_rank_irq(v, virq); + struct pending_irq *iter, *n = irq_to_pending(v, virq); unsigned long flags; bool_t running; vgic_lock_rank(v, rank, flags); - priority = v->domain->arch.vgic.handler->get_irq_priority(v, irq); + priority = v->domain->arch.vgic.handler->get_irq_priority(v, virq); vgic_unlock_rank(v, rank, flags); spin_lock_irqsave(&v->arch.vgic.lock, flags); @@ -405,7 +405,7 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq) if ( !list_empty(&n->inflight) ) { - gic_raise_inflight_irq(v, irq); + gic_raise_inflight_irq(v, virq); goto out; } @@ -413,7 +413,7 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq) /* the irq is enabled */ if ( test_bit(GIC_IRQ_GUEST_ENABLED, &n->status) ) - gic_raise_guest_irq(v, irq, priority); + gic_raise_guest_irq(v, virq, priority); list_for_each_entry ( iter, &v->arch.vgic.inflight_irqs, inflight ) { @@ -433,15 +433,15 @@ out: smp_send_event_check_mask(cpumask_of(v->processor)); } -void vgic_vcpu_inject_spi(struct domain *d, unsigned int irq) +void vgic_vcpu_inject_spi(struct domain *d, unsigned int virq) { struct vcpu *v; /* the IRQ needs to be an SPI */ - ASSERT(irq >= 32 && irq <= gic_number_lines()); + ASSERT(virq >= 32 && virq <= vgic_num_irqs(d)); - v = vgic_get_target_vcpu(d->vcpu[0], irq); - vgic_vcpu_inject_irq(v, irq); + v = vgic_get_target_vcpu(d->vcpu[0], virq); + vgic_vcpu_inject_irq(v, virq); } void arch_evtchn_inject(struct vcpu *v) diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 6286c71..cf9f257 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -213,7 +213,8 @@ extern enum gic_version gic_hw_version(void); /* Program the GIC to route an interrupt */ extern void gic_route_irq_to_xen(struct irq_desc *desc, const cpumask_t *cpu_mask, unsigned int priority); -extern void gic_route_irq_to_guest(struct domain *, struct irq_desc *desc, +extern void gic_route_irq_to_guest(struct domain *, unsigned int virq, + struct irq_desc *desc, const cpumask_t *cpu_mask, unsigned int priority); diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h index 435dfcd..f00eb11 100644 --- a/xen/include/asm-arm/irq.h +++ b/xen/include/asm-arm/irq.h @@ -40,8 +40,8 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq); void init_IRQ(void); void init_secondary_IRQ(void); -int route_irq_to_guest(struct domain *d, unsigned int irq, - const char *devname); +int route_irq_to_guest(struct domain *d, unsigned int virq, + unsigned int irq, const char *devname); void arch_move_irqs(struct vcpu *v); /* Set IRQ type for an SPI */ diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h index 8582d9d..1cd7808 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -181,8 +181,8 @@ extern int domain_vgic_init(struct domain *d); extern void domain_vgic_free(struct domain *d); extern int vcpu_vgic_init(struct vcpu *v); extern struct vcpu *vgic_get_target_vcpu(struct vcpu *v, unsigned int irq); -extern void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq); -extern void vgic_vcpu_inject_spi(struct domain *d, unsigned int irq); +extern void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int virq); +extern void vgic_vcpu_inject_spi(struct domain *d, unsigned int virq); extern void vgic_clear_pending_irqs(struct vcpu *v); extern struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq); extern struct vgic_irq_rank *vgic_rank_offset(struct vcpu *v, int b, int n, int s);