tile: add <asm/word-at-a-time.h> and enable support functions

This change enables the generic strncpy_from_user() and strnlen_user()
using word-at-a-time.h.  The tile implementation is trivial since
both tilepro and tilegx have SIMD operations that do byte-wise
comparisons against immediate zero for each byte, and return an
0x01 byte in each position where there is a 0x00 byte.

Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com>
This commit is contained in:
Chris Metcalf
2015-04-30 15:12:42 -04:00
parent 627ae54854
commit 5bf6c07a18
6 changed files with 48 additions and 150 deletions

View File

@@ -19,52 +19,6 @@
/* Access user memory, but use MMU to avoid propagating kernel exceptions. */
/*
* strnlen_user_asm takes the pointer in r0, and the length bound in r1.
* It returns the length, including the terminating NUL, or zero on exception.
* If length is greater than the bound, returns one plus the bound.
*/
STD_ENTRY(strnlen_user_asm)
{ bz r1, 2f; addi r3, r0, -1 } /* bias down to include NUL */
1: { lb_u r4, r0; addi r1, r1, -1 }
bz r4, 2f
{ bnzt r1, 1b; addi r0, r0, 1 }
2: { sub r0, r0, r3; jrp lr }
STD_ENDPROC(strnlen_user_asm)
.pushsection .fixup,"ax"
strnlen_user_fault:
{ move r0, zero; jrp lr }
ENDPROC(strnlen_user_fault)
.section __ex_table,"a"
.align 4
.word 1b, strnlen_user_fault
.popsection
/*
* strncpy_from_user_asm takes the kernel target pointer in r0,
* the userspace source pointer in r1, and the length bound (including
* the trailing NUL) in r2. On success, it returns the string length
* (not including the trailing NUL), or -EFAULT on failure.
*/
STD_ENTRY(strncpy_from_user_asm)
{ bz r2, 2f; move r3, r0 }
1: { lb_u r4, r1; addi r1, r1, 1; addi r2, r2, -1 }
{ sb r0, r4; addi r0, r0, 1 }
bz r4, 2f
bnzt r2, 1b
{ sub r0, r0, r3; jrp lr }
2: addi r0, r0, -1 /* don't count the trailing NUL */
{ sub r0, r0, r3; jrp lr }
STD_ENDPROC(strncpy_from_user_asm)
.pushsection .fixup,"ax"
strncpy_from_user_fault:
{ movei r0, -EFAULT; jrp lr }
ENDPROC(strncpy_from_user_fault)
.section __ex_table,"a"
.align 4
.word 1b, strncpy_from_user_fault
.popsection
/*
* clear_user_asm takes the user target address in r0 and the
* number of bytes to zero in r1.