We can just call copyin(9) since it already is atomic.  But check
whether the userland futex is properly aligned and return EFAULT if it
isn't such that this system call behaves like it does on strict
alignment architectures.

Also, add a prototype to <sys/systm.h> such that we can actually use it.

ok?


Index: sys/systm.h
===================================================================
RCS file: /cvs/src/sys/sys/systm.h,v
retrieving revision 1.129
diff -u -p -r1.129 systm.h
--- sys/systm.h 15 May 2017 12:26:00 -0000      1.129
+++ sys/systm.h 16 May 2017 21:41:59 -0000
@@ -207,6 +207,7 @@ int copyoutstr(const void *, void *, siz
 int    copyin(const void *, void *, size_t)
                __attribute__ ((__bounded__(__buffer__,2,3)));
 int    copyout(const void *, void *, size_t);
+int    copyin32(const uint32_t *, uint32_t *);
 
 void   arc4random_buf(void *, size_t)
                __attribute__ ((__bounded__(__buffer__,1,2)));
Index: arch/i386/i386/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.600
diff -u -p -r1.600 machdep.c
--- arch/i386/i386/machdep.c    30 Apr 2017 16:45:45 -0000      1.600
+++ arch/i386/i386/machdep.c    16 May 2017 21:41:59 -0000
@@ -3890,6 +3890,16 @@ splassert_check(int wantipl, const char 
 }
 #endif
 
+int
+copyin32(const uint32_t *uaddr, uint32_t *kaddr)
+{
+       if ((vaddr_t)uaddr & 0x3)
+               return EFAULT;
+
+       /* copyin(9) is atomic */
+       return copyin(uaddr, kaddr, sizeof(uint32_t));
+}
+
 /*
  * True if the system has any non-level interrupts which are shared
  * on the same pin.
Index: arch/amd64/amd64/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/machdep.c,v
retrieving revision 1.228
diff -u -p -r1.228 machdep.c
--- arch/amd64/amd64/machdep.c  30 Apr 2017 16:45:45 -0000      1.228
+++ arch/amd64/amd64/machdep.c  16 May 2017 21:41:59 -0000
@@ -1777,6 +1777,16 @@ splassert_check(int wantipl, const char 
 }
 #endif
 
+int
+copyin32(const uint32_t *uaddr, uint32_t *kaddr)
+{
+       if ((vaddr_t)uaddr & 0x3)
+               return EFAULT;
+
+       /* copyin(9) is atomic */
+       return copyin(uaddr, kaddr, sizeof(uint32_t));
+}
+
 void
 getbootinfo(char *bootinfo, int bootinfo_size)
 {

Reply via email to