blob: a4a379e79259d1dfb0230372c792b144b4441b0b [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Ingo Molnar2c763972011-03-18 10:42:11 +01002 * Copyright 2002, 2003 Andi Kleen, SuSE Labs.
3 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file COPYING in the main directory of this archive
6 * for more details. No warranty for anything given at all.
7 */
Jan Beulich8d379da2006-09-26 10:52:32 +02008#include <linux/linkage.h>
Jan Beulich8d379da2006-09-26 10:52:32 +02009#include <asm/errno.h>
H. Peter Anvin015e6f12012-04-20 12:19:51 -070010#include <asm/asm.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011
12/*
13 * Checksum copy with exception handling.
Ingo Molnar2c763972011-03-18 10:42:11 +010014 * On exceptions src_err_ptr or dst_err_ptr is set to -EFAULT and the
Linus Torvalds1da177e2005-04-16 15:20:36 -070015 * destination is zeroed.
Ingo Molnar2c763972011-03-18 10:42:11 +010016 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070017 * Input
18 * rdi source
19 * rsi destination
20 * edx len (32bit)
Ingo Molnar2c763972011-03-18 10:42:11 +010021 * ecx sum (32bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 * r8 src_err_ptr (int)
23 * r9 dst_err_ptr (int)
24 *
25 * Output
26 * eax 64bit sum. undefined in case of exception.
Ingo Molnar2c763972011-03-18 10:42:11 +010027 *
28 * Wrappers need to take care of valid exception sum and zeroing.
Linus Torvalds1da177e2005-04-16 15:20:36 -070029 * They also should align source or destination to 8 bytes.
30 */
31
32 .macro source
3310:
Jann Horn75045f72018-08-28 22:14:18 +020034 _ASM_EXTABLE_UA(10b, .Lbad_source)
Linus Torvalds1da177e2005-04-16 15:20:36 -070035 .endm
Ingo Molnar2c763972011-03-18 10:42:11 +010036
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 .macro dest
3820:
Jann Horn75045f72018-08-28 22:14:18 +020039 _ASM_EXTABLE_UA(20b, .Lbad_dest)
Linus Torvalds1da177e2005-04-16 15:20:36 -070040 .endm
Ingo Molnar2c763972011-03-18 10:42:11 +010041
Jann Horn75045f72018-08-28 22:14:18 +020042 /*
43 * No _ASM_EXTABLE_UA; this is used for intentional prefetch on a
44 * potentially unmapped kernel address.
45 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070046 .macro ignore L=.Lignore
4730:
H. Peter Anvin015e6f12012-04-20 12:19:51 -070048 _ASM_EXTABLE(30b, \L)
Linus Torvalds1da177e2005-04-16 15:20:36 -070049 .endm
Ingo Molnar2c763972011-03-18 10:42:11 +010050
51
Jan Beulich8d379da2006-09-26 10:52:32 +020052ENTRY(csum_partial_copy_generic)
Ingo Molnar2c763972011-03-18 10:42:11 +010053 cmpl $3*64, %edx
54 jle .Lignore
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Ingo Molnar2c763972011-03-18 10:42:11 +010056.Lignore:
57 subq $7*8, %rsp
Ingo Molnar2c763972011-03-18 10:42:11 +010058 movq %rbx, 2*8(%rsp)
Ingo Molnar2c763972011-03-18 10:42:11 +010059 movq %r12, 3*8(%rsp)
Ingo Molnar2c763972011-03-18 10:42:11 +010060 movq %r14, 4*8(%rsp)
Ingo Molnar2c763972011-03-18 10:42:11 +010061 movq %r13, 5*8(%rsp)
Josh Poimboeuf42fc6c62017-05-04 09:51:40 -050062 movq %r15, 6*8(%rsp)
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
Ingo Molnar2c763972011-03-18 10:42:11 +010064 movq %r8, (%rsp)
65 movq %r9, 1*8(%rsp)
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
Ingo Molnar2c763972011-03-18 10:42:11 +010067 movl %ecx, %eax
68 movl %edx, %ecx
Linus Torvalds1da177e2005-04-16 15:20:36 -070069
Ingo Molnar2c763972011-03-18 10:42:11 +010070 xorl %r9d, %r9d
71 movq %rcx, %r12
72
73 shrq $6, %r12
74 jz .Lhandle_tail /* < 64 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070075
76 clc
Ingo Molnar2c763972011-03-18 10:42:11 +010077
Linus Torvalds1da177e2005-04-16 15:20:36 -070078 /* main loop. clear in 64 byte blocks */
79 /* r9: zero, r8: temp2, rbx: temp1, rax: sum, rcx: saved length */
80 /* r11: temp3, rdx: temp4, r12 loopcnt */
Josh Poimboeuf42fc6c62017-05-04 09:51:40 -050081 /* r10: temp5, r15: temp6, r14 temp7, r13 temp8 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070082 .p2align 4
83.Lloop:
84 source
Ingo Molnar2c763972011-03-18 10:42:11 +010085 movq (%rdi), %rbx
Linus Torvalds1da177e2005-04-16 15:20:36 -070086 source
Ingo Molnar2c763972011-03-18 10:42:11 +010087 movq 8(%rdi), %r8
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 source
Ingo Molnar2c763972011-03-18 10:42:11 +010089 movq 16(%rdi), %r11
Linus Torvalds1da177e2005-04-16 15:20:36 -070090 source
Ingo Molnar2c763972011-03-18 10:42:11 +010091 movq 24(%rdi), %rdx
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
93 source
Ingo Molnar2c763972011-03-18 10:42:11 +010094 movq 32(%rdi), %r10
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 source
Josh Poimboeuf42fc6c62017-05-04 09:51:40 -050096 movq 40(%rdi), %r15
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 source
Ingo Molnar2c763972011-03-18 10:42:11 +010098 movq 48(%rdi), %r14
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 source
Ingo Molnar2c763972011-03-18 10:42:11 +0100100 movq 56(%rdi), %r13
101
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 ignore 2f
103 prefetcht0 5*64(%rdi)
Ingo Molnar2c763972011-03-18 10:42:11 +01001042:
105 adcq %rbx, %rax
106 adcq %r8, %rax
107 adcq %r11, %rax
108 adcq %rdx, %rax
109 adcq %r10, %rax
Josh Poimboeuf42fc6c62017-05-04 09:51:40 -0500110 adcq %r15, %rax
Ingo Molnar2c763972011-03-18 10:42:11 +0100111 adcq %r14, %rax
112 adcq %r13, %rax
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113
114 decl %r12d
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
116 dest
Ingo Molnar2c763972011-03-18 10:42:11 +0100117 movq %rbx, (%rsi)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 dest
Ingo Molnar2c763972011-03-18 10:42:11 +0100119 movq %r8, 8(%rsi)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 dest
Ingo Molnar2c763972011-03-18 10:42:11 +0100121 movq %r11, 16(%rsi)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 dest
Ingo Molnar2c763972011-03-18 10:42:11 +0100123 movq %rdx, 24(%rsi)
124
125 dest
126 movq %r10, 32(%rsi)
127 dest
Josh Poimboeuf42fc6c62017-05-04 09:51:40 -0500128 movq %r15, 40(%rsi)
Ingo Molnar2c763972011-03-18 10:42:11 +0100129 dest
130 movq %r14, 48(%rsi)
131 dest
132 movq %r13, 56(%rsi)
133
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
Ingo Molnar2c763972011-03-18 10:42:11 +0100136 leaq 64(%rdi), %rdi
137 leaq 64(%rsi), %rsi
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138
Ingo Molnar2c763972011-03-18 10:42:11 +0100139 jnz .Lloop
140
141 adcq %r9, %rax
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142
Lucas De Marchi0d2eb442011-03-17 16:24:16 -0300143 /* do last up to 56 bytes */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144.Lhandle_tail:
145 /* ecx: count */
Ingo Molnar2c763972011-03-18 10:42:11 +0100146 movl %ecx, %r10d
147 andl $63, %ecx
148 shrl $3, %ecx
149 jz .Lfold
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150 clc
151 .p2align 4
Ingo Molnar2c763972011-03-18 10:42:11 +0100152.Lloop_8:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153 source
Ingo Molnar2c763972011-03-18 10:42:11 +0100154 movq (%rdi), %rbx
155 adcq %rbx, %rax
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 decl %ecx
157 dest
Ingo Molnar2c763972011-03-18 10:42:11 +0100158 movq %rbx, (%rsi)
159 leaq 8(%rsi), %rsi /* preserve carry */
160 leaq 8(%rdi), %rdi
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 jnz .Lloop_8
Ingo Molnar2c763972011-03-18 10:42:11 +0100162 adcq %r9, %rax /* add in carry */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163
164.Lfold:
165 /* reduce checksum to 32bits */
Ingo Molnar2c763972011-03-18 10:42:11 +0100166 movl %eax, %ebx
167 shrq $32, %rax
168 addl %ebx, %eax
169 adcl %r9d, %eax
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170
Ingo Molnar2c763972011-03-18 10:42:11 +0100171 /* do last up to 6 bytes */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172.Lhandle_7:
Ingo Molnar2c763972011-03-18 10:42:11 +0100173 movl %r10d, %ecx
174 andl $7, %ecx
175 shrl $1, %ecx
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176 jz .Lhandle_1
Ingo Molnar2c763972011-03-18 10:42:11 +0100177 movl $2, %edx
178 xorl %ebx, %ebx
179 clc
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180 .p2align 4
Ingo Molnar2c763972011-03-18 10:42:11 +0100181.Lloop_1:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 source
Ingo Molnar2c763972011-03-18 10:42:11 +0100183 movw (%rdi), %bx
184 adcl %ebx, %eax
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 decl %ecx
Dave Peterson92ed0222005-07-29 22:59:20 -0700186 dest
Ingo Molnar2c763972011-03-18 10:42:11 +0100187 movw %bx, (%rsi)
188 leaq 2(%rdi), %rdi
189 leaq 2(%rsi), %rsi
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 jnz .Lloop_1
Ingo Molnar2c763972011-03-18 10:42:11 +0100191 adcl %r9d, %eax /* add in carry */
192
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193 /* handle last odd byte */
194.Lhandle_1:
Denys Vlasenko3e1aa7c2015-03-06 21:55:32 +0100195 testb $1, %r10b
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196 jz .Lende
Ingo Molnar2c763972011-03-18 10:42:11 +0100197 xorl %ebx, %ebx
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198 source
Ingo Molnar2c763972011-03-18 10:42:11 +0100199 movb (%rdi), %bl
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200 dest
Ingo Molnar2c763972011-03-18 10:42:11 +0100201 movb %bl, (%rsi)
202 addl %ebx, %eax
203 adcl %r9d, %eax /* carry */
204
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205.Lende:
Ingo Molnar2c763972011-03-18 10:42:11 +0100206 movq 2*8(%rsp), %rbx
Ingo Molnar2c763972011-03-18 10:42:11 +0100207 movq 3*8(%rsp), %r12
Ingo Molnar2c763972011-03-18 10:42:11 +0100208 movq 4*8(%rsp), %r14
Ingo Molnar2c763972011-03-18 10:42:11 +0100209 movq 5*8(%rsp), %r13
Josh Poimboeuf42fc6c62017-05-04 09:51:40 -0500210 movq 6*8(%rsp), %r15
Ingo Molnar2c763972011-03-18 10:42:11 +0100211 addq $7*8, %rsp
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212 ret
213
214 /* Exception handlers. Very simple, zeroing is done in the wrappers */
215.Lbad_source:
Ingo Molnar2c763972011-03-18 10:42:11 +0100216 movq (%rsp), %rax
217 testq %rax, %rax
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 jz .Lende
Ingo Molnar2c763972011-03-18 10:42:11 +0100219 movl $-EFAULT, (%rax)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 jmp .Lende
Ingo Molnar2c763972011-03-18 10:42:11 +0100221
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222.Lbad_dest:
Ingo Molnar2c763972011-03-18 10:42:11 +0100223 movq 8(%rsp), %rax
224 testq %rax, %rax
225 jz .Lende
226 movl $-EFAULT, (%rax)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227 jmp .Lende
Jan Beulich8d379da2006-09-26 10:52:32 +0200228ENDPROC(csum_partial_copy_generic)