1 /* Copyright 2002 Andi Kleen, SuSE Labs.
2 * Subject to the GNU Public License v2.
4 * Functions to copy from and to user space.
7 #include <linux/config.h>
9 /* #define FIX_ALIGNMENT 1 */
11 #include <asm/current.h>
12 #include <asm/offset.h>
14 /* Standard copy_to_user with segment limit checking */
22 cmpq tsk_addr_limit(%rax),%rcx
26 /* Standard copy_from_user with segment limit checking */
34 cmpq tsk_addr_limit(%rax),%rcx
36 /* FALL THROUGH to copy_user_generic */
51 * copy_user_generic - memory copy with exception handling.
59 * eax uncopied bytes or 0 if successfull.
61 .globl copy_user_generic
69 xorl %eax,%eax /*zero for the exception handler */
72 /* check for bad alignment of destination */
76 .Lafter_bad_alignment:
88 .Ls1: movq (%rsi),%r11
89 .Ls2: movq 1*8(%rsi),%r8
90 .Ls3: movq 2*8(%rsi),%r9
91 .Ls4: movq 3*8(%rsi),%r10
92 .Ld1: movq %r11,(%rdi)
93 .Ld2: movq %r8,1*8(%rdi)
94 .Ld3: movq %r9,2*8(%rdi)
95 .Ld4: movq %r10,3*8(%rdi)
97 .Ls5: movq 4*8(%rsi),%r11
98 .Ls6: movq 5*8(%rsi),%r8
99 .Ls7: movq 6*8(%rsi),%r9
100 .Ls8: movq 7*8(%rsi),%r10
101 .Ld5: movq %r11,4*8(%rdi)
102 .Ld6: movq %r8,5*8(%rdi)
103 .Ld7: movq %r9,6*8(%rdi)
104 .Ld8: movq %r10,7*8(%rdi)
122 .Ls9: movq (%rsi),%r8
123 .Ld9: movq %r8,(%rdi)
135 .Ls10: movb (%rsi),%bl
136 .Ld10: movb %bl,(%rdi)
147 /* align destination */
157 .Ls11: movb (%rsi),%bl
158 .Ld11: movb %bl,(%rdi)
163 jmp .Lafter_bad_alignment
169 /* table sorted by exception address */
170 .section __ex_table,"a"
199 /* compute 64-offset for main loop. 8 bytes accuracy with error on the
200 pessimistic side. this is gross. it would be better to fix the
202 /* eax: zero, ebx: 64 */
211 addq %rbx,%rdi /* +64 */
212 subq %rax,%rdi /* correct destination with computed offset */
214 shlq $6,%rdx /* loop counter * 64 (stride length) */
215 addq %rax,%rdx /* add offset to loopcnt */
216 andl $63,%ecx /* remaining bytes */
217 addq %rcx,%rdx /* add them */
220 /* exception on quad word loop in tail handling */
221 /* ecx: loopcnt/8, %edx: length, rdi: correct */
226 /* edx: bytes to zero, rdi: dest, eax:zero */
233 /* when there is another exception while zeroing the rest just return */