[rtems commit] arm: Fix stack alignment during interrupt handling

Sebastian Huber sebh at rtems.org
Mon Jan 17 07:17:53 UTC 2022


Module:    rtems
Branch:    master
Commit:    84ba194477bdf4959ad71f8ea3760f643e15ce78
Changeset: http://git.rtems.org/rtems/commit/?id=84ba194477bdf4959ad71f8ea3760f643e15ce78

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Jan 13 13:30:21 2022 +0100

arm: Fix stack alignment during interrupt handling

On a public interface, the stack pointer must be aligned on an 8-byte
boundary.  However, it may temporarily be only aligned on a 4-byte
boundary.  The interrupt handling code must ensure that the stack
pointer is properly aligned before it calls a function.  See also:

https://developer.arm.com/documentation/den0013/d/Interrupt-Handling/External-interrupt-requests/Nested-interrupt-handling

Update #4579.

---

 cpukit/score/cpu/arm/arm_exc_interrupt.S | 33 ++++++++++++++++++++++----------
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/cpukit/score/cpu/arm/arm_exc_interrupt.S b/cpukit/score/cpu/arm/arm_exc_interrupt.S
index a867ee6..a16dc88 100644
--- a/cpukit/score/cpu/arm/arm_exc_interrupt.S
+++ b/cpukit/score/cpu/arm/arm_exc_interrupt.S
@@ -7,7 +7,7 @@
  */
 
 /*
- * Copyright (c) 2009, 2016 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2009, 2022 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -34,6 +34,9 @@
 
 #ifdef ARM_MULTILIB_ARCH_V4
 
+#define STACK_POINTER_ADJUST r7
+#define NON_VOLATILE_SCRATCH r9
+
 #define EXCHANGE_LR r4
 #define EXCHANGE_SPSR r5
 #define EXCHANGE_CPSR r6
@@ -42,9 +45,7 @@
 #define EXCHANGE_LIST {EXCHANGE_LR, EXCHANGE_SPSR, EXCHANGE_CPSR, EXCHANGE_INT_SP}
 #define EXCHANGE_SIZE 16
 
-#define NON_VOLATILE_SCRATCH r9
-
-#define CONTEXT_LIST {r0, r1, r2, r3, EXCHANGE_LR, EXCHANGE_SPSR, r7, r12}
+#define CONTEXT_LIST {r0, r1, r2, r3, EXCHANGE_LR, EXCHANGE_SPSR, NON_VOLATILE_SCRATCH, r12}
 #define CONTEXT_SIZE 32
 
 .arm
@@ -67,12 +68,21 @@ _ARMV4_Exception_interrupt:
 	/*
 	 * Save context.  We save the link register separately because it has
 	 * to be restored in SVC mode.  The other registers can be restored in
-	 * INT mode.  Ensure that stack remains 8 byte aligned.  Use register
-	 * necessary for the stack alignment for the stack pointer of the
-	 * interrupted context.
+	 * INT mode.  Ensure that the size of the saved registers is an
+	 * integral multiple of 8 bytes.  Provide a non-volatile scratch
+	 * register which may be used accross function calls.
 	 */
 	push	CONTEXT_LIST
-	push	{NON_VOLATILE_SCRATCH, lr}
+	push	{STACK_POINTER_ADJUST, lr}
+
+	/*
+	 * On a public interface, the stack pointer must be aligned on an
+	 * 8-byte boundary.  However, it may temporarily be only aligned on a
+	 * 4-byte boundary.  Make sure the stack pointer is aligned on an
+	 * 8-byte boundary.
+	 */
+	and	STACK_POINTER_ADJUST, sp, #0x4
+	sub	sp, sp, STACK_POINTER_ADJUST
 
 	/* Get per-CPU control of current processor */
 	GET_SELF_CPU_CONTROL	r0
@@ -202,8 +212,11 @@ _ARMV4_Exception_interrupt:
 	vmsr	FPSCR, r2
 #endif /* ARM_MULTILIB_VFP */
 
-	/* Restore NON_VOLATILE_SCRATCH register and link register */
-	pop	{NON_VOLATILE_SCRATCH, lr}
+	/* Undo stack pointer adjustment */
+	add	sp, sp, STACK_POINTER_ADJUST
+
+	/* Restore STACK_POINTER_ADJUST register and link register */
+	pop	{STACK_POINTER_ADJUST, lr}
 
 	/*
 	 * XXX: Remember and restore stack pointer.  The data on the stack is



More information about the vc mailing list