* [PATCH] arm64: mm: Add PTE_DIRTY back to PAGE_KERNEL* to fix kexec/hibernation
@ 2026-02-27 18:53 Catalin Marinas
2026-02-28 6:06 ` Huang, Ying
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Catalin Marinas @ 2026-02-27 18:53 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Anshuman Khandual, Jianpeng Chang, Will Deacon, Huang, Ying,
Guenter Roeck
Commit 143937ca51cc ("arm64, mm: avoid always making PTE dirty in
pte_mkwrite()") changed pte_mkwrite_novma() to only clear PTE_RDONLY
when PTE_DIRTY is set. This was to allow writable-clean PTEs for swap
pages that haven't actually been written.
However, this broke kexec and hibernation for some platforms. Both go
through trans_pgd_create_copy() -> _copy_pte(), which calls
pte_mkwrite_novma() to make the temporary linear-map copy fully
writable. With the updated pte_mkwrite_novma(), read-only kernel pages
(without PTE_DIRTY) remain read-only in the temporary mapping.
While such behaviour is fine for user pages where hardware DBM or
trapping will make them writeable, subsequent in-kernel writes by the
kexec relocation code will fault.
Add PTE_DIRTY back to all _PAGE_KERNEL* protection definitions. This was
the case prior to 5.4, commit aa57157be69f ("arm64: Ensure
VM_WRITE|VM_SHARED ptes are clean by default"). With the kernel
linear-map PTEs always having PTE_DIRTY set, pte_mkwrite_novma()
correctly clears PTE_RDONLY.
Fixes: 143937ca51cc ("arm64, mm: avoid always making PTE dirty in pte_mkwrite()")
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: <stable@vger.kernel.org>
Reported-by: Jianpeng Chang <jianpeng.chang.cn@windriver.com>
Link: https://lore.kernel.org/r/20251204062722.3367201-1-jianpeng.chang.cn@windriver.com
Cc: Will Deacon <will@kernel.org>
Cc: "Huang, Ying" <ying.huang@linux.alibaba.com>
Cc: Guenter Roeck <linux@roeck-us.net>
---
Since no-one posted this as a proper patch, here it is. However, I could
not reproduce the initial kexec failure, so for me kexec is working with
our without this patch.
Testing appreciated before we decide to merge it. Thanks.
arch/arm64/include/asm/pgtable-prot.h | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 2b32639160de..f560e6420267 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -50,11 +50,11 @@
#define _PAGE_DEFAULT (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
-#define _PAGE_KERNEL (PROT_NORMAL)
-#define _PAGE_KERNEL_RO ((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY)
-#define _PAGE_KERNEL_ROX ((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY)
-#define _PAGE_KERNEL_EXEC (PROT_NORMAL & ~PTE_PXN)
-#define _PAGE_KERNEL_EXEC_CONT ((PROT_NORMAL & ~PTE_PXN) | PTE_CONT)
+#define _PAGE_KERNEL (PROT_NORMAL | PTE_DIRTY)
+#define _PAGE_KERNEL_RO ((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY | PTE_DIRTY)
+#define _PAGE_KERNEL_ROX ((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY | PTE_DIRTY)
+#define _PAGE_KERNEL_EXEC ((PROT_NORMAL & ~PTE_PXN) | PTE_DIRTY)
+#define _PAGE_KERNEL_EXEC_CONT ((PROT_NORMAL & ~PTE_PXN) | PTE_CONT | PTE_DIRTY)
#define _PAGE_SHARED (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
#define _PAGE_SHARED_EXEC (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE)
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] arm64: mm: Add PTE_DIRTY back to PAGE_KERNEL* to fix kexec/hibernation
2026-02-27 18:53 [PATCH] arm64: mm: Add PTE_DIRTY back to PAGE_KERNEL* to fix kexec/hibernation Catalin Marinas
@ 2026-02-28 6:06 ` Huang, Ying
2026-03-02 2:26 ` Jianpeng Chang
2026-03-04 16:59 ` Will Deacon
2 siblings, 0 replies; 4+ messages in thread
From: Huang, Ying @ 2026-02-28 6:06 UTC (permalink / raw)
To: Catalin Marinas
Cc: linux-arm-kernel, Anshuman Khandual, Jianpeng Chang, Will Deacon,
Guenter Roeck
Catalin Marinas <catalin.marinas@arm.com> writes:
> Commit 143937ca51cc ("arm64, mm: avoid always making PTE dirty in
> pte_mkwrite()") changed pte_mkwrite_novma() to only clear PTE_RDONLY
> when PTE_DIRTY is set. This was to allow writable-clean PTEs for swap
> pages that haven't actually been written.
>
> However, this broke kexec and hibernation for some platforms. Both go
> through trans_pgd_create_copy() -> _copy_pte(), which calls
> pte_mkwrite_novma() to make the temporary linear-map copy fully
> writable. With the updated pte_mkwrite_novma(), read-only kernel pages
> (without PTE_DIRTY) remain read-only in the temporary mapping.
> While such behaviour is fine for user pages where hardware DBM or
> trapping will make them writeable, subsequent in-kernel writes by the
> kexec relocation code will fault.
>
> Add PTE_DIRTY back to all _PAGE_KERNEL* protection definitions. This was
> the case prior to 5.4, commit aa57157be69f ("arm64: Ensure
> VM_WRITE|VM_SHARED ptes are clean by default"). With the kernel
> linear-map PTEs always having PTE_DIRTY set, pte_mkwrite_novma()
> correctly clears PTE_RDONLY.
>
> Fixes: 143937ca51cc ("arm64, mm: avoid always making PTE dirty in pte_mkwrite()")
> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> Cc: <stable@vger.kernel.org>
> Reported-by: Jianpeng Chang <jianpeng.chang.cn@windriver.com>
> Link: https://lore.kernel.org/r/20251204062722.3367201-1-jianpeng.chang.cn@windriver.com
> Cc: Will Deacon <will@kernel.org>
> Cc: "Huang, Ying" <ying.huang@linux.alibaba.com>
> Cc: Guenter Roeck <linux@roeck-us.net>
LGTM, Thanks! Feel free to add my
Reviewed-by: Huang Ying <ying.huang@linux.alibaba.com>
in the future versions.
> ---
>
> Since no-one posted this as a proper patch, here it is. However, I could
> not reproduce the initial kexec failure, so for me kexec is working with
> our without this patch.
>
> Testing appreciated before we decide to merge it. Thanks.
>
> arch/arm64/include/asm/pgtable-prot.h | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
> index 2b32639160de..f560e6420267 100644
> --- a/arch/arm64/include/asm/pgtable-prot.h
> +++ b/arch/arm64/include/asm/pgtable-prot.h
> @@ -50,11 +50,11 @@
>
> #define _PAGE_DEFAULT (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
>
> -#define _PAGE_KERNEL (PROT_NORMAL)
> -#define _PAGE_KERNEL_RO ((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY)
> -#define _PAGE_KERNEL_ROX ((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY)
> -#define _PAGE_KERNEL_EXEC (PROT_NORMAL & ~PTE_PXN)
> -#define _PAGE_KERNEL_EXEC_CONT ((PROT_NORMAL & ~PTE_PXN) | PTE_CONT)
> +#define _PAGE_KERNEL (PROT_NORMAL | PTE_DIRTY)
> +#define _PAGE_KERNEL_RO ((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY | PTE_DIRTY)
> +#define _PAGE_KERNEL_ROX ((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY | PTE_DIRTY)
> +#define _PAGE_KERNEL_EXEC ((PROT_NORMAL & ~PTE_PXN) | PTE_DIRTY)
> +#define _PAGE_KERNEL_EXEC_CONT ((PROT_NORMAL & ~PTE_PXN) | PTE_CONT | PTE_DIRTY)
>
> #define _PAGE_SHARED (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
> #define _PAGE_SHARED_EXEC (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE)
---
Best Regards,
Huang, Ying
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] arm64: mm: Add PTE_DIRTY back to PAGE_KERNEL* to fix kexec/hibernation
2026-02-27 18:53 [PATCH] arm64: mm: Add PTE_DIRTY back to PAGE_KERNEL* to fix kexec/hibernation Catalin Marinas
2026-02-28 6:06 ` Huang, Ying
@ 2026-03-02 2:26 ` Jianpeng Chang
2026-03-04 16:59 ` Will Deacon
2 siblings, 0 replies; 4+ messages in thread
From: Jianpeng Chang @ 2026-03-02 2:26 UTC (permalink / raw)
To: Catalin Marinas, linux-arm-kernel
Cc: Anshuman Khandual, Will Deacon, Huang, Ying, Guenter Roeck
在 2026/2/28 上午2:53, Catalin Marinas 写道:
> CAUTION: This email comes from a non Wind River email account!
> Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
> Commit 143937ca51cc ("arm64, mm: avoid always making PTE dirty in
> pte_mkwrite()") changed pte_mkwrite_novma() to only clear PTE_RDONLY
> when PTE_DIRTY is set. This was to allow writable-clean PTEs for swap
> pages that haven't actually been written.
>
> However, this broke kexec and hibernation for some platforms. Both go
> through trans_pgd_create_copy() -> _copy_pte(), which calls
> pte_mkwrite_novma() to make the temporary linear-map copy fully
> writable. With the updated pte_mkwrite_novma(), read-only kernel pages
> (without PTE_DIRTY) remain read-only in the temporary mapping.
> While such behaviour is fine for user pages where hardware DBM or
> trapping will make them writeable, subsequent in-kernel writes by the
> kexec relocation code will fault.
>
> Add PTE_DIRTY back to all _PAGE_KERNEL* protection definitions. This was
> the case prior to 5.4, commit aa57157be69f ("arm64: Ensure
> VM_WRITE|VM_SHARED ptes are clean by default"). With the kernel
> linear-map PTEs always having PTE_DIRTY set, pte_mkwrite_novma()
> correctly clears PTE_RDONLY.
>
> Fixes: 143937ca51cc ("arm64, mm: avoid always making PTE dirty in pte_mkwrite()")
> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> Cc: <stable@vger.kernel.org>
> Reported-by: Jianpeng Chang <jianpeng.chang.cn@windriver.com>
> Link: https://lore.kernel.org/r/20251204062722.3367201-1-jianpeng.chang.cn@windriver.com
> Cc: Will Deacon <will@kernel.org>
> Cc: "Huang, Ying" <ying.huang@linux.alibaba.com>
> Cc: Guenter Roeck <linux@roeck-us.net>
> ---
>
> Since no-one posted this as a proper patch, here it is. However, I could
> not reproduce the initial kexec failure, so for me kexec is working with
> our without this patch.
>
> Testing appreciated before we decide to merge it. Thanks.
Tested this patch on latest source with nxp-ls1043. kexec working with
this patch, here is the log before and after the patch:
root@nxp-ls1043:~# uname -a
Linux nxp-ls1043 7.0.0-rc1-yocto-preempt-rt+ #1 SMP PREEMPT_RT Mon Mar
2 10:06:01 CST 2026 aarch64 GNU/Linux
root@nxp-ls1043:~# kexec -l /boot/Image
root@nxp-ls1043:~# kexec -e
fsl_dpaa_mac 1ae0000.ethernet end0: Link is Down
Deleting MTD partitions on "spi0.0":
kvm: exiting hardware virtualization
kexec_core: Starting new kernel
IRQ66: set affinity failed(-22).
psci: CPU1 killed (polled 0 ms)
IRQ66: set affinity failed(-22).
psci: CPU2 killed (polled 0 ms)
--- HAGUP HERE ---
root@nxp-ls1043:~# uname -a
Linux nxp-ls1043 7.0.0-rc1-yocto-preempt-rt+ #1 SMP PREEMPT_RT Mon Mar
2 10:18:17 CST 2026 aarch64 GNU/Linux
root@nxp-ls1043:~# kexec -l /boot/Image
root@nxp-ls1043:~# kexec -e
fsl_dpaa_mac 1ae0000.ethernet end0: Link is Down
Deleting MTD partitions on "spi0.0":
kvm: exiting hardware virtualization
kexec_core: Starting new kernel
IRQ66: set affinity failed(-22).
psci: CPU1 killed (polled 0 ms)
IRQ66: set affinity failed(-22).
psci: CPU2 killed (polled 0 ms)
Booting Linux on physical CPU 0x0000000000 [0x410fd034]
Linux version 7.0.0-rc1-yocto-preempt-rt+ (aarch64-linux-gnu-gcc (Ubuntu
11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #1
SMP PREEMPT_RT Mon Mar 2 10:18:17 CST 2026
Machine model: LS1043A RDB Board
>
> arch/arm64/include/asm/pgtable-prot.h | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
> index 2b32639160de..f560e6420267 100644
> --- a/arch/arm64/include/asm/pgtable-prot.h
> +++ b/arch/arm64/include/asm/pgtable-prot.h
> @@ -50,11 +50,11 @@
>
> #define _PAGE_DEFAULT (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
>
> -#define _PAGE_KERNEL (PROT_NORMAL)
> -#define _PAGE_KERNEL_RO ((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY)
> -#define _PAGE_KERNEL_ROX ((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY)
> -#define _PAGE_KERNEL_EXEC (PROT_NORMAL & ~PTE_PXN)
> -#define _PAGE_KERNEL_EXEC_CONT ((PROT_NORMAL & ~PTE_PXN) | PTE_CONT)
> +#define _PAGE_KERNEL (PROT_NORMAL | PTE_DIRTY)
> +#define _PAGE_KERNEL_RO ((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY | PTE_DIRTY)
> +#define _PAGE_KERNEL_ROX ((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY | PTE_DIRTY)
> +#define _PAGE_KERNEL_EXEC ((PROT_NORMAL & ~PTE_PXN) | PTE_DIRTY)
> +#define _PAGE_KERNEL_EXEC_CONT ((PROT_NORMAL & ~PTE_PXN) | PTE_CONT | PTE_DIRTY)
>
> #define _PAGE_SHARED (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
> #define _PAGE_SHARED_EXEC (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE)
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] arm64: mm: Add PTE_DIRTY back to PAGE_KERNEL* to fix kexec/hibernation
2026-02-27 18:53 [PATCH] arm64: mm: Add PTE_DIRTY back to PAGE_KERNEL* to fix kexec/hibernation Catalin Marinas
2026-02-28 6:06 ` Huang, Ying
2026-03-02 2:26 ` Jianpeng Chang
@ 2026-03-04 16:59 ` Will Deacon
2 siblings, 0 replies; 4+ messages in thread
From: Will Deacon @ 2026-03-04 16:59 UTC (permalink / raw)
To: linux-arm-kernel, Catalin Marinas
Cc: kernel-team, Will Deacon, Anshuman Khandual, Jianpeng Chang,
Huang, Ying, Guenter Roeck
On Fri, 27 Feb 2026 18:53:06 +0000, Catalin Marinas wrote:
> Commit 143937ca51cc ("arm64, mm: avoid always making PTE dirty in
> pte_mkwrite()") changed pte_mkwrite_novma() to only clear PTE_RDONLY
> when PTE_DIRTY is set. This was to allow writable-clean PTEs for swap
> pages that haven't actually been written.
>
> However, this broke kexec and hibernation for some platforms. Both go
> through trans_pgd_create_copy() -> _copy_pte(), which calls
> pte_mkwrite_novma() to make the temporary linear-map copy fully
> writable. With the updated pte_mkwrite_novma(), read-only kernel pages
> (without PTE_DIRTY) remain read-only in the temporary mapping.
> While such behaviour is fine for user pages where hardware DBM or
> trapping will make them writeable, subsequent in-kernel writes by the
> kexec relocation code will fault.
>
> [...]
Applied to arm64 (for-next/fixes), thanks!
[1/1] arm64: mm: Add PTE_DIRTY back to PAGE_KERNEL* to fix kexec/hibernation
https://git.kernel.org/arm64/c/c25c4aa3f79a
Cheers,
--
Will
https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-03-04 16:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-27 18:53 [PATCH] arm64: mm: Add PTE_DIRTY back to PAGE_KERNEL* to fix kexec/hibernation Catalin Marinas
2026-02-28 6:06 ` Huang, Ying
2026-03-02 2:26 ` Jianpeng Chang
2026-03-04 16:59 ` Will Deacon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox