From patchwork Wed Mar 21 16:31:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 132225 Delivered-To: patch@linaro.org Received: by 10.46.84.29 with SMTP id i29csp2356203ljb; Wed, 21 Mar 2018 09:35:07 -0700 (PDT) X-Google-Smtp-Source: AG47ELss0WfDGkEypy2Sj3d3SR60bsnifg8tqfjGVJwVM2rqy+OfNA0z1yBhljIEtFpP4rzPNgKQ X-Received: by 10.107.136.33 with SMTP id k33mr20668608iod.4.1521650107151; Wed, 21 Mar 2018 09:35:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521650107; cv=none; d=google.com; s=arc-20160816; b=kIavBP6cbACunBo6UoR4wrqWICl0W1YIzW1oV7xVuL7X8PPd1y4E3DsMVFdwGo84Hs xG4VSQHkIDPQyNKq2DD1edSojSIX5gIxt3gU1t+y7NcJXZgG4z6xEg49h9e+/75c10oS HEuKai5q7Wd4dOscYpsj/uhbI+JzHCCNhhgncnMp4JvQgKUoCDipImw+67JBYEWB6lyn aBGhkJTYwy7K789xwu+yIgRubX/1YXJxNzJ0/kbWaFPU0P53K1hKC8Cxof7MlaEs9ib3 2vfCrTshShOgaGNqJ7kyvBAS8EaK79LKZpyPLJhRflfvliePFjLuxgQbX8Z8DwZEWlty 1IIg== 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:cc :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:references:in-reply-to:message-id:date:to:from :dkim-signature:arc-authentication-results; bh=ypkU3MtlY5vwmXC2iPCe7XIAcbqFHq/i68B2OOyeJvE=; b=Uk/g/4Ztkigr1ng2zcDFjAE3yb9Z+9BMbyM/ql0EQLwhnP+Y8XhJxDJxH3Shu7tRJu Rpnia1ghWEWUZCtEFL1VwTPXSQUHUk3iaIDhl7c6VnameWGg6R8f80vbA4uZVRlydFQq z3ChaNpOdlTFXvSu+BPiBjUw8AJllo2uOhaKH18B9uyJJOae+31iDQ0KztAATBnxNxaI WcEfS94fJ0iMxDIkgMY2itTjVjWSm89dUWxVNqv9EEvKrrOW694h85sfaW0P6WAEqSxF QiAKhS0ii4oWKjxkXwZJFrJzBScG6IXEIG2Cn9qXaoRnNU6eSNcNJW5MKznQyRPD9VFU NLDg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=b4O8Kdci; 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 l124si3341608ioa.173.2018.03.21.09.35.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 21 Mar 2018 09:35:07 -0700 (PDT) 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=b4O8Kdci; 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.89) (envelope-from ) id 1eygfX-000217-Mm; Wed, 21 Mar 2018 16:32:55 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1eygfW-0001zw-1m for xen-devel@lists.xenproject.org; Wed, 21 Mar 2018 16:32:54 +0000 X-Inumbo-ID: 77167bf4-2d25-11e8-9728-bc764e045a96 Received: from mail-wm0-x243.google.com (unknown [2a00:1450:400c:c09::243]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id 77167bf4-2d25-11e8-9728-bc764e045a96; Wed, 21 Mar 2018 17:32:37 +0100 (CET) Received: by mail-wm0-x243.google.com with SMTP id i189so7154957wmf.0 for ; Wed, 21 Mar 2018 09:32:52 -0700 (PDT) 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=oq5NRgZ6cOcJirzLq74UmwDuq0nXr+guFcrM5PVD5LQ=; b=b4O8KdcioHU9CY52B29So6Ct6imdsUSzAtHjzuRz3EztFUBdcGaJaowVxlHsO7o0Nf jUN0q9KJr1zD29/P3g45+l4fU/iUsbBgcm8hhoXKlMSPjD7UqaKVISklnNKPtS5HVtG0 F3r1SzfYf+dGeyjiqvCmV9bFeNW2xaxAlkgLU= 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=oq5NRgZ6cOcJirzLq74UmwDuq0nXr+guFcrM5PVD5LQ=; b=i1JPH2pJpsq3qEobhbd4mdlntc/S0Bp0FwJ/JGEi/P6EX9m0Kzxqx/WxSykPHCS66Q aZteI3xPR0oxMxEHtLgWJLqc0ZC4Y1Wrgg26WQ4XxmMmTbcF1WUjH4Jr1ZwRFY9G7zYA OHiMV4TVzwvDLIF/rAn91VdzIIORkzASgqgNld1oWJImgyv/NIqMPwwUnUSojXnigmKI /GgKGJ2235OKAD+Ruw7PJnplV3Ko3gKHQ+1qjSVMG3UzUnVPIeaRPlxNarSTMWDwb4HM bjw5Q3E0pDfHeW9RCa87ToFyBYR6Twna1/6iqcPaRPAHKx4BAzINSOV46MZZ1vpE92ll qRPA== X-Gm-Message-State: AElRT7EMscXUmZgGaThv0yfsgAUPuSjcoTO/1M1r1u3+GziwZWf+RF3R k25XLxw7/Alp3Fs6dAyB/1GHyQ== X-Received: by 10.28.237.26 with SMTP id l26mr3004475wmh.12.1521649971161; Wed, 21 Mar 2018 09:32:51 -0700 (PDT) Received: from e104803-lin.lan (mail.andrep.de. [217.160.17.100]) by smtp.gmail.com with ESMTPSA id n64sm4423724wmd.11.2018.03.21.09.32.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 21 Mar 2018 09:32:50 -0700 (PDT) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Wed, 21 Mar 2018 16:31:59 +0000 Message-Id: <20180321163235.12529-4-andre.przywara@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180321163235.12529-1-andre.przywara@linaro.org> References: <20180321163235.12529-1-andre.przywara@linaro.org> Subject: [Xen-devel] [PATCH v3 03/39] ARM: GIC: Allow tweaking the active and pending state of an IRQ X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: xen-devel@lists.xenproject.org, Andre Przywara MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" When playing around with hardware mapped, level triggered virtual IRQs, there is the need to explicitly set the active or pending state of an interrupt at some point. To prepare the GIC for that, we introduce a set_active_state() and a set_pending_state() function to let the VGIC manipulate the state of an associated hardware IRQ. This takes care of properly setting the _IRQ_INPROGRESS bit. Signed-off-by: Andre Przywara --- Changelog v2 ... v3: - rework setting _IRQ_INPROGRESS bit: - no change when changing active state - unconditional set/clear on changing pending state - drop introduction of gicv[23]_peek_irq() (only needed in the next patch now) Changelog v1 ... v2: - properly set _IRQ_INPROGRESS bit - add gicv[23]_peek_irq() (pulled in from later patch) - move wrappers functions into gic.h xen/arch/arm/gic-v2.c | 36 ++++++++++++++++++++++++++++++++++++ xen/arch/arm/gic-v3.c | 32 ++++++++++++++++++++++++++++++++ xen/include/asm-arm/gic.h | 24 ++++++++++++++++++++++++ 3 files changed, 92 insertions(+) diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c index aa0fc6c1a1..d1f1578c05 100644 --- a/xen/arch/arm/gic-v2.c +++ b/xen/arch/arm/gic-v2.c @@ -243,6 +243,40 @@ static void gicv2_poke_irq(struct irq_desc *irqd, uint32_t offset) writel_gicd(1U << (irqd->irq % 32), offset + (irqd->irq / 32) * 4); } +static void gicv2_set_active_state(struct irq_desc *irqd, bool active) +{ + ASSERT(spin_is_locked(&irqd->lock)); + + if ( active ) + { + if ( test_bit(_IRQ_GUEST, &irqd->status) ) + set_bit(_IRQ_INPROGRESS, &irqd->status); + gicv2_poke_irq(irqd, GICD_ISACTIVER); + } + else + { + if ( test_bit(_IRQ_GUEST, &irqd->status) ) + clear_bit(_IRQ_INPROGRESS, &irqd->status); + gicv2_poke_irq(irqd, GICD_ICACTIVER); + } +} + +static void gicv2_set_pending_state(struct irq_desc *irqd, bool pending) +{ + ASSERT(spin_is_locked(&irqd->lock)); + + if ( pending ) + { + /* The _IRQ_INPROGRESS bit will be set when the interrupt fires. */ + gicv2_poke_irq(irqd, GICD_ISPENDR); + } + else + { + /* The _IRQ_INPROGRESS remains unchanged. */ + gicv2_poke_irq(irqd, GICD_ICPENDR); + } +} + static void gicv2_set_irq_type(struct irq_desc *desc, unsigned int type) { uint32_t cfg, actual, edgebit; @@ -1278,6 +1312,8 @@ const static struct gic_hw_operations gicv2_ops = { .eoi_irq = gicv2_eoi_irq, .deactivate_irq = gicv2_dir_irq, .read_irq = gicv2_read_irq, + .set_active_state = gicv2_set_active_state, + .set_pending_state = gicv2_set_pending_state, .set_irq_type = gicv2_set_irq_type, .set_irq_priority = gicv2_set_irq_priority, .send_SGI = gicv2_send_SGI, diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c index cb41844af2..f244d51661 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -477,6 +477,36 @@ static unsigned int gicv3_read_irq(void) return irq; } +static void gicv3_set_active_state(struct irq_desc *irqd, bool active) +{ + ASSERT(spin_is_locked(&irqd->lock)); + + if ( active ) + { + if ( test_bit(_IRQ_GUEST, &irqd->status) ) + set_bit(_IRQ_INPROGRESS, &irqd->status); + gicv3_poke_irq(irqd, GICD_ISACTIVER, false); + } + else + { + if ( test_bit(_IRQ_GUEST, &irqd->status) ) + clear_bit(_IRQ_INPROGRESS, &irqd->status); + gicv3_poke_irq(irqd, GICD_ICACTIVER, false); + } +} + +static void gicv3_set_pending_state(struct irq_desc *irqd, bool pending) +{ + ASSERT(spin_is_locked(&irqd->lock)); + + if ( pending ) + /* The _IRQ_INPROGRESS bit will be set when the interrupt fires. */ + gicv3_poke_irq(irqd, GICD_ISPENDR, false); + else + /* The _IRQ_INPROGRESS bit will remain unchanged. */ + gicv3_poke_irq(irqd, GICD_ICPENDR, false); +} + static inline uint64_t gicv3_mpidr_to_affinity(int cpu) { uint64_t mpidr = cpu_logical_map(cpu); @@ -1769,6 +1799,8 @@ static const struct gic_hw_operations gicv3_ops = { .eoi_irq = gicv3_eoi_irq, .deactivate_irq = gicv3_dir_irq, .read_irq = gicv3_read_irq, + .set_active_state = gicv3_set_active_state, + .set_pending_state = gicv3_set_pending_state, .set_irq_type = gicv3_set_irq_type, .set_irq_priority = gicv3_set_irq_priority, .send_SGI = gicv3_send_sgi, diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 3079387e06..2aca243ac3 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -345,6 +345,10 @@ struct gic_hw_operations { void (*deactivate_irq)(struct irq_desc *irqd); /* Read IRQ id and Ack */ unsigned int (*read_irq)(void); + /* Force the active state of an IRQ by accessing the distributor */ + void (*set_active_state)(struct irq_desc *irqd, bool state); + /* Force the pending state of an IRQ by accessing the distributor */ + void (*set_pending_state)(struct irq_desc *irqd, bool state); /* Set IRQ type */ void (*set_irq_type)(struct irq_desc *desc, unsigned int type); /* Set IRQ priority */ @@ -393,6 +397,26 @@ static inline unsigned int gic_get_nr_lrs(void) return gic_hw_ops->info->nr_lrs; } +/* + * Set the active state of an IRQ. This should be used with care, as this + * directly forces the active bit, without considering the GIC state machine. + * For private IRQs this only works for those of the current CPU. + */ +static inline void gic_set_active_state(struct irq_desc *irqd, bool state) +{ + gic_hw_ops->set_active_state(irqd, state); +} + +/* + * Set the pending state of an IRQ. This should be used with care, as this + * directly forces the pending bit, without considering the GIC state machine. + * For private IRQs this only works for those of the current CPU. + */ +static inline void gic_set_pending_state(struct irq_desc *irqd, bool state) +{ + gic_hw_ops->set_pending_state(irqd, state); +} + void register_gic_ops(const struct gic_hw_operations *ops); int gic_make_hwdom_dt_node(const struct domain *d, const struct dt_device_node *gic,