From nobody Tue Feb 10 11:15:39 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72DDCEE14AC for ; Wed, 6 Sep 2023 16:06:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242568AbjIFQG0 (ORCPT ); Wed, 6 Sep 2023 12:06:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39114 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242011AbjIFQGW (ORCPT ); Wed, 6 Sep 2023 12:06:22 -0400 Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 150CB19A5 for ; Wed, 6 Sep 2023 09:06:04 -0700 (PDT) Received: by mail-pl1-x62d.google.com with SMTP id d9443c01a7336-1c337aeefbdso27072685ad.0 for ; Wed, 06 Sep 2023 09:06:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1694016363; x=1694621163; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=9AStTiUn2wkKE7iLM15Ptbf7v9P7cN3w/9Lr/OinoUk=; b=KW3Lsff/KOcUnmPbv+7g2bg7vEfPoL6Uo8fF2q6ru+p/YS4Vr7rS36uqfsg7MOTxDa v6O/SEZzZ1Yd60Es1ZVJWfPzLXNUApm85c4txi4xY3xedZIMnTkPNzaVJl+1XVaRanC2 3GoXrMvBeMljF7wUY/GUhGP5QYrSTuuRby6eA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1694016363; x=1694621163; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9AStTiUn2wkKE7iLM15Ptbf7v9P7cN3w/9Lr/OinoUk=; b=RlzcMcuabgNbDRrUIHcO6gfoRogsqfCSpK72bqLcyXipiaP4FdEmAJlpbRS9/mCjCJ g+FwWiC1189i1wS5dw4S21mRt+p4ia2nOYxnOhn68Dj+L+AqBZ0KM5vzbjdpUNm0jAmL gkYkraaRfi5CvcPiBkoUA0VzzI62Z3B2teaV1ky4yUtuFAO7O7kUAWKZioY3hf4E3hs+ Nb3TDN+MtqDSuOGmKyGcfg47VMJxLwmXLCc2pqnJBmfZlT2psry8VnSXd0Tys1DFDPIi 7g670oGou0bG6xQR5TqOm2bFVO2kIQcYZ/8sdZcg56CUNL9ibaJo7d9GYWs08i5C7Bxu mseQ== X-Gm-Message-State: AOJu0Yza0RPVm491O7YInXtgmoynCymLoto/htsQshhCGvNPQQpmDVPG 8VL6XYqWytzagcZhBBW18USjTg== X-Google-Smtp-Source: AGHT+IHvnL/4JaRFUJ+xW/5TxV7a56fOHoi2Ui181sO6LOlIeDV0WX7gAscP3gPGe2rpmUXdId80sQ== X-Received: by 2002:a17:902:ea01:b0:1bf:205e:fe5d with SMTP id s1-20020a170902ea0100b001bf205efe5dmr20963955plg.7.1694016363355; Wed, 06 Sep 2023 09:06:03 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:9d:2:4a07:e00a:fdae:750b]) by smtp.gmail.com with ESMTPSA id ju19-20020a170903429300b001b8c689060dsm11338859plb.28.2023.09.06.09.06.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Sep 2023 09:06:02 -0700 (PDT) From: Douglas Anderson To: Mark Rutland , Catalin Marinas , Will Deacon , Sumit Garg , Daniel Thompson , Marc Zyngier Cc: linux-arm-kernel@lists.infradead.org, "Rafael J . Wysocki" , Lecopzer Chen , Chen-Yu Tsai , Tomohiro Misono , Peter Zijlstra , Masayoshi Mizuma , Stephane Eranian , Ard Biesheuvel , kgdb-bugreport@lists.sourceforge.net, Stephen Boyd , linux-perf-users@vger.kernel.org, Thomas Gleixner , ito-yuichi@fujitsu.com, Douglas Anderson , Chen-Yu Tsai , linux-kernel@vger.kernel.org Subject: [PATCH v13 1/7] irqchip/gic-v3: Enable support for SGIs to act as NMIs Date: Wed, 6 Sep 2023 09:02:56 -0700 Message-ID: <20230906090246.v13.1.I1223c11c88937bd0cbd9b086d4ef216985797302@changeid> X-Mailer: git-send-email 2.42.0.283.g2d96d420d3-goog In-Reply-To: <20230906160505.2431857-1-dianders@chromium.org> References: <20230906160505.2431857-1-dianders@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" As of commit 6abbd6988971 ("irqchip/gic, gic-v3: Make SGIs use handle_percpu_devid_irq()") SGIs are treated the same as PPIs/EPPIs and use handle_percpu_devid_irq() by default. Unfortunately, handle_percpu_devid_irq() isn't NMI safe, and so to run in an NMI context those should use handle_percpu_devid_fasteoi_nmi(). In order to accomplish this, we just have to make room for SGIs in the array of refcounts that keeps track of which interrupts are set as NMI. We also rename the array and create a new indexing scheme that accounts for SGIs. Also, enable NMI support prior to gic_smp_init() as allocation of SGIs as IRQs/NMIs happen as part of this routine. Co-developed-by: Sumit Garg Signed-off-by: Sumit Garg Acked-by: Mark Rutland Tested-by: Chen-Yu Tsai Signed-off-by: Douglas Anderson Acked-by: Marc Zyngier --- I'll note that this change is a little more black magic to me than others in this series. I don't have a massive amounts of familiarity with all the moving parts of gic-v3, so I mostly just followed Mark Rutland's advice [1]. As per discussion [2], the hope is that this patch could get Acked by Marc Zyngier and then land through the arm64 tree. If this isn't a good idea for some reason, I'd love suggestions for alternate ways for this series to land. [1] https://lore.kernel.org/r/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.c= om [2] https://lore.kernel.org/r/ZPC1nUw3qKWrC85l@FVFF77S0Q05N.cambridge.arm.c= om Changes in v13: - s/_idx/_index/ on the patch to make function names consistent. Changes in v12: - Added a comment about why we account for 16 SGIs when Linux uses 8. Changes in v10: - Rewrite as needed for 5.11+ as per Mark Rutland and Sumit. drivers/irqchip/irq-gic-v3.c | 59 +++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index eedfa8e9f077..787ccc880b22 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -78,6 +78,13 @@ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key); #define GIC_LINE_NR min(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U) #define GIC_ESPI_NR GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer) =20 +/* + * There are 16 SGIs, though we only actually use 8 in Linux. The other 8 = SGIs + * are potentially stolen by the secure side. Some code, especially code d= ealing + * with hwirq IDs, is simplified by accounting for all 16. + */ +#define SGI_NR 16 + /* * The behaviours of RPR and PMR registers differ depending on the value of * SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the @@ -125,8 +132,8 @@ EXPORT_SYMBOL(gic_nonsecure_priorities); __priority; \ }) =20 -/* ppi_nmi_refs[n] =3D=3D number of cpus having ppi[n + 16] set as NMI */ -static refcount_t *ppi_nmi_refs; +/* rdist_nmi_refs[n] =3D=3D number of cpus having the rdist interrupt n se= t as NMI */ +static refcount_t *rdist_nmi_refs; =20 static struct gic_kvm_info gic_v3_kvm_info __initdata; static DEFINE_PER_CPU(bool, has_rss); @@ -519,9 +526,22 @@ static u32 __gic_get_ppi_index(irq_hw_number_t hwirq) } } =20 -static u32 gic_get_ppi_index(struct irq_data *d) +static u32 __gic_get_rdist_index(irq_hw_number_t hwirq) +{ + switch (__get_intid_range(hwirq)) { + case SGI_RANGE: + case PPI_RANGE: + return hwirq; + case EPPI_RANGE: + return hwirq - EPPI_BASE_INTID + 32; + default: + unreachable(); + } +} + +static u32 gic_get_rdist_index(struct irq_data *d) { - return __gic_get_ppi_index(d->hwirq); + return __gic_get_rdist_index(d->hwirq); } =20 static int gic_irq_nmi_setup(struct irq_data *d) @@ -545,11 +565,14 @@ static int gic_irq_nmi_setup(struct irq_data *d) =20 /* desc lock should already be held */ if (gic_irq_in_rdist(d)) { - u32 idx =3D gic_get_ppi_index(d); + u32 idx =3D gic_get_rdist_index(d); =20 - /* Setting up PPI as NMI, only switch handler for first NMI */ - if (!refcount_inc_not_zero(&ppi_nmi_refs[idx])) { - refcount_set(&ppi_nmi_refs[idx], 1); + /* + * Setting up a percpu interrupt as NMI, only switch handler + * for first NMI + */ + if (!refcount_inc_not_zero(&rdist_nmi_refs[idx])) { + refcount_set(&rdist_nmi_refs[idx], 1); desc->handle_irq =3D handle_percpu_devid_fasteoi_nmi; } } else { @@ -582,10 +605,10 @@ static void gic_irq_nmi_teardown(struct irq_data *d) =20 /* desc lock should already be held */ if (gic_irq_in_rdist(d)) { - u32 idx =3D gic_get_ppi_index(d); + u32 idx =3D gic_get_rdist_index(d); =20 /* Tearing down NMI, only switch handler for last NMI */ - if (refcount_dec_and_test(&ppi_nmi_refs[idx])) + if (refcount_dec_and_test(&rdist_nmi_refs[idx])) desc->handle_irq =3D handle_percpu_devid_irq; } else { desc->handle_irq =3D handle_fasteoi_irq; @@ -1279,10 +1302,10 @@ static void gic_cpu_init(void) rbase =3D gic_data_rdist_sgi_base(); =20 /* Configure SGIs/PPIs as non-secure Group-1 */ - for (i =3D 0; i < gic_data.ppi_nr + 16; i +=3D 32) + for (i =3D 0; i < gic_data.ppi_nr + SGI_NR; i +=3D 32) writel_relaxed(~0, rbase + GICR_IGROUPR0 + i / 8); =20 - gic_cpu_config(rbase, gic_data.ppi_nr + 16, gic_redist_wait_for_rwp); + gic_cpu_config(rbase, gic_data.ppi_nr + SGI_NR, gic_redist_wait_for_rwp); =20 /* initialise system registers */ gic_cpu_sys_reg_init(); @@ -1939,12 +1962,13 @@ static void gic_enable_nmi_support(void) return; } =20 - ppi_nmi_refs =3D kcalloc(gic_data.ppi_nr, sizeof(*ppi_nmi_refs), GFP_KERN= EL); - if (!ppi_nmi_refs) + rdist_nmi_refs =3D kcalloc(gic_data.ppi_nr + SGI_NR, + sizeof(*rdist_nmi_refs), GFP_KERNEL); + if (!rdist_nmi_refs) return; =20 - for (i =3D 0; i < gic_data.ppi_nr; i++) - refcount_set(&ppi_nmi_refs[i], 0); + for (i =3D 0; i < gic_data.ppi_nr + SGI_NR; i++) + refcount_set(&rdist_nmi_refs[i], 0); =20 pr_info("Pseudo-NMIs enabled using %s ICC_PMR_EL1 synchronisation\n", gic_has_relaxed_pmr_sync() ? "relaxed" : "forced"); @@ -2061,6 +2085,7 @@ static int __init gic_init_bases(phys_addr_t dist_phy= s_base, =20 gic_dist_init(); gic_cpu_init(); + gic_enable_nmi_support(); gic_smp_init(); gic_cpu_pm_init(); =20 @@ -2073,8 +2098,6 @@ static int __init gic_init_bases(phys_addr_t dist_phy= s_base, gicv2m_init(handle, gic_data.domain); } =20 - gic_enable_nmi_support(); - return 0; =20 out_free: --=20 2.42.0.283.g2d96d420d3-goog