summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorPatrick Wildt <patrick@cvs.openbsd.org>2016-04-24 01:31:03 +0000
committerPatrick Wildt <patrick@cvs.openbsd.org>2016-04-24 01:31:03 +0000
commitbf1f09569cf26e9977e3b421e93953ee50c50c9a (patch)
tree0be697b4c61246378d61c137cff0a28623fa9828 /sys/arch
parent2d726edd07709d05b6d94dff9d1a98d6503cc295 (diff)
EABI's Procedure Call Standard (AAPCS) requires the stack pointer
to be 8-byte aligned. To guarantee this, align the stack pointers passed to user processes and make sure the in-kernel stacks are properly aligned, too. ok jsg@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/arm/arm/cpuswitch.S6
-rw-r--r--sys/arch/arm/arm/cpuswitch7.S6
-rw-r--r--sys/arch/arm/arm/vm_machdep.c7
-rw-r--r--sys/arch/arm/include/frame.h11
4 files changed, 23 insertions, 7 deletions
diff --git a/sys/arch/arm/arm/cpuswitch.S b/sys/arch/arm/arm/cpuswitch.S
index 98e2dbe6969..62a37e2383a 100644
--- a/sys/arch/arm/arm/cpuswitch.S
+++ b/sys/arch/arm/arm/cpuswitch.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpuswitch.S,v 1.15 2016/01/31 00:14:50 jsg Exp $ */
+/* $OpenBSD: cpuswitch.S,v 1.16 2016/04/24 01:31:02 patrick Exp $ */
/* $NetBSD: cpuswitch.S,v 1.41 2003/11/15 08:44:18 scw Exp $ */
/*
@@ -171,6 +171,7 @@ ENTRY(cpu_idle_leave)
ENTRY(cpu_switchto)
stmfd sp!, {r4-r7, lr}
+ sub sp, sp, #4
#ifdef MULTIPROCESSOR
/* XXX use curcpu() */
@@ -451,6 +452,7 @@ ENTRY(cpu_switchto)
* 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}
/* LINTSTUB: Func: void savectx(struct pcb *pcb) */
@@ -461,6 +463,7 @@ ENTRY(savectx)
/* Push registers.*/
stmfd sp!, {r4-r7, lr}
+ sub sp, sp, #4
/* Store all the registers in the process's pcb */
#ifndef __XSCALE__
@@ -473,6 +476,7 @@ ENTRY(savectx)
#endif
/* Pull the regs of the stack */
+ add sp, sp, #4
ldmfd sp!, {r4-r7, pc}
ENTRY(proc_trampoline)
diff --git a/sys/arch/arm/arm/cpuswitch7.S b/sys/arch/arm/arm/cpuswitch7.S
index 43bf7da5906..8ebcfacc031 100644
--- a/sys/arch/arm/arm/cpuswitch7.S
+++ b/sys/arch/arm/arm/cpuswitch7.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpuswitch7.S,v 1.6 2016/04/04 09:13:44 patrick Exp $ */
+/* $OpenBSD: cpuswitch7.S,v 1.7 2016/04/24 01:31:02 patrick Exp $ */
/* $NetBSD: cpuswitch.S,v 1.41 2003/11/15 08:44:18 scw Exp $ */
/*
@@ -158,6 +158,7 @@ ENTRY(cpu_idle_leave)
ENTRY(cpu_switchto)
stmfd sp!, {r4-r7, lr}
+ sub sp, sp, #4
/* Get curcpu from TPIDRPRW. */
mrc p15, 0, r3, c13, c0, 4
@@ -371,6 +372,7 @@ ENTRY(cpu_switchto)
* 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}
/* LINTSTUB: Func: void savectx(struct pcb *pcb) */
@@ -381,12 +383,14 @@ ENTRY(savectx)
/* Push registers.*/
stmfd sp!, {r4-r7, lr}
+ sub sp, sp, #4
/* Store all the registers in the process's pcb */
add r2, r0, #(PCB_R8)
stmia r2, {r8-r13}
/* Pull the regs of the stack */
+ add sp, sp, #4
ldmfd sp!, {r4-r7, pc}
ENTRY(proc_trampoline)
diff --git a/sys/arch/arm/arm/vm_machdep.c b/sys/arch/arm/arm/vm_machdep.c
index 06f217b7189..bb69e88b31e 100644
--- a/sys/arch/arm/arm/vm_machdep.c
+++ b/sys/arch/arm/arm/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.16 2015/08/15 22:20:20 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.17 2016/04/24 01:31:02 patrick Exp $ */
/* $NetBSD: vm_machdep.c,v 1.31 2004/01/04 11:33:29 jdolecek Exp $ */
/*
@@ -140,10 +140,11 @@ cpu_fork(p1, p2, stack, stacksize, func, arg)
*tf = *p1->p_addr->u_pcb.pcb_tf;
/*
- * If specified, give the child a different stack.
+ * If specified, give the child a different stack (make sure
+ * it's 8-byte aligned).
*/
if (stack != NULL)
- tf->tf_usr_sp = (u_int)stack + stacksize;
+ tf->tf_usr_sp = ((vaddr_t)(stack) + stacksize) & -8;
sf = (struct switchframe *)tf - 1;
sf->sf_r4 = (u_int)func;
diff --git a/sys/arch/arm/include/frame.h b/sys/arch/arm/include/frame.h
index 31b2936a865..e2031486c28 100644
--- a/sys/arch/arm/include/frame.h
+++ b/sys/arch/arm/include/frame.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: frame.h,v 1.7 2016/01/31 00:14:50 jsg Exp $ */
+/* $OpenBSD: frame.h,v 1.8 2016/04/24 01:31:02 patrick Exp $ */
/* $NetBSD: frame.h,v 1.9 2003/12/01 08:48:33 scw Exp $ */
/*
@@ -75,6 +75,7 @@ typedef struct trapframe {
register_t tf_svc_sp;
register_t tf_svc_lr;
register_t tf_pc;
+ register_t tf_pad;
} trapframe_t;
/* Register numbers */
@@ -137,6 +138,7 @@ typedef struct irqframe {
unsigned int if_svc_sp;
unsigned int if_svc_lr;
unsigned int if_pc;
+ unsigned int if_pad;
} irqframe_t;
#define clockframe irqframe
@@ -146,6 +148,7 @@ typedef struct irqframe {
*/
struct switchframe {
+ u_int sf_pad;
u_int sf_r4;
u_int sf_r5;
u_int sf_r6;
@@ -203,6 +206,7 @@ struct frame {
*/
#define PUSHFRAME \
+ sub sp, sp, #4; /* Align the stack */ \
str lr, [sp, #-4]!; /* Push the return address */ \
sub sp, sp, #(4*17); /* Adjust the stack pointer */ \
stmia sp, {r0-r14}^; /* Push the user mode registers */ \
@@ -221,7 +225,8 @@ struct frame {
ldmia sp, {r0-r14}^; /* Restore registers (usr mode) */ \
mov r0, r0; /* NOP for previous instruction */ \
add sp, sp, #(4*17); /* Adjust the stack pointer */ \
- ldr lr, [sp], #0x0004 /* Pull the return address */
+ ldr lr, [sp], #0x0004; /* Pull the return address */ \
+ add sp, sp, #4 /* Align the stack */
/*
* PUSHFRAMEINSVC - macro to push a trap frame on the stack in SVC32 mode
@@ -241,6 +246,8 @@ struct frame {
orr r2, r2, #(PSR_SVC32_MODE); \
msr cpsr_c, r2; /* Punch into SVC mode */ \
mov r2, sp; /* Save SVC sp */ \
+ bic sp, sp, #7; /* Align sp to an 8-byte address */ \
+ sub sp, sp, #4; /* Pad trapframe to keep alignment */ \
str r0, [sp, #-4]!; /* Push return address */ \
str lr, [sp, #-4]!; /* Push SVC lr */ \
str r2, [sp, #-4]!; /* Push SVC sp */ \