Skip to content

Commit 311c34a

Browse files
ebiggerskdave
authored andcommitted
btrfs-progs: crypto: x86/crc32c - access 32-bit arguments as 32-bit
(Linux kernel commit eebcadfa21e66a893846ec168fb7c26a46a510cd). Fix crc32c-pcl-intel-asm_64.S to access 32-bit arguments as 32-bit values instead of 64-bit, since the upper bits of the corresponding 64-bit registers are not guaranteed to be zero. Also update the type of the length argument to be unsigned int rather than int, as the assembly code treats it as unsigned. Note: there haven't been any reports of this bug actually causing incorrect behavior. Neither gcc nor clang guarantee zero-extension to 64 bits, but zero-extension is likely to happen in practice because most instructions that operate on 32-bit registers zero-extend to 64 bits. Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 55deb32 commit 311c34a

File tree

2 files changed

+27
-32
lines changed

2 files changed

+27
-32
lines changed

crypto/crc32c-pcl-intel-asm_64.S

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
# regular CRC code that does not interleave the CRC instructions.
6363
#define SMALL_SIZE 200
6464

65-
# unsigned int crc_pcl(u8 *buffer, int len, unsigned int crc_init);
65+
# unsigned int crc_pcl(const u8 *buffer, unsigned int len, unsigned int crc_init);
6666

6767
.text
6868
###SYM_FUNC_START(crc_pcl)
@@ -77,14 +77,11 @@ crc_pcl:
7777
#define block_0 %rcx
7878
#define block_1 %rdx
7979
#define block_2 %r11
80-
#define len %rsi
81-
#define len_dw %esi
82-
#define len_w %si
83-
#define len_b %sil
84-
#define crc_init_arg %rdx
80+
#define len %esi
81+
#define crc_init_arg %edx
8582
#define tmp %rbx
86-
#define crc_init %r8
87-
#define crc_init_dw %r8d
83+
#define crc_init %r8d
84+
#define crc_init_q %r8
8885
#define crc1 %r9
8986
#define crc2 %r10
9087

@@ -112,9 +109,9 @@ crc_pcl:
112109
movq (bufptmp), tmp # load a quadward from the buffer
113110
add %bufp, bufptmp # align buffer pointer for quadword
114111
# processing
115-
sub %bufp, len # update buffer length
112+
sub bufp_dw, len # update buffer length
116113
.Lalign_loop:
117-
crc32b %bl, crc_init_dw # compute crc32 of 1-byte
114+
crc32b %bl, crc_init # compute crc32 of 1-byte
118115
shr $8, tmp # get next byte
119116
dec %bufp
120117
jne .Lalign_loop
@@ -126,15 +123,14 @@ crc_pcl:
126123
################################################################
127124

128125
## compute num of bytes to be processed
129-
movq len, tmp # save num bytes in tmp
130126

131-
cmpq $128*24, len
127+
cmp $128*24, len
132128
jae .Lfull_block
133129

134130
.Lcontinue_block:
135131
## len < 128*24
136132
movq $2731, %rax # 2731 = ceil(2^16 / 24)
137-
mul len_dw
133+
mul len
138134
shrq $16, %rax
139135

140136
## eax contains floor(bytes / 24) = num 24-byte chunks to do
@@ -183,7 +179,7 @@ crc_pcl:
183179
LABEL crc_ %i
184180
.noaltmacro
185181
ENDBR
186-
crc32q -i*8(block_0), crc_init
182+
crc32q -i*8(block_0), crc_init_q
187183
crc32q -i*8(block_1), crc1
188184
crc32q -i*8(block_2), crc2
189185
i=(i-1)
@@ -193,7 +189,7 @@ LABEL crc_ %i
193189
LABEL crc_ %i
194190
.noaltmacro
195191
ENDBR
196-
crc32q -i*8(block_0), crc_init
192+
crc32q -i*8(block_0), crc_init_q
197193
crc32q -i*8(block_1), crc1
198194
# SKIP crc32 -i*8(block_2), crc2 ; Don't do this one yet
199195

@@ -207,9 +203,9 @@ LABEL crc_ %i
207203
shlq $3, %rax # rax *= 8
208204
pmovzxdq (%bufp,%rax), %xmm0 # 2 consts: K1:K2
209205
leal (%eax,%eax,2), %eax # rax *= 3 (total *24)
210-
subq %rax, tmp # tmp -= rax*24
206+
sub %eax, len # len -= rax*24
211207

212-
movq crc_init, %xmm1 # CRC for block 1
208+
movq crc_init_q, %xmm1 # CRC for block 1
213209
pclmulqdq $0x00, %xmm0, %xmm1 # Multiply by K2
214210

215211
movq crc1, %xmm2 # CRC for block 2
@@ -218,19 +214,18 @@ LABEL crc_ %i
218214
pxor %xmm2,%xmm1
219215
movq %xmm1, %rax
220216
xor -i*8(block_2), %rax
221-
mov crc2, crc_init
222-
crc32 %rax, crc_init
217+
mov crc2, crc_init_q
218+
crc32 %rax, crc_init_q
223219

224220
################################################################
225221
## 5) Check for end:
226222
################################################################
227223

228224
LABEL crc_ 0
229225
ENDBR
230-
mov tmp, len
231-
cmp $128*24, tmp
226+
cmp $128*24, len
232227
jae .Lfull_block
233-
cmp $SMALL_SIZE, tmp
228+
cmp $SMALL_SIZE, len
234229
jae .Lcontinue_block
235230

236231
#######################################################################
@@ -239,30 +234,30 @@ LABEL crc_ 0
239234
.Lsmall:
240235
test len, len
241236
jz .Ldone
242-
mov len_dw, %eax
237+
mov len, %eax
243238
shr $3, %eax
244239
jz .Ldo_dword
245240
.Ldo_qwords:
246-
crc32q (bufptmp), crc_init
241+
crc32q (bufptmp), crc_init_q
247242
add $8, bufptmp
248243
dec %eax
249244
jnz .Ldo_qwords
250245
.Ldo_dword:
251-
test $4, len_dw
246+
test $4, len
252247
jz .Ldo_word
253-
crc32l (bufptmp), crc_init_dw
248+
crc32l (bufptmp), crc_init
254249
add $4, bufptmp
255250
.Ldo_word:
256-
test $2, len_dw
251+
test $2, len
257252
jz .Ldo_byte
258-
crc32w (bufptmp), crc_init_dw
253+
crc32w (bufptmp), crc_init
259254
add $2, bufptmp
260255
.Ldo_byte:
261-
test $1, len_dw
256+
test $1, len
262257
jz .Ldone
263-
crc32b (bufptmp), crc_init_dw
258+
crc32b (bufptmp), crc_init
264259
.Ldone:
265-
movq crc_init, %rax
260+
mov crc_init, %eax
266261
popq %rsi
267262
popq %rdi
268263
popq %rbx

crypto/crc32c.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ static uint32_t (*crc32c_impl)(uint32_t crc, unsigned char const *data, uint32_t
2020

2121
#ifdef __GLIBC__
2222

23-
/* asmlinkage */ unsigned int crc_pcl(const unsigned char *buffer, int len, unsigned int crc_init);
23+
/* asmlinkage */ unsigned int crc_pcl(const unsigned char *buffer, unsigned int len, unsigned int crc_init);
2424
static unsigned int crc32c_pcl(uint32_t crc, unsigned char const *data, uint32_t len) {
2525
return crc_pcl(data, len, crc);
2626
}

0 commit comments

Comments
 (0)