[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220124174744.1054712-31-ardb@kernel.org>
Date: Mon, 24 Jan 2022 18:47:42 +0100
From: Ard Biesheuvel <ardb@...nel.org>
To: linux@...linux.org.uk, linux-arm-kernel@...ts.infradead.org
Cc: linux-hardening@...r.kernel.org, Ard Biesheuvel <ardb@...nel.org>,
Nicolas Pitre <nico@...xnic.net>,
Arnd Bergmann <arnd@...db.de>,
Kees Cook <keescook@...omium.org>,
Keith Packard <keithpac@...zon.com>,
Linus Walleij <linus.walleij@...aro.org>,
Nick Desaulniers <ndesaulniers@...gle.com>,
Tony Lindgren <tony@...mide.com>,
Marc Zyngier <maz@...nel.org>,
Vladimir Murzin <vladimir.murzin@....com>,
Jesse Taube <mr.bossman075@...il.com>
Subject: [PATCH v5 30/32] ARM: switch_to: clean up Thumb2 code path
The load/store-multiple instructions that essentially perform the
switch_to operation in ARM mode, by loading/storing all callee save
registers as well the stack pointer and the link register or program
counter, is split into 3 separate loads or stores for Thumb-2, with the
IP register used as a temporary to capture the target address.
We can clean this up a bit, by sticking with a single STMIA or LDMIA
instruction, but one that uses IP instead of SP.
While at it, switch to a MOVW/MOVT pair to load thread_notify_head.
Signed-off-by: Ard Biesheuvel <ardb@...nel.org>
---
arch/arm/kernel/entry-armv.S | 24 +++++++++++---------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index a4009e4302bb..86be80159c14 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -773,14 +773,14 @@ ENDPROC(__fiq_usr)
* r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info
* previous and next are guaranteed not to be the same.
*/
+ .align 5
ENTRY(__switch_to)
UNWIND(.fnstart )
UNWIND(.cantunwind )
- add ip, r1, #TI_CPU_SAVE
- ARM( stmia ip!, {r4 - sl, fp, sp, lr} ) @ Store most regs on stack
- THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack
- THUMB( str sp, [ip], #4 )
- THUMB( str lr, [ip], #4 )
+ add r3, r1, #TI_CPU_SAVE
+ ARM( stmia r3, {r4 - sl, fp, sp, lr} ) @ Store most regs on stack
+ THUMB( mov ip, sp )
+ THUMB( stmia r3, {r4 - sl, fp, ip, lr} ) @ Thumb2 does not permit SP here
ldr r4, [r2, #TI_TP_VALUE]
ldr r5, [r2, #TI_TP_VALUE + 4]
#ifdef CONFIG_CPU_USE_DOMAINS
@@ -805,20 +805,22 @@ ENTRY(__switch_to)
#endif
mov r5, r0
add r4, r2, #TI_CPU_SAVE
- ldr r0, =thread_notify_head
+ mov_l r0, thread_notify_head
mov r1, #THREAD_NOTIFY_SWITCH
bl atomic_notifier_call_chain
#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP) && \
!defined(CONFIG_STACKPROTECTOR_PER_TASK)
str r9, [r8]
#endif
- THUMB( mov ip, r4 )
mov r0, r5
set_current r7, r8
- ARM( ldmia r4, {r4 - sl, fp, sp, pc} ) @ Load all regs saved previously
- THUMB( ldmia ip!, {r4 - sl, fp} ) @ Load all regs saved previously
- THUMB( ldr sp, [ip], #4 )
- THUMB( ldr pc, [ip] )
+#if !defined(CONFIG_THUMB2_KERNEL)
+ ldmia r4, {r4 - sl, fp, sp, pc} @ Load all regs saved previously
+#else
+ ldmia r4, {r4 - sl, fp, ip, lr} @ Thumb2 does not permit SP here
+ mov sp, ip
+ ret lr
+#endif
UNWIND(.fnend )
ENDPROC(__switch_to)
--
2.30.2
Powered by blists - more mailing lists