public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
* [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