diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-07-29 18:31:12 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-07-29 18:31:12 +0000 |
commit | ac24c148389b1e7d3cadced1d7cd219e3ca280a5 (patch) | |
tree | 5d8afa506fd09ec8e8515d01617c9ffc5f76b674 | |
parent | 2d8712c8ebf00810368617a9f970123259391500 (diff) |
Get rid of non-equivalent aliases of the pcb by moving the fpu state out
of the pcb and using the p_addr member of 'struct proc' to calculate the
address of the kernel stack when switching to virtual mode after taking a trap.
Remove the now unecessary cache flushes; they're actually harmful since they
create non-equivalent aliases. This seems to fix the memory corruption we
have been observing from time to time.
This diff does not rename fpu_curpcb, which is now somewhat incorrectly named.
I hope to change things back again as soon as we are able to map the pcb 1:1.
-rw-r--r-- | sys/arch/hppa/hppa/genassym.cf | 3 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/hpux_machdep.c | 11 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/locore.S | 8 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/machdep.c | 16 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/pmap.c | 4 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/process_machdep.c | 3 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/vm_machdep.c | 41 | ||||
-rw-r--r-- | sys/arch/hppa/include/pcb.h | 16 |
8 files changed, 35 insertions, 67 deletions
diff --git a/sys/arch/hppa/hppa/genassym.cf b/sys/arch/hppa/hppa/genassym.cf index aaa4058315c..f17aecfd78a 100644 --- a/sys/arch/hppa/hppa/genassym.cf +++ b/sys/arch/hppa/hppa/genassym.cf @@ -1,4 +1,4 @@ -# $OpenBSD: genassym.cf,v 1.32 2009/02/14 19:03:50 kettenis Exp $ +# $OpenBSD: genassym.cf,v 1.33 2009/07/29 18:31:11 kettenis Exp $ # # Copyright (c) 1982, 1990, 1993 @@ -145,7 +145,6 @@ struct pcb member pcb_fpregs member pcb_onfault member pcb_space -member pcb_uva member pcb_ksp struct user diff --git a/sys/arch/hppa/hppa/hpux_machdep.c b/sys/arch/hppa/hppa/hpux_machdep.c index 351c3961bd6..ffcad83594b 100644 --- a/sys/arch/hppa/hppa/hpux_machdep.c +++ b/sys/arch/hppa/hppa/hpux_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hpux_machdep.c,v 1.2 2005/03/26 20:37:24 mickey Exp $ */ +/* $OpenBSD: hpux_machdep.c,v 1.3 2009/07/29 18:31:11 kettenis Exp $ */ /* * Copyright (c) 2005 Michael Shalayeff @@ -115,11 +115,10 @@ hpux_setregs(struct proc *p, struct exec_package *pack, u_long stack, copyout(&zero, (caddr_t)(stack + HPPA_FRAME_CRP), sizeof(register_t)); /* reset any of the pending FPU exceptions */ - pcb->pcb_fpregs[0] = ((u_int64_t)HPPA_FPU_INIT) << 32; - pcb->pcb_fpregs[1] = 0; - pcb->pcb_fpregs[2] = 0; - pcb->pcb_fpregs[3] = 0; - fdcache(HPPA_SID_KERNEL, (vaddr_t)pcb->pcb_fpregs, 8 * 4); + pcb->pcb_fpregs->fpr_regs[0] = ((u_int64_t)HPPA_FPU_INIT) << 32; + pcb->pcb_fpregs->fpr_regs[1] = 0; + pcb->pcb_fpregs->fpr_regs[2] = 0; + pcb->pcb_fpregs->fpr_regs[3] = 0; if (tf->tf_cr30 == fpu_curpcb) { fpu_curpcb = 0; /* force an fpu ctxsw, we won't be hugged by the cpu_switch */ diff --git a/sys/arch/hppa/hppa/locore.S b/sys/arch/hppa/hppa/locore.S index 217add80e3c..e7b75483035 100644 --- a/sys/arch/hppa/hppa/locore.S +++ b/sys/arch/hppa/hppa/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.160 2009/02/14 19:03:50 kettenis Exp $ */ +/* $OpenBSD: locore.S,v 1.161 2009/07/29 18:31:11 kettenis Exp $ */ /* * Copyright (c) 1998-2004 Michael Shalayeff @@ -198,7 +198,6 @@ $start_zero_tf mtctl arg3, cr30 stw r0, U_PCB+PCB_ONFAULT(arg3) stw r0, U_PCB+PCB_SPACE(arg3) /* XXX HPPA_SID_KERNEL == 0 */ - stw arg3, U_PCB+PCB_UVA(arg3) ldil L%(USPACE+NBPG), arg0 /* normal U plus red zone */ add arg0, arg3, arg0 ldil L%proc0paddr, t1 @@ -1628,10 +1627,11 @@ ENTRY(TLABEL(all),0) comb,<> t1, t2, $trap_from_kernel dep r0, 31, 6, sp - mfctl cr30, t2 + ldil L%curproc, t2 + ldw R%curproc(t2), t2 depi 1, T_USER_POS, 1, r1 depi 1, TFF_LAST_POS, 1, r1 - ldw U_PCB+PCB_UVA(t2), sp + ldw P_ADDR(t2), sp ldo NBPG(sp), sp $trap_from_kernel diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c index 843dac586e3..d7053f805f0 100644 --- a/sys/arch/hppa/hppa/machdep.c +++ b/sys/arch/hppa/hppa/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.173 2009/06/15 17:01:25 beck Exp $ */ +/* $OpenBSD: machdep.c,v 1.174 2009/07/29 18:31:11 kettenis Exp $ */ /* * Copyright (c) 1999-2003 Michael Shalayeff @@ -164,6 +164,7 @@ paddr_t avail_end; struct user *proc0paddr; long mem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(64) / sizeof(long)]; struct extent *hppa_ex; +struct pool hppa_fppl; struct vm_map *exec_map = NULL; struct vm_map *phys_map = NULL; @@ -421,6 +422,8 @@ hppa_init(start) #endif ficacheall(); fdcacheall(); + + pool_init(&hppa_fppl, sizeof(struct fpreg), 16, 0, 0, "hppafp", NULL); } void @@ -1233,11 +1236,10 @@ setregs(p, pack, stack, retval) fpu_exit(); fpu_curpcb = 0; } - pcb->pcb_fpregs[0] = ((u_int64_t)HPPA_FPU_INIT) << 32; - pcb->pcb_fpregs[1] = 0; - pcb->pcb_fpregs[2] = 0; - pcb->pcb_fpregs[3] = 0; - fdcache(HPPA_SID_KERNEL, (vaddr_t)pcb->pcb_fpregs, 8 * 4); + pcb->pcb_fpregs->fpr_regs[0] = ((u_int64_t)HPPA_FPU_INIT) << 32; + pcb->pcb_fpregs->fpr_regs[1] = 0; + pcb->pcb_fpregs->fpr_regs[2] = 0; + pcb->pcb_fpregs->fpr_regs[3] = 0; retval[1] = 0; } @@ -1456,8 +1458,6 @@ sys_sigreturn(p, v, retval) tf->tf_r31 = ksc.sc_regs[31]; bcopy(ksc.sc_fpregs, p->p_addr->u_pcb.pcb_fpregs, sizeof(ksc.sc_fpregs)); - fdcache(HPPA_SID_KERNEL, (vaddr_t)p->p_addr->u_pcb.pcb_fpregs, - sizeof(ksc.sc_fpregs)); tf->tf_iioq_head = ksc.sc_pcoqh | HPPA_PC_PRIV_USER; tf->tf_iioq_tail = ksc.sc_pcoqt | HPPA_PC_PRIV_USER; diff --git a/sys/arch/hppa/hppa/pmap.c b/sys/arch/hppa/hppa/pmap.c index 70f4ff147f7..a2829a528c6 100644 --- a/sys/arch/hppa/hppa/pmap.c +++ b/sys/arch/hppa/hppa/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.140 2009/07/26 15:47:23 kettenis Exp $ */ +/* $OpenBSD: pmap.c,v 1.141 2009/07/29 18:31:11 kettenis Exp $ */ /* * Copyright (c) 1998-2004 Michael Shalayeff @@ -1151,8 +1151,6 @@ pmap_activate(struct proc *p) struct pcb *pcb = &p->p_addr->u_pcb; pcb->pcb_space = pmap->pm_space; - pcb->pcb_uva = (vaddr_t)p->p_addr; - fdcache(HPPA_SID_KERNEL, (vaddr_t)pcb, PAGE_SIZE); } void diff --git a/sys/arch/hppa/hppa/process_machdep.c b/sys/arch/hppa/hppa/process_machdep.c index ed329879051..192bf61d72c 100644 --- a/sys/arch/hppa/hppa/process_machdep.c +++ b/sys/arch/hppa/hppa/process_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: process_machdep.c,v 1.14 2007/07/20 20:52:51 kettenis Exp $ */ +/* $OpenBSD: process_machdep.c,v 1.15 2009/07/29 18:31:11 kettenis Exp $ */ /* * Copyright (c) 1999-2004 Michael Shalayeff @@ -160,7 +160,6 @@ process_write_fpregs(p, fpregs) } bcopy(fpregs, p->p_addr->u_pcb.pcb_fpregs, 32 * 8); - fdcache(HPPA_SID_KERNEL, (vaddr_t)p->p_addr->u_pcb.pcb_fpregs, 32 * 8); return (0); } diff --git a/sys/arch/hppa/hppa/vm_machdep.c b/sys/arch/hppa/hppa/vm_machdep.c index b93d42f3102..3b67e465cd8 100644 --- a/sys/arch/hppa/hppa/vm_machdep.c +++ b/sys/arch/hppa/hppa/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.67 2009/06/26 18:55:20 miod Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.68 2009/07/29 18:31:11 kettenis Exp $ */ /* * Copyright (c) 1999-2004 Michael Shalayeff @@ -38,6 +38,7 @@ #include <sys/ptrace.h> #include <sys/exec.h> #include <sys/core.h> +#include <sys/pool.h> #include <machine/cpufunc.h> #include <machine/pmap.h> @@ -45,6 +46,7 @@ #include <uvm/uvm.h> +extern struct pool hppa_fppl; /* * Dump the machine specific header information at the start of a core dump. @@ -103,7 +105,6 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) struct pcb *pcbp; struct trapframe *tf; register_t sp, osp; - paddr_t pa; #ifdef DIAGNOSTIC if (round_page(sizeof(struct user)) > NBPG) @@ -115,38 +116,25 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) mtctl(0, CR_CCR); } - /* - * Stash the physical for the pcb of U for later perusal - */ - if (!pmap_extract(pmap_kernel(), (vaddr_t)p2->p_addr, &pa)) - panic("pmap_extract(%p) failed", p2->p_addr); - - /* - * XXX This shouldn't be necessary, since there shouldn't be any - * allocated cache lines for this new pcb. But for some reason - * that is not the case... - */ - fdcache(HPPA_SID_KERNEL, pa, PAGE_SIZE); - pdtlb(HPPA_SID_KERNEL, pa); - pitlb(HPPA_SID_KERNEL, pa); - pcbp = &p2->p_addr->u_pcb; bcopy(&p1->p_addr->u_pcb, pcbp, sizeof(*pcbp)); /* space is cached for the copy{in,out}'s pleasure */ pcbp->pcb_space = p2->p_vmspace->vm_map.pmap->pm_space; - pcbp->pcb_uva = (vaddr_t)p2->p_addr; + pcbp->pcb_fpregs = pool_get(&hppa_fppl, PR_WAITOK); + *pcbp->pcb_fpregs = *p1->p_addr->u_pcb.pcb_fpregs; /* reset any of the pending FPU exceptions from parent */ - pcbp->pcb_fpregs[0] = HPPA_FPU_FORK(pcbp->pcb_fpregs[0]); - pcbp->pcb_fpregs[1] = 0; - pcbp->pcb_fpregs[2] = 0; - pcbp->pcb_fpregs[3] = 0; + pcbp->pcb_fpregs->fpr_regs[0] = + HPPA_FPU_FORK(pcbp->pcb_fpregs->fpr_regs[0]); + pcbp->pcb_fpregs->fpr_regs[1] = 0; + pcbp->pcb_fpregs->fpr_regs[2] = 0; + pcbp->pcb_fpregs->fpr_regs[3] = 0; sp = (register_t)p2->p_addr + NBPG; p2->p_md.md_regs = tf = (struct trapframe *)sp; sp += sizeof(struct trapframe); bcopy(p1->p_md.md_regs, tf, sizeof(*tf)); - tf->tf_cr30 = pa; + tf->tf_cr30 = (paddr_t)pcbp->pcb_fpregs; tf->tf_sr0 = tf->tf_sr1 = tf->tf_sr2 = tf->tf_sr3 = tf->tf_sr4 = tf->tf_sr5 = tf->tf_sr6 = @@ -181,11 +169,6 @@ cpu_fork(p1, p2, stack, stacksize, func, arg) *HPPA_FRAME_CARG(0, sp) = (register_t)arg; *HPPA_FRAME_CARG(1, sp) = KERNMODE(func); pcbp->pcb_ksp = sp; - - fdcache(HPPA_SID_KERNEL, (vaddr_t)p2->p_addr, PAGE_SIZE); - pdtlb(HPPA_SID_KERNEL, (vaddr_t)p2->p_addr); - ficache(HPPA_SID_KERNEL, (vaddr_t)p2->p_addr, PAGE_SIZE); - pitlb(HPPA_SID_KERNEL, (vaddr_t)p2->p_addr); } void @@ -194,11 +177,13 @@ cpu_exit(p) { extern paddr_t fpu_curpcb; /* from locore.S */ struct trapframe *tf = p->p_md.md_regs; + struct pcb *pcb = &p->p_addr->u_pcb; if (fpu_curpcb == tf->tf_cr30) { fpu_exit(); fpu_curpcb = 0; } + pool_put(&hppa_fppl, pcb->pcb_fpregs); pmap_deactivate(p); sched_exit(p); diff --git a/sys/arch/hppa/include/pcb.h b/sys/arch/hppa/include/pcb.h index 68d7a0ba384..d6032d20412 100644 --- a/sys/arch/hppa/include/pcb.h +++ b/sys/arch/hppa/include/pcb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pcb.h,v 1.11 2007/07/29 20:15:56 kettenis Exp $ */ +/* $OpenBSD: pcb.h,v 1.12 2009/07/29 18:31:11 kettenis Exp $ */ /* * Copyright (c) 1999-2004 Michael Shalayeff @@ -33,19 +33,7 @@ #include <machine/reg.h> struct pcb { - u_int64_t pcb_fpregs[HPPA_NFPREGS+1]; /* not in the trapframe */ - vaddr_t pcb_uva; /* KVA for U-area */ - - /* - * The members above are primarily accessed by there physical - * address, wheras the members below are accessed exclusively - * by there virtual address. Unfortunately this structure - * ends up being non-equivalently mapped, which will cause - * data corruption if those members share a cache line. Since - * the maximum cache line size is 64 bytes, adding 64 bytes of - * padding makes sure that will never happen. - */ - u_char pcb_pad[64]; + struct fpreg *pcb_fpregs; /* not in the trapframe */ u_int pcb_ksp; /* kernel sp for ctxsw */ u_int pcb_onfault; /* SW copy fault handler */ |