summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2009-07-29 18:31:12 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2009-07-29 18:31:12 +0000
commitac24c148389b1e7d3cadced1d7cd219e3ca280a5 (patch)
tree5d8afa506fd09ec8e8515d01617c9ffc5f76b674
parent2d8712c8ebf00810368617a9f970123259391500 (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.cf3
-rw-r--r--sys/arch/hppa/hppa/hpux_machdep.c11
-rw-r--r--sys/arch/hppa/hppa/locore.S8
-rw-r--r--sys/arch/hppa/hppa/machdep.c16
-rw-r--r--sys/arch/hppa/hppa/pmap.c4
-rw-r--r--sys/arch/hppa/hppa/process_machdep.c3
-rw-r--r--sys/arch/hppa/hppa/vm_machdep.c41
-rw-r--r--sys/arch/hppa/include/pcb.h16
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 */