]> git.proxmox.com Git - ceph.git/blame - ceph/src/spdk/test/unit/lib/util/dif.c/dif_ut.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / test / unit / lib / util / dif.c / dif_ut.c
CommitLineData
9f95a23c
TL
1/*-
2 * BSD LICENSE
3 *
4 * Copyright (c) Intel Corporation.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include "spdk/stdinc.h"
35
36#include "spdk_cunit.h"
37
38#include "util/dif.c"
39
40#define DATA_PATTERN(offset) ((uint8_t)(0xAB + (offset)))
41#define GUARD_SEED 0xCD
42
43static int
44ut_data_pattern_generate(struct iovec *iovs, int iovcnt,
45 uint32_t block_size, uint32_t md_size, uint32_t num_blocks)
46{
47 struct _dif_sgl sgl;
48 uint32_t offset_blocks, offset_in_block, buf_len, data_offset, i;
49 uint8_t *buf;
50
51 _dif_sgl_init(&sgl, iovs, iovcnt);
52
53 if (!_dif_sgl_is_valid(&sgl, block_size * num_blocks)) {
54 return -1;
55 }
56
57 offset_blocks = 0;
58 data_offset = 0;
59
60 while (offset_blocks < num_blocks) {
61 offset_in_block = 0;
62 while (offset_in_block < block_size) {
63 _dif_sgl_get_buf(&sgl, (void *)&buf, &buf_len);
64 if (offset_in_block < block_size - md_size) {
65 buf_len = spdk_min(buf_len,
66 block_size - md_size - offset_in_block);
67 for (i = 0; i < buf_len; i++) {
68 buf[i] = DATA_PATTERN(data_offset + i);
69 }
70 data_offset += buf_len;
71 } else {
72 buf_len = spdk_min(buf_len, block_size - offset_in_block);
73 memset(buf, 0, buf_len);
74 }
75 _dif_sgl_advance(&sgl, buf_len);
76 offset_in_block += buf_len;
77 }
78 offset_blocks++;
79 }
80
81 return 0;
82}
83
84static int
85ut_data_pattern_verify(struct iovec *iovs, int iovcnt,
86 uint32_t block_size, uint32_t md_size, uint32_t num_blocks)
87{
88 struct _dif_sgl sgl;
89 uint32_t offset_blocks, offset_in_block, buf_len, data_offset, i;
90 uint8_t *buf;
91
92 _dif_sgl_init(&sgl, iovs, iovcnt);
93
94 if (!_dif_sgl_is_valid(&sgl, block_size * num_blocks)) {
95 return -1;
96 }
97
98 offset_blocks = 0;
99 data_offset = 0;
100
101 while (offset_blocks < num_blocks) {
102 offset_in_block = 0;
103 while (offset_in_block < block_size) {
104 _dif_sgl_get_buf(&sgl, (void *)&buf, &buf_len);
105
106 if (offset_in_block < block_size - md_size) {
107 buf_len = spdk_min(buf_len,
108 block_size - md_size - offset_in_block);
109 for (i = 0; i < buf_len; i++) {
110 if (buf[i] != DATA_PATTERN(data_offset + i)) {
111 return -1;
112 }
113 }
114 data_offset += buf_len;
115 } else {
116 buf_len = spdk_min(buf_len, block_size - offset_in_block);
117 }
118 _dif_sgl_advance(&sgl, buf_len);
119 offset_in_block += buf_len;
120 }
121 offset_blocks++;
122 }
123
124 return 0;
125}
126
127static void
128_iov_alloc_buf(struct iovec *iov, uint32_t len)
129{
130 iov->iov_base = calloc(1, len);
131 iov->iov_len = len;
132 SPDK_CU_ASSERT_FATAL(iov->iov_base != NULL);
133}
134
135static void
136_iov_free_buf(struct iovec *iov)
137{
138 free(iov->iov_base);
139}
140
141static void
142_iov_set_buf(struct iovec *iov, uint8_t *buf, uint32_t buf_len)
143{
144 iov->iov_base = buf;
145 iov->iov_len = buf_len;
146}
147
148static bool
149_iov_check(struct iovec *iov, void *iov_base, uint32_t iov_len)
150{
151 return (iov->iov_base == iov_base && iov->iov_len == iov_len);
152}
153
154static void
155_dif_generate_and_verify(struct iovec *iov,
156 uint32_t block_size, uint32_t md_size, bool dif_loc,
157 enum spdk_dif_type dif_type, uint32_t dif_flags,
158 uint32_t ref_tag, uint32_t e_ref_tag,
159 uint16_t app_tag, uint16_t apptag_mask, uint16_t e_app_tag,
160 bool expect_pass)
161{
162 struct spdk_dif_ctx ctx = {};
163 uint32_t guard_interval;
164 uint16_t guard = 0;
165 int rc;
166
167 rc = ut_data_pattern_generate(iov, 1, block_size, md_size, 1);
168 CU_ASSERT(rc == 0);
169
170 guard_interval = _get_guard_interval(block_size, md_size, dif_loc, true);
171
172 ctx.dif_type = dif_type;
173 ctx.dif_flags = dif_flags;
174 ctx.init_ref_tag = ref_tag;
175 ctx.app_tag = app_tag;
176
177 if (dif_flags & SPDK_DIF_FLAGS_GUARD_CHECK) {
178 guard = spdk_crc16_t10dif(0, iov->iov_base, guard_interval);
179 }
180
181 _dif_generate(iov->iov_base + guard_interval, guard, 0, &ctx);
182
183 ctx.init_ref_tag = e_ref_tag;
184 ctx.apptag_mask = apptag_mask;
185 ctx.app_tag = e_app_tag;
186
187 rc = _dif_verify(iov->iov_base + guard_interval, guard, 0, &ctx, NULL);
188 CU_ASSERT((expect_pass && rc == 0) || (!expect_pass && rc != 0));
189
190 rc = ut_data_pattern_verify(iov, 1, block_size, md_size, 1);
191 CU_ASSERT(rc == 0);
192}
193
194static void
195dif_generate_and_verify_test(void)
196{
197 struct iovec iov;
198 uint32_t dif_flags;
199
200 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
201 SPDK_DIF_FLAGS_REFTAG_CHECK;
202
203 _iov_alloc_buf(&iov, 4096 + 128);
204
205 /* Positive cases */
206
207 /* The case that DIF is contained in the first 8 bytes of metadata. */
208 _dif_generate_and_verify(&iov,
209 4096 + 128, 128, true,
210 SPDK_DIF_TYPE1, dif_flags,
211 22, 22,
212 0x22, 0xFFFF, 0x22,
213 true);
214
215 /* The case that DIF is contained in the last 8 bytes of metadata. */
216 _dif_generate_and_verify(&iov,
217 4096 + 128, 128, false,
218 SPDK_DIF_TYPE1, dif_flags,
219 22, 22,
220 0x22, 0xFFFF, 0x22,
221 true);
222
223 /* Negative cases */
224
225 /* Reference tag doesn't match. */
226 _dif_generate_and_verify(&iov,
227 4096 + 128, 128, false,
228 SPDK_DIF_TYPE1, dif_flags,
229 22, 23,
230 0x22, 0xFFFF, 0x22,
231 false);
232
233 /* Application tag doesn't match. */
234 _dif_generate_and_verify(&iov,
235 4096 + 128, 128, false,
236 SPDK_DIF_TYPE1, dif_flags,
237 22, 22,
238 0x22, 0xFFFF, 0x23,
239 false);
240
241 _iov_free_buf(&iov);
242}
243
244static void
245dif_disable_check_test(void)
246{
247 struct iovec iov;
248 uint32_t dif_flags;
249
250 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
251 SPDK_DIF_FLAGS_REFTAG_CHECK;
252
253 _iov_alloc_buf(&iov, 4096 + 128);
254
255 /* The case that DIF check is disabled when the Application Tag is 0xFFFF for
256 * Type 1. DIF check is disabled and pass is expected.
257 */
258 _dif_generate_and_verify(&iov,
259 4096 + 128, 128, false,
260 SPDK_DIF_TYPE1, dif_flags,
261 22, 22,
262 0xFFFF, 0xFFFF, 0x22,
263 true);
264
265 /* The case that DIF check is not disabled when the Application Tag is 0xFFFF but
266 * the Reference Tag is not 0xFFFFFFFF for Type 3. DIF check is not disabled and
267 * fail is expected.
268 */
269 _dif_generate_and_verify(&iov,
270 4096 + 128, 128, false,
271 SPDK_DIF_TYPE3, dif_flags,
272 22, 22,
273 0xFFFF, 0xFFFF, 0x22,
274 false);
275
276 /* The case that DIF check is disabled when the Application Tag is 0xFFFF and
277 * the Reference Tag is 0xFFFFFFFF for Type 3. DIF check is disabled and
278 * pass is expected.
279 */
280 _dif_generate_and_verify(&iov,
281 4096 + 128, 128, false,
282 SPDK_DIF_TYPE3, dif_flags,
283 0xFFFFFFFF, 22,
284 0xFFFF, 0xFFFF, 0x22,
285 true);
286
287 _iov_free_buf(&iov);
288}
289
290static void
291dif_sec_512_md_0_error_test(void)
292{
293 struct spdk_dif_ctx ctx = {};
294 int rc;
295
296 /* Metadata size is 0. */
297 rc = spdk_dif_ctx_init(&ctx, 512, 0, true, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 0, 0);
298 CU_ASSERT(rc != 0);
299}
300
301static void
302dif_guard_seed_test(void)
303{
304 struct iovec iov;
305 struct spdk_dif_ctx ctx = {};
306 struct spdk_dif_error err_blk = {};
307 struct spdk_dif *dif;
308 uint16_t guard;
309 int rc;
310
311 _iov_alloc_buf(&iov, 512 + 8);
312
313 memset(iov.iov_base, 0, 512 + 8);
314
315 dif = (struct spdk_dif *)(iov.iov_base + 512);
316
317 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1,
318 SPDK_DIF_FLAGS_GUARD_CHECK, 0, 0, 0, 0, 0);
319 CU_ASSERT(rc == 0);
320
321 rc = spdk_dif_generate(&iov, 1, 1, &ctx);
322 CU_ASSERT(rc == 0);
323
324 /* Guard should be zero if the block is all zero and seed is not added. */
325 guard = from_be16(&dif->guard);
326 CU_ASSERT(guard == 0);
327
328 rc = spdk_dif_verify(&iov, 1, 1, &ctx, &err_blk);
329 CU_ASSERT(rc == 0);
330
331 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1,
332 SPDK_DIF_FLAGS_GUARD_CHECK, 0, 0, 0, 0, GUARD_SEED);
333 CU_ASSERT(rc == 0);
334
335 rc = spdk_dif_generate(&iov, 1, 1, &ctx);
336 CU_ASSERT(rc == 0);
337
338 /* Guard should not be zero if the block is all zero but seed is added. */
339 guard = from_be16(&dif->guard);
340 CU_ASSERT(guard != 0);
341
342 rc = spdk_dif_verify(&iov, 1, 1, &ctx, &err_blk);
343 CU_ASSERT(rc == 0);
344
345 _iov_free_buf(&iov);
346}
347
348static void
349dif_generate_and_verify(struct iovec *iovs, int iovcnt,
350 uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
351 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
352 uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag)
353{
354 struct spdk_dif_ctx ctx = {};
355 int rc;
356
357 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks);
358 CU_ASSERT(rc == 0);
359
360 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags,
361 init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED);
362 CU_ASSERT(rc == 0);
363
364 rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx);
365 CU_ASSERT(rc == 0);
366
367 rc = spdk_dif_verify(iovs, iovcnt, num_blocks, &ctx, NULL);
368 CU_ASSERT(rc == 0);
369
370 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, md_size, num_blocks);
371 CU_ASSERT(rc == 0);
372}
373
374static void
375dif_disable_sec_512_md_8_single_iov_test(void)
376{
377 struct iovec iov;
378
379 _iov_alloc_buf(&iov, 512 + 8);
380
381 dif_generate_and_verify(&iov, 1, 512 + 8, 8, 1, false, SPDK_DIF_DISABLE, 0, 0, 0, 0);
382
383 _iov_free_buf(&iov);
384}
385
386static void
387dif_sec_512_md_8_prchk_0_single_iov_test(void)
388{
389 struct iovec iov;
390
391 _iov_alloc_buf(&iov, 512 + 8);
392
393 dif_generate_and_verify(&iov, 1, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1, 0, 0, 0, 0);
394
395 _iov_free_buf(&iov);
396}
397
398static void
399dif_sec_512_md_8_prchk_0_1_2_4_multi_iovs_test(void)
400{
401 struct iovec iovs[4];
402 int i, num_blocks;
403
404 num_blocks = 0;
405
406 for (i = 0; i < 4; i++) {
407 _iov_alloc_buf(&iovs[i], (512 + 8) * (i + 1));
408 num_blocks += i + 1;
409 }
410
411 dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1,
412 0, 22, 0xFFFF, 0x22);
413
414 dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1,
415 SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22);
416
417 dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1,
418 SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22);
419
420 dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1,
421 SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22);
422
423 for (i = 0; i < 4; i++) {
424 _iov_free_buf(&iovs[i]);
425 }
426}
427
428static void
429dif_sec_4096_md_128_prchk_7_multi_iovs_test(void)
430{
431 struct iovec iovs[4];
432 int i, num_blocks;
433 uint32_t dif_flags;
434
435 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
436 SPDK_DIF_FLAGS_REFTAG_CHECK;
437
438 num_blocks = 0;
439
440 for (i = 0; i < 4; i++) {
441 _iov_alloc_buf(&iovs[i], (4096 + 128) * (i + 1));
442 num_blocks += i + 1;
443 }
444
445 dif_generate_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, false, SPDK_DIF_TYPE1,
446 dif_flags, 22, 0xFFFF, 0x22);
447
448 dif_generate_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, true, SPDK_DIF_TYPE1,
449 dif_flags, 22, 0xFFFF, 0x22);
450
451 for (i = 0; i < 4; i++) {
452 _iov_free_buf(&iovs[i]);
453 }
454}
455
456static void
457dif_sec_512_md_8_prchk_7_multi_iovs_split_data_and_md_test(void)
458{
459 struct iovec iovs[2];
460 uint32_t dif_flags;
461
462 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
463 SPDK_DIF_FLAGS_REFTAG_CHECK;
464
465 _iov_alloc_buf(&iovs[0], 512);
466 _iov_alloc_buf(&iovs[1], 8);
467
468 dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1,
469 dif_flags, 22, 0xFFFF, 0x22);
470
471 _iov_free_buf(&iovs[0]);
472 _iov_free_buf(&iovs[1]);
473}
474
475static void
476dif_sec_512_md_8_prchk_7_multi_iovs_split_data_test(void)
477{
478 struct iovec iovs[2];
479 uint32_t dif_flags;
480
481 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
482 SPDK_DIF_FLAGS_REFTAG_CHECK;
483
484 _iov_alloc_buf(&iovs[0], 256);
485 _iov_alloc_buf(&iovs[1], 264);
486
487 dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1,
488 dif_flags, 22, 0xFFFF, 0x22);
489
490 _iov_free_buf(&iovs[0]);
491 _iov_free_buf(&iovs[1]);
492}
493
494static void
495dif_sec_512_md_8_prchk_7_multi_iovs_split_guard_test(void)
496{
497 struct iovec iovs[2];
498 uint32_t dif_flags;
499
500 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
501 SPDK_DIF_FLAGS_REFTAG_CHECK;
502
503 _iov_alloc_buf(&iovs[0], 513);
504 _iov_alloc_buf(&iovs[1], 7);
505
506 dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1,
507 dif_flags, 22, 0xFFFF, 0x22);
508
509 _iov_free_buf(&iovs[0]);
510 _iov_free_buf(&iovs[1]);
511}
512
513static void
514dif_sec_512_md_8_prchk_7_multi_iovs_split_apptag_test(void)
515{
516 struct iovec iovs[2];
517 uint32_t dif_flags;
518
519 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
520 SPDK_DIF_FLAGS_REFTAG_CHECK;
521
522 _iov_alloc_buf(&iovs[0], 515);
523 _iov_alloc_buf(&iovs[1], 5);
524
525 dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1,
526 dif_flags, 22, 0xFFFF, 0x22);
527
528 _iov_free_buf(&iovs[0]);
529 _iov_free_buf(&iovs[1]);
530}
531
532static void
533dif_sec_512_md_8_prchk_7_multi_iovs_split_reftag_test(void)
534{
535 struct iovec iovs[2];
536 uint32_t dif_flags;
537
538 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
539 SPDK_DIF_FLAGS_REFTAG_CHECK;
540
541 _iov_alloc_buf(&iovs[0], 518);
542 _iov_alloc_buf(&iovs[1], 2);
543
544 dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1,
545 dif_flags, 22, 0xFFFF, 0x22);
546
547 _iov_free_buf(&iovs[0]);
548 _iov_free_buf(&iovs[1]);
549}
550
551static void
552dif_sec_512_md_8_prchk_7_multi_iovs_complex_splits_test(void)
553{
554 struct iovec iovs[9];
555 uint32_t dif_flags;
556 int i;
557
558 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
559 SPDK_DIF_FLAGS_REFTAG_CHECK;
560
561 /* data[0][255:0] */
562 _iov_alloc_buf(&iovs[0], 256);
563
564 /* data[0][511:256], guard[0][0] */
565 _iov_alloc_buf(&iovs[1], 256 + 1);
566
567 /* guard[0][1], apptag[0][0] */
568 _iov_alloc_buf(&iovs[2], 1 + 1);
569
570 /* apptag[0][1], reftag[0][0] */
571 _iov_alloc_buf(&iovs[3], 1 + 1);
572
573 /* reftag[0][3:1], data[1][255:0] */
574 _iov_alloc_buf(&iovs[4], 3 + 256);
575
576 /* data[1][511:256], guard[1][0] */
577 _iov_alloc_buf(&iovs[5], 256 + 1);
578
579 /* guard[1][1], apptag[1][0] */
580 _iov_alloc_buf(&iovs[6], 1 + 1);
581
582 /* apptag[1][1], reftag[1][0] */
583 _iov_alloc_buf(&iovs[7], 1 + 1);
584
585 /* reftag[1][3:1] */
586 _iov_alloc_buf(&iovs[8], 3);
587
588 dif_generate_and_verify(iovs, 9, 512 + 8, 8, 2, false, SPDK_DIF_TYPE1, dif_flags,
589 22, 0xFFFF, 0x22);
590
591 for (i = 0; i < 9; i++) {
592 _iov_free_buf(&iovs[i]);
593 }
594}
595
596static void
597dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test(void)
598{
599 struct iovec iovs[11];
600 uint32_t dif_flags;
601 int i;
602
603 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
604 SPDK_DIF_FLAGS_REFTAG_CHECK;
605
606 /* data[0][1000:0] */
607 _iov_alloc_buf(&iovs[0], 1000);
608
609 /* data[0][3095:1000], guard[0][0] */
610 _iov_alloc_buf(&iovs[1], 3096 + 1);
611
612 /* guard[0][1], apptag[0][0] */
613 _iov_alloc_buf(&iovs[2], 1 + 1);
614
615 /* apptag[0][1], reftag[0][0] */
616 _iov_alloc_buf(&iovs[3], 1 + 1);
617
618 /* reftag[0][3:1], ignore[0][59:0] */
619 _iov_alloc_buf(&iovs[4], 3 + 60);
620
621 /* ignore[119:60], data[1][3050:0] */
622 _iov_alloc_buf(&iovs[5], 60 + 3051);
623
624 /* data[1][4095:3050], guard[1][0] */
625 _iov_alloc_buf(&iovs[6], 1045 + 1);
626
627 /* guard[1][1], apptag[1][0] */
628 _iov_alloc_buf(&iovs[7], 1 + 1);
629
630 /* apptag[1][1], reftag[1][0] */
631 _iov_alloc_buf(&iovs[8], 1 + 1);
632
633 /* reftag[1][3:1], ignore[1][9:0] */
634 _iov_alloc_buf(&iovs[9], 3 + 10);
635
636 /* ignore[1][127:9] */
637 _iov_alloc_buf(&iovs[10], 118);
638
639 dif_generate_and_verify(iovs, 11, 4096 + 128, 128, 2, false, SPDK_DIF_TYPE1, dif_flags,
640 22, 0xFFFF, 0x22);
641 dif_generate_and_verify(iovs, 11, 4096 + 128, 128, 2, true, SPDK_DIF_TYPE1, dif_flags,
642 22, 0xFFFF, 0x22);
643
644 for (i = 0; i < 11; i++) {
645 _iov_free_buf(&iovs[i]);
646 }
647}
648
649static void
650_dif_inject_error_and_verify(struct iovec *iovs, int iovcnt,
651 uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
652 uint32_t inject_flags, bool dif_loc)
653{
654 struct spdk_dif_ctx ctx = {};
655 struct spdk_dif_error err_blk = {};
656 uint32_t inject_offset = 0, dif_flags;
657 int rc;
658
659 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
660 SPDK_DIF_FLAGS_REFTAG_CHECK;
661
662 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks);
663 CU_ASSERT(rc == 0);
664
665 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc,
666 SPDK_DIF_TYPE1, dif_flags, 88, 0xFFFF, 0x88, 0, GUARD_SEED);
667 CU_ASSERT(rc == 0);
668
669 rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx);
670 CU_ASSERT(rc == 0);
671
672 rc = spdk_dif_inject_error(iovs, iovcnt, num_blocks, &ctx, inject_flags, &inject_offset);
673 CU_ASSERT(rc == 0);
674
675 rc = spdk_dif_verify(iovs, iovcnt, num_blocks, &ctx, &err_blk);
676 CU_ASSERT(rc != 0);
677 if (inject_flags == SPDK_DIF_DATA_ERROR) {
678 CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type);
679 } else {
680 CU_ASSERT(inject_flags == err_blk.err_type);
681 }
682 CU_ASSERT(inject_offset == err_blk.err_offset);
683
684 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, md_size, num_blocks);
685 CU_ASSERT((rc == 0 && (inject_flags != SPDK_DIF_DATA_ERROR)) ||
686 (rc != 0 && (inject_flags == SPDK_DIF_DATA_ERROR)));
687}
688
689static void
690dif_inject_error_and_verify(struct iovec *iovs, int iovcnt,
691 uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
692 uint32_t inject_flags)
693{
694 /* The case that DIF is contained in the first 8 bytes of metadata. */
695 _dif_inject_error_and_verify(iovs, iovcnt, block_size, md_size, num_blocks,
696 inject_flags, true);
697
698 /* The case that DIF is contained in the last 8 bytes of metadata. */
699 _dif_inject_error_and_verify(iovs, iovcnt, block_size, md_size, num_blocks,
700 inject_flags, false);
701}
702
703static void
704dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test(void)
705{
706 struct iovec iovs[4];
707 int i, num_blocks;
708
709 num_blocks = 0;
710
711 for (i = 0; i < 4; i++) {
712 _iov_alloc_buf(&iovs[i], (4096 + 128) * (i + 1));
713 num_blocks += i + 1;
714 }
715
716 dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, SPDK_DIF_GUARD_ERROR);
717 dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, SPDK_DIF_APPTAG_ERROR);
718 dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, SPDK_DIF_REFTAG_ERROR);
719 dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, SPDK_DIF_DATA_ERROR);
720
721 for (i = 0; i < 4; i++) {
722 _iov_free_buf(&iovs[i]);
723 }
724}
725
726static void
727dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_and_md_test(void)
728{
729 struct iovec iovs[2];
730
731 _iov_alloc_buf(&iovs[0], 4096);
732 _iov_alloc_buf(&iovs[1], 128);
733
734 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_GUARD_ERROR);
735 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_APPTAG_ERROR);
736 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_REFTAG_ERROR);
737 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_DATA_ERROR);
738
739 _iov_free_buf(&iovs[0]);
740 _iov_free_buf(&iovs[1]);
741}
742
743static void
744dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_test(void)
745{
746 struct iovec iovs[2];
747
748 _iov_alloc_buf(&iovs[0], 2048);
749 _iov_alloc_buf(&iovs[1], 2048 + 128);
750
751 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_GUARD_ERROR);
752 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_APPTAG_ERROR);
753 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_REFTAG_ERROR);
754 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_DATA_ERROR);
755
756 _iov_free_buf(&iovs[0]);
757 _iov_free_buf(&iovs[1]);
758}
759
760static void
761dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_guard_test(void)
762{
763 struct iovec iovs[2];
764
765 _iov_alloc_buf(&iovs[0], 4096 + 1);
766 _iov_alloc_buf(&iovs[1], 127);
767
768 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_GUARD_ERROR);
769 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_APPTAG_ERROR);
770 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_REFTAG_ERROR);
771 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_DATA_ERROR);
772
773 _iov_free_buf(&iovs[0]);
774 _iov_free_buf(&iovs[1]);
775}
776
777static void
778dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_apptag_test(void)
779{
780 struct iovec iovs[2];
781
782 _iov_alloc_buf(&iovs[0], 4096 + 3);
783 _iov_alloc_buf(&iovs[1], 125);
784
785 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_GUARD_ERROR);
786 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_APPTAG_ERROR);
787 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_REFTAG_ERROR);
788 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_DATA_ERROR);
789
790 _iov_free_buf(&iovs[0]);
791 _iov_free_buf(&iovs[1]);
792}
793
794static void
795dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_test(void)
796{
797 struct iovec iovs[2];
798
799 _iov_alloc_buf(&iovs[0], 4096 + 6);
800 _iov_alloc_buf(&iovs[1], 122);
801
802 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_GUARD_ERROR);
803 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_APPTAG_ERROR);
804 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_REFTAG_ERROR);
805 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_DATA_ERROR);
806
807 _iov_free_buf(&iovs[0]);
808 _iov_free_buf(&iovs[1]);
809}
810
811static void
812dif_copy_gen_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
813 uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
814 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
815 uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag)
816{
817 struct spdk_dif_ctx ctx = {};
818 int rc;
819
820 rc = ut_data_pattern_generate(iovs, iovcnt, block_size - md_size, 0, num_blocks);
821 CU_ASSERT(rc == 0);
822
823 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags,
824 init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED);
825 CU_ASSERT(rc == 0);
826
827 rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx);
828 CU_ASSERT(rc == 0);
829
830 rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx, NULL);
831 CU_ASSERT(rc == 0);
832
833 rc = ut_data_pattern_verify(iovs, iovcnt, block_size - md_size, 0, num_blocks);
834 CU_ASSERT(rc == 0);
835}
836
837static void
838dif_copy_sec_512_md_8_prchk_0_single_iov(void)
839{
840 struct iovec iov, bounce_iov;
841
842 _iov_alloc_buf(&iov, 512 * 4);
843 _iov_alloc_buf(&bounce_iov, (512 + 8) * 4);
844
845 dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 512 + 8, 8, 4,
846 false, SPDK_DIF_TYPE1, 0, 0, 0, 0);
847 dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 512 + 8, 8, 4,
848 true, SPDK_DIF_TYPE1, 0, 0, 0, 0);
849
850 _iov_free_buf(&iov);
851 _iov_free_buf(&bounce_iov);
852}
853
854static void
855dif_copy_sec_512_md_8_prchk_0_1_2_4_multi_iovs(void)
856{
857 struct iovec iovs[4], bounce_iov;
858 int i, num_blocks;
859
860 num_blocks = 0;
861
862 for (i = 0; i < 4; i++) {
863 _iov_alloc_buf(&iovs[i], 512 * (i + 1));
864 num_blocks += i + 1;
865 }
866
867 _iov_alloc_buf(&bounce_iov, (512 + 8) * num_blocks);
868
869 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks,
870 false, SPDK_DIF_TYPE1, 0, 22, 0xFFFF, 0x22);
871
872 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks,
873 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22);
874
875 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks,
876 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22);
877
878 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks,
879 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22);
880
881 for (i = 0; i < 4; i++) {
882 _iov_free_buf(&iovs[i]);
883 }
884 _iov_free_buf(&bounce_iov);
885}
886
887static void
888dif_copy_sec_4096_md_128_prchk_7_multi_iovs(void)
889{
890 struct iovec iovs[4], bounce_iov;
891 uint32_t dif_flags;
892 int i, num_blocks;
893
894 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
895 SPDK_DIF_FLAGS_REFTAG_CHECK;
896
897 num_blocks = 0;
898
899 for (i = 0; i < 4; i++) {
900 _iov_alloc_buf(&iovs[i], 4096 * (i + 1));
901 num_blocks += i + 1;
902 }
903
904 _iov_alloc_buf(&bounce_iov, (4096 + 128) * num_blocks);
905
906 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks,
907 false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22);
908 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks,
909 true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22);
910
911 for (i = 0; i < 4; i++) {
912 _iov_free_buf(&iovs[i]);
913 }
914 _iov_free_buf(&bounce_iov);
915}
916
917static void
918dif_copy_sec_512_md_8_prchk_7_multi_iovs_split_data(void)
919{
920 struct iovec iovs[2], bounce_iov;
921 uint32_t dif_flags;
922
923 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
924 SPDK_DIF_FLAGS_REFTAG_CHECK;
925
926 _iov_alloc_buf(&iovs[0], 256);
927 _iov_alloc_buf(&iovs[1], 256);
928
929 _iov_alloc_buf(&bounce_iov, 512 + 8);
930
931 dif_copy_gen_and_verify(iovs, 2, &bounce_iov, 512 + 8, 8, 1,
932 false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22);
933
934 _iov_free_buf(&iovs[0]);
935 _iov_free_buf(&iovs[1]);
936 _iov_free_buf(&bounce_iov);
937}
938
939static void
940dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits(void)
941{
942 struct iovec iovs[6], bounce_iov;
943 uint32_t dif_flags;
944 int i;
945
946 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
947 SPDK_DIF_FLAGS_REFTAG_CHECK;
948
949 /* data[0][255:0] */
950 _iov_alloc_buf(&iovs[0], 256);
951
952 /* data[0][511:256], data[1][255:0] */
953 _iov_alloc_buf(&iovs[1], 256 + 256);
954
955 /* data[1][382:256] */
956 _iov_alloc_buf(&iovs[2], 128);
957
958 /* data[1][383] */
959 _iov_alloc_buf(&iovs[3], 1);
960
961 /* data[1][510:384] */
962 _iov_alloc_buf(&iovs[4], 126);
963
964 /* data[1][511], data[2][511:0], data[3][511:0] */
965 _iov_alloc_buf(&iovs[5], 1 + 512 * 2);
966
967 _iov_alloc_buf(&bounce_iov, (512 + 8) * 4);
968
969 dif_copy_gen_and_verify(iovs, 6, &bounce_iov, 512 + 8, 8, 4,
970 true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22);
971
972 for (i = 0; i < 6; i++) {
973 _iov_free_buf(&iovs[i]);
974 }
975 _iov_free_buf(&bounce_iov);
976}
977
978static void
979_dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
980 uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
981 uint32_t inject_flags, bool dif_loc)
982{
983 struct spdk_dif_ctx ctx = {};
984 struct spdk_dif_error err_blk = {};
985 uint32_t inject_offset = 0, dif_flags;
986 int rc;
987
988 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
989 SPDK_DIF_FLAGS_REFTAG_CHECK;
990
991 rc = ut_data_pattern_generate(iovs, iovcnt, block_size - md_size, 0, num_blocks);
992 CU_ASSERT(rc == 0);
993
994 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, SPDK_DIF_TYPE1, dif_flags,
995 88, 0xFFFF, 0x88, 0, GUARD_SEED);
996 SPDK_CU_ASSERT_FATAL(rc == 0);
997
998 rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx);
999 CU_ASSERT(rc == 0);
1000
1001 rc = spdk_dif_inject_error(bounce_iov, 1, num_blocks, &ctx, inject_flags, &inject_offset);
1002 CU_ASSERT(rc == 0);
1003
1004 rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx, &err_blk);
1005 CU_ASSERT(rc != 0);
1006 if (inject_flags == SPDK_DIF_DATA_ERROR) {
1007 CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type);
1008 } else {
1009 CU_ASSERT(inject_flags == err_blk.err_type);
1010 }
1011 CU_ASSERT(inject_offset == err_blk.err_offset);
1012}
1013
1014static void
1015dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
1016 uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
1017 uint32_t inject_flags)
1018{
1019 /* The case that DIF is contained in the first 8 bytes of metadata. */
1020 _dif_copy_inject_error_and_verify(iovs, iovcnt, bounce_iov,
1021 block_size, md_size, num_blocks,
1022 inject_flags, true);
1023
1024 /* The case that DIF is contained in the last 8 bytes of metadata. */
1025 _dif_copy_inject_error_and_verify(iovs, iovcnt, bounce_iov,
1026 block_size, md_size, num_blocks,
1027 inject_flags, false);
1028}
1029
1030static void
1031dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test(void)
1032{
1033 struct iovec iovs[4], bounce_iov;
1034 int i, num_blocks;
1035
1036 num_blocks = 0;
1037
1038 for (i = 0; i < 4; i++) {
1039 _iov_alloc_buf(&iovs[i], 4096 * (i + 1));
1040 num_blocks += i + 1;
1041 }
1042
1043 _iov_alloc_buf(&bounce_iov, (4096 + 128) * num_blocks);
1044
1045 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1046 num_blocks, SPDK_DIF_GUARD_ERROR);
1047
1048 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1049 num_blocks, SPDK_DIF_APPTAG_ERROR);
1050
1051 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1052 num_blocks, SPDK_DIF_REFTAG_ERROR);
1053
1054 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1055 num_blocks, SPDK_DIF_DATA_ERROR);
1056
1057 for (i = 0; i < 4; i++) {
1058 _iov_free_buf(&iovs[i]);
1059 }
1060 _iov_free_buf(&bounce_iov);
1061}
1062
1063static void
1064dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test(void)
1065{
1066 struct iovec iovs[4], bounce_iov;
1067 int i;
1068
1069 _iov_alloc_buf(&iovs[0], 2048);
1070 _iov_alloc_buf(&iovs[1], 2048);
1071 _iov_alloc_buf(&iovs[2], 1);
1072 _iov_alloc_buf(&iovs[3], 4095);
1073
1074 _iov_alloc_buf(&bounce_iov, (4096 + 128) * 2);
1075
1076 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1077 2, SPDK_DIF_GUARD_ERROR);
1078
1079 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1080 2, SPDK_DIF_APPTAG_ERROR);
1081
1082 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1083 2, SPDK_DIF_REFTAG_ERROR);
1084
1085 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1086 2, SPDK_DIF_DATA_ERROR);
1087
1088 for (i = 0; i < 4; i++) {
1089 _iov_free_buf(&iovs[i]);
1090 }
1091 _iov_free_buf(&bounce_iov);
1092}
1093
1094static void
1095dix_sec_512_md_0_error(void)
1096{
1097 struct spdk_dif_ctx ctx;
1098 int rc;
1099
1100 rc = spdk_dif_ctx_init(&ctx, 512, 0, false, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 0, 0);
1101 CU_ASSERT(rc != 0);
1102}
1103
1104static void
1105dix_generate_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov,
1106 uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
1107 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
1108 uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag)
1109{
1110 struct spdk_dif_ctx ctx;
1111 int rc;
1112
1113 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, 0, num_blocks);
1114 CU_ASSERT(rc == 0);
1115
1116 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags,
1117 init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED);
1118 CU_ASSERT(rc == 0);
1119
1120 rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx);
1121 CU_ASSERT(rc == 0);
1122
1123 rc = spdk_dix_verify(iovs, iovcnt, md_iov, num_blocks, &ctx, NULL);
1124 CU_ASSERT(rc == 0);
1125
1126 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, 0, num_blocks);
1127 CU_ASSERT(rc == 0);
1128}
1129
1130static void
1131dix_sec_512_md_8_prchk_0_single_iov(void)
1132{
1133 struct iovec iov, md_iov;
1134
1135 _iov_alloc_buf(&iov, 512 * 4);
1136 _iov_alloc_buf(&md_iov, 8 * 4);
1137
1138 dix_generate_and_verify(&iov, 1, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1, 0, 0, 0, 0);
1139 dix_generate_and_verify(&iov, 1, &md_iov, 512, 8, 4, true, SPDK_DIF_TYPE1, 0, 0, 0, 0);
1140
1141 _iov_free_buf(&iov);
1142 _iov_free_buf(&md_iov);
1143}
1144
1145static void
1146dix_sec_512_md_8_prchk_0_1_2_4_multi_iovs(void)
1147{
1148 struct iovec iovs[4], md_iov;
1149 int i, num_blocks;
1150
1151 num_blocks = 0;
1152
1153 for (i = 0; i < 4; i++) {
1154 _iov_alloc_buf(&iovs[i], 512 * (i + 1));
1155 num_blocks += i + 1;
1156 }
1157 _iov_alloc_buf(&md_iov, 8 * num_blocks);
1158
1159 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1,
1160 0, 22, 0xFFFF, 0x22);
1161
1162 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1,
1163 SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22);
1164
1165 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1,
1166 SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22);
1167
1168 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1,
1169 SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22);
1170
1171 for (i = 0; i < 4; i++) {
1172 _iov_free_buf(&iovs[i]);
1173 }
1174 _iov_free_buf(&md_iov);
1175}
1176
1177static void
1178dix_sec_4096_md_128_prchk_7_multi_iovs(void)
1179{
1180 struct iovec iovs[4], md_iov;
1181 uint32_t dif_flags;
1182 int i, num_blocks;
1183
1184 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1185 SPDK_DIF_FLAGS_REFTAG_CHECK;
1186
1187 num_blocks = 0;
1188
1189 for (i = 0; i < 4; i++) {
1190 _iov_alloc_buf(&iovs[i], 4096 * (i + 1));
1191 num_blocks += i + 1;
1192 }
1193 _iov_alloc_buf(&md_iov, 128 * num_blocks);
1194
1195 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1,
1196 dif_flags, 22, 0xFFFF, 0x22);
1197 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1,
1198 dif_flags, 22, 0xFFFF, 0x22);
1199
1200 for (i = 0; i < 4; i++) {
1201 _iov_free_buf(&iovs[i]);
1202 }
1203 _iov_free_buf(&md_iov);
1204}
1205
1206static void
1207dix_sec_512_md_8_prchk_7_multi_iovs_split_data(void)
1208{
1209 struct iovec iovs[2], md_iov;
1210 uint32_t dif_flags;
1211
1212 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1213 SPDK_DIF_FLAGS_REFTAG_CHECK;
1214
1215 _iov_alloc_buf(&iovs[0], 256);
1216 _iov_alloc_buf(&iovs[1], 256);
1217 _iov_alloc_buf(&md_iov, 8);
1218
1219 dix_generate_and_verify(iovs, 2, &md_iov, 512, 8, 1, false, SPDK_DIF_TYPE1,
1220 dif_flags, 22, 0xFFFF, 0x22);
1221
1222 _iov_free_buf(&iovs[0]);
1223 _iov_free_buf(&iovs[1]);
1224 _iov_free_buf(&md_iov);
1225}
1226
1227static void
1228dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits(void)
1229{
1230 struct iovec iovs[6], md_iov;
1231 uint32_t dif_flags;
1232 int i;
1233
1234 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1235 SPDK_DIF_FLAGS_REFTAG_CHECK;
1236
1237 /* data[0][255:0] */
1238 _iov_alloc_buf(&iovs[0], 256);
1239
1240 /* data[0][511:256], data[1][255:0] */
1241 _iov_alloc_buf(&iovs[1], 256 + 256);
1242
1243 /* data[1][382:256] */
1244 _iov_alloc_buf(&iovs[2], 128);
1245
1246 /* data[1][383] */
1247 _iov_alloc_buf(&iovs[3], 1);
1248
1249 /* data[1][510:384] */
1250 _iov_alloc_buf(&iovs[4], 126);
1251
1252 /* data[1][511], data[2][511:0], data[3][511:0] */
1253 _iov_alloc_buf(&iovs[5], 1 + 512 * 2);
1254
1255 _iov_alloc_buf(&md_iov, 8 * 4);
1256
1257 dix_generate_and_verify(iovs, 6, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1,
1258 dif_flags, 22, 0xFFFF, 0x22);
1259
1260 for (i = 0; i < 6; i++) {
1261 _iov_free_buf(&iovs[i]);
1262 }
1263 _iov_free_buf(&md_iov);
1264}
1265
1266static void
1267_dix_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov,
1268 uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
1269 uint32_t inject_flags, bool dif_loc)
1270{
1271 struct spdk_dif_ctx ctx = {};
1272 struct spdk_dif_error err_blk = {};
1273 uint32_t inject_offset = 0, dif_flags;
1274 int rc;
1275
1276 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1277 SPDK_DIF_FLAGS_REFTAG_CHECK;
1278
1279 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, 0, num_blocks);
1280 CU_ASSERT(rc == 0);
1281
1282 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, SPDK_DIF_TYPE1, dif_flags,
1283 88, 0xFFFF, 0x88, 0, GUARD_SEED);
1284 CU_ASSERT(rc == 0);
1285
1286 rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx);
1287 CU_ASSERT(rc == 0);
1288
1289 rc = spdk_dix_inject_error(iovs, iovcnt, md_iov, num_blocks, &ctx, inject_flags, &inject_offset);
1290 CU_ASSERT(rc == 0);
1291
1292 rc = spdk_dix_verify(iovs, iovcnt, md_iov, num_blocks, &ctx, &err_blk);
1293 CU_ASSERT(rc != 0);
1294
1295 if (inject_flags == SPDK_DIF_DATA_ERROR) {
1296 CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type);
1297 } else {
1298 CU_ASSERT(inject_flags == err_blk.err_type);
1299 }
1300 CU_ASSERT(inject_offset == err_blk.err_offset);
1301}
1302
1303static void
1304dix_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov,
1305 uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
1306 uint32_t inject_flags)
1307{
1308 /* The case that DIF is contained in the first 8 bytes of metadata. */
1309 _dix_inject_error_and_verify(iovs, iovcnt, md_iov, block_size, md_size, num_blocks,
1310 inject_flags, true);
1311
1312 /* The case that DIF is contained in the last 8 bytes of metadata. */
1313 _dix_inject_error_and_verify(iovs, iovcnt, md_iov, block_size, md_size, num_blocks,
1314 inject_flags, false);
1315}
1316
1317static void
1318dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test(void)
1319{
1320 struct iovec iovs[4], md_iov;
1321 int i, num_blocks;
1322
1323 num_blocks = 0;
1324
1325 for (i = 0; i < 4; i++) {
1326 _iov_alloc_buf(&iovs[i], 4096 * (i + 1));
1327 num_blocks += i + 1;
1328 }
1329
1330 _iov_alloc_buf(&md_iov, 128 * num_blocks);
1331
1332 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, SPDK_DIF_GUARD_ERROR);
1333 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, SPDK_DIF_APPTAG_ERROR);
1334 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, SPDK_DIF_REFTAG_ERROR);
1335 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, SPDK_DIF_DATA_ERROR);
1336
1337 for (i = 0; i < 4; i++) {
1338 _iov_free_buf(&iovs[i]);
1339 }
1340 _iov_free_buf(&md_iov);
1341}
1342
1343static void
1344dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test(void)
1345{
1346 struct iovec iovs[4], md_iov;
1347 int i;
1348
1349 _iov_alloc_buf(&iovs[0], 2048);
1350 _iov_alloc_buf(&iovs[1], 2048);
1351 _iov_alloc_buf(&iovs[2], 1);
1352 _iov_alloc_buf(&iovs[3], 4095);
1353
1354 _iov_alloc_buf(&md_iov, 128 * 2);
1355
1356 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, SPDK_DIF_GUARD_ERROR);
1357 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, SPDK_DIF_APPTAG_ERROR);
1358 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, SPDK_DIF_REFTAG_ERROR);
1359 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, SPDK_DIF_DATA_ERROR);
1360
1361 for (i = 0; i < 4; i++) {
1362 _iov_free_buf(&iovs[i]);
1363 }
1364 _iov_free_buf(&md_iov);
1365}
1366
1367static int
1368ut_readv(uint32_t read_base, uint32_t read_len, struct iovec *iovs, int iovcnt)
1369{
1370 int i;
1371 uint32_t j, offset;
1372 uint8_t *buf;
1373
1374 offset = 0;
1375 for (i = 0; i < iovcnt; i++) {
1376 buf = iovs[i].iov_base;
1377 for (j = 0; j < iovs[i].iov_len; j++, offset++) {
1378 if (offset >= read_len) {
1379 return offset;
1380 }
1381 buf[j] = DATA_PATTERN(read_base + offset);
1382 }
1383 }
1384
1385 return offset;
1386}
1387
1388static void
1389set_md_interleave_iovs_test(void)
1390{
1391 struct spdk_dif_ctx ctx = {};
1392 struct spdk_dif_error err_blk = {};
f67539c2 1393 struct iovec iov1, iov2, dif_iovs[4] = {};
9f95a23c
TL
1394 uint32_t dif_check_flags, data_len, read_len, data_offset, mapped_len = 0;
1395 uint8_t *buf1, *buf2;
1396 int rc;
1397
1398 dif_check_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1399 SPDK_DIF_FLAGS_REFTAG_CHECK;
1400
1401 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
1402 dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED);
1403 CU_ASSERT(rc == 0);
1404
1405 /* The first data buffer:
1406 * - Create iovec array to Leave a space for metadata for each block
1407 * - Split vectored read and so creating iovec array is done before every vectored read.
1408 */
1409 buf1 = calloc(1, (4096 + 128) * 4);
1410 SPDK_CU_ASSERT_FATAL(buf1 != NULL);
1411 _iov_set_buf(&iov1, buf1, (4096 + 128) * 4);
1412
1413 data_offset = 0;
1414 data_len = 4096 * 4;
1415
1416 /* 1st read */
1417 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
1418 data_offset, data_len, &mapped_len, &ctx);
1419 CU_ASSERT(rc == 4);
1420 CU_ASSERT(mapped_len == 4096 * 4);
1421 CU_ASSERT(_iov_check(&dif_iovs[0], buf1, 4096) == true);
1422 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true);
1423 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true);
1424 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 4096) == true);
1425
1426 read_len = ut_readv(data_offset, 1024, dif_iovs, 4);
1427 CU_ASSERT(read_len == 1024);
1428
1429 rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx);
1430 CU_ASSERT(rc == 0);
1431
1432 data_offset += read_len;
f67539c2 1433 data_len -= read_len;
9f95a23c
TL
1434
1435 /* 2nd read */
1436 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
1437 data_offset, data_len, &mapped_len, &ctx);
1438 CU_ASSERT(rc == 4);
1439 CU_ASSERT(mapped_len == 3072 + 4096 * 3);
1440 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 1024, 3072) == true);
1441 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true);
1442 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true);
1443 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 4096) == true);
1444
1445 read_len = ut_readv(data_offset, 3071, dif_iovs, 4);
1446 CU_ASSERT(read_len == 3071);
1447
1448 rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx);
1449 CU_ASSERT(rc == 0);
1450
1451 data_offset += read_len;
f67539c2 1452 data_len -= read_len;
9f95a23c
TL
1453
1454 /* 3rd read */
1455 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
1456 data_offset, data_len, &mapped_len, &ctx);
1457 CU_ASSERT(rc == 4);
1458 CU_ASSERT(mapped_len == 1 + 4096 * 3);
1459 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 4095, 1) == true);
1460 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true);
1461 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true);
1462 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 4096) == true);
1463
1464 read_len = ut_readv(data_offset, 1 + 4096 * 2 + 512, dif_iovs, 4);
1465 CU_ASSERT(read_len == 1 + 4096 * 2 + 512);
1466
1467 rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx);
1468 CU_ASSERT(rc == 0);
1469
1470 data_offset += read_len;
f67539c2 1471 data_len -= read_len;
9f95a23c
TL
1472
1473 /* 4th read */
1474 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
1475 data_offset, data_len, &mapped_len, &ctx);
1476 CU_ASSERT(rc == 1);
1477 CU_ASSERT(mapped_len == 3584);
1478 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + (4096 + 128) * 3 + 512, 3584) == true);
1479
1480 read_len = ut_readv(data_offset, 3584, dif_iovs, 1);
1481 CU_ASSERT(read_len == 3584);
1482
1483 rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx);
1484 CU_ASSERT(rc == 0);
1485
1486 data_offset += read_len;
1487 CU_ASSERT(data_offset == 4096 * 4);
f67539c2
TL
1488 data_len -= read_len;
1489 CU_ASSERT(data_len == 0);
9f95a23c
TL
1490
1491 /* The second data buffer:
1492 * - Set data pattern with a space for metadata for each block.
1493 */
1494 buf2 = calloc(1, (4096 + 128) * 4);
1495 SPDK_CU_ASSERT_FATAL(buf2 != NULL);
1496 _iov_set_buf(&iov2, buf2, (4096 + 128) * 4);
1497
1498 rc = ut_data_pattern_generate(&iov2, 1, 4096 + 128, 128, 4);
1499 CU_ASSERT(rc == 0);
1500 rc = spdk_dif_generate(&iov2, 1, 4, &ctx);
1501 CU_ASSERT(rc == 0);
1502
1503 rc = spdk_dif_verify(&iov1, 1, 4, &ctx, &err_blk);
1504 CU_ASSERT(rc == 0);
1505
1506 rc = spdk_dif_verify(&iov2, 1, 4, &ctx, &err_blk);
1507 CU_ASSERT(rc == 0);
1508
1509 /* Compare the first and the second data buffer by byte. */
1510 rc = memcmp(buf1, buf2, (4096 + 128) * 4);
1511 CU_ASSERT(rc == 0);
1512
1513 free(buf1);
1514 free(buf2);
1515}
1516
1517static void
1518set_md_interleave_iovs_split_test(void)
1519{
1520 struct spdk_dif_ctx ctx = {};
1521 struct spdk_dif_error err_blk = {};
f67539c2 1522 struct iovec iovs1[7], iovs2[7], dif_iovs[8] = {};
9f95a23c
TL
1523 uint32_t dif_check_flags, data_len, read_len, data_offset, mapped_len = 0;
1524 int rc, i;
1525
1526 dif_check_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1527 SPDK_DIF_FLAGS_REFTAG_CHECK;
1528
1529 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1,
1530 dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED);
1531 CU_ASSERT(rc == 0);
1532
1533 /* The first SGL data buffer:
1534 * - Create iovec array to leave a space for metadata for each block
1535 * - Split vectored read and so creating iovec array is done before every vectored read.
1536 */
1537 _iov_alloc_buf(&iovs1[0], 512 + 8 + 128);
1538 _iov_alloc_buf(&iovs1[1], 128);
1539 _iov_alloc_buf(&iovs1[2], 256 + 8);
1540 _iov_alloc_buf(&iovs1[3], 100);
1541 _iov_alloc_buf(&iovs1[4], 412 + 5);
1542 _iov_alloc_buf(&iovs1[5], 3 + 300);
1543 _iov_alloc_buf(&iovs1[6], 212 + 8);
1544
1545 data_offset = 0;
1546 data_len = 512 * 4;
1547
1548 /* 1st read */
1549 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7,
1550 data_offset, data_len, &mapped_len, &ctx);
1551 CU_ASSERT(rc == 8);
1552 CU_ASSERT(mapped_len == 512 * 4);
1553 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base, 512) == true);
1554 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true);
1555 CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true);
1556 CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true);
1557 CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true);
1558 CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true);
1559 CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true);
1560 CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true);
1561
1562 read_len = ut_readv(data_offset, 128, dif_iovs, 8);
1563 CU_ASSERT(read_len == 128);
1564
1565 rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx);
1566 CU_ASSERT(rc == 0);
1567
1568 data_offset += read_len;
f67539c2 1569 data_len -= read_len;
9f95a23c
TL
1570
1571 /* 2nd read */
1572 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7,
1573 data_offset, data_len, &mapped_len, &ctx);
1574 CU_ASSERT(rc == 8);
1575 CU_ASSERT(mapped_len == 384 + 512 * 3);
1576 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base + 128, 384) == true);
1577 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true);
1578 CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true);
1579 CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true);
1580 CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true);
1581 CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true);
1582 CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true);
1583 CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true);
1584
1585 read_len = ut_readv(data_offset, 383, dif_iovs, 8);
1586 CU_ASSERT(read_len == 383);
1587
1588 rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx);
1589 CU_ASSERT(rc == 0);
1590
1591 data_offset += read_len;
f67539c2 1592 data_len -= read_len;
9f95a23c
TL
1593
1594 /* 3rd read */
1595 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7,
1596 data_offset, data_len, &mapped_len, &ctx);
1597 CU_ASSERT(rc == 8);
1598 CU_ASSERT(mapped_len == 1 + 512 * 3);
1599 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base + 511, 1) == true);
1600 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true);
1601 CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true);
1602 CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true);
1603 CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true);
1604 CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true);
1605 CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true);
1606 CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true);
1607
1608 read_len = ut_readv(data_offset, 1 + 512 * 2 + 128, dif_iovs, 8);
1609 CU_ASSERT(read_len == 1 + 512 * 2 + 128);
1610
1611 rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx);
1612 CU_ASSERT(rc == 0);
1613
1614 data_offset += read_len;
f67539c2 1615 data_len -= read_len;
9f95a23c
TL
1616
1617 /* 4th read */
1618 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7,
1619 data_offset, data_len, &mapped_len, &ctx);
1620 CU_ASSERT(rc == 2);
1621 CU_ASSERT(mapped_len == 384);
1622 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[5].iov_base + 3 + 128, 172) == true);
1623 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[6].iov_base, 212) == true);
1624
1625 read_len = ut_readv(data_offset, 384, dif_iovs, 8);
1626 CU_ASSERT(read_len == 384);
1627
1628 rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx);
1629 CU_ASSERT(rc == 0);
1630
1631 data_offset += read_len;
1632 CU_ASSERT(data_offset == 512 * 4);
f67539c2
TL
1633 data_len -= read_len;
1634 CU_ASSERT(data_len == 0);
9f95a23c
TL
1635
1636 /* The second SGL data buffer:
1637 * - Set data pattern with a space for metadata for each block.
1638 */
1639 _iov_alloc_buf(&iovs2[0], 512 + 8 + 128);
1640 _iov_alloc_buf(&iovs2[1], 128);
1641 _iov_alloc_buf(&iovs2[2], 256 + 8);
1642 _iov_alloc_buf(&iovs2[3], 100);
1643 _iov_alloc_buf(&iovs2[4], 412 + 5);
1644 _iov_alloc_buf(&iovs2[5], 3 + 300);
1645 _iov_alloc_buf(&iovs2[6], 212 + 8);
1646
1647 rc = ut_data_pattern_generate(iovs2, 7, 512 + 8, 8, 4);
1648 CU_ASSERT(rc == 0);
1649 rc = spdk_dif_generate(iovs2, 7, 4, &ctx);
1650 CU_ASSERT(rc == 0);
1651
1652 rc = spdk_dif_verify(iovs1, 7, 4, &ctx, &err_blk);
1653 CU_ASSERT(rc == 0);
1654
1655 rc = spdk_dif_verify(iovs2, 7, 4, &ctx, &err_blk);
1656 CU_ASSERT(rc == 0);
1657
1658 /* Compare the first and the second SGL data buffer by byte. */
1659 for (i = 0; i < 7; i++) {
1660 rc = memcmp(iovs1[i].iov_base, iovs2[i].iov_base,
1661 iovs1[i].iov_len);
1662 CU_ASSERT(rc == 0);
1663 }
1664
1665 for (i = 0; i < 7; i++) {
1666 _iov_free_buf(&iovs1[i]);
1667 _iov_free_buf(&iovs2[i]);
1668 }
1669}
1670
1671static void
1672dif_generate_stream_test(void)
1673{
1674 struct iovec iov;
1675 struct spdk_dif_ctx ctx;
1676 struct spdk_dif_error err_blk;
1677 uint32_t dif_flags;
1678 int rc;
1679
1680 _iov_alloc_buf(&iov, (512 + 8) * 5);
1681
1682 rc = ut_data_pattern_generate(&iov, 1, 512 + 8, 8, 5);
1683 CU_ASSERT(rc == 0);
1684
1685 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1686 SPDK_DIF_FLAGS_REFTAG_CHECK;
1687
1688 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, dif_flags,
1689 22, 0xFFFF, 0x22, 0, GUARD_SEED);
1690 CU_ASSERT(rc == 0);
1691
1692 rc = spdk_dif_generate_stream(&iov, 1, 0, 511, &ctx);
1693 CU_ASSERT(rc == 0);
1694
1695 rc = spdk_dif_generate_stream(&iov, 1, 511, 1, &ctx);
1696 CU_ASSERT(rc == 0);
1697
1698 rc = spdk_dif_generate_stream(&iov, 1, 512, 256, &ctx);
1699 CU_ASSERT(rc == 0);
1700
1701 rc = spdk_dif_generate_stream(&iov, 1, 768, 512, &ctx);
1702 CU_ASSERT(rc == 0);
1703
1704 rc = spdk_dif_generate_stream(&iov, 1, 1280, 1024, &ctx);
1705 CU_ASSERT(rc == 0);
1706
1707 rc = spdk_dif_generate_stream(&iov, 1, 2304, 256, &ctx);
1708 CU_ASSERT(rc == 0);
1709
1710 rc = spdk_dif_generate_stream(&iov, 1, 2560, 512, &ctx);
1711 CU_ASSERT(rc == -ERANGE);
1712
1713 rc = spdk_dif_verify(&iov, 1, 5, &ctx, &err_blk);
1714 CU_ASSERT(rc == 0);
1715
1716 rc = ut_data_pattern_verify(&iov, 1, 512 + 8, 8, 5);
1717 CU_ASSERT(rc == 0);
1718
1719 _iov_free_buf(&iov);
1720}
1721
f67539c2
TL
1722static void
1723set_md_interleave_iovs_alignment_test(void)
1724{
1725 struct iovec iovs[3], dif_iovs[5] = {};
1726 uint32_t mapped_len = 0;
1727 int rc;
1728 struct spdk_dif_ctx ctx;
1729
1730 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1,
1731 0, 0, 0, 0, 0, 0);
1732 CU_ASSERT(rc == 0);
1733
1734 /* The case that buffer size is smaller than necessary. */
1735 _iov_set_buf(&iovs[0], (uint8_t *)0xDEADBEEF, 1024);
1736 _iov_set_buf(&iovs[1], (uint8_t *)0xFEEDBEEF, 1024);
1737 _iov_set_buf(&iovs[2], (uint8_t *)0xC0FFEE, 24);
1738
1739 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 0, 2048, &mapped_len, &ctx);
1740 CU_ASSERT(rc == -ERANGE);
1741
1742 /* The folllowing are the normal cases. */
1743 _iov_set_buf(&iovs[2], (uint8_t *)0xC0FFEE, 32);
1744
1745 /* data length is less than a data block size. */
1746 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 0, 500, &mapped_len, &ctx);
1747 CU_ASSERT(rc == 1);
1748 CU_ASSERT(mapped_len == 500);
1749 CU_ASSERT(_iov_check(&dif_iovs[0], (void *)0xDEADBEEF, 500) == true);
1750
1751 /* Pass enough number of iovecs */
1752 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 500, 1000, &mapped_len, &ctx);
1753 CU_ASSERT(rc == 4);
1754 CU_ASSERT(mapped_len == 1000);
1755 CU_ASSERT(_iov_check(&dif_iovs[0], (void *)(0xDEADBEEF + 500), 12) == true);
1756 CU_ASSERT(_iov_check(&dif_iovs[1], (void *)(0xDEADBEEF + 520), 504) == true);
1757 CU_ASSERT(_iov_check(&dif_iovs[2], (void *)0xFEEDBEEF, 8) == true);
1758 CU_ASSERT(_iov_check(&dif_iovs[3], (void *)(0xFEEDBEEF + 16), 476) == true);
1759
1760 /* Pass iovecs smaller than necessary */
1761 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 3, iovs, 3, 500, 1000, &mapped_len, &ctx);
1762 CU_ASSERT(rc == 3);
1763 CU_ASSERT(mapped_len == 524);
1764 CU_ASSERT(_iov_check(&dif_iovs[0], (void *)(0xDEADBEEF + 500), 12) == true);
1765 CU_ASSERT(_iov_check(&dif_iovs[1], (void *)(0xDEADBEEF + 520), 504) == true);
1766 CU_ASSERT(_iov_check(&dif_iovs[2], (void *)0xFEEDBEEF, 8) == true);
1767
1768 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 1500, 500, &mapped_len, &ctx);
1769 CU_ASSERT(rc == 2);
1770 CU_ASSERT(mapped_len == 500);
1771 CU_ASSERT(_iov_check(&dif_iovs[0], (void *)(0xFEEDBEEF + 492), 36) == true);
1772 CU_ASSERT(_iov_check(&dif_iovs[1], (void *)(0xFEEDBEEF + 536), 464) == true);
1773
1774 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 2000, 48, &mapped_len, &ctx);
1775 CU_ASSERT(rc == 2);
1776 CU_ASSERT(mapped_len == 48);
1777 CU_ASSERT(_iov_check(&dif_iovs[0], (void *)0xFEEDBEEF + 1000, 24) == true);
1778 CU_ASSERT(_iov_check(&dif_iovs[1], (void *)0xC0FFEE, 24) == true);
1779}
1780
1781static void
1782_dif_generate_split_test(void)
1783{
1784 struct spdk_dif_ctx ctx = {};
1785 struct iovec iov;
1786 uint8_t *buf1, *buf2;
1787 struct _dif_sgl sgl;
1788 uint16_t guard = 0, prev_guard;
1789 uint32_t dif_flags;
1790 int rc;
1791
1792 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1793 SPDK_DIF_FLAGS_REFTAG_CHECK;
1794
1795 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
1796 dif_flags, 0, 0, 0, 0, GUARD_SEED);
1797 CU_ASSERT(rc == 0);
1798
1799 buf1 = calloc(1, 4096 + 128);
1800 SPDK_CU_ASSERT_FATAL(buf1 != NULL);
1801 _iov_set_buf(&iov, buf1, 4096 + 128);
1802
1803 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1);
1804 CU_ASSERT(rc == 0);
1805
1806 _dif_sgl_init(&sgl, &iov, 1);
1807
1808 guard = GUARD_SEED;
1809 prev_guard = GUARD_SEED;
1810
1811 guard = _dif_generate_split(&sgl, 0, 1000, guard, 0, &ctx);
1812 CU_ASSERT(sgl.iov_offset == 1000);
1813 CU_ASSERT(guard == spdk_crc16_t10dif(prev_guard, buf1, 1000));
1814
1815 prev_guard = guard;
1816
1817 guard = _dif_generate_split(&sgl, 1000, 3000, guard, 0, &ctx);
1818 CU_ASSERT(sgl.iov_offset == 4000);
1819 CU_ASSERT(guard == spdk_crc16_t10dif(prev_guard, buf1 + 1000, 3000));
1820
1821 guard = _dif_generate_split(&sgl, 4000, 96 + 128, guard, 0, &ctx);
1822 CU_ASSERT(guard == GUARD_SEED);
1823 CU_ASSERT(sgl.iov_offset == 0);
1824 CU_ASSERT(sgl.iovcnt == 0);
1825
1826 rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 1);
1827 CU_ASSERT(rc == 0);
1828
1829 _dif_sgl_init(&sgl, &iov, 1);
1830
1831 rc = dif_verify(&sgl, 1, &ctx, NULL);
1832 CU_ASSERT(rc == 0);
1833
1834 buf2 = calloc(1, 4096 + 128);
1835 SPDK_CU_ASSERT_FATAL(buf2 != NULL);
1836 _iov_set_buf(&iov, buf2, 4096 + 128);
1837
1838 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1);
1839 CU_ASSERT(rc == 0);
1840
1841 _dif_sgl_init(&sgl, &iov, 1);
1842
1843 dif_generate(&sgl, 1, &ctx);
1844
1845 rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 1);
1846 CU_ASSERT(rc == 0);
1847
1848 _dif_sgl_init(&sgl, &iov, 1);
1849
1850 rc = dif_verify(&sgl, 1, &ctx, NULL);
1851 CU_ASSERT(rc == 0);
1852
1853 rc = memcmp(buf1, buf2, 4096 + 128);
1854 CU_ASSERT(rc == 0);
1855
1856 free(buf1);
1857 free(buf2);
1858}
1859
1860static void
1861set_md_interleave_iovs_multi_segments_test(void)
1862{
1863 struct spdk_dif_ctx ctx = {};
1864 struct spdk_dif_error err_blk = {};
1865 struct iovec iov1 = {}, iov2 = {}, dif_iovs[4] = {};
1866 uint32_t dif_check_flags, data_len, read_len, data_offset, read_offset, mapped_len = 0;
1867 uint8_t *buf1, *buf2;
1868 int rc;
1869
1870 dif_check_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1871 SPDK_DIF_FLAGS_REFTAG_CHECK;
1872
1873 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
1874 dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED);
1875 CU_ASSERT(rc == 0);
1876
1877 /* The first data buffer:
1878 * - Data buffer is split into multi data segments
1879 * - For each data segment,
1880 * - Create iovec array to Leave a space for metadata for each block
1881 * - Split vectored read and so creating iovec array is done before every vectored read.
1882 */
1883 buf1 = calloc(1, (4096 + 128) * 4);
1884 SPDK_CU_ASSERT_FATAL(buf1 != NULL);
1885 _iov_set_buf(&iov1, buf1, (4096 + 128) * 4);
1886
1887 /* 1st data segment */
1888 data_offset = 0;
1889 data_len = 1024;
1890
1891 spdk_dif_ctx_set_data_offset(&ctx, data_offset);
1892
1893 read_offset = 0;
1894
1895 /* 1st read in 1st data segment */
1896 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
1897 read_offset, data_len - read_offset,
1898 &mapped_len, &ctx);
1899 CU_ASSERT(rc == 1);
1900 CU_ASSERT(mapped_len == 1024);
1901 CU_ASSERT(_iov_check(&dif_iovs[0], buf1, 1024) == true);
1902
1903 read_len = ut_readv(data_offset + read_offset, 1024, dif_iovs, 4);
1904 CU_ASSERT(read_len == 1024);
1905
1906 rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx);
1907 CU_ASSERT(rc == 0);
1908
1909 read_offset += read_len;
1910 CU_ASSERT(read_offset == data_len);
1911
1912 /* 2nd data segment */
1913 data_offset += data_len;
1914 data_len = 3072 + 4096 * 2 + 512;
1915
1916 spdk_dif_ctx_set_data_offset(&ctx, data_offset);
1917 _iov_set_buf(&iov1, buf1 + 1024, 3072 + 128 + (4096 + 128) * 3 + 512);
1918
1919 read_offset = 0;
1920
1921 /* 1st read in 2nd data segment */
1922 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
1923 read_offset, data_len - read_offset,
1924 &mapped_len, &ctx);
1925 CU_ASSERT(rc == 4);
1926 CU_ASSERT(mapped_len == 3072 + 4096 * 2 + 512);
1927 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 1024, 3072) == true);
1928 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true);
1929 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true);
1930 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 512) == true);
1931
1932 read_len = ut_readv(data_offset + read_offset, 3071, dif_iovs, 4);
1933 CU_ASSERT(read_len == 3071);
1934
1935 rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx);
1936 CU_ASSERT(rc == 0);
1937
1938 read_offset += read_len;
1939
1940 /* 2nd read in 2nd data segment */
1941 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
1942 read_offset, data_len - read_offset,
1943 &mapped_len, &ctx);
1944 CU_ASSERT(rc == 4);
1945 CU_ASSERT(mapped_len == 1 + 4096 * 2 + 512);
1946 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 4095, 1) == true);
1947 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true);
1948 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true);
1949 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 512) == true);
1950
1951 read_len = ut_readv(data_offset + read_offset, 1 + 4096 * 2 + 512, dif_iovs, 4);
1952 CU_ASSERT(read_len == 1 + 4096 * 2 + 512);
1953
1954 rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx);
1955 CU_ASSERT(rc == 0);
1956
1957 read_offset += read_len;
1958 CU_ASSERT(read_offset == data_len);
1959
1960 /* 3rd data segment */
1961 data_offset += data_len;
1962 data_len = 3584;
1963
1964 spdk_dif_ctx_set_data_offset(&ctx, data_offset);
1965 _iov_set_buf(&iov1, buf1 + (4096 + 128) * 3 + 512, 3584 + 128);
1966
1967 read_offset = 0;
1968
1969 /* 1st read in 3rd data segment */
1970 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
1971 read_offset, data_len - read_offset,
1972 &mapped_len, &ctx);
1973 CU_ASSERT(rc == 1);
1974 CU_ASSERT(mapped_len == 3584);
1975 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + (4096 + 128) * 3 + 512, 3584) == true);
1976
1977 read_len = ut_readv(data_offset + read_offset, 3584, dif_iovs, 1);
1978 CU_ASSERT(read_len == 3584);
1979
1980 rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx);
1981 CU_ASSERT(rc == 0);
1982
1983 read_offset += read_len;
1984 CU_ASSERT(read_offset == data_len);
1985 data_offset += data_len;
1986 CU_ASSERT(data_offset == 4096 * 4);
1987
1988 spdk_dif_ctx_set_data_offset(&ctx, 0);
1989 _iov_set_buf(&iov1, buf1, (4096 + 128) * 4);
1990
1991 /* The second data buffer:
1992 * - Set data pattern with a space for metadata for each block.
1993 */
1994 buf2 = calloc(1, (4096 + 128) * 4);
1995 SPDK_CU_ASSERT_FATAL(buf2 != NULL);
1996 _iov_set_buf(&iov2, buf2, (4096 + 128) * 4);
1997
1998 rc = ut_data_pattern_generate(&iov2, 1, 4096 + 128, 128, 4);
1999 CU_ASSERT(rc == 0);
2000
2001 rc = spdk_dif_generate(&iov2, 1, 4, &ctx);
2002 CU_ASSERT(rc == 0);
2003
2004 rc = spdk_dif_verify(&iov1, 1, 4, &ctx, &err_blk);
2005 CU_ASSERT(rc == 0);
2006
2007 rc = spdk_dif_verify(&iov2, 1, 4, &ctx, &err_blk);
2008 CU_ASSERT(rc == 0);
2009
2010 /* Compare the first and the second data buffer by byte. */
2011 rc = memcmp(buf1, buf2, (4096 + 128) * 4);
2012 CU_ASSERT(rc == 0);
2013
2014 free(buf1);
2015 free(buf2);
2016}
2017
2018static void
2019_dif_verify_split_test(void)
2020{
2021 struct spdk_dif_ctx ctx = {};
2022 struct spdk_dif_error err_blk = {};
2023 struct iovec iov;
2024 uint8_t *buf;
2025 struct _dif_sgl sgl;
2026 uint16_t guard = 0, prev_guard = 0;
2027 uint32_t dif_flags;
2028 int rc;
2029
2030 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2031 SPDK_DIF_FLAGS_REFTAG_CHECK;
2032
2033 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
2034 dif_flags, 0, 0, 0, 0, GUARD_SEED);
2035 CU_ASSERT(rc == 0);
2036
2037 buf = calloc(1, 4096 + 128);
2038 SPDK_CU_ASSERT_FATAL(buf != NULL);
2039 _iov_set_buf(&iov, buf, 4096 + 128);
2040
2041 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1);
2042 CU_ASSERT(rc == 0);
2043
2044 _dif_sgl_init(&sgl, &iov, 1);
2045
2046 dif_generate(&sgl, 1, &ctx);
2047
2048 _dif_sgl_init(&sgl, &iov, 1);
2049
2050 guard = GUARD_SEED;
2051 prev_guard = GUARD_SEED;
2052
2053 rc = _dif_verify_split(&sgl, 0, 1000, &guard, 0, &ctx, &err_blk);
2054 CU_ASSERT(rc == 0);
2055 CU_ASSERT(guard == spdk_crc16_t10dif(prev_guard, buf, 1000));
2056 CU_ASSERT(sgl.iov_offset == 1000);
2057
2058 prev_guard = guard;
2059
2060 rc = _dif_verify_split(&sgl, 1000, 3000, &guard, 0, &ctx, &err_blk);
2061 CU_ASSERT(rc == 0);
2062 CU_ASSERT(guard == spdk_crc16_t10dif(prev_guard, buf + 1000, 3000));
2063 CU_ASSERT(sgl.iov_offset == 4000);
2064
2065 rc = _dif_verify_split(&sgl, 4000, 96 + 128, &guard, 0, &ctx, &err_blk);
2066 CU_ASSERT(rc == 0);
2067 CU_ASSERT(guard == GUARD_SEED);
2068 CU_ASSERT(sgl.iov_offset == 0);
2069 CU_ASSERT(sgl.iovcnt == 0);
2070
2071 _dif_sgl_init(&sgl, &iov, 1);
2072
2073 rc = dif_verify(&sgl, 1, &ctx, &err_blk);
2074 CU_ASSERT(rc == 0);
2075
2076 rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 1);
2077 CU_ASSERT(rc == 0);
2078
2079 free(buf);
2080}
2081
2082static void
2083dif_verify_stream_multi_segments_test(void)
2084{
2085 struct spdk_dif_ctx ctx = {};
2086 struct spdk_dif_error err_blk = {};
2087 struct iovec iov = {};
2088 uint8_t *buf;
2089 uint32_t dif_flags;
2090 int rc;
2091
2092 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2093 SPDK_DIF_FLAGS_REFTAG_CHECK;
2094
2095 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
2096 dif_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED);
2097 CU_ASSERT(rc == 0);
2098
2099 buf = calloc(1, (4096 + 128) * 4);
2100 SPDK_CU_ASSERT_FATAL(buf != NULL);
2101 _iov_set_buf(&iov, buf, (4096 + 128) * 4);
2102
2103 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 4);
2104 CU_ASSERT(rc == 0);
2105
2106 rc = spdk_dif_generate(&iov, 1, 4, &ctx);
2107 CU_ASSERT(rc == 0);
2108
2109 /* 1st data segment */
2110 _iov_set_buf(&iov, buf, 1024);
2111 spdk_dif_ctx_set_data_offset(&ctx, 0);
2112
2113 rc = spdk_dif_verify_stream(&iov, 1, 0, 1024, &ctx, &err_blk);
2114 CU_ASSERT(rc == 0);
2115
2116 /* 2nd data segment */
2117 _iov_set_buf(&iov, buf + 1024, (3072 + 128) + (4096 + 128) * 2 + 512);
2118 spdk_dif_ctx_set_data_offset(&ctx, 1024);
2119
2120 rc = spdk_dif_verify_stream(&iov, 1, 0, 3072 + 4096 * 2 + 512, &ctx, &err_blk);
2121 CU_ASSERT(rc == 0);
2122
2123 /* 3rd data segment */
2124 _iov_set_buf(&iov, buf + (4096 + 128) * 3 + 512, 3584 + 128);
2125 spdk_dif_ctx_set_data_offset(&ctx, 4096 * 3);
2126
2127 rc = spdk_dif_verify_stream(&iov, 1, 0, 3584, &ctx, &err_blk);
2128 CU_ASSERT(rc == 0);
2129
2130 /* verify all data segments once */
2131 _iov_set_buf(&iov, buf, (4096 + 128) * 4);
2132 spdk_dif_ctx_set_data_offset(&ctx, 0);
2133
2134 rc = spdk_dif_verify(&iov, 1, 4, &ctx, &err_blk);
2135 CU_ASSERT(rc == 0);
2136
2137 rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 4);
2138 CU_ASSERT(rc == 0);
2139
2140 free(buf);
2141}
2142
9f95a23c
TL
2143#define UT_CRC32C_XOR 0xffffffffUL
2144
2145static void
2146update_crc32c_test(void)
2147{
2148 struct spdk_dif_ctx ctx = {};
2149 struct iovec iovs[7];
2150 uint32_t crc32c1, crc32c2, crc32c3, crc32c4;
2151 uint32_t dif_flags;
2152 int i, rc;
2153
2154 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2155 SPDK_DIF_FLAGS_REFTAG_CHECK;
2156
2157 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1,
2158 dif_flags, 0, 0, 0, 0, 0);
2159 CU_ASSERT(rc == 0);
2160
2161 /* data[0][255:0] */
2162 _iov_alloc_buf(&iovs[0], 256);
2163
2164 /* data[0][511:256], md[0][0] */
2165 _iov_alloc_buf(&iovs[1], 256 + 1);
2166
2167 /* md[0][4:1] */
2168 _iov_alloc_buf(&iovs[2], 4);
2169
2170 /* md[0][7:5], data[1][122:0] */
2171 _iov_alloc_buf(&iovs[3], 3 + 123);
2172
2173 /* data[1][511:123], md[1][5:0] */
f67539c2 2174 _iov_alloc_buf(&iovs[4], 389 + 6);
9f95a23c
TL
2175
2176 /* md[1][7:6], data[2][511:0], md[2][7:0], data[3][431:0] */
2177 _iov_alloc_buf(&iovs[5], 2 + 512 + 8 + 432);
2178
2179 /* data[3][511:432], md[3][7:0] */
2180 _iov_alloc_buf(&iovs[6], 80 + 8);
2181
2182 rc = ut_data_pattern_generate(iovs, 7, 512 + 8, 8, 4);
2183 CU_ASSERT(rc == 0);
2184
2185 crc32c1 = UT_CRC32C_XOR;
2186
2187 rc = spdk_dif_update_crc32c(iovs, 7, 4, &crc32c1, &ctx);
2188 CU_ASSERT(rc == 0);
2189
2190 /* Test if DIF doesn't affect CRC for split case. */
2191 rc = spdk_dif_generate(iovs, 7, 4, &ctx);
2192 CU_ASSERT(rc == 0);
2193
2194 crc32c2 = UT_CRC32C_XOR;
2195
2196 rc = spdk_dif_update_crc32c(iovs, 7, 4, &crc32c2, &ctx);
2197 CU_ASSERT(rc == 0);
2198
2199 CU_ASSERT(crc32c1 == crc32c2);
2200
2201 for (i = 0; i < 7; i++) {
2202 _iov_free_buf(&iovs[i]);
2203 }
2204
2205 /* Test if CRC is same regardless of splitting. */
2206 for (i = 0; i < 4; i++) {
2207 _iov_alloc_buf(&iovs[i], 512 + 8);
2208 }
2209
2210 rc = ut_data_pattern_generate(iovs, 4, 512 + 8, 8, 4);
2211 CU_ASSERT(rc == 0);
2212
2213 crc32c3 = UT_CRC32C_XOR;
2214
2215 rc = spdk_dif_update_crc32c(iovs, 4, 4, &crc32c3, &ctx);
2216 CU_ASSERT(rc == 0);
2217
2218 CU_ASSERT(crc32c1 == crc32c3);
2219
2220 /* Test if DIF doesn't affect CRC for non-split case. */
2221 rc = spdk_dif_generate(iovs, 4, 4, &ctx);
2222 CU_ASSERT(rc == 0);
2223
2224 crc32c4 = UT_CRC32C_XOR;
2225
2226 rc = spdk_dif_update_crc32c(iovs, 4, 4, &crc32c4, &ctx);
2227 CU_ASSERT(rc == 0);
2228
2229 CU_ASSERT(crc32c1 == crc32c4);
2230
2231 for (i = 0; i < 4; i++) {
2232 _iov_free_buf(&iovs[i]);
2233 }
2234}
2235
f67539c2
TL
2236static void
2237_dif_update_crc32c_split_test(void)
2238{
2239 struct spdk_dif_ctx ctx = {};
2240 struct iovec iov;
2241 uint8_t *buf;
2242 struct _dif_sgl sgl;
2243 uint32_t dif_flags, crc32c, prev_crc32c;
2244 int rc;
2245
2246 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2247 SPDK_DIF_FLAGS_REFTAG_CHECK;
2248
2249 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
2250 dif_flags, 0, 0, 0, 0, GUARD_SEED);
2251 CU_ASSERT(rc == 0);
2252
2253 buf = calloc(1, 4096 + 128);
2254 SPDK_CU_ASSERT_FATAL(buf != NULL);
2255 _iov_set_buf(&iov, buf, 4096 + 128);
2256
2257 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1);
2258 CU_ASSERT(rc == 0);
2259
2260 _dif_sgl_init(&sgl, &iov, 1);
2261
2262 dif_generate(&sgl, 1, &ctx);
2263
2264 _dif_sgl_init(&sgl, &iov, 1);
2265
2266 crc32c = _dif_update_crc32c_split(&sgl, 0, 1000, UT_CRC32C_XOR, &ctx);
2267 CU_ASSERT(crc32c == spdk_crc32c_update(buf, 1000, UT_CRC32C_XOR));
2268
2269 prev_crc32c = crc32c;
2270
2271 crc32c = _dif_update_crc32c_split(&sgl, 1000, 3000, prev_crc32c, &ctx);
2272 CU_ASSERT(crc32c == spdk_crc32c_update(buf + 1000, 3000, prev_crc32c));
2273
2274 prev_crc32c = crc32c;
2275
2276 crc32c = _dif_update_crc32c_split(&sgl, 4000, 96 + 128, prev_crc32c, &ctx);
2277 CU_ASSERT(crc32c == spdk_crc32c_update(buf + 4000, 96, prev_crc32c));
2278
2279 CU_ASSERT(crc32c == spdk_crc32c_update(buf, 4096, UT_CRC32C_XOR));
2280
2281 free(buf);
2282}
2283
2284static void
2285dif_update_crc32c_stream_multi_segments_test(void)
2286{
2287 struct spdk_dif_ctx ctx = {};
2288 struct iovec iov = {};
2289 uint8_t *buf;
2290 uint32_t dif_flags, crc32c1, crc32c2;
2291 int rc;
2292
2293 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2294 SPDK_DIF_FLAGS_REFTAG_CHECK;
2295
2296 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
2297 dif_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED);
2298 CU_ASSERT(rc == 0);
2299
2300 buf = calloc(1, (4096 + 128) * 4);
2301 SPDK_CU_ASSERT_FATAL(buf != NULL);
2302 _iov_set_buf(&iov, buf, (4096 + 128) * 4);
2303
2304 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 4);
2305 CU_ASSERT(rc == 0);
2306
2307 rc = spdk_dif_generate(&iov, 1, 4, &ctx);
2308 CU_ASSERT(rc == 0);
2309
2310 crc32c1 = UT_CRC32C_XOR;
2311 crc32c2 = UT_CRC32C_XOR;
2312
2313 /* 1st data segment */
2314 _iov_set_buf(&iov, buf, 1024);
2315 spdk_dif_ctx_set_data_offset(&ctx, 0);
2316
2317 rc = spdk_dif_update_crc32c_stream(&iov, 1, 0, 1024, &crc32c1, &ctx);
2318 CU_ASSERT(rc == 0);
2319
2320 /* 2nd data segment */
2321 _iov_set_buf(&iov, buf + 1024, (3072 + 128) + (4096 + 128) * 2 + 512);
2322 spdk_dif_ctx_set_data_offset(&ctx, 1024);
2323
2324 rc = spdk_dif_update_crc32c_stream(&iov, 1, 0, 3072 + 4096 * 2 + 512, &crc32c1, &ctx);
2325 CU_ASSERT(rc == 0);
2326
2327 /* 3rd data segment */
2328 _iov_set_buf(&iov, buf + (4096 + 128) * 3 + 512, 3584 + 128);
2329 spdk_dif_ctx_set_data_offset(&ctx, 4096 * 3);
2330
2331 rc = spdk_dif_update_crc32c_stream(&iov, 1, 0, 3584, &crc32c1, &ctx);
2332 CU_ASSERT(rc == 0);
2333
2334 /* Update CRC32C for all data segments once */
2335 _iov_set_buf(&iov, buf, (4096 + 128) * 4);
2336 spdk_dif_ctx_set_data_offset(&ctx, 0);
2337
2338 rc = spdk_dif_update_crc32c(&iov, 1, 4, &crc32c2, &ctx);
2339 CU_ASSERT(rc == 0);
2340
2341 CU_ASSERT(crc32c1 == crc32c2);
2342
2343 free(buf);
2344}
2345
2346static void
2347get_range_with_md_test(void)
2348{
2349 struct spdk_dif_ctx ctx = {};
2350 uint32_t buf_offset, buf_len;
2351 int rc;
2352
2353 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, 0, 0, 0, 0, 0, 0, 0);
2354 CU_ASSERT(rc == 0);
2355
2356 spdk_dif_get_range_with_md(0, 2048, &buf_offset, &buf_len, &ctx);
2357 CU_ASSERT(buf_offset == 0);
2358 CU_ASSERT(buf_len == 2048);
2359
2360 spdk_dif_get_range_with_md(2048, 4096, &buf_offset, &buf_len, &ctx);
2361 CU_ASSERT(buf_offset == 2048);
2362 CU_ASSERT(buf_len == 4096 + 128);
2363
2364 spdk_dif_get_range_with_md(4096, 10240, &buf_offset, &buf_len, &ctx);
2365 CU_ASSERT(buf_offset == 4096 + 128);
2366 CU_ASSERT(buf_len == 10240 + 256);
2367
2368 spdk_dif_get_range_with_md(10240, 2048, &buf_offset, &buf_len, &ctx);
2369 CU_ASSERT(buf_offset == 10240 + 256);
2370 CU_ASSERT(buf_len == 2048 + 128);
2371
2372 buf_len = spdk_dif_get_length_with_md(6144, &ctx);
2373 CU_ASSERT(buf_len == 6144 + 128);
2374}
2375
2376static void
2377dif_generate_remap_and_verify(struct iovec *iovs, int iovcnt,
2378 uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
2379 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
2380 uint32_t init_ref_tag, uint32_t remapped_init_ref_tag,
2381 uint16_t apptag_mask, uint16_t app_tag)
2382{
2383 struct spdk_dif_ctx ctx = {};
2384 int rc;
2385
2386 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks);
2387 CU_ASSERT(rc == 0);
2388
2389 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags,
2390 init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED);
2391 CU_ASSERT(rc == 0);
2392
2393 rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx);
2394 CU_ASSERT(rc == 0);
2395
2396 spdk_dif_ctx_set_remapped_init_ref_tag(&ctx, remapped_init_ref_tag);
2397
2398 rc = spdk_dif_remap_ref_tag(iovs, iovcnt, num_blocks, &ctx, NULL);
2399 CU_ASSERT(rc == 0);
2400
2401 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags,
2402 remapped_init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED);
2403 CU_ASSERT(rc == 0);
2404
2405 rc = spdk_dif_verify(iovs, iovcnt, num_blocks, &ctx, NULL);
2406 CU_ASSERT(rc == 0);
2407
2408 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, md_size, num_blocks);
2409 CU_ASSERT(rc == 0);
2410}
2411
2412static void
2413dif_sec_4096_md_128_prchk_7_multi_iovs_remap_test(void)
2414{
2415 struct iovec iovs[4];
2416 int i, num_blocks;
2417 uint32_t dif_flags;
2418
2419 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2420 SPDK_DIF_FLAGS_REFTAG_CHECK;
2421
2422 num_blocks = 0;
2423
2424 for (i = 0; i < 4; i++) {
2425 _iov_alloc_buf(&iovs[i], (512 + 8) * (i + 1));
2426 num_blocks += i + 1;
2427 }
2428
2429 dif_generate_remap_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1,
2430 dif_flags, 22, 99, 0xFFFF, 0x22);
2431
2432 dif_generate_remap_and_verify(iovs, 4, 512 + 8, 8, num_blocks, true, SPDK_DIF_TYPE1,
2433 dif_flags, 22, 99, 0xFFFF, 0x22);
2434
2435 for (i = 0; i < 4; i++) {
2436 _iov_free_buf(&iovs[i]);
2437 }
2438}
2439
2440static void
2441dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_remap_test(void)
2442{
2443 struct iovec iovs[11];
2444 uint32_t dif_flags;
2445 int i;
2446
2447 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2448 SPDK_DIF_FLAGS_REFTAG_CHECK;
2449
2450 /* data[0][1000:0] */
2451 _iov_alloc_buf(&iovs[0], 1000);
2452
2453 /* data[0][3095:1000], guard[0][0] */
2454 _iov_alloc_buf(&iovs[1], 3096 + 1);
2455
2456 /* guard[0][1], apptag[0][0] */
2457 _iov_alloc_buf(&iovs[2], 1 + 1);
2458
2459 /* apptag[0][1], reftag[0][0] */
2460 _iov_alloc_buf(&iovs[3], 1 + 1);
2461
2462 /* reftag[0][3:1], ignore[0][59:0] */
2463 _iov_alloc_buf(&iovs[4], 3 + 60);
2464
2465 /* ignore[119:60], data[1][3050:0] */
2466 _iov_alloc_buf(&iovs[5], 60 + 3051);
2467
2468 /* data[1][4095:3050], guard[1][0] */
2469 _iov_alloc_buf(&iovs[6], 1045 + 1);
2470
2471 /* guard[1][1], apptag[1][0] */
2472 _iov_alloc_buf(&iovs[7], 1 + 1);
2473
2474 /* apptag[1][1], reftag[1][0] */
2475 _iov_alloc_buf(&iovs[8], 1 + 1);
2476
2477 /* reftag[1][3:1], ignore[1][9:0] */
2478 _iov_alloc_buf(&iovs[9], 3 + 10);
2479
2480 /* ignore[1][127:9] */
2481 _iov_alloc_buf(&iovs[10], 118);
2482
2483 dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, false, SPDK_DIF_TYPE1, dif_flags,
2484 22, 99, 0xFFFF, 0x22);
2485 dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, true, SPDK_DIF_TYPE1, dif_flags,
2486 22, 99, 0xFFFF, 0x22);
2487
2488 for (i = 0; i < 11; i++) {
2489 _iov_free_buf(&iovs[i]);
2490 }
2491}
2492
2493static void
2494dix_generate_remap_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov,
2495 uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
2496 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
2497 uint32_t init_ref_tag, uint32_t remapped_init_ref_tag,
2498 uint16_t apptag_mask, uint16_t app_tag)
2499{
2500 struct spdk_dif_ctx ctx;
2501 int rc;
2502
2503 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, 0, num_blocks);
2504 CU_ASSERT(rc == 0);
2505
2506 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags,
2507 init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED);
2508 CU_ASSERT(rc == 0);
2509
2510 rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx);
2511 CU_ASSERT(rc == 0);
2512
2513 spdk_dif_ctx_set_remapped_init_ref_tag(&ctx, remapped_init_ref_tag);
2514
2515 rc = spdk_dix_remap_ref_tag(md_iov, num_blocks, &ctx, NULL);
2516 CU_ASSERT(rc == 0);
2517
2518 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags,
2519 remapped_init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED);
2520 CU_ASSERT(rc == 0);
2521
2522 rc = spdk_dix_verify(iovs, iovcnt, md_iov, num_blocks, &ctx, NULL);
2523 CU_ASSERT(rc == 0);
2524
2525 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, 0, num_blocks);
2526 CU_ASSERT(rc == 0);
2527}
2528
2529static void
2530dix_sec_4096_md_128_prchk_7_multi_iovs_remap(void)
2531{
2532 struct iovec iovs[4], md_iov;
2533 uint32_t dif_flags;
2534 int i, num_blocks;
2535
2536 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2537 SPDK_DIF_FLAGS_REFTAG_CHECK;
2538
2539 num_blocks = 0;
2540
2541 for (i = 0; i < 4; i++) {
2542 _iov_alloc_buf(&iovs[i], 4096 * (i + 1));
2543 num_blocks += i + 1;
2544 }
2545 _iov_alloc_buf(&md_iov, 128 * num_blocks);
2546
2547 dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1,
2548 dif_flags, 22, 99, 0xFFFF, 0x22);
2549 dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1,
2550 dif_flags, 22, 99, 0xFFFF, 0x22);
2551
2552 for (i = 0; i < 4; i++) {
2553 _iov_free_buf(&iovs[i]);
2554 }
2555 _iov_free_buf(&md_iov);
2556}
2557
2558static void
2559dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits_remap(void)
2560{
2561 struct iovec iovs[6], md_iov;
2562 uint32_t dif_flags;
2563 int i;
2564
2565 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2566 SPDK_DIF_FLAGS_REFTAG_CHECK;
2567
2568 /* data[0][255:0] */
2569 _iov_alloc_buf(&iovs[0], 256);
2570
2571 /* data[0][511:256], data[1][255:0] */
2572 _iov_alloc_buf(&iovs[1], 256 + 256);
2573
2574 /* data[1][382:256] */
2575 _iov_alloc_buf(&iovs[2], 128);
2576
2577 /* data[1][383] */
2578 _iov_alloc_buf(&iovs[3], 1);
2579
2580 /* data[1][510:384] */
2581 _iov_alloc_buf(&iovs[4], 126);
2582
2583 /* data[1][511], data[2][511:0], data[3][511:0] */
2584 _iov_alloc_buf(&iovs[5], 1 + 512 * 2);
2585
2586 _iov_alloc_buf(&md_iov, 8 * 4);
2587
2588 dix_generate_remap_and_verify(iovs, 6, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1,
2589 dif_flags, 22, 99, 0xFFFF, 0x22);
2590
2591 for (i = 0; i < 6; i++) {
2592 _iov_free_buf(&iovs[i]);
2593 }
2594 _iov_free_buf(&md_iov);
2595}
2596
9f95a23c
TL
2597int
2598main(int argc, char **argv)
2599{
2600 CU_pSuite suite = NULL;
2601 unsigned int num_failures;
2602
f67539c2
TL
2603 CU_set_error_action(CUEA_ABORT);
2604 CU_initialize_registry();
9f95a23c
TL
2605
2606 suite = CU_add_suite("dif", NULL, NULL);
9f95a23c 2607
f67539c2
TL
2608 CU_ADD_TEST(suite, dif_generate_and_verify_test);
2609 CU_ADD_TEST(suite, dif_disable_check_test);
2610 CU_ADD_TEST(suite, dif_sec_512_md_0_error_test);
2611 CU_ADD_TEST(suite, dif_guard_seed_test);
2612 CU_ADD_TEST(suite, dif_disable_sec_512_md_8_single_iov_test);
2613 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_0_single_iov_test);
2614 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_0_1_2_4_multi_iovs_test);
2615 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_test);
2616 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_data_and_md_test);
2617 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_data_test);
2618 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_guard_test);
2619 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_apptag_test);
2620 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_reftag_test);
2621 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_complex_splits_test);
2622 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test);
2623 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test);
2624 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_and_md_test);
2625 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_test);
2626 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_guard_test);
2627 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_apptag_test);
2628 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_test);
2629 CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_0_single_iov);
2630 CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_0_1_2_4_multi_iovs);
2631 CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_7_multi_iovs);
2632 CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_7_multi_iovs_split_data);
2633 CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits);
2634 CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test);
2635 CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test);
2636 CU_ADD_TEST(suite, dix_sec_512_md_0_error);
2637 CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_0_single_iov);
2638 CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_0_1_2_4_multi_iovs);
2639 CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs);
2640 CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_7_multi_iovs_split_data);
2641 CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits);
2642 CU_ADD_TEST(suite, dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test);
2643 CU_ADD_TEST(suite, dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test);
2644 CU_ADD_TEST(suite, set_md_interleave_iovs_test);
2645 CU_ADD_TEST(suite, set_md_interleave_iovs_split_test);
2646 CU_ADD_TEST(suite, dif_generate_stream_test);
2647 CU_ADD_TEST(suite, set_md_interleave_iovs_alignment_test);
2648 CU_ADD_TEST(suite, _dif_generate_split_test);
2649 CU_ADD_TEST(suite, set_md_interleave_iovs_multi_segments_test);
2650 CU_ADD_TEST(suite, _dif_verify_split_test);
2651 CU_ADD_TEST(suite, dif_verify_stream_multi_segments_test);
2652 CU_ADD_TEST(suite, update_crc32c_test);
2653 CU_ADD_TEST(suite, _dif_update_crc32c_split_test);
2654 CU_ADD_TEST(suite, dif_update_crc32c_stream_multi_segments_test);
2655 CU_ADD_TEST(suite, get_range_with_md_test);
2656 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_remap_test);
2657 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_remap_test);
2658 CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs_remap);
2659 CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits_remap);
9f95a23c
TL
2660
2661 CU_basic_set_mode(CU_BRM_VERBOSE);
2662
2663 CU_basic_run_tests();
2664
2665 num_failures = CU_get_number_of_failures();
2666 CU_cleanup_registry();
2667
2668 return num_failures;
2669}