* [PATCH v2] arm64: fix cleared E0POE bit after cpu_suspend()/resume()
@ 2026-01-07 16:21 Yeoreum Yun
2026-01-07 16:54 ` Kevin Brodsky
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Yeoreum Yun @ 2026-01-07 16:21 UTC (permalink / raw)
To: linux-pm, linux-arm-kernel, linux-kernel
Cc: rafael, pavel, catalin.marinas, will, anshuman.khandual,
ryan.roberts, yang, joey.gouly, kevin.brodsky, Yeoreum Yun,
stable
TCR2_ELx.E0POE is set during smp_init().
However, this bit is not reprogrammed when the CPU enters suspension and
later resumes via cpu_resume(), as __cpu_setup() does not re-enable E0POE
and there is no save/restore logic for the TCR2_ELx system register.
As a result, the E0POE feature no longer works after cpu_resume().
To address this, save and restore TCR2_EL1 in the cpu_suspend()/cpu_resume()
path, rather than adding related logic to __cpu_setup(), taking into account
possible future extensions of the TCR2_ELx feature.
Cc: stable@vger.kernel.org
Fixes: bf83dae90fbc ("arm64: enable the Permission Overlay Extension for EL0")
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
Patch History
==============
from v1 to v2:
- following @Kevin Brodsky suggestion.
- https://lore.kernel.org/all/20260105200707.2071169-1-yeoreum.yun@arm.com/
NOTE:
This patch based on v6.19-rc4
---
arch/arm64/include/asm/suspend.h | 2 +-
arch/arm64/mm/proc.S | 8 ++++++++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h
index e65f33edf9d6..e9ce68d50ba4 100644
--- a/arch/arm64/include/asm/suspend.h
+++ b/arch/arm64/include/asm/suspend.h
@@ -2,7 +2,7 @@
#ifndef __ASM_SUSPEND_H
#define __ASM_SUSPEND_H
-#define NR_CTX_REGS 13
+#define NR_CTX_REGS 14
#define NR_CALLEE_SAVED_REGS 12
/*
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 01e868116448..5d907ce3b6d3 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -110,6 +110,10 @@ SYM_FUNC_START(cpu_do_suspend)
* call stack.
*/
str x18, [x0, #96]
+alternative_if ARM64_HAS_TCR2
+ mrs x2, REG_TCR2_EL1
+ str x2, [x0, #104]
+alternative_else_nop_endif
ret
SYM_FUNC_END(cpu_do_suspend)
@@ -144,6 +148,10 @@ SYM_FUNC_START(cpu_do_resume)
msr tcr_el1, x8
msr vbar_el1, x9
msr mdscr_el1, x10
+alternative_if ARM64_HAS_TCR2
+ ldr x2, [x0, #104]
+ msr REG_TCR2_EL1, x2
+alternative_else_nop_endif
msr sctlr_el1, x12
set_this_cpu_offset x13
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2] arm64: fix cleared E0POE bit after cpu_suspend()/resume()
2026-01-07 16:21 [PATCH v2] arm64: fix cleared E0POE bit after cpu_suspend()/resume() Yeoreum Yun
@ 2026-01-07 16:54 ` Kevin Brodsky
2026-01-07 17:30 ` Yeoreum Yun
2026-01-08 5:25 ` Anshuman Khandual
2026-01-09 18:00 ` Catalin Marinas
2 siblings, 1 reply; 6+ messages in thread
From: Kevin Brodsky @ 2026-01-07 16:54 UTC (permalink / raw)
To: Yeoreum Yun, linux-pm, linux-arm-kernel, linux-kernel
Cc: rafael, pavel, catalin.marinas, will, anshuman.khandual,
ryan.roberts, yang, joey.gouly, stable
On 07/01/2026 17:21, Yeoreum Yun wrote:
> TCR2_ELx.E0POE is set during smp_init().
> However, this bit is not reprogrammed when the CPU enters suspension and
> later resumes via cpu_resume(), as __cpu_setup() does not re-enable E0POE
> and there is no save/restore logic for the TCR2_ELx system register.
>
> As a result, the E0POE feature no longer works after cpu_resume().
>
> To address this, save and restore TCR2_EL1 in the cpu_suspend()/cpu_resume()
> path, rather than adding related logic to __cpu_setup(), taking into account
> possible future extensions of the TCR2_ELx feature.
>
> Cc: stable@vger.kernel.org
> Fixes: bf83dae90fbc ("arm64: enable the Permission Overlay Extension for EL0")
> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> ---
>
> Patch History
> ==============
> from v1 to v2:
> - following @Kevin Brodsky suggestion.
> - https://lore.kernel.org/all/20260105200707.2071169-1-yeoreum.yun@arm.com/
>
> NOTE:
> This patch based on v6.19-rc4
> ---
> arch/arm64/include/asm/suspend.h | 2 +-
> arch/arm64/mm/proc.S | 8 ++++++++
> 2 files changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h
> index e65f33edf9d6..e9ce68d50ba4 100644
> --- a/arch/arm64/include/asm/suspend.h
> +++ b/arch/arm64/include/asm/suspend.h
> @@ -2,7 +2,7 @@
> #ifndef __ASM_SUSPEND_H
> #define __ASM_SUSPEND_H
>
> -#define NR_CTX_REGS 13
> +#define NR_CTX_REGS 14
> #define NR_CALLEE_SAVED_REGS 12
>
> /*
> diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
> index 01e868116448..5d907ce3b6d3 100644
> --- a/arch/arm64/mm/proc.S
> +++ b/arch/arm64/mm/proc.S
> @@ -110,6 +110,10 @@ SYM_FUNC_START(cpu_do_suspend)
> * call stack.
> */
> str x18, [x0, #96]
> +alternative_if ARM64_HAS_TCR2
> + mrs x2, REG_TCR2_EL1
> + str x2, [x0, #104]
> +alternative_else_nop_endif
> ret
> SYM_FUNC_END(cpu_do_suspend)
>
> @@ -144,6 +148,10 @@ SYM_FUNC_START(cpu_do_resume)
> msr tcr_el1, x8
> msr vbar_el1, x9
> msr mdscr_el1, x10
> +alternative_if ARM64_HAS_TCR2
> + ldr x2, [x0, #104]
> + msr REG_TCR2_EL1, x2
> +alternative_else_nop_endif
Maybe this could be pushed further down cpu_do_resume, next to DISR_EL1
maybe (since it's also conditional)? Otherwise the diff LGTM:
Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com>
- Kevin
> msr sctlr_el1, x12
> set_this_cpu_offset x13
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] arm64: fix cleared E0POE bit after cpu_suspend()/resume()
2026-01-07 16:54 ` Kevin Brodsky
@ 2026-01-07 17:30 ` Yeoreum Yun
2026-01-12 9:36 ` Kevin Brodsky
0 siblings, 1 reply; 6+ messages in thread
From: Yeoreum Yun @ 2026-01-07 17:30 UTC (permalink / raw)
To: Kevin Brodsky
Cc: linux-pm, linux-arm-kernel, linux-kernel, rafael, pavel,
catalin.marinas, will, anshuman.khandual, ryan.roberts, yang,
joey.gouly, stable
Hi Kevin,
[...]
> > @@ -144,6 +148,10 @@ SYM_FUNC_START(cpu_do_resume)
> > msr tcr_el1, x8
> > msr vbar_el1, x9
> > msr mdscr_el1, x10
> > +alternative_if ARM64_HAS_TCR2
> > + ldr x2, [x0, #104]
> > + msr REG_TCR2_EL1, x2
> > +alternative_else_nop_endif
>
> Maybe this could be pushed further down cpu_do_resume, next to DISR_EL1
> maybe (since it's also conditional)? Otherwise the diff LGTM:
Sorry but IIUC, currently there is no DISR_EL1 save/restore not yet?
and I think current place is good where before restore SCTLR_EL1 which
before MMU enabled.
Am I missing something?
Thanks.
--
Sincerely,
Yeoreum Yun
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] arm64: fix cleared E0POE bit after cpu_suspend()/resume()
2026-01-07 16:21 [PATCH v2] arm64: fix cleared E0POE bit after cpu_suspend()/resume() Yeoreum Yun
2026-01-07 16:54 ` Kevin Brodsky
@ 2026-01-08 5:25 ` Anshuman Khandual
2026-01-09 18:00 ` Catalin Marinas
2 siblings, 0 replies; 6+ messages in thread
From: Anshuman Khandual @ 2026-01-08 5:25 UTC (permalink / raw)
To: Yeoreum Yun, linux-pm, linux-arm-kernel, linux-kernel
Cc: rafael, pavel, catalin.marinas, will, ryan.roberts, yang,
joey.gouly, kevin.brodsky, stable
On 07/01/26 9:51 PM, Yeoreum Yun wrote:
> TCR2_ELx.E0POE is set during smp_init().
> However, this bit is not reprogrammed when the CPU enters suspension and
> later resumes via cpu_resume(), as __cpu_setup() does not re-enable E0POE
> and there is no save/restore logic for the TCR2_ELx system register.
>
> As a result, the E0POE feature no longer works after cpu_resume().
>
> To address this, save and restore TCR2_EL1 in the cpu_suspend()/cpu_resume()
> path, rather than adding related logic to __cpu_setup(), taking into account
> possible future extensions of the TCR2_ELx feature.
>
> Cc: stable@vger.kernel.org
> Fixes: bf83dae90fbc ("arm64: enable the Permission Overlay Extension for EL0")
> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> ---
>
> Patch History
> ==============
> from v1 to v2:
> - following @Kevin Brodsky suggestion.
> - https://lore.kernel.org/all/20260105200707.2071169-1-yeoreum.yun@arm.com/
>
> NOTE:
> This patch based on v6.19-rc4
> ---
> arch/arm64/include/asm/suspend.h | 2 +-
> arch/arm64/mm/proc.S | 8 ++++++++
> 2 files changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h
> index e65f33edf9d6..e9ce68d50ba4 100644
> --- a/arch/arm64/include/asm/suspend.h
> +++ b/arch/arm64/include/asm/suspend.h
> @@ -2,7 +2,7 @@
> #ifndef __ASM_SUSPEND_H
> #define __ASM_SUSPEND_H
>
> -#define NR_CTX_REGS 13
> +#define NR_CTX_REGS 14
> #define NR_CALLEE_SAVED_REGS 12
>
> /*
> diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
> index 01e868116448..5d907ce3b6d3 100644
> --- a/arch/arm64/mm/proc.S
> +++ b/arch/arm64/mm/proc.S
> @@ -110,6 +110,10 @@ SYM_FUNC_START(cpu_do_suspend)
> * call stack.
> */
> str x18, [x0, #96]
> +alternative_if ARM64_HAS_TCR2
> + mrs x2, REG_TCR2_EL1
> + str x2, [x0, #104]
> +alternative_else_nop_endif
> ret
> SYM_FUNC_END(cpu_do_suspend)
>
> @@ -144,6 +148,10 @@ SYM_FUNC_START(cpu_do_resume)
> msr tcr_el1, x8
> msr vbar_el1, x9
> msr mdscr_el1, x10
> +alternative_if ARM64_HAS_TCR2
> + ldr x2, [x0, #104]
> + msr REG_TCR2_EL1, x2
> +alternative_else_nop_endif
>
> msr sctlr_el1, x12
> set_this_cpu_offset x13
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>
LGTM
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] arm64: fix cleared E0POE bit after cpu_suspend()/resume()
2026-01-07 16:21 [PATCH v2] arm64: fix cleared E0POE bit after cpu_suspend()/resume() Yeoreum Yun
2026-01-07 16:54 ` Kevin Brodsky
2026-01-08 5:25 ` Anshuman Khandual
@ 2026-01-09 18:00 ` Catalin Marinas
2 siblings, 0 replies; 6+ messages in thread
From: Catalin Marinas @ 2026-01-09 18:00 UTC (permalink / raw)
To: linux-pm, linux-arm-kernel, linux-kernel, Yeoreum Yun
Cc: rafael, pavel, will, anshuman.khandual, ryan.roberts, yang,
joey.gouly, kevin.brodsky, stable
On Wed, 07 Jan 2026 16:21:15 +0000, Yeoreum Yun wrote:
> TCR2_ELx.E0POE is set during smp_init().
> However, this bit is not reprogrammed when the CPU enters suspension and
> later resumes via cpu_resume(), as __cpu_setup() does not re-enable E0POE
> and there is no save/restore logic for the TCR2_ELx system register.
>
> As a result, the E0POE feature no longer works after cpu_resume().
>
> [...]
Applied to arm64 (for-next/fixes), thanks!
[1/1] arm64: fix cleared E0POE bit after cpu_suspend()/resume()
https://git.kernel.org/arm64/c/bdf3f4176092
--
Catalin
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] arm64: fix cleared E0POE bit after cpu_suspend()/resume()
2026-01-07 17:30 ` Yeoreum Yun
@ 2026-01-12 9:36 ` Kevin Brodsky
0 siblings, 0 replies; 6+ messages in thread
From: Kevin Brodsky @ 2026-01-12 9:36 UTC (permalink / raw)
To: Yeoreum Yun
Cc: linux-pm, linux-arm-kernel, linux-kernel, rafael, pavel,
catalin.marinas, will, anshuman.khandual, ryan.roberts, yang,
joey.gouly, stable
On 07/01/2026 18:30, Yeoreum Yun wrote:
> Hi Kevin,
>
> [...]
>
>>> @@ -144,6 +148,10 @@ SYM_FUNC_START(cpu_do_resume)
>>> msr tcr_el1, x8
>>> msr vbar_el1, x9
>>> msr mdscr_el1, x10
>>> +alternative_if ARM64_HAS_TCR2
>>> + ldr x2, [x0, #104]
>>> + msr REG_TCR2_EL1, x2
>>> +alternative_else_nop_endif
>> Maybe this could be pushed further down cpu_do_resume, next to DISR_EL1
>> maybe (since it's also conditional)? Otherwise the diff LGTM:
> Sorry but IIUC, currently there is no DISR_EL1 save/restore not yet?
It's zeroed at the end of cpu_do_resume, but yes it's not saved.
> and I think current place is good where before restore SCTLR_EL1 which
> before MMU enabled.
Fair enough, and I can see that other registers are not restored in the
same order as they're saved, so we're not breaking an existing pattern.
Either way Catalin took the patch so this is settled :)
- Kevin
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-01-12 9:36 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-07 16:21 [PATCH v2] arm64: fix cleared E0POE bit after cpu_suspend()/resume() Yeoreum Yun
2026-01-07 16:54 ` Kevin Brodsky
2026-01-07 17:30 ` Yeoreum Yun
2026-01-12 9:36 ` Kevin Brodsky
2026-01-08 5:25 ` Anshuman Khandual
2026-01-09 18:00 ` Catalin Marinas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox