From nobody Sun May 24 20:35:13 2026 Received: from relay.smtp-ext.broadcom.com (relay.smtp-ext.broadcom.com [192.19.166.228]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 08F1F4A33 for ; Sat, 23 May 2026 00:08:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.19.166.228 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779494928; cv=none; b=Ip5g7vZj386wkCHSvsCfbudxH79CN/q1LDRmTzPdhBIF6z5aE2eBTm9lupV0bxC8lCv9GFAQpFmMy/hVfaJdLM3tKa2oO0EJBNzVfWSwXO9sagVb5nI5hgBnRtIRu5Ny8NzGqfJbGw0S7bQH+1Fu8kEU/umenuV7QCXcrZb6jjU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779494928; c=relaxed/simple; bh=2sJbe5aNcbDbTxr/zYWLUir+Mj6TearfTKYTm7ulyIo=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=OsyveT4R8XulNePd06GYA8g3uT3qLRD34V1Q3qPEdLpY8fDwvz2zlvg0Jso4FlL7gLClH3UbWoZyyDjH7BDiKK5TO8nuXMiID2xNJC/x6m4EnVwSbyy6P9GWrIDZatMGF18ofkcQym6Aw0RanwIrDBVbN01fVfQnUBlnfzj4lTQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com; spf=fail smtp.mailfrom=broadcom.com; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b=tr0ctYZd; arc=none smtp.client-ip=192.19.166.228 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=broadcom.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=broadcom.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="tr0ctYZd" Received: from mail-lvn-it-01.broadcom.com (mail-lvn-it-01.lvn.broadcom.net [10.36.132.253]) by relay.smtp-ext.broadcom.com (Postfix) with ESMTP id 61C02C010AFE; Fri, 22 May 2026 17:08:40 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 relay.smtp-ext.broadcom.com 61C02C010AFE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1779494920; bh=2sJbe5aNcbDbTxr/zYWLUir+Mj6TearfTKYTm7ulyIo=; h=From:To:Cc:Subject:Date:From; b=tr0ctYZduMOKejbygefyQ6ZXs0WgoS9plo0ZiZZqiG2AGg9PDyVmMDrk/WF8PQdkr po0+bbf1Wh7jRd5QmREv6l3hasyrys8TPA2r5xqPoGRs6woe22ONNdipwtf+QXQv1N C3uFBONXLrgpLDooCHJhnoqeGgkSrJmu2ZjGTTcY= Received: from stbirv-lnx-1.igp.broadcom.net (stbirv-lnx-1.igp.broadcom.net [10.67.48.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail-lvn-it-01.broadcom.com (Postfix) with ESMTPSA id 431A7A83; Fri, 22 May 2026 17:08:40 -0700 (PDT) From: Florian Fainelli To: linux-arm-kernel@lists.infradead.org Cc: bcm-kernel-feedback-list@broadcom.com, Florian Fainelli , Catalin Marinas , Linus Walleij , Russell King , Linus Walleij , "Russell King (Oracle)" , Kees Cook , linux-kernel@vger.kernel.org (open list) Subject: [PATCH] ARM: mm: fix kexec and hibernation with CONFIG_CPU_TTBR0_PAN Date: Fri, 22 May 2026 17:08:37 -0700 Message-Id: <20260523000839.430550-1-florian.fainelli@broadcom.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Commit 7af5b901e847 ("ARM: 9358/2: Implement PAN for LPAE by TTBR0 page table walks disablement") implemented PAN for LPAE kernels by setting TTBCR.EPD0 on every kernel entry, disabling TTBR0 page-table walks while running in kernel mode. The commit correctly updated cpu_suspend() in arch/arm/kernel/suspend.c, but missed two other code paths that switch the CPU to the identity mapping before jumping to low-PA (TTBR0-range) physical addresses: 1. setup_mm_for_reboot() in arch/arm/mm/idmap.c, used by the kexec reboot path. With TTBCR.EPD0 still set, the subsequent branch to the identity-mapped cpu_v7_reset causes a PrefetchAbort because the TTBR0 page-table walk needed to resolve the identity-mapped address is disabled. This manifests as a hard hang or "bad PC value" panic on LPAE kernels booted on CPUs that strictly enforce EPD0 for instruction fetch (e.g. Cortex-A53 in AArch32 mode) while the same image may accidentally work on Cortex-A15 due to microarchitectural differences in EPD0 enforcement. 2. arch_restore_image() in arch/arm/kernel/hibernate.c, which calls cpu_switch_mm(idmap_pgd, &init_mm) directly without going through setup_mm_for_reboot(), leaving TTBCR.EPD0 set while the identity mapping is active. Fix both sites by calling uaccess_save_and_enable() before switching to the identity mapping, mirroring what the original commit did for cpu_suspend(). Fixes: 7af5b901e847 ("ARM: 9358/2: Implement PAN for LPAE by TTBR0 page tab= le walks disablement") Cc: Catalin Marinas Cc: Linus Walleij Assisted-by: Cursor:claude-sonnet-4.6 Signed-off-by: Florian Fainelli --- arch/arm/kernel/hibernate.c | 10 ++++++++++ arch/arm/mm/idmap.c | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/arch/arm/kernel/hibernate.c b/arch/arm/kernel/hibernate.c index 38a90a3d12b2..231a76af09a0 100644 --- a/arch/arm/kernel/hibernate.c +++ b/arch/arm/kernel/hibernate.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "reboot.h" =20 int pfn_is_nosave(unsigned long pfn) @@ -82,6 +83,15 @@ static void notrace arch_restore_image(void *unused) { struct pbe *pbe; =20 + /* + * With CONFIG_CPU_TTBR0_PAN enabled, TTBCR.EPD0 is set to block + * TTBR0 page-table walks. The identity mapping used here lives at + * low (user-space) virtual addresses and is only reachable via + * TTBR0, so re-enable those walks before switching page tables. + * On non-PAN kernels this is a no-op. + */ + if (IS_ENABLED(CONFIG_CPU_TTBR0_PAN)) + uaccess_save_and_enable(); cpu_switch_mm(idmap_pgd, &init_mm); for (pbe =3D restore_pblist; pbe; pbe =3D pbe->next) copy_page(pbe->orig_address, pbe->address); diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index 4a833e89782a..70403e968d2a 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -11,6 +11,7 @@ #include #include #include +#include =20 /* * Note: accesses outside of the kernel image and the identity map area @@ -133,6 +134,17 @@ early_initcall(init_static_idmap); */ void setup_mm_for_reboot(void) { + /* + * With CONFIG_CPU_TTBR0_PAN enabled, TTBCR.EPD0 is set whenever + * user-space access is disabled in order to block TTBR0 page-table + * walks. The identity mapping lives at low (user-space) virtual + * addresses and can only be reached via TTBR0, so we must re-enable + * those walks before switching page tables. On non-PAN kernels this + * is a no-op. + */ + if (IS_ENABLED(CONFIG_CPU_TTBR0_PAN)) + uaccess_save_and_enable(); + /* Switch to the identity mapping. */ cpu_switch_mm(idmap_pgd, &init_mm); local_flush_bp_all(); --=20 2.34.1