Fix stack alignment in the kernel to be on an 8 byte boundary as required
by AAPCS.
This commit is contained in:
parent
833d853cbf
commit
078996e049
@ -211,10 +211,12 @@ ENTRY(cpu_throw)
|
|||||||
GET_PCPU(r6)
|
GET_PCPU(r6)
|
||||||
str r7, [r6, #PC_CURPCB]
|
str r7, [r6, #PC_CURPCB]
|
||||||
|
|
||||||
|
add sp, sp, #4;
|
||||||
ldmfd sp!, {r4-r7, pc}
|
ldmfd sp!, {r4-r7, pc}
|
||||||
|
|
||||||
ENTRY(cpu_switch)
|
ENTRY(cpu_switch)
|
||||||
stmfd sp!, {r4-r7, lr}
|
stmfd sp!, {r4-r7, lr}
|
||||||
|
sub sp, sp, #4;
|
||||||
mov r6, r2 /* Save the mutex */
|
mov r6, r2 /* Save the mutex */
|
||||||
|
|
||||||
.Lswitch_resume:
|
.Lswitch_resume:
|
||||||
@ -488,6 +490,7 @@ ENTRY(cpu_switch)
|
|||||||
* Pull the registers that got pushed when either savectx() or
|
* Pull the registers that got pushed when either savectx() or
|
||||||
* cpu_switch() was called and return.
|
* cpu_switch() was called and return.
|
||||||
*/
|
*/
|
||||||
|
add sp, sp, #4;
|
||||||
ldmfd sp!, {r4-r7, pc}
|
ldmfd sp!, {r4-r7, pc}
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
.Lswitch_bogons:
|
.Lswitch_bogons:
|
||||||
@ -501,6 +504,7 @@ ENTRY(cpu_switch)
|
|||||||
#endif
|
#endif
|
||||||
ENTRY(savectx)
|
ENTRY(savectx)
|
||||||
stmfd sp!, {r4-r7, lr}
|
stmfd sp!, {r4-r7, lr}
|
||||||
|
sub sp, sp, #4
|
||||||
/*
|
/*
|
||||||
* r0 = pcb
|
* r0 = pcb
|
||||||
*/
|
*/
|
||||||
@ -528,6 +532,7 @@ ENTRY(savectx)
|
|||||||
bl _C_LABEL(vfp_store)
|
bl _C_LABEL(vfp_store)
|
||||||
1:
|
1:
|
||||||
#endif /* ARM_VFP_SUPPORT */
|
#endif /* ARM_VFP_SUPPORT */
|
||||||
|
add sp, sp, #4;
|
||||||
ldmfd sp!, {r4-r7, pc}
|
ldmfd sp!, {r4-r7, pc}
|
||||||
|
|
||||||
ENTRY(fork_trampoline)
|
ENTRY(fork_trampoline)
|
||||||
|
@ -73,6 +73,12 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <machine/md_var.h>
|
#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
|
#ifndef NSFBUFS
|
||||||
#define NSFBUFS (512 + maxusers * 16)
|
#define NSFBUFS (512 + maxusers * 16)
|
||||||
#endif
|
#endif
|
||||||
@ -131,8 +137,8 @@ cpu_fork(register struct thread *td1, register struct proc *p2,
|
|||||||
pcb2->un_32.pcb32_sp = td2->td_kstack +
|
pcb2->un_32.pcb32_sp = td2->td_kstack +
|
||||||
USPACE_SVC_STACK_TOP - sizeof(*pcb2);
|
USPACE_SVC_STACK_TOP - sizeof(*pcb2);
|
||||||
pmap_activate(td2);
|
pmap_activate(td2);
|
||||||
td2->td_frame = tf =
|
td2->td_frame = tf = (struct trapframe *)STACKALIGN(
|
||||||
(struct trapframe *)pcb2->un_32.pcb32_sp - 1;
|
pcb2->un_32.pcb32_sp - sizeof(struct trapframe));
|
||||||
*tf = *td1->td_frame;
|
*tf = *td1->td_frame;
|
||||||
sf = (struct switchframe *)tf - 1;
|
sf = (struct switchframe *)tf - 1;
|
||||||
sf->sf_r4 = (u_int)fork_return;
|
sf->sf_r4 = (u_int)fork_return;
|
||||||
@ -142,6 +148,8 @@ cpu_fork(register struct thread *td1, register struct proc *p2,
|
|||||||
tf->tf_r0 = 0;
|
tf->tf_r0 = 0;
|
||||||
tf->tf_r1 = 0;
|
tf->tf_r1 = 0;
|
||||||
pcb2->un_32.pcb32_sp = (u_int)sf;
|
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(). */
|
/* Setup to release spin count in fork_exit(). */
|
||||||
td2->td_md.md_spinlock_count = 1;
|
td2->td_md.md_spinlock_count = 1;
|
||||||
@ -345,6 +353,8 @@ cpu_set_upcall(struct thread *td, struct thread *td0)
|
|||||||
tf->tf_r0 = 0;
|
tf->tf_r0 = 0;
|
||||||
td->td_pcb->un_32.pcb32_sp = (u_int)sf;
|
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;
|
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(). */
|
/* Setup to release spin count in fork_exit(). */
|
||||||
td->td_md.md_spinlock_count = 1;
|
td->td_md.md_spinlock_count = 1;
|
||||||
@ -438,6 +448,8 @@ cpu_set_fork_handler(struct thread *td, void (*func)(void *), void *arg)
|
|||||||
sf->sf_r4 = (u_int)func;
|
sf->sf_r4 = (u_int)func;
|
||||||
sf->sf_r5 = (u_int)arg;
|
sf->sf_r5 = (u_int)arg;
|
||||||
td->td_pcb->un_32.pcb32_sp = (u_int)sf;
|
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"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -138,10 +138,14 @@ typedef struct irqframe {
|
|||||||
} irqframe_t;
|
} 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 {
|
struct switchframe {
|
||||||
|
u_int pad; /* Used to pad the struct to a multiple of 8-bytes */
|
||||||
u_int sf_r4;
|
u_int sf_r4;
|
||||||
u_int sf_r5;
|
u_int sf_r5;
|
||||||
u_int sf_r6;
|
u_int sf_r6;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user