From: "Andi Kleen" Give out of line get_user better calling conventions Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton --- 25-akpm/arch/x86_64/lib/getuser.S | 65 ++++++++++++++++++++--------------- 25-akpm/include/asm-x86_64/uaccess.h | 13 +++---- 2 files changed, 44 insertions(+), 34 deletions(-) diff -puN arch/x86_64/lib/getuser.S~x86_64-give-out-of-line-get_user-better-calling arch/x86_64/lib/getuser.S --- 25/arch/x86_64/lib/getuser.S~x86_64-give-out-of-line-get_user-better-calling Wed Mar 23 15:38:41 2005 +++ 25-akpm/arch/x86_64/lib/getuser.S Wed Mar 23 15:38:41 2005 @@ -2,6 +2,7 @@ * __get_user functions. * * (C) Copyright 1998 Linus Torvalds + * (C) Copyright 2005 Andi Kleen * * These functions have a non-standard call interface * to make them more efficient, especially as they @@ -12,12 +13,14 @@ /* * __get_user_X * - * Inputs: %rax contains the address + * Inputs: %rcx contains the address. + * The register is modified, but all changes are undone + * before returning because the C code doesn't know about it. * * Outputs: %rax is error code (0 or -EFAULT) * %rdx contains zero-extended value * - * %rbx is destroyed. + * %r8 is destroyed. * * These functions should not modify any other registers, * as they get called from within inline assembly. @@ -33,52 +36,60 @@ .p2align 4 .globl __get_user_1 __get_user_1: - GET_THREAD_INFO(%rbx) - cmpq threadinfo_addr_limit(%rbx),%rax + GET_THREAD_INFO(%r8) + cmpq threadinfo_addr_limit(%r8),%rcx jae bad_get_user -1: movzb (%rax),%edx - xorq %rax,%rax +1: movzb (%rcx),%edx + xorl %eax,%eax ret .p2align 4 .globl __get_user_2 __get_user_2: - GET_THREAD_INFO(%rbx) - addq $1,%rax - jc bad_get_user - cmpq threadinfo_addr_limit(%rbx),%rax - jae bad_get_user -2: movzwl -1(%rax),%edx - xorq %rax,%rax + GET_THREAD_INFO(%r8) + addq $1,%rcx + jc 20f + cmpq threadinfo_addr_limit(%r8),%rcx + jae 20f + decq %rcx +2: movzwl (%rcx),%edx + xorl %eax,%eax ret +20: decq %rcx + jmp bad_get_user .p2align 4 .globl __get_user_4 __get_user_4: - GET_THREAD_INFO(%rbx) - addq $3,%rax - jc bad_get_user - cmpq threadinfo_addr_limit(%rbx),%rax - jae bad_get_user -3: movl -3(%rax),%edx - xorq %rax,%rax + GET_THREAD_INFO(%r8) + addq $3,%rcx + jc 30f + cmpq threadinfo_addr_limit(%r8),%rcx + jae 30f + subq $3,%rcx +3: movl (%rcx),%edx + xorl %eax,%eax ret +30: subq $3,%rcx + jmp bad_get_user .p2align 4 .globl __get_user_8 __get_user_8: - GET_THREAD_INFO(%rbx) - addq $7,%rax + GET_THREAD_INFO(%r8) + addq $7,%rcx jc bad_get_user - cmpq threadinfo_addr_limit(%rbx),%rax + cmpq threadinfo_addr_limit(%r8),%rcx jae bad_get_user -4: movq -7(%rax),%rdx - xorq %rax,%rax + subq $7,%rcx +4: movq (%rcx),%rdx + xorl %eax,%eax ret +40: subq $7,%rcx + jmp bad_get_user -ENTRY(bad_get_user) bad_get_user: - xorq %rdx,%rdx + xorl %edx,%edx movq $(-EFAULT),%rax ret diff -puN include/asm-x86_64/uaccess.h~x86_64-give-out-of-line-get_user-better-calling include/asm-x86_64/uaccess.h --- 25/include/asm-x86_64/uaccess.h~x86_64-give-out-of-line-get_user-better-calling Wed Mar 23 15:38:41 2005 +++ 25-akpm/include/asm-x86_64/uaccess.h Wed Mar 23 15:38:41 2005 @@ -91,16 +91,11 @@ struct exception_table_entry * accesses to the same area of user memory). */ -extern void __get_user_1(void); -extern void __get_user_2(void); -extern void __get_user_4(void); -extern void __get_user_8(void); - #define __get_user_x(size,ret,x,ptr) \ __asm__ __volatile__("call __get_user_" #size \ :"=a" (ret),"=d" (x) \ - :"0" (ptr) \ - :"rbx") + :"c" (ptr) \ + :"r8") /* Careful: we have to cast the result to the type of the pointer for sign reasons */ #define get_user(x,ptr) \ @@ -210,6 +205,10 @@ struct __large_struct { unsigned long bu __gu_err; \ }) +extern int __get_user_1(void); +extern int __get_user_2(void); +extern int __get_user_4(void); +extern int __get_user_8(void); extern int __get_user_bad(void); #define __get_user_size(x,ptr,size,retval) \ _