Remove all dregs of a per-thread undefined-exception-mode stack. This is
a leftover from the days when a low-level debugger had hooks in the undefined exception vector and needed stack space to function. These days it effectively isn't used because we switch immediately to the svc32 mode stack on exception entry. For that, the single undef mode stack per core that gets set up at init time works fine. The stack wasn't necessary but it was harmful, because the space for it was carved out of the normal per-thread svc32 stack, in effect cutting that 8K stack in half. If svc32 mode used more than 4k of stack space it wandered down into the undef mode stack, and then an undef exception would overwrite a couple words on the stack while switching to svc32 mode, corrupting the scv32 stack. Having another stack abut the bottom of the svc32 stack also effectively mooted the guard page below the stack. This work is based on analysis and patches submitted by Juergen Weiss.
This commit is contained in:
parent
ba1c2daad4
commit
f00519b613
@ -60,7 +60,6 @@ ASSYM(PCB_NOALIGNFLT, PCB_NOALIGNFLT);
|
|||||||
ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
|
ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
|
||||||
ASSYM(PCB_DACR, offsetof(struct pcb, pcb_dacr));
|
ASSYM(PCB_DACR, offsetof(struct pcb, pcb_dacr));
|
||||||
ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
|
ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
|
||||||
ASSYM(PCB_UND_SP, offsetof(struct pcb, un_32.pcb32_und_sp));
|
|
||||||
ASSYM(PCB_PAGEDIR, offsetof(struct pcb, pcb_pagedir));
|
ASSYM(PCB_PAGEDIR, offsetof(struct pcb, pcb_pagedir));
|
||||||
ASSYM(PCB_L1VEC, offsetof(struct pcb, pcb_l1vec));
|
ASSYM(PCB_L1VEC, offsetof(struct pcb, pcb_l1vec));
|
||||||
ASSYM(PCB_PL1VEC, offsetof(struct pcb, pcb_pl1vec));
|
ASSYM(PCB_PL1VEC, offsetof(struct pcb, pcb_pl1vec));
|
||||||
|
@ -379,8 +379,6 @@ cpu_startup(void *dummy)
|
|||||||
|
|
||||||
bufinit();
|
bufinit();
|
||||||
vm_pager_bufferinit();
|
vm_pager_bufferinit();
|
||||||
pcb->un_32.pcb32_und_sp = (u_int)thread0.td_kstack +
|
|
||||||
USPACE_UNDEF_STACK_TOP;
|
|
||||||
pcb->un_32.pcb32_sp = (u_int)thread0.td_kstack +
|
pcb->un_32.pcb32_sp = (u_int)thread0.td_kstack +
|
||||||
USPACE_SVC_STACK_TOP;
|
USPACE_SVC_STACK_TOP;
|
||||||
vector_page_setprot(VM_PROT_READ);
|
vector_page_setprot(VM_PROT_READ);
|
||||||
|
@ -303,17 +303,6 @@ ENTRY(cpu_switch)
|
|||||||
/* Get the user structure for the new process in r9 */
|
/* Get the user structure for the new process in r9 */
|
||||||
ldr r9, [r1, #(TD_PCB)]
|
ldr r9, [r1, #(TD_PCB)]
|
||||||
|
|
||||||
mrs r3, cpsr
|
|
||||||
/*
|
|
||||||
* We can do that, since
|
|
||||||
* PSR_SVC32_MODE|PSR_UND32_MODE == MSR_UND32_MODE
|
|
||||||
*/
|
|
||||||
orr r8, r3, #(PSR_UND32_MODE)
|
|
||||||
msr cpsr_c, r8
|
|
||||||
|
|
||||||
str sp, [r2, #(PCB_UND_SP)]
|
|
||||||
|
|
||||||
msr cpsr_c, r3 /* Restore the old mode */
|
|
||||||
/* rem: r2 = old PCB */
|
/* rem: r2 = old PCB */
|
||||||
/* rem: r9 = new PCB */
|
/* rem: r9 = new PCB */
|
||||||
/* rem: interrupts are enabled */
|
/* rem: interrupts are enabled */
|
||||||
@ -422,10 +411,6 @@ ENTRY(cpu_switch)
|
|||||||
movne r0, #0 /* We *know* vector_page's VA is 0x0 */
|
movne r0, #0 /* We *know* vector_page's VA is 0x0 */
|
||||||
movne lr, pc
|
movne lr, pc
|
||||||
ldrne pc, [r10, #CF_TLB_FLUSHID_SE]
|
ldrne pc, [r10, #CF_TLB_FLUSHID_SE]
|
||||||
/*
|
|
||||||
* We can do that, since
|
|
||||||
* PSR_SVC32_MODE|PSR_UND32_MODE == MSR_UND32_MODE
|
|
||||||
*/
|
|
||||||
|
|
||||||
.Lcs_context_switched:
|
.Lcs_context_switched:
|
||||||
|
|
||||||
@ -444,17 +429,6 @@ ENTRY(cpu_switch)
|
|||||||
|
|
||||||
/* rem: r9 = new PCB */
|
/* rem: r9 = new PCB */
|
||||||
|
|
||||||
mrs r3, cpsr
|
|
||||||
/*
|
|
||||||
* We can do that, since
|
|
||||||
* PSR_SVC32_MODE|PSR_UND32_MODE == MSR_UND32_MODE
|
|
||||||
*/
|
|
||||||
orr r2, r3, #(PSR_UND32_MODE)
|
|
||||||
msr cpsr_c, r2
|
|
||||||
|
|
||||||
ldr sp, [r9, #(PCB_UND_SP)]
|
|
||||||
|
|
||||||
msr cpsr_c, r3 /* Restore the old mode */
|
|
||||||
/* Restore all the save registers */
|
/* Restore all the save registers */
|
||||||
#ifndef _ARM_ARCH_5E
|
#ifndef _ARM_ARCH_5E
|
||||||
add r7, r9, #PCB_R8
|
add r7, r9, #PCB_R8
|
||||||
|
@ -144,7 +144,6 @@ cpu_fork(register struct thread *td1, register struct proc *p2,
|
|||||||
bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
|
bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
|
||||||
mdp2 = &p2->p_md;
|
mdp2 = &p2->p_md;
|
||||||
bcopy(&td1->td_proc->p_md, mdp2, sizeof(*mdp2));
|
bcopy(&td1->td_proc->p_md, mdp2, sizeof(*mdp2));
|
||||||
pcb2->un_32.pcb32_und_sp = td2->td_kstack + USPACE_UNDEF_STACK_TOP;
|
|
||||||
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);
|
||||||
@ -366,7 +365,6 @@ cpu_set_upcall(struct thread *td, struct thread *td0)
|
|||||||
tf->tf_spsr &= ~PSR_C_bit;
|
tf->tf_spsr &= ~PSR_C_bit;
|
||||||
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;
|
|
||||||
KASSERT((td->td_pcb->un_32.pcb32_sp & 7) == 0,
|
KASSERT((td->td_pcb->un_32.pcb32_sp & 7) == 0,
|
||||||
("cpu_set_upcall: Incorrect stack alignment"));
|
("cpu_set_upcall: Incorrect stack alignment"));
|
||||||
|
|
||||||
|
@ -125,10 +125,8 @@
|
|||||||
#define KSTACK_GUARD_PAGES 1
|
#define KSTACK_GUARD_PAGES 1
|
||||||
#endif /* !KSTACK_GUARD_PAGES */
|
#endif /* !KSTACK_GUARD_PAGES */
|
||||||
|
|
||||||
#define USPACE_SVC_STACK_TOP KSTACK_PAGES * PAGE_SIZE
|
#define USPACE_SVC_STACK_TOP (KSTACK_PAGES * PAGE_SIZE)
|
||||||
#define USPACE_SVC_STACK_BOTTOM (USPACE_SVC_STACK_TOP - 0x1000)
|
|
||||||
#define USPACE_UNDEF_STACK_TOP (USPACE_SVC_STACK_BOTTOM - 0x10)
|
|
||||||
#define USPACE_UNDEF_STACK_BOTTOM (FPCONTEXTSIZE + 10)
|
|
||||||
/*
|
/*
|
||||||
* Mach derived conversion macros
|
* Mach derived conversion macros
|
||||||
*/
|
*/
|
||||||
|
@ -61,7 +61,6 @@ struct pcb_arm32 {
|
|||||||
u_int pcb32_sp; /* used */
|
u_int pcb32_sp; /* used */
|
||||||
u_int pcb32_lr;
|
u_int pcb32_lr;
|
||||||
u_int pcb32_pc;
|
u_int pcb32_pc;
|
||||||
u_int pcb32_und_sp;
|
|
||||||
};
|
};
|
||||||
#define pcb_pagedir un_32.pcb32_pagedir
|
#define pcb_pagedir un_32.pcb32_pagedir
|
||||||
#define pcb_pl1vec un_32.pcb32_pl1vec
|
#define pcb_pl1vec un_32.pcb32_pl1vec
|
||||||
|
Loading…
Reference in New Issue
Block a user