From patchwork Mon Mar 5 16:03:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 130682 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp2854007lja; Mon, 5 Mar 2018 08:07:19 -0800 (PST) X-Google-Smtp-Source: AG47ELuEKati7CNy3hDDvwLZmyKBVU031MdP8gDxpMGDXbCL81D1r4N1bG8rQow4v2fizn5VPATA X-Received: by 10.36.140.3 with SMTP id j3mr15119836itd.66.1520266039528; Mon, 05 Mar 2018 08:07:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520266039; cv=none; d=google.com; s=arc-20160816; b=b/bhdNI304Oazxg9vwcxiJOtOHcP7tFCFacFIgdcLtHEwT/KbLU6yz9SAWo8KwUKTh ltgltX5ziZdxuym76x/aih2XwyfHotkpBwCEYGOLgR5Th56ihoISokSxSs2QJYwJfT71 1yw7bwiVTI8+uDX+dVa4jM0YExesVjS9wxfJfmRUiy1Ju6WCjMIACuOiREQQOuS0zcY3 vw6J6btrXkQkd6Gg98m+zbgGutbDw2HJn+6klX2vMxUHE2ONlT6mNzil5ap0bXpLR7Rc 6W2jm73pfh778cL/Ah1oFTz1Vf5QG4MWdsEZL/TKhUQQDQ01nu7QV2FTYmjN5u7HGDci ZSeg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:cc:references:in-reply-to:message-id:date:to :from:dkim-signature:arc-authentication-results; bh=gdoW6i6taxL1eR70+7ynHWxhT2w+XZZS4Xxhjik5WqE=; b=UCXd0nabKqq92NdiDONRoQ9j/lwGVsGKrgoLCzmyxQKEaUC+DpXS9R/hOGAGzwduJz pt8W8PJevNe7HsJsLwRtRPOZxZAg9swWk0JMHIv0vQDWoQlon5uXpRfHkaVdhvmH22g5 mRz4X0u9DOUJW7iwUXCBgCOkAorDjgW+eioI7wh1yfEY+FNC23jXgmaS2AWXAS5aHCG9 nZBBLSH/7IthSpQeYMDw86MusfzAfAB/hGfni/H/GHSeTZAEaRXnGyl0wdu+43QOmIT9 Kaeom9pc+xpot3UojLYjX4a3A719lArmoJBeKXRV0HYah1i6acTfX6Wap1cqOnweaSCm gJkg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=PCCqyFF7; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id g202si5840619ita.3.2018.03.05.08.07.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 05 Mar 2018 08:07:19 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=PCCqyFF7; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1essbN-0007H9-Vg; Mon, 05 Mar 2018 16:04:37 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1essbM-0007Fa-PN for xen-devel@lists.xenproject.org; Mon, 05 Mar 2018 16:04:36 +0000 X-Inumbo-ID: be51ed0b-208e-11e8-ba59-bc764e045a96 Received: from mail-wm0-x244.google.com (unknown [2a00:1450:400c:c09::244]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id be51ed0b-208e-11e8-ba59-bc764e045a96; Mon, 05 Mar 2018 17:03:29 +0100 (CET) Received: by mail-wm0-x244.google.com with SMTP id q83so16995335wme.5 for ; Mon, 05 Mar 2018 08:04:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=E/jemPBiSaqT07ZFFCU9hwJd3/2nhj0bucxQ3qt8pLc=; b=PCCqyFF7AGqSWydIN/FxfaHP1ABJOKaW3HHC6Ontc/0XeifbBvmfLID35XmbaeCHcd uvvWhyG13vgR3iRh05Hmk3nyHopAlPd7CdkEZ69mDNUrS73EkVgmHu5Qw3rupi5HZhCA ogv9s+MAUPyVIDbJjkVmlDXCYoV3ld6WmmUF0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=E/jemPBiSaqT07ZFFCU9hwJd3/2nhj0bucxQ3qt8pLc=; b=K+1pGcMtAq5d6fynuV9k4W2rcayneJ7oXQoXA8Fgm7JM5qWzEzHmtoCNn5UFD3WO+n cV7dszG/22FDIO2HbpTknsrGbG+kyMXBIJ+OMDcEH9QWT9J1SR6rcafLDmATzod/pZYA 9Igqqqb0iMjSRUWLvhsrpqhxlEpiLxJwuj4fEMF7eJRIrcXU1H+Ud+6VQ3MatFGCk61n rwcfW1g/6mkLmyDUahTXT0TUtgZmxkI1pzkvTw/N2xyoJ/y/mfDJESXfI+uQU2g2h9H8 K9xLsyE+F5TurPlAjVAl+d/z28zq+Ec5gUtrCdcFbDzWoDj6MmD2pEhcG1hcNnKjtW0W bL8g== X-Gm-Message-State: AElRT7ERMEEd9daFHFjlD3do5lET7XqIZ+8SMgElXdr5KzsI0N5VDHUC ZzJqnjX+jjI7eZVvy+cbM4wCyDI8nGU= X-Received: by 10.28.197.205 with SMTP id v196mr8141692wmf.141.1520265873626; Mon, 05 Mar 2018 08:04:33 -0800 (PST) Received: from e104803-lin.lan (mail.andrep.de. [217.160.17.100]) by smtp.gmail.com with ESMTPSA id y6sm6574381wmy.14.2018.03.05.08.04.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 05 Mar 2018 08:04:33 -0800 (PST) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Mon, 5 Mar 2018 16:03:29 +0000 Message-Id: <20180305160415.16760-12-andre.przywara@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180305160415.16760-1-andre.przywara@linaro.org> References: <20180305160415.16760-1-andre.przywara@linaro.org> Cc: xen-devel@lists.xenproject.org Subject: [Xen-devel] [PATCH 11/57] ARM: VGIC: change to level-IRQ compatible IRQ injection interface X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" At the moment vgic_vcpu_inject_irq() is the interface for Xen internal code and virtual devices to inject IRQs into a guest. This interface has two shortcomings: 1) It requires a VCPU pointer, which we may not know (and don't need!) for shared interrupts. A second function (vgic_vcpu_inject_spi()), was there to work around this issue. 2) This interface only really supports edge triggered IRQs, which is what the Xen VGIC emulates only anyway. However this needs to and will change, so we need to add the desired level (high or low) to the interface. This replaces the existing injection call (taking a VCPU and an IRQ parameter) with a new one, taking domain, VCPU, IRQ and level parameters. The VCPU can be NULL in case we don't know and don't care. We change all call sites to use this new interface. This still doesn't give us the missing level IRQ handling, but at least prepares the callers to do the right thing later automatically. Signed-off-by: Andre Przywara --- Changelog RFC ... v1: - no change xen/arch/arm/domain.c | 4 ++-- xen/arch/arm/gic-v3-lpi.c | 2 +- xen/arch/arm/irq.c | 2 +- xen/arch/arm/time.c | 2 +- xen/arch/arm/vgic.c | 43 +++++++++++++++++++++++++------------------ xen/arch/arm/vpl011.c | 2 +- xen/arch/arm/vtimer.c | 4 ++-- xen/include/asm-arm/vgic.h | 4 ++-- 8 files changed, 35 insertions(+), 28 deletions(-) diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 8546443bad..a7bba3ad44 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -952,14 +952,14 @@ void vcpu_mark_events_pending(struct vcpu *v) if ( already_pending ) return; - vgic_vcpu_inject_irq(v, v->domain->arch.evtchn_irq); + vgic_inject_irq(v->domain, v, v->domain->arch.evtchn_irq, true); } /* The ARM spec declares that even if local irqs are masked in * the CPSR register, an irq should wake up a cpu from WFI anyway. * For this reason we need to check for irqs that need delivery, * ignoring the CPSR register, *after* calling SCHEDOP_block to - * avoid races with vgic_vcpu_inject_irq. + * avoid races with vgic_inject_irq. */ void vcpu_block_unless_event_pending(struct vcpu *v) { diff --git a/xen/arch/arm/gic-v3-lpi.c b/xen/arch/arm/gic-v3-lpi.c index 84582157b8..efd5cd62fb 100644 --- a/xen/arch/arm/gic-v3-lpi.c +++ b/xen/arch/arm/gic-v3-lpi.c @@ -153,7 +153,7 @@ void vgic_vcpu_inject_lpi(struct domain *d, unsigned int virq) if ( vcpu_id >= d->max_vcpus ) return; - vgic_vcpu_inject_irq(d->vcpu[vcpu_id], virq); + vgic_inject_irq(d, d->vcpu[vcpu_id], virq, true); } /* diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c index 29af10e82c..aa4e832cae 100644 --- a/xen/arch/arm/irq.c +++ b/xen/arch/arm/irq.c @@ -225,7 +225,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(info->d, info->virq); + vgic_inject_irq(info->d, NULL, info->virq, true); goto out_no_end; } diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c index 36f640f0c1..c11fcfeadd 100644 --- a/xen/arch/arm/time.c +++ b/xen/arch/arm/time.c @@ -260,7 +260,7 @@ static void vtimer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs) current->arch.virt_timer.ctl = READ_SYSREG32(CNTV_CTL_EL0); WRITE_SYSREG32(current->arch.virt_timer.ctl | CNTx_CTL_MASK, CNTV_CTL_EL0); - vgic_vcpu_inject_irq(current, current->arch.virt_timer.irq); + vgic_inject_irq(current->domain, current, current->arch.virt_timer.irq, true); } /* diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c index c3fdcebbde..3c77d5fef6 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -291,7 +291,7 @@ bool vgic_migrate_irq(struct vcpu *old, struct vcpu *new, unsigned int irq) vgic_remove_irq_from_queues(old, p); irq_set_affinity(p->desc, cpumask_of(new->processor)); spin_unlock_irqrestore(&old->arch.vgic.lock, flags); - vgic_vcpu_inject_irq(new, irq); + vgic_inject_irq(new->domain, new, irq, true); return true; } /* if the IRQ is in a GICH_LR register, set GIC_IRQ_GUEST_MIGRATING @@ -450,7 +450,7 @@ bool vgic_to_sgi(struct vcpu *v, register_t sgir, enum gic_sgi_mode irqmode, sgir, target->list); continue; } - vgic_vcpu_inject_irq(d->vcpu[vcpuid], virq); + vgic_inject_irq(d, d->vcpu[vcpuid], virq, true); } break; case SGI_TARGET_OTHERS: @@ -459,12 +459,12 @@ bool vgic_to_sgi(struct vcpu *v, register_t sgir, enum gic_sgi_mode irqmode, { if ( i != current->vcpu_id && d->vcpu[i] != NULL && is_vcpu_online(d->vcpu[i]) ) - vgic_vcpu_inject_irq(d->vcpu[i], virq); + vgic_inject_irq(d, d->vcpu[i], virq, true); } break; case SGI_TARGET_SELF: perfc_incr(vgic_sgi_self); - vgic_vcpu_inject_irq(d->vcpu[current->vcpu_id], virq); + vgic_inject_irq(d, current, virq, true); break; default: gprintk(XENLOG_WARNING, @@ -524,13 +524,29 @@ void vgic_remove_irq_from_queues(struct vcpu *v, struct pending_irq *p) gic_remove_from_lr_pending(v, p); } -void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int virq) +int vgic_inject_irq(struct domain *d, struct vcpu *v, unsigned int virq, + bool level) { uint8_t priority; struct pending_irq *iter, *n; unsigned long flags; bool running; + /* + * For edge triggered interrupts we always ignore a "falling edge". + * For level triggered interrupts we shouldn't, but do anyways. + */ + if ( !level ) + return 0; + + if ( !v ) + { + /* The IRQ needs to be an SPI if no vCPU is specified. */ + ASSERT(virq >= 32 && virq <= vgic_num_irqs(d)); + + v = vgic_get_target_vcpu(d->vcpu[0], virq); + }; + spin_lock_irqsave(&v->arch.vgic.lock, flags); n = irq_to_pending(v, virq); @@ -538,14 +554,14 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int virq) if ( unlikely(!n) ) { spin_unlock_irqrestore(&v->arch.vgic.lock, flags); - return; + return 0; } /* vcpu offline */ if ( test_bit(_VPF_down, &v->pause_flags) ) { spin_unlock_irqrestore(&v->arch.vgic.lock, flags); - return; + return 0; } set_bit(GIC_IRQ_GUEST_QUEUED, &n->status); @@ -582,22 +598,13 @@ out: perfc_incr(vgic_cross_cpu_intr_inject); smp_send_event_check_mask(cpumask_of(v->processor)); } -} - -void vgic_vcpu_inject_spi(struct domain *d, unsigned int virq) -{ - struct vcpu *v; - /* the IRQ needs to be an SPI */ - ASSERT(virq >= 32 && virq <= vgic_num_irqs(d)); - - v = vgic_get_target_vcpu(d->vcpu[0], virq); - vgic_vcpu_inject_irq(v, virq); + return 0; } void arch_evtchn_inject(struct vcpu *v) { - vgic_vcpu_inject_irq(v, v->domain->arch.evtchn_irq); + vgic_inject_irq(v->domain, v, v->domain->arch.evtchn_irq, true); } bool vgic_evtchn_irq_pending(struct vcpu *v) diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c index 7788c2fc32..5dcf4bec18 100644 --- a/xen/arch/arm/vpl011.c +++ b/xen/arch/arm/vpl011.c @@ -68,7 +68,7 @@ static void vpl011_update_interrupt_status(struct domain *d) * status bit has been set since the last time. */ if ( uartmis & ~vpl011->shadow_uartmis ) - vgic_vcpu_inject_spi(d, GUEST_VPL011_SPI); + vgic_inject_irq(d, NULL, GUEST_VPL011_SPI, true); vpl011->shadow_uartmis = uartmis; } diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c index f52a723a5f..8164f6c7f1 100644 --- a/xen/arch/arm/vtimer.c +++ b/xen/arch/arm/vtimer.c @@ -46,7 +46,7 @@ static void phys_timer_expired(void *data) if ( !(t->ctl & CNTx_CTL_MASK) ) { perfc_incr(vtimer_phys_inject); - vgic_vcpu_inject_irq(t->v, t->irq); + vgic_inject_irq(t->v->domain, t->v, t->irq, true); } else perfc_incr(vtimer_phys_masked); @@ -56,7 +56,7 @@ static void virt_timer_expired(void *data) { struct vtimer *t = data; t->ctl |= CNTx_CTL_MASK; - vgic_vcpu_inject_irq(t->v, t->irq); + vgic_inject_irq(t->v->domain, t->v, t->irq, true); perfc_incr(vtimer_virt_inject); } diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h index d03298e12c..b75fdeb068 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -202,8 +202,8 @@ extern int domain_vgic_init(struct domain *d, unsigned int nr_spis); 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 virq); -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 int vgic_inject_irq(struct domain *d, struct vcpu *v, unsigned int virq, + bool level); extern void vgic_remove_irq_from_queues(struct vcpu *v, struct pending_irq *p); extern void gic_remove_from_lr_pending(struct vcpu *v, struct pending_irq *p); extern void vgic_clear_pending_irqs(struct vcpu *v);