Here is a copyin32(9) for mips64. With futex(2) using it, the regress
tests pass on loongson, octeon and sgi. Source addresses with wrong
alignment are handled by the on-fault logic in itsa() trap handler.
OK?
Index: arch/mips64/mips64/lcore_access.S
===================================================================
RCS file: src/sys/arch/mips64/mips64/lcore_access.S,v
retrieving revision 1.26
diff -u -p -r1.26 lcore_access.S
--- arch/mips64/mips64/lcore_access.S 23 May 2016 20:11:49 -0000 1.26
+++ arch/mips64/mips64/lcore_access.S 18 May 2017 13:06:41 -0000
@@ -255,6 +255,31 @@ NON_LEAF(copyout, FRAMESZ(CF_SZ), ra)
move v0, zero
END(copyout)
+/*
+ * Copy an aligned 32-bit word atomically from user space into the kernel
+ * copyin32(from, to)
+ * uint32_t *from; (user source address)
+ * uint32_t *to; (kernel destination address)
+ */
+NON_LEAF(copyin32, FRAMESZ(CF_SZ), ra)
+ PTR_SUBU sp, sp, FRAMESZ(CF_SZ)
+ .mask 0x80000000, (CF_RA_OFFS - FRAMESZ(CF_SZ))
+ PTR_S ra, CF_RA_OFFS(sp)
+ blt a0, zero, _copyerr # make sure address is in user space
+ li v0, KT_COPYERR
+ GET_CPU_INFO(t1, t0)
+ PTR_L t3, CI_CURPROCPADDR(t1)
+ sw v0, PCB_ONFAULT(t3)
+
+ lw v1, 0(a0)
+ sw v1, 0(a1)
+
+ sw zero, PCB_ONFAULT(t3)
+ PTR_ADDU sp, sp, FRAMESZ(CF_SZ)
+ j ra
+ move v0, zero
+END(copyin32)
+
_copyerr:
PTR_L ra, CF_RA_OFFS(sp)
GET_CPU_INFO(t1, t0)