Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/powerpc Cast to register_t instead of int to be nic...
details: https://anonhg.NetBSD.org/src/rev/4e90b0048864
branches: trunk
changeset: 541844:4e90b0048864
user: matt <matt%NetBSD.org@localhost>
date: Sun Jan 19 02:43:11 2003 +0000
description:
Cast to register_t instead of int to be nicer for LP64.
Simplify copyin/copyout/copyinstr/copyoutstr. Fix bug
where the user virtual address was not updated so that
if the user's buffer crossed a segment boundary, the
wrong data could be copied. Localize USER_SR to the
ILP32 version of setusr/unsetusr.
diffstat:
sys/arch/powerpc/include/pcb.h | 10 +-
sys/arch/powerpc/mpc6xx/genassym.cf | 8 +-
sys/arch/powerpc/powerpc/trap.c | 217 +++++++++++++++++----------------
sys/arch/powerpc/powerpc/vm_machdep.c | 26 ++-
4 files changed, 138 insertions(+), 123 deletions(-)
diffs (truncated from 478 to 300 lines):
diff -r c539686de484 -r 4e90b0048864 sys/arch/powerpc/include/pcb.h
--- a/sys/arch/powerpc/include/pcb.h Sun Jan 19 02:39:47 2003 +0000
+++ b/sys/arch/powerpc/include/pcb.h Sun Jan 19 02:43:11 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pcb.h,v 1.11 2002/11/03 22:36:23 matt Exp $ */
+/* $NetBSD: pcb.h,v 1.12 2003/01/19 02:43:11 matt Exp $ */
/*-
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -46,12 +46,14 @@
struct pmap *pcb_pmreal; /* real address of above */
register_t pcb_sp; /* saved SP */
int pcb_spl; /* saved SPL */
+ int pcb_flags;
+#define PCB_FPU 1 /* Process had FPU initialized */
+#define PCB_ALTIVEC 2 /* Process had AltiVec initialized */
struct cpu_info * __volatile pcb_fpcpu; /* CPU with our FP state */
struct cpu_info * __volatile pcb_veccpu;/* CPU with our VECTOR state */
faultbuf *pcb_onfault; /* For use during copyin/copyout */
- int pcb_flags;
-#define PCB_FPU 1 /* Process had FPU initialized */
-#define PCB_ALTIVEC 2 /* Process had AltiVec initialized */
+ vaddr_t pcb_kmapsr; /* where to map user segment in kernel */
+ vaddr_t pcb_umapsr; /* the user segment mapped in kernel */
struct fpu pcb_fpu; /* Floating point processor */
struct vreg *pcb_vr;
};
diff -r c539686de484 -r 4e90b0048864 sys/arch/powerpc/mpc6xx/genassym.cf
--- a/sys/arch/powerpc/mpc6xx/genassym.cf Sun Jan 19 02:39:47 2003 +0000
+++ b/sys/arch/powerpc/mpc6xx/genassym.cf Sun Jan 19 02:43:11 2003 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.7 2003/01/18 06:23:31 thorpej Exp $
+# $NetBSD: genassym.cf,v 1.8 2003/01/19 02:43:12 matt Exp $
#
# Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -42,6 +42,8 @@
include <powerpc/cpu.h>
+define CALLFRAMELEN CALLFRAMELEN
+
define FRAMELEN FRAMELEN
define FRAME_0 offsetof(struct trapframe, fixreg[0])
define FRAME_1 offsetof(struct trapframe, fixreg[1])
@@ -95,7 +97,7 @@
define SPFRAME_R3 offsetof(struct spillframe, r3)
define SPFRAME_R0 offsetof(struct spillframe, r0)
-define SFRAMELEN roundup(sizeof(struct switchframe), 16)
+define SFRAMELEN roundup(sizeof(struct switchframe), CALLFRAMELEN)
define PCB_PMR offsetof(struct pcb, pcb_pmreal)
define PCB_SP offsetof(struct pcb, pcb_sp)
@@ -114,7 +116,7 @@
define L_PRIORITY offsetof(struct lwp, l_priority)
define L_PROC offsetof(struct lwp, l_proc)
-define LSONPROC LSONPROC
+define LSONPROC LSONPROC
define P_MD_SYSCALL offsetof(struct proc, p_md.md_syscall)
define CI_SIZE sizeof(struct cpu_info)
diff -r c539686de484 -r 4e90b0048864 sys/arch/powerpc/powerpc/trap.c
--- a/sys/arch/powerpc/powerpc/trap.c Sun Jan 19 02:39:47 2003 +0000
+++ b/sys/arch/powerpc/powerpc/trap.c Sun Jan 19 02:43:11 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.76 2003/01/18 21:28:12 matt Exp $ */
+/* $NetBSD: trap.c,v 1.77 2003/01/19 02:43:12 matt Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -66,10 +66,11 @@
#endif
static int fix_unaligned __P((struct lwp *l, struct trapframe *frame));
-static inline void setusr __P((int));
+static inline vaddr_t setusr __P((vaddr_t, size_t *));
+static inline void unsetusr __P((void));
void trap __P((struct trapframe *)); /* Called from locore / trap_subr */
-int setfault __P((faultbuf)); /* defined in locore.S */
+int setfault __P((faultbuf)); /* defined in locore.S */
/* Why are these not defined in a header? */
int badaddr __P((void *, size_t));
int badaddr_read __P((void *, size_t, int *));
@@ -120,7 +121,7 @@
*/
if ((frame->dsisr & DSISR_NOTFOUND) &&
vm_map_pmap(kernel_map)->pm_evictions > 0 &&
- (va >> ADDR_SR_SHFT) != USER_SR &&
+ (va >> ADDR_SR_SHFT) != pcb->pcb_kmapsr &&
pmap_pte_spill(vm_map_pmap(kernel_map), trunc_page(va)))
return;
@@ -129,13 +130,9 @@
*/
if (intr_depth < 0) {
KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
- if ((va >> ADDR_SR_SHFT) == USER_SR) {
- sr_t user_sr;
-
- asm ("mfsr %0, %1"
- : "=r"(user_sr) : "K"(USER_SR));
+ if ((va >> ADDR_SR_SHFT) == pcb->pcb_kmapsr) {
va &= ADDR_PIDX | ADDR_POFF;
- va |= user_sr << ADDR_SR_SHFT;
+ va |= pcb->pcb_umapsr << ADDR_SR_SHFT;
map = &p->p_vmspace->vm_map;
/* KERNEL_PROC_LOCK(l); */
@@ -400,44 +397,72 @@
userret(l, frame);
}
-static inline void
-setusr(content)
- int content;
+#ifdef _LP64
+static inline vaddr_t
+setusr(vaddr_t uva, size_t *len_p)
+{
+ *len_p = SEGMENT_LENGTH - (uva & ~SEGMENT_MASK);
+ return pmap_setusr(uva) + (uva & ~SEGMENT_MASK);
+}
+static void
+unsetusr(void)
+{
+ pmap_unsetusr();
+}
+#else
+static inline vaddr_t
+setusr(vaddr_t uva, size_t *len_p)
{
- asm volatile ("isync; mtsr %0,%1; isync"
- :: "n"(USER_SR), "r"(content));
+ struct pcb *pcb = curpcb;
+ vaddr_t p;
+ KASSERT(pcb->pcb_kmapsr == 0);
+ pcb->pcb_kmapsr = USER_SR;
+ pcb->pcb_umapsr = uva >> ADDR_SR_SHFT;
+ *len_p = SEGMENT_LENGTH - (uva & ~SEGMENT_MASK);
+ p = (USER_SR << ADDR_SR_SHFT) + (uva & ~SEGMENT_MASK);
+ __asm __volatile ("isync; mtsr %0,%1; isync"
+ :: "n"(USER_SR), "r"(pcb->pcb_pm->pm_sr[pcb->pcb_umapsr]));
+ return p;
}
+static void
+unsetusr(void)
+{
+ curpcb->pcb_kmapsr = 0;
+ __asm __volatile ("isync; mtsr %0,%1; isync"
+ :: "n"(USER_SR), "r"(EMPTY_SEGMENT));
+}
+#endif
+
int
copyin(udaddr, kaddr, len)
const void *udaddr;
void *kaddr;
size_t len;
{
- const char *up = udaddr;
+ vaddr_t uva = (vaddr_t) udaddr;
char *kp = kaddr;
- char *p;
- int rv;
- size_t l;
faultbuf env;
+ int rv;
- if ((rv = setfault(env)) != 0) {
- curpcb->pcb_onfault = 0;
- return rv;
- }
+ if ((rv = setfault(env)) != 0)
+ goto out;
+
while (len > 0) {
- p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
- l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
- if (l > len)
- l = len;
- setusr(curpcb->pcb_pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]);
- memcpy(kp, p, l);
- up += l;
- kp += l;
- len -= l;
+ size_t seglen;
+ vaddr_t p = setusr(uva, &seglen);
+ if (seglen > len)
+ seglen = len;
+ memcpy(kp, (const char *) p, seglen);
+ uva += seglen;
+ kp += seglen;
+ len -= seglen;
}
+
+ out:
+ unsetusr();
curpcb->pcb_onfault = 0;
- return 0;
+ return rv;
}
int
@@ -447,29 +472,28 @@
size_t len;
{
const char *kp = kaddr;
- char *up = udaddr;
- char *p;
- int rv;
- size_t l;
+ vaddr_t uva = (vaddr_t) udaddr;
faultbuf env;
+ int rv;
- if ((rv = setfault(env)) != 0) {
- curpcb->pcb_onfault = 0;
- return rv;
- }
+ if ((rv = setfault(env)) != 0)
+ goto out;
+
while (len > 0) {
- p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
- l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
- if (l > len)
- l = len;
- setusr(curpcb->pcb_pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]);
- memcpy(p, kp, l);
- up += l;
- kp += l;
- len -= l;
+ size_t seglen;
+ vaddr_t p = setusr(uva, &seglen);
+ if (seglen > len)
+ seglen = len;
+ memcpy((char *)p, kp, seglen);
+ uva += seglen;
+ kp += seglen;
+ len -= seglen;
}
+
+ out:
+ unsetusr();
curpcb->pcb_onfault = 0;
- return 0;
+ return rv;
}
/*
@@ -492,15 +516,12 @@
int rv;
oldfault = curpcb->pcb_onfault;
- if ((rv = setfault(env)) != 0) {
- curpcb->pcb_onfault = oldfault;
- return rv;
- }
- memcpy(dst, src, len);
+ if ((rv = setfault(env)) == 0)
+ memcpy(dst, src, len);
curpcb->pcb_onfault = oldfault;
- return 0;
+ return rv;
}
int
@@ -542,7 +563,7 @@
x = *(volatile int32_t *)addr;
break;
default:
- panic("badaddr: invalid size (%d)", size);
+ panic("badaddr: invalid size (%lu)", (u_long) size);
}
/* Make sure we took the machine check, if we caused one. */
@@ -631,41 +652,34 @@
size_t len;
size_t *done;
{
- const char *up = udaddr;
+ vaddr_t uva = (vaddr_t) udaddr;
char *kp = kaddr;
- char *p;
- size_t l, ls, d;
faultbuf env;
int rv;
- if ((rv = setfault(env)) != 0) {
- curpcb->pcb_onfault = 0;
- return rv;
- }
- d = 0;
+ if ((rv = setfault(env)) != 0)
Home |
Main Index |
Thread Index |
Old Index