svn commit: r247864 - in head/sys/arm: arm include

Andrew Turner andrew at FreeBSD.org
Wed Mar 6 06:19:57 UTC 2013


Author: andrew
Date: Wed Mar  6 06:19:56 2013
New Revision: 247864
URL: http://svnweb.freebsd.org/changeset/base/247864

Log:
  Fix stack alignment in the kernel to be on an 8 byte boundary as required
  by AAPCS.

Modified:
  head/sys/arm/arm/swtch.S
  head/sys/arm/arm/vm_machdep.c
  head/sys/arm/include/frame.h

Modified: head/sys/arm/arm/swtch.S
==============================================================================
--- head/sys/arm/arm/swtch.S	Wed Mar  6 04:58:48 2013	(r247863)
+++ head/sys/arm/arm/swtch.S	Wed Mar  6 06:19:56 2013	(r247864)
@@ -211,10 +211,12 @@ ENTRY(cpu_throw)
 	GET_PCPU(r6)
 	str	r7, [r6, #PC_CURPCB]
 
+	add	sp, sp, #4;
 	ldmfd	sp!, {r4-r7, pc}
 
 ENTRY(cpu_switch)
 	stmfd	sp!, {r4-r7, lr}
+	sub	sp, sp, #4;
 	mov	r6, r2 /* Save the mutex */
 
 .Lswitch_resume:
@@ -488,6 +490,7 @@ ENTRY(cpu_switch)
 	 * Pull the registers that got pushed when either savectx() or
 	 * cpu_switch() was called and return.
 	 */
+	add	sp, sp, #4;
 	ldmfd	sp!, {r4-r7, pc}
 #ifdef DIAGNOSTIC
 .Lswitch_bogons:
@@ -501,6 +504,7 @@ ENTRY(cpu_switch)
 #endif
 ENTRY(savectx)
 	stmfd   sp!, {r4-r7, lr}
+	sub	sp, sp, #4
 	/*
 	 * r0 = pcb
 	 */
@@ -528,6 +532,7 @@ ENTRY(savectx)
 	bl	_C_LABEL(vfp_store)
 1:
 #endif		/* ARM_VFP_SUPPORT */
+	add	sp, sp, #4;
 	ldmfd	sp!, {r4-r7, pc}
 
 ENTRY(fork_trampoline)

Modified: head/sys/arm/arm/vm_machdep.c
==============================================================================
--- head/sys/arm/arm/vm_machdep.c	Wed Mar  6 04:58:48 2013	(r247863)
+++ head/sys/arm/arm/vm_machdep.c	Wed Mar  6 06:19:56 2013	(r247864)
@@ -73,6 +73,12 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/md_var.h>
 
+/*
+ * struct switchframe must be a multiple of 8 for correct stack alignment
+ */
+CTASSERT(sizeof(struct switchframe) == 24);
+CTASSERT(sizeof(struct trapframe) == 76);
+
 #ifndef NSFBUFS
 #define NSFBUFS		(512 + maxusers * 16)
 #endif
@@ -131,8 +137,8 @@ cpu_fork(register struct thread *td1, re
 	pcb2->un_32.pcb32_sp = td2->td_kstack +
 	    USPACE_SVC_STACK_TOP - sizeof(*pcb2);
 	pmap_activate(td2);
-	td2->td_frame = tf =
-	    (struct trapframe *)pcb2->un_32.pcb32_sp - 1;
+	td2->td_frame = tf = (struct trapframe *)STACKALIGN(
+	    pcb2->un_32.pcb32_sp - sizeof(struct trapframe));
 	*tf = *td1->td_frame;
 	sf = (struct switchframe *)tf - 1;
 	sf->sf_r4 = (u_int)fork_return;
@@ -142,6 +148,8 @@ cpu_fork(register struct thread *td1, re
 	tf->tf_r0 = 0;
 	tf->tf_r1 = 0;
 	pcb2->un_32.pcb32_sp = (u_int)sf;
+	KASSERT((pcb2->un_32.pcb32_sp & 7) == 0,
+	    ("cpu_fork: Incorrect stack alignment"));
 
 	/* Setup to release spin count in fork_exit(). */
 	td2->td_md.md_spinlock_count = 1;
@@ -345,6 +353,8 @@ cpu_set_upcall(struct thread *td, struct
 	tf->tf_r0 = 0;
 	td->td_pcb->un_32.pcb32_sp = (u_int)sf;
 	td->td_pcb->un_32.pcb32_und_sp = td->td_kstack + USPACE_UNDEF_STACK_TOP;
+	KASSERT((td->td_pcb->un_32.pcb32_sp & 7) == 0,
+	    ("cpu_set_upcall: Incorrect stack alignment"));
 
 	/* Setup to release spin count in fork_exit(). */
 	td->td_md.md_spinlock_count = 1;
@@ -438,6 +448,8 @@ cpu_set_fork_handler(struct thread *td, 
 	sf->sf_r4 = (u_int)func;
 	sf->sf_r5 = (u_int)arg;
 	td->td_pcb->un_32.pcb32_sp = (u_int)sf;
+	KASSERT((td->td_pcb->un_32.pcb32_sp & 7) == 0,
+	    ("cpu_set_fork_handler: Incorrect stack alignment"));
 }
 
 /*

Modified: head/sys/arm/include/frame.h
==============================================================================
--- head/sys/arm/include/frame.h	Wed Mar  6 04:58:48 2013	(r247863)
+++ head/sys/arm/include/frame.h	Wed Mar  6 06:19:56 2013	(r247864)
@@ -138,10 +138,14 @@ typedef struct irqframe {
 } irqframe_t;
 
 /*
- * Switch frame
+ * Switch frame.
+ *
+ * It is important this is a multiple of 8 bytes so the stack is correctly
+ * aligned when we create new threads.
  */
 
 struct switchframe {
+	u_int	pad;	/* Used to pad the struct to a multiple of 8-bytes */
 	u_int	sf_r4;
 	u_int	sf_r5;
 	u_int	sf_r6;


More information about the svn-src-all mailing list