From patchwork Thu Aug 22 10:23:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Rutland X-Patchwork-Id: 13773193 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 078FFC5320E for ; Thu, 22 Aug 2024 10:26:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=XeyPVa8j82ZAZnhI5CIpB+llAO2ri4OId8Q5ECxjBdQ=; b=h+1wF4eyUXclIiKIe7bWujbzL+ JztFlNZ2/13+SX2dzmvj4fV3e4xZa/bw2crb9fxgJOtvsZOBWWMPcj8t5UNGirlo+H4+nM2S1+NsH uphy2n+LA8GCBwuWvEsxeVmFfMWqF7wPwiloV4eApoE9IGSUVqPeIzMp5VmXumYKbm5GcM+kaqS5k bFfLsO/Cxq5OafiLdB3o9i9ZGlWN3DY0zXfS4ClMG8xlRagAKKWhys7oRMDjW/m/SPxJblfXV/i5G QDomw7ry8u3bb7/87VkppPfZHlFb7S+ZXhvIqnLUZdCURYC/R5k4aNY52KlN7M5aHlSI/9vggoMoo b1NSjBEg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sh51C-0000000CQap-3NJe; Thu, 22 Aug 2024 10:26:14 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sh4yL-0000000CPrf-1Lry for linux-arm-kernel@lists.infradead.org; Thu, 22 Aug 2024 10:23:19 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B4140DA7; Thu, 22 Aug 2024 03:23:42 -0700 (PDT) Received: from lakrids.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.121.207.14]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id BAB8E3F66E; Thu, 22 Aug 2024 03:23:14 -0700 (PDT) From: Mark Rutland To: linux-arm-kernel@lists.infradead.org Cc: alexandru.elisei@arm.com, andre.przywara@arm.com, catalin.marinas@arm.com, mark.rutland@arm.com, maz@kernel.org, tglx@linutronix.de, will@kernel.org Subject: [PATCH v2] irqchip/gic-v3: init SRE before poking sysregs Date: Thu, 22 Aug 2024 11:23:08 +0100 Message-Id: <20240822102308.283733-1-mark.rutland@arm.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240822_032317_496792_73A20BB4 X-CRM114-Status: GOOD ( 14.11 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The GICv3 driver pokes GICv3 system registers in gic_prio_init() before gic_cpu_sys_reg_init() ensures that GICv3 system registers have been enabled by writing to ICC_SRE_EL1.SRE. On arm64 this is benign as has_useable_gicv3_cpuif() runs earlier during cpufeature detection, and this enables the GICv3 system registers. On 32-bit arm we're not so lucky, and when booting on an FVP using the boot-wrapper, the accesses in gic_prio_init() end up being UNDEFINED and crash the kernel during boot. This is a regression introduced by commit: d447bf09a4013541 ("irqchip/gic-v3: Detect GICD_CTRL.DS and SCR_EL3.FIQ earlier") ... which added gic_prio_init(). Fix this by factoring out the SRE initialization into a new gic_cpu_sys_reg_enable(),, and calling this early in the three paths where SRE may not have been initialized: (1) gic_init_bases(), before the primary CPU pokes GICv3 sysregs in gic_prio_init(). (2) gic_starting_cpu(), before secondary CPUs initialize GICv3 sysregs in gic_cpu_init(). (3) gic_cpu_pm_notifier(), before CPUs re-initialize GICv3 sysregs in gic_cpu_sys_reg_init(). Fixes: d447bf09a4013541 ("irqchip/gic-v3: Detect GICD_CTRL.DS and SCR_EL3.FIQ earlier") Signed-off-by: Mark Rutland Reviewed-by: Marc Zyngier Cc: Alexandru Elisei Cc: Andre Przywara Cc: Catalin Marinas Cc: Thomas Gleixner Cc: Will Deacon --- drivers/irqchip/irq-gic-v3.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) Since v1 [1]: * Simplify and cleanup commit message * Rename gic_sre_init() => gic_cpu_sys_reg_enable() [1] https://lore.kernel.org/linux-arm-kernel/20240820155506.100164-1-mark.rutland@arm.com diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index c19083bfb9432..74f21e03d4a37 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1154,14 +1154,8 @@ static void gic_update_rdist_properties(void) gic_data.rdists.has_vpend_valid_dirty ? "Valid+Dirty " : ""); } -static void gic_cpu_sys_reg_init(void) +static void gic_cpu_sys_reg_enable(void) { - int i, cpu = smp_processor_id(); - u64 mpidr = gic_cpu_to_affinity(cpu); - u64 need_rss = MPIDR_RS(mpidr); - bool group0; - u32 pribits; - /* * Need to check that the SRE bit has actually been set. If * not, it means that SRE is disabled at EL2. We're going to @@ -1172,6 +1166,16 @@ static void gic_cpu_sys_reg_init(void) if (!gic_enable_sre()) pr_err("GIC: unable to set SRE (disabled at EL2), panic ahead\n"); +} + +static void gic_cpu_sys_reg_init(void) +{ + int i, cpu = smp_processor_id(); + u64 mpidr = gic_cpu_to_affinity(cpu); + u64 need_rss = MPIDR_RS(mpidr); + bool group0; + u32 pribits; + pribits = gic_get_pribits(); group0 = gic_has_group0(); @@ -1333,6 +1337,7 @@ static int gic_check_rdist(unsigned int cpu) static int gic_starting_cpu(unsigned int cpu) { + gic_cpu_sys_reg_enable(); gic_cpu_init(); if (gic_dist_supports_lpis()) @@ -1498,6 +1503,7 @@ static int gic_cpu_pm_notifier(struct notifier_block *self, if (cmd == CPU_PM_EXIT) { if (gic_dist_security_disabled()) gic_enable_redist(true); + gic_cpu_sys_reg_enable(); gic_cpu_sys_reg_init(); } else if (cmd == CPU_PM_ENTER && gic_dist_security_disabled()) { gic_write_grpen1(0); @@ -2070,6 +2076,7 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base, gic_update_rdist_properties(); + gic_cpu_sys_reg_enable(); gic_prio_init(); gic_dist_init(); gic_cpu_init();