svn commit: r258024 - in head/sys: conf powerpc/aim powerpc/booke powerpc/powerpc
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Tue Nov 12 01:15:27 UTC 2013
Author: nwhitehorn
Date: Mon Nov 11 23:37:16 2013
New Revision: 258024
URL: http://svnweb.freebsd.org/changeset/base/258024
Log:
Use the same implementation of copyinout.c for both AIM and Book-E. This
fixes some bugs in both implementations related to validity checks on
mapping bounds.
Added:
head/sys/powerpc/powerpc/copyinout.c
- copied, changed from r257990, head/sys/powerpc/aim/copyinout.c
Deleted:
head/sys/powerpc/aim/copyinout.c
head/sys/powerpc/booke/copyinout.c
Modified:
head/sys/conf/files.powerpc
Modified: head/sys/conf/files.powerpc
==============================================================================
--- head/sys/conf/files.powerpc Mon Nov 11 22:07:56 2013 (r258023)
+++ head/sys/conf/files.powerpc Mon Nov 11 23:37:16 2013 (r258024)
@@ -86,7 +86,6 @@ libkern/qdivrem.c optional powerpc
libkern/ucmpdi2.c optional powerpc
libkern/udivdi3.c optional powerpc
libkern/umoddi3.c optional powerpc
-powerpc/aim/copyinout.c optional aim
powerpc/aim/interrupt.c optional aim
powerpc/aim/locore.S optional aim no-obj
powerpc/aim/machdep.c optional aim
@@ -98,7 +97,6 @@ powerpc/aim/mp_cpudep.c optional aim sm
powerpc/aim/slb.c optional aim powerpc64
powerpc/aim/trap.c optional aim
powerpc/aim/uma_machdep.c optional aim
-powerpc/booke/copyinout.c optional booke
powerpc/booke/interrupt.c optional booke
powerpc/booke/locore.S optional booke no-obj
powerpc/booke/machdep.c optional booke
@@ -173,6 +171,7 @@ powerpc/powerpc/bcopy.c standard
powerpc/powerpc/bus_machdep.c standard
powerpc/powerpc/busdma_machdep.c standard
powerpc/powerpc/clock.c standard
+powerpc/powerpc/copyinout.c standard
powerpc/powerpc/copystr.c standard
powerpc/powerpc/cpu.c standard
powerpc/powerpc/db_disasm.c optional ddb
Copied and modified: head/sys/powerpc/powerpc/copyinout.c (from r257990, head/sys/powerpc/aim/copyinout.c)
==============================================================================
--- head/sys/powerpc/aim/copyinout.c Mon Nov 11 14:08:25 2013 (r257990, copy source)
+++ head/sys/powerpc/powerpc/copyinout.c Mon Nov 11 23:37:16 2013 (r258024)
@@ -69,9 +69,11 @@ __FBSDID("$FreeBSD$");
#include <machine/pcb.h>
#include <machine/sr.h>
#include <machine/slb.h>
+#include <machine/vmparam.h>
int setfault(faultbuf); /* defined in locore.S */
+#ifdef AIM
/*
* Makes sure that the right segment of userspace is mapped in.
*/
@@ -132,6 +134,43 @@ set_user_sr(pmap_t pm, const void *addr)
}
#endif
+static __inline int
+map_user_ptr(pmap_t pm, const void *uaddr, void **kaddr, size_t ulen,
+ size_t *klen)
+{
+ size_t l;
+
+ *kaddr = (char *)USER_ADDR + ((uintptr_t)uaddr & ~SEGMENT_MASK);
+
+ l = ((char *)USER_ADDR + SEGMENT_LENGTH) - (char *)(*kaddr);
+ if (l > ulen)
+ l = ulen;
+ if (klen)
+ *klen = l;
+ else if (l != ulen)
+ return (EFAULT);
+
+ set_user_sr(pm, uaddr);
+
+ return (0);
+}
+#else /* Book-E uses a combined kernel/user mapping */
+static __inline int
+map_user_ptr(pmap_t pm, const void *uaddr, void **kaddr, size_t ulen,
+ size_t *klen)
+{
+
+ if ((uintptr_t)uaddr + ulen > VM_MAXUSER_ADDRESS + PAGE_SIZE)
+ return (EFAULT);
+
+ *kaddr = (void *)(uintptr_t)uaddr;
+ if (klen)
+ *klen = ulen;
+
+ return (0);
+}
+#endif
+
int
copyout(const void *kaddr, void *udaddr, size_t len)
{
@@ -154,13 +193,10 @@ copyout(const void *kaddr, void *udaddr,
up = udaddr;
while (len > 0) {
- p = (char *)USER_ADDR + ((uintptr_t)up & ~SEGMENT_MASK);
-
- l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
- if (l > len)
- l = len;
-
- set_user_sr(pm,up);
+ if (map_user_ptr(pm, udaddr, (void **)&p, len, &l)) {
+ td->td_pcb->pcb_onfault = NULL;
+ return (-1);
+ }
bcopy(kp, p, l);
@@ -195,13 +231,10 @@ copyin(const void *udaddr, void *kaddr,
up = udaddr;
while (len > 0) {
- p = (char *)USER_ADDR + ((uintptr_t)up & ~SEGMENT_MASK);
-
- l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
- if (l > len)
- l = len;
-
- set_user_sr(pm,up);
+ if (map_user_ptr(pm, udaddr, (void **)&p, len, &l)) {
+ td->td_pcb->pcb_onfault = NULL;
+ return (-1);
+ }
bcopy(p, kp, l);
@@ -269,14 +302,16 @@ subyte(void *addr, int byte)
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (char *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
if (setfault(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
- set_user_sr(pm,addr);
+ if (map_user_ptr(pm, addr, (void **)&p, sizeof(*p), NULL)) {
+ td->td_pcb->pcb_onfault = NULL;
+ return (-1);
+ }
*p = (char)byte;
@@ -295,14 +330,16 @@ suword32(void *addr, int word)
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (int *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
if (setfault(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
- set_user_sr(pm,addr);
+ if (map_user_ptr(pm, addr, (void **)&p, sizeof(*p), NULL)) {
+ td->td_pcb->pcb_onfault = NULL;
+ return (-1);
+ }
*p = word;
@@ -321,14 +358,16 @@ suword(void *addr, long word)
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (long *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
if (setfault(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
- set_user_sr(pm,addr);
+ if (map_user_ptr(pm, addr, (void **)&p, sizeof(*p), NULL)) {
+ td->td_pcb->pcb_onfault = NULL;
+ return (-1);
+ }
*p = word;
@@ -361,14 +400,16 @@ fubyte(const void *addr)
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (u_char *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
if (setfault(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
- set_user_sr(pm,addr);
+ if (map_user_ptr(pm, addr, (void **)&p, sizeof(*p), NULL)) {
+ td->td_pcb->pcb_onfault = NULL;
+ return (-1);
+ }
val = *p;
@@ -387,14 +428,16 @@ fuword32(const void *addr)
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (int32_t *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
if (setfault(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
- set_user_sr(pm,addr);
+ if (map_user_ptr(pm, addr, (void **)&p, sizeof(*p), NULL)) {
+ td->td_pcb->pcb_onfault = NULL;
+ return (-1);
+ }
val = *p;
@@ -413,14 +456,16 @@ fuword(const void *addr)
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (long *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
if (setfault(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
- set_user_sr(pm,addr);
+ if (map_user_ptr(pm, addr, (void **)&p, sizeof(*p), NULL)) {
+ td->td_pcb->pcb_onfault = NULL;
+ return (-1);
+ }
val = *p;
@@ -446,15 +491,18 @@ casuword32(volatile uint32_t *addr, uint
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (uint32_t *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
-
- set_user_sr(pm,(const void *)(vm_offset_t)addr);
if (setfault(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
+ if (map_user_ptr(pm, (void *)(uintptr_t)addr, (void **)&p, sizeof(*p),
+ NULL)) {
+ td->td_pcb->pcb_onfault = NULL;
+ return (-1);
+ }
+
__asm __volatile (
"1:\tlwarx %0, 0, %2\n\t" /* load old value */
"cmplw %3, %0\n\t" /* compare */
@@ -491,15 +539,18 @@ casuword(volatile u_long *addr, u_long o
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- p = (u_long *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK));
-
- set_user_sr(pm,(const void *)(vm_offset_t)addr);
if (setfault(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
+ if (map_user_ptr(pm, (void *)(uintptr_t)addr, (void **)&p, sizeof(*p),
+ NULL)) {
+ td->td_pcb->pcb_onfault = NULL;
+ return (-1);
+ }
+
__asm __volatile (
"1:\tldarx %0, 0, %2\n\t" /* load old value */
"cmpld %3, %0\n\t" /* compare */
More information about the svn-src-head
mailing list