Use the ABI-mandated thread pointer register (r2 for ppc32, r13 for ppc64)
instead of a PCPU field for curthread. This averts a race on SMP systems with a high interrupt rate where the thread looking up the value of curthread could be preempted and migrated between obtaining the PCPU pointer and reading the value of pc_curthread, resulting in curthread being observed to be the current thread on the thread's original CPU. This played merry havoc with the system, in particular with mutexes. Many thanks to jhb for helping me work this one out. Note that Book-E is in principle susceptible to the same problem, but has not been modified yet due to lack of Book-E hardware. MFC after: 2 weeks
This commit is contained in:
parent
6a4ba2279d
commit
e69dff491d
@ -142,7 +142,7 @@ copyout(const void *kaddr, void *udaddr, size_t len)
|
|||||||
char *up, *p;
|
char *up, *p;
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
pm = &td->td_proc->p_vmspace->vm_pmap;
|
pm = &td->td_proc->p_vmspace->vm_pmap;
|
||||||
|
|
||||||
if (setfault(env)) {
|
if (setfault(env)) {
|
||||||
@ -183,7 +183,7 @@ copyin(const void *udaddr, void *kaddr, size_t len)
|
|||||||
char *kp, *p;
|
char *kp, *p;
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
pm = &td->td_proc->p_vmspace->vm_pmap;
|
pm = &td->td_proc->p_vmspace->vm_pmap;
|
||||||
|
|
||||||
if (setfault(env)) {
|
if (setfault(env)) {
|
||||||
@ -225,7 +225,7 @@ copyinstr(const void *udaddr, void *kaddr, size_t len, size_t *done)
|
|||||||
size_t l;
|
size_t l;
|
||||||
int rv, c;
|
int rv, c;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
pm = &td->td_proc->p_vmspace->vm_pmap;
|
pm = &td->td_proc->p_vmspace->vm_pmap;
|
||||||
|
|
||||||
if (setfault(env)) {
|
if (setfault(env)) {
|
||||||
@ -267,7 +267,7 @@ subyte(void *addr, int byte)
|
|||||||
faultbuf env;
|
faultbuf env;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
pm = &td->td_proc->p_vmspace->vm_pmap;
|
pm = &td->td_proc->p_vmspace->vm_pmap;
|
||||||
p = (char *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
p = (char *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
||||||
|
|
||||||
@ -293,7 +293,7 @@ suword32(void *addr, int word)
|
|||||||
faultbuf env;
|
faultbuf env;
|
||||||
int *p;
|
int *p;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
pm = &td->td_proc->p_vmspace->vm_pmap;
|
pm = &td->td_proc->p_vmspace->vm_pmap;
|
||||||
p = (int *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
p = (int *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
||||||
|
|
||||||
@ -319,7 +319,7 @@ suword(void *addr, long word)
|
|||||||
faultbuf env;
|
faultbuf env;
|
||||||
long *p;
|
long *p;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
pm = &td->td_proc->p_vmspace->vm_pmap;
|
pm = &td->td_proc->p_vmspace->vm_pmap;
|
||||||
p = (long *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
p = (long *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
||||||
|
|
||||||
@ -359,7 +359,7 @@ fubyte(const void *addr)
|
|||||||
u_char *p;
|
u_char *p;
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
pm = &td->td_proc->p_vmspace->vm_pmap;
|
pm = &td->td_proc->p_vmspace->vm_pmap;
|
||||||
p = (u_char *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
p = (u_char *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
||||||
|
|
||||||
@ -385,7 +385,7 @@ fuword32(const void *addr)
|
|||||||
faultbuf env;
|
faultbuf env;
|
||||||
int32_t *p, val;
|
int32_t *p, val;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
pm = &td->td_proc->p_vmspace->vm_pmap;
|
pm = &td->td_proc->p_vmspace->vm_pmap;
|
||||||
p = (int32_t *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
p = (int32_t *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
||||||
|
|
||||||
@ -411,7 +411,7 @@ fuword(const void *addr)
|
|||||||
faultbuf env;
|
faultbuf env;
|
||||||
long *p, val;
|
long *p, val;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
pm = &td->td_proc->p_vmspace->vm_pmap;
|
pm = &td->td_proc->p_vmspace->vm_pmap;
|
||||||
p = (long *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
p = (long *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
||||||
|
|
||||||
@ -444,7 +444,7 @@ casuword32(volatile uint32_t *addr, uint32_t old, uint32_t new)
|
|||||||
faultbuf env;
|
faultbuf env;
|
||||||
uint32_t *p, val;
|
uint32_t *p, val;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
pm = &td->td_proc->p_vmspace->vm_pmap;
|
pm = &td->td_proc->p_vmspace->vm_pmap;
|
||||||
p = (uint32_t *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
p = (uint32_t *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
||||||
|
|
||||||
@ -489,7 +489,7 @@ casuword(volatile u_long *addr, u_long old, u_long new)
|
|||||||
faultbuf env;
|
faultbuf env;
|
||||||
u_long *p, val;
|
u_long *p, val;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
pm = &td->td_proc->p_vmspace->vm_pmap;
|
pm = &td->td_proc->p_vmspace->vm_pmap;
|
||||||
p = (u_long *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
p = (u_long *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
|
||||||
|
|
||||||
|
@ -181,8 +181,7 @@ setfault:
|
|||||||
mflr 0
|
mflr 0
|
||||||
mfcr 12
|
mfcr 12
|
||||||
mfsprg 4,0
|
mfsprg 4,0
|
||||||
lwz 4,PC_CURTHREAD(4)
|
lwz 4,TD_PCB(2) /* curthread = r2 */
|
||||||
lwz 4,TD_PCB(4)
|
|
||||||
stw 3,PCB_ONFAULT(4)
|
stw 3,PCB_ONFAULT(4)
|
||||||
stw 0,0(3)
|
stw 0,0(3)
|
||||||
stw 1,4(3)
|
stw 1,4(3)
|
||||||
|
@ -203,8 +203,7 @@ ASENTRY(setfault)
|
|||||||
mflr 0
|
mflr 0
|
||||||
mfcr 12
|
mfcr 12
|
||||||
mfsprg 4,0
|
mfsprg 4,0
|
||||||
ld 4,PC_CURTHREAD(4)
|
ld 4,TD_PCB(13) /* curthread = r13 */
|
||||||
ld 4,TD_PCB(4)
|
|
||||||
std 3,PCB_ONFAULT(4)
|
std 3,PCB_ONFAULT(4)
|
||||||
std 0,0(3)
|
std 0,0(3)
|
||||||
std 1,8(3)
|
std 1,8(3)
|
||||||
|
@ -303,7 +303,7 @@ powerpc_init(vm_offset_t startkernel, vm_offset_t endkernel,
|
|||||||
*/
|
*/
|
||||||
pc = __pcpu;
|
pc = __pcpu;
|
||||||
pcpu_init(pc, 0, sizeof(struct pcpu));
|
pcpu_init(pc, 0, sizeof(struct pcpu));
|
||||||
pc->pc_curthread = &thread0;
|
curthread_reg = pc->pc_curthread = &thread0;
|
||||||
pc->pc_cpuid = 0;
|
pc->pc_cpuid = 0;
|
||||||
|
|
||||||
__asm __volatile("mtsprg 0, %0" :: "r"(pc));
|
__asm __volatile("mtsprg 0, %0" :: "r"(pc));
|
||||||
@ -745,7 +745,7 @@ kcopy(const void *src, void *dst, size_t len)
|
|||||||
faultbuf env, *oldfault;
|
faultbuf env, *oldfault;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
oldfault = td->td_pcb->pcb_onfault;
|
oldfault = td->td_pcb->pcb_onfault;
|
||||||
if ((rv = setfault(env)) != 0) {
|
if ((rv = setfault(env)) != 0) {
|
||||||
td->td_pcb->pcb_onfault = oldfault;
|
td->td_pcb->pcb_onfault = oldfault;
|
||||||
|
@ -88,7 +88,7 @@ cpudep_ap_bootstrap(void)
|
|||||||
msr = PSL_KERNSET & ~PSL_EE;
|
msr = PSL_KERNSET & ~PSL_EE;
|
||||||
mtmsr(msr);
|
mtmsr(msr);
|
||||||
|
|
||||||
pcpup->pc_curthread = pcpup->pc_idlethread;
|
curthread_reg = pcpup->pc_curthread = pcpup->pc_idlethread;
|
||||||
pcpup->pc_curpcb = pcpup->pc_curthread->td_pcb;
|
pcpup->pc_curpcb = pcpup->pc_curthread->td_pcb;
|
||||||
sp = pcpup->pc_curpcb->pcb_sp;
|
sp = pcpup->pc_curpcb->pcb_sp;
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@
|
|||||||
* void cpu_throw(struct thread *old, struct thread *new)
|
* void cpu_throw(struct thread *old, struct thread *new)
|
||||||
*/
|
*/
|
||||||
ENTRY(cpu_throw)
|
ENTRY(cpu_throw)
|
||||||
mr %r15, %r4
|
mr %r2, %r4
|
||||||
b cpu_switchin
|
b cpu_switchin
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -89,10 +89,9 @@ ENTRY(cpu_switch)
|
|||||||
mflr %r16 /* Save the link register */
|
mflr %r16 /* Save the link register */
|
||||||
stw %r16,PCB_LR(%r6)
|
stw %r16,PCB_LR(%r6)
|
||||||
stw %r1,PCB_SP(%r6) /* Save the stack pointer */
|
stw %r1,PCB_SP(%r6) /* Save the stack pointer */
|
||||||
stw %r2,PCB_TOC(%r6) /* Save the TOC pointer */
|
|
||||||
|
|
||||||
mr %r14,%r3 /* Copy the old thread ptr... */
|
mr %r14,%r3 /* Copy the old thread ptr... */
|
||||||
mr %r15,%r4 /* and the new thread ptr in scratch */
|
mr %r2,%r4 /* and the new thread ptr in curthread */
|
||||||
mr %r16,%r5 /* and the new lock */
|
mr %r16,%r5 /* and the new lock */
|
||||||
mr %r17,%r6 /* and the PCB */
|
mr %r17,%r6 /* and the PCB */
|
||||||
|
|
||||||
@ -122,24 +121,24 @@ cpu_switchin:
|
|||||||
lis %r6,blocked_lock@ha
|
lis %r6,blocked_lock@ha
|
||||||
addi %r6,%r6,blocked_lock@l
|
addi %r6,%r6,blocked_lock@l
|
||||||
blocked_loop:
|
blocked_loop:
|
||||||
lwz %r7,TD_LOCK(%r15)
|
lwz %r7,TD_LOCK(%r2)
|
||||||
cmpw %r6,%r7
|
cmpw %r6,%r7
|
||||||
beq blocked_loop
|
beq blocked_loop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mfsprg %r7,0 /* Get the pcpu pointer */
|
mfsprg %r7,0 /* Get the pcpu pointer */
|
||||||
stw %r15,PC_CURTHREAD(%r7) /* Store new current thread */
|
stw %r2,PC_CURTHREAD(%r7) /* Store new current thread */
|
||||||
lwz %r17,TD_PCB(%r15) /* Store new current PCB */
|
lwz %r17,TD_PCB(%r2) /* Store new current PCB */
|
||||||
stw %r17,PC_CURPCB(%r7)
|
stw %r17,PC_CURPCB(%r7)
|
||||||
|
|
||||||
mr %r3,%r15 /* Get new thread ptr */
|
mr %r3,%r2 /* Get new thread ptr */
|
||||||
bl pmap_activate /* Activate the new address space */
|
bl pmap_activate /* Activate the new address space */
|
||||||
|
|
||||||
lwz %r6, PCB_FLAGS(%r17)
|
lwz %r6, PCB_FLAGS(%r17)
|
||||||
/* Restore FPU context if needed */
|
/* Restore FPU context if needed */
|
||||||
andi. %r6, %r6, PCB_FPU
|
andi. %r6, %r6, PCB_FPU
|
||||||
beq .L3
|
beq .L3
|
||||||
mr %r3,%r15 /* Pass curthread to enable_fpu */
|
mr %r3,%r2 /* Pass curthread to enable_fpu */
|
||||||
bl enable_fpu
|
bl enable_fpu
|
||||||
|
|
||||||
.L3:
|
.L3:
|
||||||
@ -147,7 +146,7 @@ blocked_loop:
|
|||||||
/* Restore Altivec context if needed */
|
/* Restore Altivec context if needed */
|
||||||
andi. %r6, %r6, PCB_VEC
|
andi. %r6, %r6, PCB_VEC
|
||||||
beq .L4
|
beq .L4
|
||||||
mr %r3,%r15 /* Pass curthread to enable_vec */
|
mr %r3,%r2 /* Pass curthread to enable_vec */
|
||||||
bl enable_vec
|
bl enable_vec
|
||||||
|
|
||||||
/* thread to restore is in r3 */
|
/* thread to restore is in r3 */
|
||||||
@ -163,7 +162,6 @@ blocked_loop:
|
|||||||
mtsr USER_SR,%r5
|
mtsr USER_SR,%r5
|
||||||
isync
|
isync
|
||||||
lwz %r1,PCB_SP(%r3) /* Load the stack pointer */
|
lwz %r1,PCB_SP(%r3) /* Load the stack pointer */
|
||||||
lwz %r2,PCB_TOC(%r3) /* Load the TOC pointer */
|
|
||||||
/*
|
/*
|
||||||
* Perform a dummy stwcx. to clear any reservations we may have
|
* Perform a dummy stwcx. to clear any reservations we may have
|
||||||
* inherited from the previous thread. It doesn't matter if the
|
* inherited from the previous thread. It doesn't matter if the
|
||||||
|
@ -69,7 +69,7 @@
|
|||||||
* void cpu_throw(struct thread *old, struct thread *new)
|
* void cpu_throw(struct thread *old, struct thread *new)
|
||||||
*/
|
*/
|
||||||
ENTRY(cpu_throw)
|
ENTRY(cpu_throw)
|
||||||
mr %r15, %r4
|
mr %r13, %r4
|
||||||
b cpu_switchin
|
b cpu_switchin
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -83,7 +83,6 @@ ENTRY(cpu_switch)
|
|||||||
ld %r6,TD_PCB(%r3) /* Get the old thread's PCB ptr */
|
ld %r6,TD_PCB(%r3) /* Get the old thread's PCB ptr */
|
||||||
std %r12,PCB_CONTEXT(%r6) /* Save the non-volatile GP regs.
|
std %r12,PCB_CONTEXT(%r6) /* Save the non-volatile GP regs.
|
||||||
These can now be used for scratch */
|
These can now be used for scratch */
|
||||||
std %r13,PCB_CONTEXT+1*8(%r6)
|
|
||||||
std %r14,PCB_CONTEXT+2*8(%r6)
|
std %r14,PCB_CONTEXT+2*8(%r6)
|
||||||
std %r15,PCB_CONTEXT+3*8(%r6)
|
std %r15,PCB_CONTEXT+3*8(%r6)
|
||||||
std %r16,PCB_CONTEXT+4*8(%r6)
|
std %r16,PCB_CONTEXT+4*8(%r6)
|
||||||
@ -111,7 +110,7 @@ ENTRY(cpu_switch)
|
|||||||
std %r2,PCB_TOC(%r6) /* Save the TOC pointer */
|
std %r2,PCB_TOC(%r6) /* Save the TOC pointer */
|
||||||
|
|
||||||
mr %r14,%r3 /* Copy the old thread ptr... */
|
mr %r14,%r3 /* Copy the old thread ptr... */
|
||||||
mr %r15,%r4 /* and the new thread ptr in scratch */
|
mr %r13,%r4 /* and the new thread ptr in curthread*/
|
||||||
mr %r16,%r5 /* and the new lock */
|
mr %r16,%r5 /* and the new lock */
|
||||||
mr %r17,%r6 /* and the PCB */
|
mr %r17,%r6 /* and the PCB */
|
||||||
|
|
||||||
@ -148,19 +147,19 @@ cpu_switchin:
|
|||||||
lis %r6,blocked_lock@ha
|
lis %r6,blocked_lock@ha
|
||||||
addi %r6,%r6,blocked_lock@l
|
addi %r6,%r6,blocked_lock@l
|
||||||
blocked_loop:
|
blocked_loop:
|
||||||
ld %r7,TD_LOCK(%r15)
|
ld %r7,TD_LOCK(%r13)
|
||||||
cmpd %r6,%r7
|
cmpd %r6,%r7
|
||||||
beq blocked_loop
|
beq blocked_loop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mfsprg %r7,0 /* Get the pcpu pointer */
|
mfsprg %r7,0 /* Get the pcpu pointer */
|
||||||
std %r15,PC_CURTHREAD(%r7) /* Store new current thread */
|
std %r13,PC_CURTHREAD(%r7) /* Store new current thread */
|
||||||
ld %r17,TD_PCB(%r15) /* Store new current PCB */
|
ld %r17,TD_PCB(%r13) /* Store new current PCB */
|
||||||
std %r17,PC_CURPCB(%r7)
|
std %r17,PC_CURPCB(%r7)
|
||||||
|
|
||||||
stdu %r1,-48(%r1)
|
stdu %r1,-48(%r1)
|
||||||
|
|
||||||
mr %r3,%r15 /* Get new thread ptr */
|
mr %r3,%r13 /* Get new thread ptr */
|
||||||
bl pmap_activate /* Activate the new address space */
|
bl pmap_activate /* Activate the new address space */
|
||||||
nop
|
nop
|
||||||
|
|
||||||
@ -168,7 +167,7 @@ blocked_loop:
|
|||||||
/* Restore FPU context if needed */
|
/* Restore FPU context if needed */
|
||||||
andi. %r6, %r6, PCB_FPU
|
andi. %r6, %r6, PCB_FPU
|
||||||
beq .L3
|
beq .L3
|
||||||
mr %r3,%r15 /* Pass curthread to enable_fpu */
|
mr %r3,%r13 /* Pass curthread to enable_fpu */
|
||||||
bl enable_fpu
|
bl enable_fpu
|
||||||
nop
|
nop
|
||||||
|
|
||||||
@ -177,7 +176,7 @@ blocked_loop:
|
|||||||
/* Restore Altivec context if needed */
|
/* Restore Altivec context if needed */
|
||||||
andi. %r6, %r6, PCB_VEC
|
andi. %r6, %r6, PCB_VEC
|
||||||
beq .L4
|
beq .L4
|
||||||
mr %r3,%r15 /* Pass curthread to enable_vec */
|
mr %r3,%r13 /* Pass curthread to enable_vec */
|
||||||
bl enable_vec
|
bl enable_vec
|
||||||
nop
|
nop
|
||||||
|
|
||||||
@ -186,7 +185,6 @@ blocked_loop:
|
|||||||
addi %r1,%r1,48
|
addi %r1,%r1,48
|
||||||
mr %r3,%r17 /* Recover PCB ptr */
|
mr %r3,%r17 /* Recover PCB ptr */
|
||||||
ld %r12,PCB_CONTEXT(%r3) /* Load the non-volatile GP regs. */
|
ld %r12,PCB_CONTEXT(%r3) /* Load the non-volatile GP regs. */
|
||||||
ld %r13,PCB_CONTEXT+1*8(%r3)
|
|
||||||
ld %r14,PCB_CONTEXT+2*8(%r3)
|
ld %r14,PCB_CONTEXT+2*8(%r3)
|
||||||
ld %r15,PCB_CONTEXT+3*8(%r3)
|
ld %r15,PCB_CONTEXT+3*8(%r3)
|
||||||
ld %r16,PCB_CONTEXT+4*8(%r3)
|
ld %r16,PCB_CONTEXT+4*8(%r3)
|
||||||
|
@ -149,7 +149,7 @@ trap(struct trapframe *frame)
|
|||||||
|
|
||||||
PCPU_INC(cnt.v_trap);
|
PCPU_INC(cnt.v_trap);
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
p = td->td_proc;
|
p = td->td_proc;
|
||||||
|
|
||||||
type = ucode = frame->exc;
|
type = ucode = frame->exc;
|
||||||
@ -452,7 +452,7 @@ syscall(struct trapframe *frame)
|
|||||||
struct syscall_args sa;
|
struct syscall_args sa;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
td->td_frame = frame;
|
td->td_frame = frame;
|
||||||
|
|
||||||
#ifdef __powerpc64__
|
#ifdef __powerpc64__
|
||||||
@ -600,7 +600,7 @@ badaddr_read(void *addr, size_t size, int *rptr)
|
|||||||
/* Get rid of any stale machine checks that have been waiting. */
|
/* Get rid of any stale machine checks that have been waiting. */
|
||||||
__asm __volatile ("sync; isync");
|
__asm __volatile ("sync; isync");
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
|
|
||||||
if (setfault(env)) {
|
if (setfault(env)) {
|
||||||
td->td_pcb->pcb_onfault = 0;
|
td->td_pcb->pcb_onfault = 0;
|
||||||
|
@ -155,9 +155,15 @@
|
|||||||
stw %r28,FRAME_AIM_DAR+8(1); \
|
stw %r28,FRAME_AIM_DAR+8(1); \
|
||||||
stw %r29,FRAME_AIM_DSISR+8(1); /* save dsisr/srr0/srr1 */ \
|
stw %r29,FRAME_AIM_DSISR+8(1); /* save dsisr/srr0/srr1 */ \
|
||||||
stw %r30,FRAME_SRR0+8(1); \
|
stw %r30,FRAME_SRR0+8(1); \
|
||||||
stw %r31,FRAME_SRR1+8(1)
|
stw %r31,FRAME_SRR1+8(1); \
|
||||||
|
lwz %r2,PC_CURTHREAD(%r2) /* set curthread pointer */
|
||||||
|
|
||||||
#define FRAME_LEAVE(savearea) \
|
#define FRAME_LEAVE(savearea) \
|
||||||
|
/* Disable exceptions: */ \
|
||||||
|
mfmsr %r2; \
|
||||||
|
andi. %r2,%r2,~PSL_EE@l; \
|
||||||
|
mtmsr %r2; \
|
||||||
|
isync; \
|
||||||
/* Now restore regs: */ \
|
/* Now restore regs: */ \
|
||||||
lwz %r2,FRAME_SRR0+8(%r1); \
|
lwz %r2,FRAME_SRR0+8(%r1); \
|
||||||
lwz %r3,FRAME_SRR1+8(%r1); \
|
lwz %r3,FRAME_SRR1+8(%r1); \
|
||||||
@ -209,7 +215,7 @@
|
|||||||
mtsprg3 %r3; \
|
mtsprg3 %r3; \
|
||||||
/* Disable translation, machine check and recoverability: */ \
|
/* Disable translation, machine check and recoverability: */ \
|
||||||
mfmsr %r2; \
|
mfmsr %r2; \
|
||||||
andi. %r2,%r2,~(PSL_DR|PSL_IR|PSL_EE|PSL_ME|PSL_RI)@l; \
|
andi. %r2,%r2,~(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \
|
||||||
mtmsr %r2; \
|
mtmsr %r2; \
|
||||||
isync; \
|
isync; \
|
||||||
/* Decide whether we return to user mode: */ \
|
/* Decide whether we return to user mode: */ \
|
||||||
@ -764,8 +770,8 @@ CNAME(trapexit):
|
|||||||
bf 17,1f /* branch if PSL_PR is false */
|
bf 17,1f /* branch if PSL_PR is false */
|
||||||
|
|
||||||
GET_CPUINFO(%r3) /* get per-CPU pointer */
|
GET_CPUINFO(%r3) /* get per-CPU pointer */
|
||||||
lwz %r4, PC_CURTHREAD(%r3) /* deref to get curthread */
|
lwz %r4, TD_FLAGS(%r2) /* get thread flags value
|
||||||
lwz %r4, TD_FLAGS(%r4) /* get thread flags value */
|
* (r2 is curthread) */
|
||||||
lis %r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@h
|
lis %r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@h
|
||||||
ori %r5,%r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@l
|
ori %r5,%r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@l
|
||||||
and. %r4,%r4,%r5
|
and. %r4,%r4,%r5
|
||||||
|
@ -179,9 +179,15 @@ restore_kernsrs:
|
|||||||
std %r28,FRAME_AIM_DAR+48(1); \
|
std %r28,FRAME_AIM_DAR+48(1); \
|
||||||
std %r29,FRAME_AIM_DSISR+48(1); /* save dsisr/srr0/srr1 */ \
|
std %r29,FRAME_AIM_DSISR+48(1); /* save dsisr/srr0/srr1 */ \
|
||||||
std %r30,FRAME_SRR0+48(1); \
|
std %r30,FRAME_SRR0+48(1); \
|
||||||
std %r31,FRAME_SRR1+48(1)
|
std %r31,FRAME_SRR1+48(1); \
|
||||||
|
ld %r13,PC_CURTHREAD(%r2) /* set kernel curthread */
|
||||||
|
|
||||||
#define FRAME_LEAVE(savearea) \
|
#define FRAME_LEAVE(savearea) \
|
||||||
|
/* Disable exceptions: */ \
|
||||||
|
mfmsr %r2; \
|
||||||
|
andi. %r2,%r2,~PSL_EE@l; \
|
||||||
|
mtmsr %r2; \
|
||||||
|
isync; \
|
||||||
/* Now restore regs: */ \
|
/* Now restore regs: */ \
|
||||||
ld %r2,FRAME_SRR0+48(%r1); \
|
ld %r2,FRAME_SRR0+48(%r1); \
|
||||||
ld %r3,FRAME_SRR1+48(%r1); \
|
ld %r3,FRAME_SRR1+48(%r1); \
|
||||||
@ -233,7 +239,7 @@ restore_kernsrs:
|
|||||||
mtsprg3 %r3; \
|
mtsprg3 %r3; \
|
||||||
/* Disable translation, machine check and recoverability: */ \
|
/* Disable translation, machine check and recoverability: */ \
|
||||||
mfmsr %r2; \
|
mfmsr %r2; \
|
||||||
andi. %r2,%r2,~(PSL_DR|PSL_IR|PSL_EE|PSL_ME|PSL_RI)@l; \
|
andi. %r2,%r2,~(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \
|
||||||
mtmsr %r2; \
|
mtmsr %r2; \
|
||||||
isync; \
|
isync; \
|
||||||
/* Decide whether we return to user mode: */ \
|
/* Decide whether we return to user mode: */ \
|
||||||
@ -526,8 +532,7 @@ CNAME(trapexit):
|
|||||||
bf 17,1f /* branch if PSL_PR is false */
|
bf 17,1f /* branch if PSL_PR is false */
|
||||||
|
|
||||||
GET_CPUINFO(%r3) /* get per-CPU pointer */
|
GET_CPUINFO(%r3) /* get per-CPU pointer */
|
||||||
ld %r4, PC_CURTHREAD(%r3) /* deref to get curthread */
|
lwz %r4, TD_FLAGS(%r13) /* get thread flags value */
|
||||||
lwz %r4, TD_FLAGS(%r4) /* get thread flags value */
|
|
||||||
lis %r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@h
|
lis %r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@h
|
||||||
ori %r5,%r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@l
|
ori %r5,%r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@l
|
||||||
and. %r4,%r4,%r5
|
and. %r4,%r4,%r5
|
||||||
|
@ -87,7 +87,7 @@ copyout(const void *kaddr, void *udaddr, size_t len)
|
|||||||
if (!is_uaddr(udaddr))
|
if (!is_uaddr(udaddr))
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
|
|
||||||
if (setfault(env)) {
|
if (setfault(env)) {
|
||||||
td->td_pcb->pcb_onfault = NULL;
|
td->td_pcb->pcb_onfault = NULL;
|
||||||
@ -109,7 +109,7 @@ copyin(const void *udaddr, void *kaddr, size_t len)
|
|||||||
if (!is_uaddr(udaddr) || is_uaddr(kaddr))
|
if (!is_uaddr(udaddr) || is_uaddr(kaddr))
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
|
|
||||||
if (setfault(env)) {
|
if (setfault(env)) {
|
||||||
td->td_pcb->pcb_onfault = NULL;
|
td->td_pcb->pcb_onfault = NULL;
|
||||||
@ -135,7 +135,7 @@ copyinstr(const void *udaddr, void *kaddr, size_t len, size_t *done)
|
|||||||
if (!is_uaddr(udaddr) || is_uaddr(kaddr))
|
if (!is_uaddr(udaddr) || is_uaddr(kaddr))
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
|
|
||||||
if (setfault(env)) {
|
if (setfault(env)) {
|
||||||
td->td_pcb->pcb_onfault = NULL;
|
td->td_pcb->pcb_onfault = NULL;
|
||||||
@ -175,7 +175,7 @@ subyte(void *addr, int byte)
|
|||||||
if (!is_uaddr(addr))
|
if (!is_uaddr(addr))
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
|
|
||||||
if (setfault(env)) {
|
if (setfault(env)) {
|
||||||
td->td_pcb->pcb_onfault = NULL;
|
td->td_pcb->pcb_onfault = NULL;
|
||||||
@ -197,7 +197,7 @@ suword(void *addr, long word)
|
|||||||
if (!is_uaddr(addr))
|
if (!is_uaddr(addr))
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
|
|
||||||
if (setfault(env)) {
|
if (setfault(env)) {
|
||||||
td->td_pcb->pcb_onfault = NULL;
|
td->td_pcb->pcb_onfault = NULL;
|
||||||
@ -228,7 +228,7 @@ fubyte(const void *addr)
|
|||||||
if (!is_uaddr(addr))
|
if (!is_uaddr(addr))
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
|
|
||||||
if (setfault(env)) {
|
if (setfault(env)) {
|
||||||
td->td_pcb->pcb_onfault = NULL;
|
td->td_pcb->pcb_onfault = NULL;
|
||||||
@ -251,7 +251,7 @@ fuword(const void *addr)
|
|||||||
if (!is_uaddr(addr))
|
if (!is_uaddr(addr))
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
|
|
||||||
if (setfault(env)) {
|
if (setfault(env)) {
|
||||||
td->td_pcb->pcb_onfault = NULL;
|
td->td_pcb->pcb_onfault = NULL;
|
||||||
@ -288,7 +288,7 @@ casuword(volatile u_long *addr, u_long old, u_long new)
|
|||||||
if (!((vm_offset_t)addr <= VM_MAXUSER_ADDRESS))
|
if (!((vm_offset_t)addr <= VM_MAXUSER_ADDRESS))
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
|
|
||||||
if (setfault(env)) {
|
if (setfault(env)) {
|
||||||
td->td_pcb->pcb_onfault = NULL;
|
td->td_pcb->pcb_onfault = NULL;
|
||||||
|
@ -118,7 +118,7 @@ powerpc_decr_interrupt(struct trapframe *framep)
|
|||||||
struct thread *td;
|
struct thread *td;
|
||||||
struct trapframe *oldframe;
|
struct trapframe *oldframe;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
critical_enter();
|
critical_enter();
|
||||||
atomic_add_int(&td->td_intr_nesting_level, 1);
|
atomic_add_int(&td->td_intr_nesting_level, 1);
|
||||||
oldframe = td->td_intr_frame;
|
oldframe = td->td_intr_frame;
|
||||||
|
@ -145,7 +145,7 @@ trap(struct trapframe *frame)
|
|||||||
|
|
||||||
PCPU_INC(cnt.v_trap);
|
PCPU_INC(cnt.v_trap);
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
p = td->td_proc;
|
p = td->td_proc;
|
||||||
|
|
||||||
type = frame->exc;
|
type = frame->exc;
|
||||||
@ -382,7 +382,7 @@ syscall(struct trapframe *frame)
|
|||||||
struct syscall_args sa;
|
struct syscall_args sa;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
td->td_frame = frame;
|
td->td_frame = frame;
|
||||||
|
|
||||||
error = syscallenter(td, &sa);
|
error = syscallenter(td, &sa);
|
||||||
@ -480,7 +480,7 @@ badaddr_read(void *addr, size_t size, int *rptr)
|
|||||||
/* Get rid of any stale machine checks that have been waiting. */
|
/* Get rid of any stale machine checks that have been waiting. */
|
||||||
__asm __volatile ("sync; isync");
|
__asm __volatile ("sync; isync");
|
||||||
|
|
||||||
td = PCPU_GET(curthread);
|
td = curthread;
|
||||||
|
|
||||||
if (setfault(env)) {
|
if (setfault(env)) {
|
||||||
td->td_pcb->pcb_onfault = 0;
|
td->td_pcb->pcb_onfault = 0;
|
||||||
|
@ -135,6 +135,14 @@ struct pmap;
|
|||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
|
|
||||||
#define pcpup ((struct pcpu *) powerpc_get_pcpup())
|
#define pcpup ((struct pcpu *) powerpc_get_pcpup())
|
||||||
|
#ifdef __powerpc64__
|
||||||
|
register struct thread *curthread_reg __asm("%r13");
|
||||||
|
#else
|
||||||
|
register struct thread *curthread_reg __asm("%r2");
|
||||||
|
#endif
|
||||||
|
#ifdef AIM /* Book-E not yet adapted */
|
||||||
|
#define curthread curthread_reg
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PCPU_GET(member) (pcpup->pc_ ## member)
|
#define PCPU_GET(member) (pcpup->pc_ ## member)
|
||||||
|
|
||||||
|
@ -87,10 +87,11 @@ ASENTRY(ofwcall)
|
|||||||
* later.
|
* later.
|
||||||
*/
|
*/
|
||||||
mr %r5,%r1
|
mr %r5,%r1
|
||||||
lis %r1,(ofwstk+OFWSTKSZ-16)@ha
|
lis %r1,(ofwstk+OFWSTKSZ-32)@ha
|
||||||
addi %r1,%r1,(ofwstk+OFWSTKSZ-16)@l
|
addi %r1,%r1,(ofwstk+OFWSTKSZ-32)@l
|
||||||
stw %r5,8(%r1) /* Save real stack pointer */
|
stw %r5,20(%r1) /* Save real stack pointer */
|
||||||
stw %r6,12(%r1) /* Save old MSR */
|
stw %r2,24(%r1) /* Save curthread */
|
||||||
|
stw %r6,28(%r1) /* Save old MSR */
|
||||||
li %r5,0
|
li %r5,0
|
||||||
stw %r5,4(%r1)
|
stw %r5,4(%r1)
|
||||||
stw %r5,0(%r1)
|
stw %r5,0(%r1)
|
||||||
@ -100,8 +101,9 @@ ASENTRY(ofwcall)
|
|||||||
bctrl
|
bctrl
|
||||||
|
|
||||||
/* Reload stack pointer and MSR from the OFW stack */
|
/* Reload stack pointer and MSR from the OFW stack */
|
||||||
lwz %r6,12(%r1)
|
lwz %r6,28(%r1)
|
||||||
lwz %r1,8(%r1)
|
lwz %r2,24(%r1)
|
||||||
|
lwz %r1,20(%r1)
|
||||||
|
|
||||||
/* Now set the real MSR */
|
/* Now set the real MSR */
|
||||||
mtmsr %r6
|
mtmsr %r6
|
||||||
|
@ -96,10 +96,6 @@ machdep_ap_bootstrap(void)
|
|||||||
printf("SMP: AP CPU #%d launched\n", PCPU_GET(cpuid));
|
printf("SMP: AP CPU #%d launched\n", PCPU_GET(cpuid));
|
||||||
mtx_unlock_spin(&ap_boot_mtx);
|
mtx_unlock_spin(&ap_boot_mtx);
|
||||||
|
|
||||||
/* Initialize curthread */
|
|
||||||
PCPU_SET(curthread, PCPU_GET(idlethread));
|
|
||||||
PCPU_SET(curpcb, curthread->td_pcb);
|
|
||||||
|
|
||||||
/* Start per-CPU event timers. */
|
/* Start per-CPU event timers. */
|
||||||
cpu_initclocks_ap();
|
cpu_initclocks_ap();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user