Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86/asm changes from Ingo Molnar: "Misc optimizations" * 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86: Slightly tweak the access_ok() C variant for better code x86: Replace assembly access_ok() with a C variant x86-64, copy_user: Use leal to produce 32-bit results x86-64, copy_user: Remove zero byte check before copy user buffer.
This commit is contained in:
commit
4cd4156994
@ -40,22 +40,30 @@
|
|||||||
/*
|
/*
|
||||||
* Test whether a block of memory is a valid user space address.
|
* Test whether a block of memory is a valid user space address.
|
||||||
* Returns 0 if the range is valid, nonzero otherwise.
|
* Returns 0 if the range is valid, nonzero otherwise.
|
||||||
*
|
|
||||||
* This is equivalent to the following test:
|
|
||||||
* (u33)addr + (u33)size > (u33)current->addr_limit.seg (u65 for x86_64)
|
|
||||||
*
|
|
||||||
* This needs 33-bit (65-bit for x86_64) arithmetic. We have a carry...
|
|
||||||
*/
|
*/
|
||||||
|
static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, unsigned long limit)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If we have used "sizeof()" for the size,
|
||||||
|
* we know it won't overflow the limit (but
|
||||||
|
* it might overflow the 'addr', so it's
|
||||||
|
* important to subtract the size from the
|
||||||
|
* limit, not add it to the address).
|
||||||
|
*/
|
||||||
|
if (__builtin_constant_p(size))
|
||||||
|
return addr > limit - size;
|
||||||
|
|
||||||
|
/* Arbitrary sizes? Be careful about overflow */
|
||||||
|
addr += size;
|
||||||
|
if (addr < size)
|
||||||
|
return true;
|
||||||
|
return addr > limit;
|
||||||
|
}
|
||||||
|
|
||||||
#define __range_not_ok(addr, size, limit) \
|
#define __range_not_ok(addr, size, limit) \
|
||||||
({ \
|
({ \
|
||||||
unsigned long flag, roksum; \
|
|
||||||
__chk_user_ptr(addr); \
|
__chk_user_ptr(addr); \
|
||||||
asm("add %3,%1 ; sbb %0,%0 ; cmp %1,%4 ; sbb $0,%0" \
|
__chk_range_not_ok((unsigned long __force)(addr), size, limit); \
|
||||||
: "=&r" (flag), "=r" (roksum) \
|
|
||||||
: "1" (addr), "g" ((long)(size)), \
|
|
||||||
"rm" (limit)); \
|
|
||||||
flag; \
|
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,7 +86,7 @@
|
|||||||
* this function, memory access functions may still return -EFAULT.
|
* this function, memory access functions may still return -EFAULT.
|
||||||
*/
|
*/
|
||||||
#define access_ok(type, addr, size) \
|
#define access_ok(type, addr, size) \
|
||||||
(likely(__range_not_ok(addr, size, user_addr_max()) == 0))
|
likely(!__range_not_ok(addr, size, user_addr_max()))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The exception table consists of pairs of addresses relative to the
|
* The exception table consists of pairs of addresses relative to the
|
||||||
|
@ -186,7 +186,7 @@ ENTRY(copy_user_generic_unrolled)
|
|||||||
30: shll $6,%ecx
|
30: shll $6,%ecx
|
||||||
addl %ecx,%edx
|
addl %ecx,%edx
|
||||||
jmp 60f
|
jmp 60f
|
||||||
40: lea (%rdx,%rcx,8),%rdx
|
40: leal (%rdx,%rcx,8),%edx
|
||||||
jmp 60f
|
jmp 60f
|
||||||
50: movl %ecx,%edx
|
50: movl %ecx,%edx
|
||||||
60: jmp copy_user_handle_tail /* ecx is zerorest also */
|
60: jmp copy_user_handle_tail /* ecx is zerorest also */
|
||||||
@ -236,8 +236,6 @@ ENDPROC(copy_user_generic_unrolled)
|
|||||||
ENTRY(copy_user_generic_string)
|
ENTRY(copy_user_generic_string)
|
||||||
CFI_STARTPROC
|
CFI_STARTPROC
|
||||||
ASM_STAC
|
ASM_STAC
|
||||||
andl %edx,%edx
|
|
||||||
jz 4f
|
|
||||||
cmpl $8,%edx
|
cmpl $8,%edx
|
||||||
jb 2f /* less than 8 bytes, go to byte copy loop */
|
jb 2f /* less than 8 bytes, go to byte copy loop */
|
||||||
ALIGN_DESTINATION
|
ALIGN_DESTINATION
|
||||||
@ -249,12 +247,12 @@ ENTRY(copy_user_generic_string)
|
|||||||
2: movl %edx,%ecx
|
2: movl %edx,%ecx
|
||||||
3: rep
|
3: rep
|
||||||
movsb
|
movsb
|
||||||
4: xorl %eax,%eax
|
xorl %eax,%eax
|
||||||
ASM_CLAC
|
ASM_CLAC
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.section .fixup,"ax"
|
.section .fixup,"ax"
|
||||||
11: lea (%rdx,%rcx,8),%rcx
|
11: leal (%rdx,%rcx,8),%ecx
|
||||||
12: movl %ecx,%edx /* ecx is zerorest also */
|
12: movl %ecx,%edx /* ecx is zerorest also */
|
||||||
jmp copy_user_handle_tail
|
jmp copy_user_handle_tail
|
||||||
.previous
|
.previous
|
||||||
@ -279,12 +277,10 @@ ENDPROC(copy_user_generic_string)
|
|||||||
ENTRY(copy_user_enhanced_fast_string)
|
ENTRY(copy_user_enhanced_fast_string)
|
||||||
CFI_STARTPROC
|
CFI_STARTPROC
|
||||||
ASM_STAC
|
ASM_STAC
|
||||||
andl %edx,%edx
|
|
||||||
jz 2f
|
|
||||||
movl %edx,%ecx
|
movl %edx,%ecx
|
||||||
1: rep
|
1: rep
|
||||||
movsb
|
movsb
|
||||||
2: xorl %eax,%eax
|
xorl %eax,%eax
|
||||||
ASM_CLAC
|
ASM_CLAC
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user