X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fx86_64%2Flib%2Fgetuser.S;h=3844d5e885a4deafcc035334e7d86b48351daf52;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=61a1f75aba87801fc499a649fe9f7dc729a4d2fa;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/x86_64/lib/getuser.S b/arch/x86_64/lib/getuser.S index 61a1f75ab..3844d5e88 100644 --- a/arch/x86_64/lib/getuser.S +++ b/arch/x86_64/lib/getuser.S @@ -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. @@ -26,59 +29,67 @@ #include #include #include -#include +#include #include .text .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 - jc bad_get_user - cmpq threadinfo_addr_limit(%rbx),%rax - jae bad_get_user -4: movq -7(%rax),%rdx - xorq %rax,%rax + GET_THREAD_INFO(%r8) + addq $7,%rcx + jc 40f + cmpq threadinfo_addr_limit(%r8),%rcx + jae 40f + 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