Author: jhibbits
Date: Sun Feb  3 00:19:34 2013
New Revision: 246275
URL: http://svnweb.freebsd.org/changeset/base/246275

Log:
  Fix the PowerPC DTrace copy functions.  The kernel doesn't hold the same view 
to
  the user map, so use the md copy in/out functions provided by the kernel.
  
  MFC with:     r242723

Modified:
  head/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S
  head/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c

Modified: head/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S
==============================================================================
--- head/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S       Sun Feb  3 00:02:59 
2013        (r246274)
+++ head/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S       Sun Feb  3 00:19:34 
2013        (r246275)
@@ -19,6 +19,8 @@
  *
  * CDDL HEADER END
  *
+ * Portions Copyright 2012,2013 Justin Hibbits <jhibb...@freebsd.org>
+ *
  * $FreeBSD$
  */
 /*
@@ -114,48 +116,6 @@ ASENTRY_NOPROF(dtrace_fulword)
 END(dtrace_fulword)
 
 /*
-uint8_t
-dtrace_fuword8_nocheck(void *addr)
-*/
-ASENTRY_NOPROF(dtrace_fuword8_nocheck)
-       lbz     %r3,0(%r3)
-       blr
-END(dtrace_fuword8_nocheck)
-
-/*
-uint16_t
-dtrace_fuword16_nocheck(void *addr)
-*/
-ASENTRY_NOPROF(dtrace_fuword16_nocheck)
-       lhz     %r3,0(%r3)
-       blr
-END(dtrace_fuword16_nocheck)
-
-/*
-uint32_t
-dtrace_fuword32_nocheck(void *addr)
-*/
-ASENTRY_NOPROF(dtrace_fuword32_nocheck)
-       lwz     %r3,0(%r3)
-       blr
-END(dtrace_fuword32_nocheck)
-
-/*
-uint64_t
-dtrace_fuword64_nocheck(void *addr)
-*/
-ASENTRY_NOPROF(dtrace_fuword64_nocheck)
-#if defined(__powerpc64__)
-       ld      %r3,0(%r3)
-#else
-       lwz     %r5,0(%r3)
-       lwz     %r4,4(%r3)
-       mr      %r3,%r5
-#endif
-       blr
-END(dtrace_fuword64_nocheck)
-
-/*
 XXX: unoptimized
 void
 dtrace_copy(uintptr_t src, uintptr_t dest, size_t size)

Modified: head/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c
==============================================================================
--- head/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c       Sun Feb  3 00:02:59 
2013        (r246274)
+++ head/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c       Sun Feb  3 00:19:34 
2013        (r246275)
@@ -19,6 +19,8 @@
  *
  * CDDL HEADER END
  *
+ * Portions Copyright 2012,2013 Justin Hibbits <jhibb...@freebsd.org>
+ *
  * $FreeBSD$
  */
 /*
@@ -45,11 +47,6 @@
 
 #include "regset.h"
 
-uint8_t dtrace_fuword8_nocheck(void *);
-uint16_t dtrace_fuword16_nocheck(void *);
-uint32_t dtrace_fuword32_nocheck(void *);
-uint64_t dtrace_fuword64_nocheck(void *);
-
 /* Offset to the LR Save word (ppc32) */
 #define RETURN_OFFSET  4
 #define RETURN_OFFSET64        8
@@ -462,31 +459,63 @@ dtrace_copyin(uintptr_t uaddr, uintptr_t
     volatile uint16_t *flags)
 {
        if (dtrace_copycheck(uaddr, kaddr, size))
-               dtrace_copy(uaddr, kaddr, size);
+               if (copyin((const void *)uaddr, (void *)kaddr, size)) {
+                       DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+                       cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
+               }
 }
 
 void
 dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size,
     volatile uint16_t *flags)
 {
-       if (dtrace_copycheck(uaddr, kaddr, size))
-               dtrace_copy(kaddr, uaddr, size);
+       if (dtrace_copycheck(uaddr, kaddr, size)) {
+               if (copyout((const void *)kaddr, (void *)uaddr, size)) {
+                       DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+                       cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
+               }
+       }
 }
 
 void
 dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
     volatile uint16_t *flags)
 {
-       if (dtrace_copycheck(uaddr, kaddr, size))
-               dtrace_copystr(uaddr, kaddr, size, flags);
+       size_t actual;
+       int    error;
+
+       if (dtrace_copycheck(uaddr, kaddr, size)) {
+               error = copyinstr((const void *)uaddr, (void *)kaddr,
+                   size, &actual);
+               
+               /* ENAMETOOLONG is not a fault condition. */
+               if (error && error != ENAMETOOLONG) {
+                       DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+                       cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
+               }
+       }
 }
 
+/*
+ * The bulk of this function could be replaced to match dtrace_copyinstr() 
+ * if we ever implement a copyoutstr().
+ */
 void
 dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size,
     volatile uint16_t *flags)
 {
-       if (dtrace_copycheck(uaddr, kaddr, size))
-               dtrace_copystr(kaddr, uaddr, size, flags);
+       size_t len;
+
+       if (dtrace_copycheck(uaddr, kaddr, size)) {
+               len = strlen((const char *)kaddr);
+               if (len > size)
+                       len = size;
+
+               if (copyout((const void *)kaddr, (void *)uaddr, len)) {
+                       DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+                       cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
+               }
+       }
 }
 
 uint8_t
@@ -497,18 +526,21 @@ dtrace_fuword8(void *uaddr)
                cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
                return (0);
        }
-       return (dtrace_fuword8_nocheck(uaddr));
+       return (fubyte(uaddr));
 }
 
 uint16_t
 dtrace_fuword16(void *uaddr)
 {
-       if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
-               DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
-               cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
-               return (0);
+       uint16_t ret = 0;
+
+       if (dtrace_copycheck((uintptr_t)uaddr, (uintptr_t)&ret, sizeof(ret))) {
+               if (copyin((const void *)uaddr, (void *)&ret, sizeof(ret))) {
+                       DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+                       cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
+               }
        }
-       return (dtrace_fuword16_nocheck(uaddr));
+       return ret;
 }
 
 uint32_t
@@ -519,16 +551,19 @@ dtrace_fuword32(void *uaddr)
                cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
                return (0);
        }
-       return (dtrace_fuword32_nocheck(uaddr));
+       return (fuword32(uaddr));
 }
 
 uint64_t
 dtrace_fuword64(void *uaddr)
 {
-       if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
-               DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
-               cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
-               return (0);
+       uint64_t ret = 0;
+
+       if (dtrace_copycheck((uintptr_t)uaddr, (uintptr_t)&ret, sizeof(ret))) {
+               if (copyin((const void *)uaddr, (void *)&ret, sizeof(ret))) {
+                       DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+                       cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
+               }
        }
-       return (dtrace_fuword64_nocheck(uaddr));
+       return ret;
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to