From patchwork Tue Aug 28 15:51:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 10578835 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7E278139B for ; Tue, 28 Aug 2018 16:11:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6C5BC2A72F for ; Tue, 28 Aug 2018 16:11:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 692D52A72A; Tue, 28 Aug 2018 16:11:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8CA9A2A74A for ; Tue, 28 Aug 2018 16:11:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=c8ehiJR6mVPCCIfwJ3BnhmimXYKDpADQxSVfdpCjDIM=; b=rTWp5ZALYFScHF13kPNI29+XTt 4OvGf4d/auGx3BGZ07ljtAz9CCbhle/SF8veYMztgP7oNq96csYQeTMnZ/QYushPyMwt3BSdCiFrE jL0xkzzGEaAc7B0VqZ3pywhRjmVpbXrUCM53S6KhVaAjzFphO4I4GBGRWj0ywFppaYmih4Wgmp4ct 1D0BzEF5QSb3gZl0bz+ONRY682Q+bRTZEBbjMAedPVKoIGt4v/EmAIwWA2vrDwPwCb1ugqe2Ee2nR oQL3fqCmoT1qNv/wSKhPpowz60xYjjk+TLqp8KDeY+TfkWDhydrQZFyL3sKkwi+tepo7dH6F4F6Vf QW4rnppg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fugaP-0001PP-37; Tue, 28 Aug 2018 16:11:21 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fugIY-0005UT-SO for linux-arm-kernel@lists.infradead.org; Tue, 28 Aug 2018 15:53:08 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7E9F1ED1; Tue, 28 Aug 2018 08:52:52 -0700 (PDT) Received: from e112298-lin.Emea.Arm.com (usa-sjc-imap-foss1.foss.arm.com [10.72.51.249]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 49A823F557; Tue, 28 Aug 2018 08:52:50 -0700 (PDT) From: Julien Thierry To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v5 27/27] irqchip/gic-v3: Allow interrupts to be set as pseudo-NMI Date: Tue, 28 Aug 2018 16:51:37 +0100 Message-Id: <1535471497-38854-28-git-send-email-julien.thierry@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1535471497-38854-1-git-send-email-julien.thierry@arm.com> References: <1535471497-38854-1-git-send-email-julien.thierry@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180828_085255_099480_92B574CF X-CRM114-Status: GOOD ( 14.96 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, daniel.thompson@linaro.org, Jason Cooper , Julien Thierry , marc.zyngier@arm.com, catalin.marinas@arm.com, will.deacon@arm.com, linux-kernel@vger.kernel.org, christoffer.dall@arm.com, james.morse@arm.com, joel@joelfernandes.org, Thomas Gleixner MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Implement NMI callbacks for GICv3 irqchip. Install NMI safe handlers when setting up interrupt line as NMI. Only SPIs and PPIs are allowed to be set up as NMI. Signed-off-by: Julien Thierry Cc: Thomas Gleixner Cc: Jason Cooper Cc: Marc Zyngier --- drivers/irqchip/irq-gic-v3.c | 73 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 1af2fcc..b1b255a 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -311,6 +311,70 @@ static int gic_irq_get_irqchip_state(struct irq_data *d, return 0; } +static int gic_irq_set_irqchip_prio(struct irq_data *d, u8 prio) +{ + struct irq_desc *desc = irq_to_desc(d->irq); + /* Number of CPUs having PPI (idx + 16) setup as NMI */ + static uint32_t nb_ppinmi_refs[16] = { 0 }; + + if (gic_peek_irq(d, GICD_ISENABLER)) { + pr_err("Cannot set NMI property of enabled IRQ %u\n", d->irq); + return -EINVAL; + } + + /* + * A secondary irq_chip should be in charge of LPI request, + * it should not be possible to get there + */ + if (WARN_ON(gic_irq(d) >= 8192)) + return -EINVAL; + + /* desc lock should already be held */ + if (prio == GICD_INT_NMI_PRI) { + if (gic_irq(d) < 32) { + /* Setting up NMI, only switch handler for first NMI */ + if (nb_ppinmi_refs[gic_irq(d) - 16] == 0) + desc->handle_irq = handle_percpu_devid_fasteoi_nmi; + + nb_ppinmi_refs[gic_irq(d) - 16]++; + } else { + desc->handle_irq = handle_fasteoi_nmi; + } + } else if (prio == GICD_INT_DEF_PRI) { + if (gic_irq(d) < 32) { + /* Tearing down NMI, only switch handler for last NMI */ + if (nb_ppinmi_refs[gic_irq(d) - 16] == 1) + desc->handle_irq = handle_percpu_devid_irq; + + nb_ppinmi_refs[gic_irq(d) - 16]--; + } else { + desc->handle_irq = handle_fasteoi_irq; + } + } else { + return -EINVAL; + } + + gic_set_irq_prio(gic_irq(d), gic_dist_base(d), prio); + + return 0; +} + +static int gic_irq_nmi_setup(struct irq_data *d) +{ + if (!gic_supports_nmi()) + return -EINVAL; + + return gic_irq_set_irqchip_prio(d, GICD_INT_NMI_PRI); +} + +static void gic_irq_nmi_teardown(struct irq_data *d) +{ + if (WARN_ON(!gic_supports_nmi())) + return; + + gic_irq_set_irqchip_prio(d, GICD_INT_DEF_PRI); +} + static void gic_eoi_irq(struct irq_data *d) { gic_write_eoir(gic_irq(d)); @@ -937,6 +1001,8 @@ static inline void gic_cpu_pm_init(void) { } .irq_set_affinity = gic_set_affinity, .irq_get_irqchip_state = gic_irq_get_irqchip_state, .irq_set_irqchip_state = gic_irq_set_irqchip_state, + .irq_nmi_setup = gic_irq_nmi_setup, + .irq_nmi_teardown = gic_irq_nmi_teardown, .flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND, @@ -952,6 +1018,8 @@ static inline void gic_cpu_pm_init(void) { } .irq_get_irqchip_state = gic_irq_get_irqchip_state, .irq_set_irqchip_state = gic_irq_set_irqchip_state, .irq_set_vcpu_affinity = gic_irq_set_vcpu_affinity, + .irq_nmi_setup = gic_irq_nmi_setup, + .irq_nmi_teardown = gic_irq_nmi_teardown, .flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND, @@ -1147,6 +1215,11 @@ static int partition_domain_translate(struct irq_domain *d, static void gic_enable_nmi_support(void) { static_branch_enable(&have_non_secure_prio_view); + + if (static_branch_likely(&supports_deactivate_key)) + gic_eoimode1_chip.flags |= IRQCHIP_SUPPORTS_NMI; + else + gic_chip.flags |= IRQCHIP_SUPPORTS_NMI; } static int __init gic_init_bases(void __iomem *dist_base,