[PATCH] x86_64: Clean up copy_*_user
[linux-2.6.git] / arch / x86_64 / lib / copy_user.S
1 /* Copyright 2002 Andi Kleen, SuSE Labs.
2  * Subject to the GNU Public License v2.
3  * 
4  * Functions to copy from and to user space.            
5  */              
6
7         #include <asm/current.h>
8         #include <asm/asm-offsets.h>
9         #include <asm/thread_info.h>
10
11 /* Standard copy_to_user with segment limit checking */         
12         .globl copy_to_user
13         .p2align 4      
14 copy_to_user:
15         GET_THREAD_INFO(%rax)
16         movq %rdi,%rcx
17         addq %rdx,%rcx
18         jc  bad_to_user
19         cmpq threadinfo_addr_limit(%rax),%rcx
20         jae bad_to_user
21         jmp copy_user_generic
22
23 /* Standard copy_from_user with segment limit checking */       
24         .globl copy_from_user
25         .p2align 4      
26 copy_from_user:
27         GET_THREAD_INFO(%rax)
28         movq %rsi,%rcx
29         addq %rdx,%rcx
30         jc  bad_from_user
31         cmpq threadinfo_addr_limit(%rax),%rcx
32         jae  bad_from_user
33         /* FALL THROUGH to copy_user_generic */
34         
35         .section .fixup,"ax"
36         /* must zero dest */
37 bad_from_user:
38         movl %edx,%ecx
39         xorl %eax,%eax
40         rep
41         stosb
42 bad_to_user:
43         movl    %edx,%eax
44         ret
45         .previous
46         
47                 
48 /*
49  * copy_user_generic - memory copy with exception handling.
50  *      
51  * Input:       
52  * rdi destination
53  * rsi source
54  * rdx count
55  *
56  * Only 4GB of copy is supported. This shouldn't be a problem
57  * because the kernel normally only writes from/to page sized chunks
58  * even if user space passed a longer buffer.
59  * And more would be dangerous because both Intel and AMD have
60  * errata with rep movsq > 4GB. If someone feels the need to fix
61  * this please consider this.
62  *
63  * Output:              
64  * eax uncopied bytes or 0 if successful.
65  */
66
67         .globl copy_user_generic
68 copy_user_generic:
69         movl %edx,%ecx
70         shrl $3,%ecx
71         andl $7,%edx    
72         jz   5f
73 1:      rep 
74         movsq 
75         movl %edx,%ecx
76         xor %eax,%eax
77 2:      rep
78         movsb
79         ret
80         /* align here? */
81 5:      xorl %eax,%eax
82 6:      rep movsq
83         ret
84
85         .section .fixup,"ax"
86 3:      lea (%rdx,%rcx,8),%rax
87         ret
88 4:      movl %ecx,%eax
89         ret
90         .previous
91
92         .section __ex_table,"a"
93         .quad 1b,3b
94         .quad 2b,4b
95         .quad 6b,4b
96         .previous