Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2019 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk/stdinc.h"
7 : :
8 : : #include "spdk_internal/cunit.h"
9 : :
10 : : #include "util/dif.c"
11 : :
12 : : #define DATA_PATTERN(offset) ((uint8_t)(0xAB + (offset)))
13 : : #define GUARD_SEED 0xCD
14 : :
15 : : static int
16 : 2598 : ut_data_pattern_generate(struct iovec *iovs, int iovcnt,
17 : : uint32_t block_size, uint32_t md_size, uint32_t num_blocks)
18 : : {
19 : 2165 : struct _dif_sgl sgl;
20 : 2165 : uint32_t offset_blocks, offset_in_block, buf_len, data_offset, i;
21 : 2165 : uint8_t *buf;
22 : :
23 : 2598 : _dif_sgl_init(&sgl, iovs, iovcnt);
24 : :
25 [ - + ]: 2598 : if (!_dif_sgl_is_valid(&sgl, block_size * num_blocks)) {
26 : 0 : return -1;
27 : : }
28 : :
29 : 2598 : offset_blocks = 0;
30 : 2598 : data_offset = 0;
31 : :
32 [ + + ]: 13806 : while (offset_blocks < num_blocks) {
33 : 11208 : offset_in_block = 0;
34 [ + + ]: 29544 : while (offset_in_block < block_size) {
35 : 18336 : _dif_sgl_get_buf(&sgl, (void *)&buf, &buf_len);
36 [ + + ]: 18336 : if (offset_in_block < block_size - md_size) {
37 : 12486 : buf_len = spdk_min(buf_len,
38 : : block_size - md_size - offset_in_block);
39 [ + + ]: 41705665 : for (i = 0; i < buf_len; i++) {
40 : 41693180 : buf[i] = DATA_PATTERN(data_offset + i);
41 : : }
42 : 12486 : data_offset += buf_len;
43 : : } else {
44 : 5850 : buf_len = spdk_min(buf_len, block_size - offset_in_block);
45 [ - + ]: 5850 : memset(buf, 0, buf_len);
46 : : }
47 : 18336 : _dif_sgl_advance(&sgl, buf_len);
48 : 18336 : offset_in_block += buf_len;
49 : : }
50 : 11208 : offset_blocks++;
51 : : }
52 : :
53 : 2598 : return 0;
54 : : }
55 : :
56 : : static int
57 : 1908 : ut_data_pattern_verify(struct iovec *iovs, int iovcnt,
58 : : uint32_t block_size, uint32_t md_size, uint32_t num_blocks)
59 : : {
60 : 1590 : struct _dif_sgl sgl;
61 : 1590 : uint32_t offset_blocks, offset_in_block, buf_len, data_offset, i;
62 : 1590 : uint8_t *buf;
63 : :
64 : 1908 : _dif_sgl_init(&sgl, iovs, iovcnt);
65 : :
66 [ - + ]: 1908 : if (!_dif_sgl_is_valid(&sgl, block_size * num_blocks)) {
67 : 0 : return -1;
68 : : }
69 : :
70 : 1908 : offset_blocks = 0;
71 : 1908 : data_offset = 0;
72 : :
73 [ + + ]: 8850 : while (offset_blocks < num_blocks) {
74 : 7158 : offset_in_block = 0;
75 [ + + ]: 19578 : while (offset_in_block < block_size) {
76 : 12636 : _dif_sgl_get_buf(&sgl, (void *)&buf, &buf_len);
77 : :
78 [ + + ]: 12636 : if (offset_in_block < block_size - md_size) {
79 : 7764 : buf_len = spdk_min(buf_len,
80 : : block_size - md_size - offset_in_block);
81 [ + + ]: 24968325 : for (i = 0; i < buf_len; i++) {
82 [ + + ]: 24960782 : if (buf[i] != DATA_PATTERN(data_offset + i)) {
83 : 216 : return -1;
84 : : }
85 : : }
86 : 7548 : data_offset += buf_len;
87 : : } else {
88 : 4872 : buf_len = spdk_min(buf_len, block_size - offset_in_block);
89 : : }
90 : 12420 : _dif_sgl_advance(&sgl, buf_len);
91 : 12420 : offset_in_block += buf_len;
92 : : }
93 : 6942 : offset_blocks++;
94 : : }
95 : :
96 : 1692 : return 0;
97 : : }
98 : :
99 : : static void
100 : 1842 : _iov_alloc_buf(struct iovec *iov, uint32_t len)
101 : : {
102 : 1842 : iov->iov_base = calloc(1, len);
103 : 1842 : iov->iov_len = len;
104 [ - + ]: 1842 : SPDK_CU_ASSERT_FATAL(iov->iov_base != NULL);
105 : 1842 : }
106 : :
107 : : static void
108 : 1842 : _iov_free_buf(struct iovec *iov)
109 : : {
110 : 1842 : free(iov->iov_base);
111 : 1842 : }
112 : :
113 : : static void
114 : 402 : _iov_set_buf(struct iovec *iov, uint8_t *buf, uint32_t buf_len)
115 : : {
116 : 402 : iov->iov_base = buf;
117 : 402 : iov->iov_len = buf_len;
118 : 402 : }
119 : :
120 : : static bool
121 : 642 : _iov_check(struct iovec *iov, void *iov_base, uint32_t iov_len)
122 : : {
123 [ + - + - ]: 642 : return (iov->iov_base == iov_base && iov->iov_len == iov_len);
124 : : }
125 : :
126 : : static uint64_t
127 : 198 : _generate_guard(uint64_t guard_seed, void *buf, size_t buf_len,
128 : : enum spdk_dif_pi_format dif_pi_format)
129 : : {
130 : : uint64_t guard;
131 : :
132 [ + + ]: 198 : if (dif_pi_format == SPDK_DIF_PI_FORMAT_16) {
133 : 66 : guard = (uint64_t)spdk_crc16_t10dif((uint16_t)guard_seed, buf, buf_len);
134 [ + + ]: 132 : } else if (dif_pi_format == SPDK_DIF_PI_FORMAT_32) {
135 : 66 : guard = (uint64_t)spdk_crc32c_nvme(buf, buf_len, guard_seed);
136 : : } else {
137 : 66 : guard = spdk_crc64_nvme(buf, buf_len, guard_seed);
138 : : }
139 : :
140 : 198 : return guard;
141 : : }
142 : :
143 : : static void
144 : 126 : _dif_generate_and_verify(struct iovec *iov,
145 : : uint32_t block_size, uint32_t md_size, bool dif_loc,
146 : : enum spdk_dif_type dif_type, uint32_t dif_flags,
147 : : enum spdk_dif_pi_format dif_pi_format,
148 : : uint64_t ref_tag, uint64_t e_ref_tag,
149 : : uint16_t app_tag, uint16_t apptag_mask, uint16_t e_app_tag,
150 : : bool expect_pass)
151 : : {
152 : 126 : struct spdk_dif_ctx ctx = {};
153 : : uint32_t guard_interval;
154 : 126 : uint64_t guard = 0;
155 : : int rc;
156 : :
157 : 126 : rc = ut_data_pattern_generate(iov, 1, block_size, md_size, 1);
158 : 126 : CU_ASSERT(rc == 0);
159 : :
160 : 126 : ctx.dif_pi_format = dif_pi_format;
161 : :
162 : 126 : guard_interval = _get_guard_interval(block_size, md_size, dif_loc, true,
163 : 126 : _dif_size(ctx.dif_pi_format));
164 : :
165 : 126 : ctx.dif_type = dif_type;
166 : 126 : ctx.dif_flags = dif_flags;
167 : 126 : ctx.init_ref_tag = ref_tag;
168 : 126 : ctx.app_tag = app_tag;
169 : :
170 [ + - ]: 126 : if (dif_flags & SPDK_DIF_FLAGS_GUARD_CHECK) {
171 : 126 : guard = _generate_guard(0, iov->iov_base, guard_interval, ctx.dif_pi_format);
172 : : }
173 : 126 : _dif_generate(iov->iov_base + guard_interval, guard, 0, &ctx);
174 : :
175 : 126 : ctx.init_ref_tag = e_ref_tag;
176 : 126 : ctx.apptag_mask = apptag_mask;
177 : 126 : ctx.app_tag = e_app_tag;
178 : :
179 : 126 : rc = _dif_verify(iov->iov_base + guard_interval, guard, 0, &ctx, NULL);
180 [ + + - + : 126 : CU_ASSERT((expect_pass && rc == 0) || (!expect_pass && rc != 0));
+ - + - ]
181 : :
182 : 126 : rc = ut_data_pattern_verify(iov, 1, block_size, md_size, 1);
183 : 126 : CU_ASSERT(rc == 0);
184 : 126 : }
185 : :
186 : : static void
187 : 6 : dif_generate_and_verify_test(void)
188 : : {
189 : 5 : struct iovec iov;
190 : : uint32_t dif_flags;
191 : :
192 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
193 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
194 : :
195 : 6 : _iov_alloc_buf(&iov, 4096 + 128);
196 : :
197 : : /* Positive cases */
198 : :
199 : : /* The case that DIF is contained in the first 8/16 bytes of metadata. */
200 : 6 : _dif_generate_and_verify(&iov,
201 : : 4096 + 128, 128, true,
202 : : SPDK_DIF_TYPE1, dif_flags,
203 : : SPDK_DIF_PI_FORMAT_16,
204 : : 22, 22,
205 : : 0x22, 0xFFFF, 0x22,
206 : : true);
207 : :
208 : 6 : _dif_generate_and_verify(&iov,
209 : : 4096 + 128, 128, true,
210 : : SPDK_DIF_TYPE1, dif_flags,
211 : : SPDK_DIF_PI_FORMAT_32,
212 : : 22, 22,
213 : : 0x22, 0xFFFF, 0x22,
214 : : true);
215 : :
216 : 6 : _dif_generate_and_verify(&iov,
217 : : 4096 + 128, 128, true,
218 : : SPDK_DIF_TYPE1, dif_flags,
219 : : SPDK_DIF_PI_FORMAT_64,
220 : : 22, 22,
221 : : 0x22, 0xFFFF, 0x22,
222 : : true);
223 : :
224 : : /* The case that DIF is contained in the last 8/16 bytes of metadata. */
225 : 6 : _dif_generate_and_verify(&iov,
226 : : 4096 + 128, 128, false,
227 : : SPDK_DIF_TYPE1, dif_flags,
228 : : SPDK_DIF_PI_FORMAT_16,
229 : : 22, 22,
230 : : 0x22, 0xFFFF, 0x22,
231 : : true);
232 : :
233 : 6 : _dif_generate_and_verify(&iov,
234 : : 4096 + 128, 128, false,
235 : : SPDK_DIF_TYPE1, dif_flags,
236 : : SPDK_DIF_PI_FORMAT_32,
237 : : 22, 22,
238 : : 0x22, 0xFFFF, 0x22,
239 : : true);
240 : :
241 : 6 : _dif_generate_and_verify(&iov,
242 : : 4096 + 128, 128, false,
243 : : SPDK_DIF_TYPE1, dif_flags,
244 : : SPDK_DIF_PI_FORMAT_64,
245 : : 22, 22,
246 : : 0x22, 0xFFFF, 0x22,
247 : : true);
248 : :
249 : : /* Negative cases */
250 : :
251 : : /* Reference tag doesn't match. */
252 : 6 : _dif_generate_and_verify(&iov,
253 : : 4096 + 128, 128, false,
254 : : SPDK_DIF_TYPE1, dif_flags,
255 : : SPDK_DIF_PI_FORMAT_16,
256 : : 22, 23,
257 : : 0x22, 0xFFFF, 0x22,
258 : : false);
259 : :
260 : 6 : _dif_generate_and_verify(&iov,
261 : : 4096 + 128, 128, false,
262 : : SPDK_DIF_TYPE1, dif_flags,
263 : : SPDK_DIF_PI_FORMAT_32,
264 : : 22, 23,
265 : : 0x22, 0xFFFF, 0x22,
266 : : false);
267 : :
268 : 6 : _dif_generate_and_verify(&iov,
269 : : 4096 + 128, 128, false,
270 : : SPDK_DIF_TYPE1, dif_flags,
271 : : SPDK_DIF_PI_FORMAT_64,
272 : : 22, 23,
273 : : 0x22, 0xFFFF, 0x22,
274 : : false);
275 : :
276 : : /* Application tag doesn't match. */
277 : 6 : _dif_generate_and_verify(&iov,
278 : : 4096 + 128, 128, false,
279 : : SPDK_DIF_TYPE1, dif_flags,
280 : : SPDK_DIF_PI_FORMAT_16,
281 : : 22, 22,
282 : : 0x22, 0xFFFF, 0x23,
283 : : false);
284 : :
285 : 6 : _dif_generate_and_verify(&iov,
286 : : 4096 + 128, 128, false,
287 : : SPDK_DIF_TYPE1, dif_flags,
288 : : SPDK_DIF_PI_FORMAT_32,
289 : : 22, 22,
290 : : 0x22, 0xFFFF, 0x23,
291 : : false);
292 : :
293 : 6 : _dif_generate_and_verify(&iov,
294 : : 4096 + 128, 128, false,
295 : : SPDK_DIF_TYPE1, dif_flags,
296 : : SPDK_DIF_PI_FORMAT_64,
297 : : 22, 22,
298 : : 0x22, 0xFFFF, 0x23,
299 : : false);
300 : :
301 : 6 : _iov_free_buf(&iov);
302 : 6 : }
303 : :
304 : : static void
305 : 6 : dif_disable_check_test(void)
306 : : {
307 : 5 : struct iovec iov;
308 : : uint32_t dif_flags;
309 : :
310 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
311 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
312 : :
313 : 6 : _iov_alloc_buf(&iov, 4096 + 128);
314 : :
315 : : /* The case that DIF check is disabled when the Application Tag is 0xFFFF for
316 : : * Type 1. DIF check is disabled and pass is expected.
317 : : */
318 : 6 : _dif_generate_and_verify(&iov,
319 : : 4096 + 128, 128, false,
320 : : SPDK_DIF_TYPE1, dif_flags,
321 : : SPDK_DIF_PI_FORMAT_16,
322 : : 22, 22,
323 : : 0xFFFF, 0xFFFF, 0x22,
324 : : true);
325 : :
326 : 6 : _dif_generate_and_verify(&iov,
327 : : 4096 + 128, 128, false,
328 : : SPDK_DIF_TYPE1, dif_flags,
329 : : SPDK_DIF_PI_FORMAT_32,
330 : : 22, 22,
331 : : 0xFFFF, 0xFFFF, 0x22,
332 : : true);
333 : :
334 : 6 : _dif_generate_and_verify(&iov,
335 : : 4096 + 128, 128, false,
336 : : SPDK_DIF_TYPE1, dif_flags,
337 : : SPDK_DIF_PI_FORMAT_64,
338 : : 22, 22,
339 : : 0xFFFF, 0xFFFF, 0x22,
340 : : true);
341 : :
342 : : /* The case that DIF check is not disabled when the Application Tag is 0xFFFF but
343 : : * the Reference Tag is not 0xFFFFFFFF for Type 3. DIF check is not disabled and
344 : : * fail is expected.
345 : : */
346 : 6 : _dif_generate_and_verify(&iov,
347 : : 4096 + 128, 128, false,
348 : : SPDK_DIF_TYPE3, dif_flags,
349 : : SPDK_DIF_PI_FORMAT_16,
350 : : 22, 22,
351 : : 0xFFFF, 0xFFFF, 0x22,
352 : : false);
353 : :
354 : 6 : _dif_generate_and_verify(&iov,
355 : : 4096 + 128, 128, false,
356 : : SPDK_DIF_TYPE3, dif_flags,
357 : : SPDK_DIF_PI_FORMAT_32,
358 : : 22, 22,
359 : : 0xFFFF, 0xFFFF, 0x22,
360 : : false);
361 : :
362 : 6 : _dif_generate_and_verify(&iov,
363 : : 4096 + 128, 128, false,
364 : : SPDK_DIF_TYPE3, dif_flags,
365 : : SPDK_DIF_PI_FORMAT_64,
366 : : 22, 22,
367 : : 0xFFFF, 0xFFFF, 0x22,
368 : : false);
369 : :
370 : : /* The case that DIF check is disabled when the Application Tag is 0xFFFF and
371 : : * the Reference Tag is 0xFFFFFFFF for Type 3. DIF check is disabled and
372 : : * pass is expected.
373 : : */
374 : 6 : _dif_generate_and_verify(&iov,
375 : : 4096 + 128, 128, false,
376 : : SPDK_DIF_TYPE3, dif_flags,
377 : : SPDK_DIF_PI_FORMAT_16,
378 : : 0xFFFFFFFF, 22,
379 : : 0xFFFF, 0xFFFF, 0x22,
380 : : true);
381 : :
382 : 6 : _dif_generate_and_verify(&iov,
383 : : 4096 + 128, 128, false,
384 : : SPDK_DIF_TYPE3, dif_flags,
385 : : SPDK_DIF_PI_FORMAT_32,
386 : : 0xFFFFFFFFFFFFFFFF, 22,
387 : : 0xFFFF, 0xFFFF, 0x22,
388 : : true);
389 : :
390 : 6 : _dif_generate_and_verify(&iov,
391 : : 4096 + 128, 128, false,
392 : : SPDK_DIF_TYPE3, dif_flags,
393 : : SPDK_DIF_PI_FORMAT_64,
394 : : 0xFFFFFFFFFFFFFFFF, 22,
395 : : 0xFFFF, 0xFFFF, 0x22,
396 : : true);
397 : :
398 : 6 : _iov_free_buf(&iov);
399 : 6 : }
400 : :
401 : : static void
402 : 66 : _dif_generate_and_verify_different_pi_format(uint32_t dif_flags,
403 : : enum spdk_dif_pi_format dif_pi_format_1, enum spdk_dif_pi_format dif_pi_format_2)
404 : : {
405 : 66 : struct spdk_dif_ctx ctx_1 = {}, ctx_2 = {};
406 : : int rc;
407 : 55 : struct spdk_dif_ctx_init_ext_opts dif_opts;
408 : 55 : struct iovec iov;
409 : 66 : struct spdk_dif_error err_blk = {};
410 : 66 : uint8_t expected_err_type = 0;
411 : :
412 [ + + ]: 66 : if (dif_flags & SPDK_DIF_FLAGS_GUARD_CHECK) {
413 : 24 : expected_err_type = SPDK_DIF_GUARD_ERROR;
414 [ + + ]: 42 : } else if (dif_flags & SPDK_DIF_FLAGS_APPTAG_CHECK) {
415 : 24 : expected_err_type = SPDK_DIF_APPTAG_ERROR;
416 [ + - ]: 18 : } else if (dif_flags & SPDK_DIF_FLAGS_REFTAG_CHECK) {
417 : 18 : expected_err_type = SPDK_DIF_REFTAG_ERROR;
418 : : } else {
419 : 0 : CU_ASSERT(false);
420 : : }
421 : :
422 : 66 : CU_ASSERT(dif_pi_format_1 != dif_pi_format_2);
423 : :
424 : 66 : _iov_alloc_buf(&iov, 4096 + 128);
425 : :
426 : 66 : rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1);
427 : 66 : CU_ASSERT(rc == 0);
428 : :
429 : 66 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
430 : 66 : dif_opts.dif_pi_format = dif_pi_format_1;
431 : 66 : rc = spdk_dif_ctx_init(&ctx_1, 4096 + 128, 128, true, true, SPDK_DIF_TYPE1, dif_flags,
432 : : 12, 0xFFFF, 23, 0, 0, &dif_opts);
433 : 66 : CU_ASSERT(rc == 0);
434 : :
435 : 66 : rc = spdk_dif_generate(&iov, 1, 1, &ctx_1);
436 : 66 : CU_ASSERT(rc == 0);
437 : :
438 : 66 : dif_opts.dif_pi_format = dif_pi_format_2;
439 : 66 : rc = spdk_dif_ctx_init(&ctx_2, 4096 + 128, 128, true, true, SPDK_DIF_TYPE1, dif_flags,
440 : : 12, 0xFFFF, 23, 0, 0, &dif_opts);
441 : 66 : CU_ASSERT(rc == 0);
442 : :
443 : 66 : rc = spdk_dif_verify(&iov, 1, 1, &ctx_2, &err_blk);
444 : 66 : CU_ASSERT(rc != 0);
445 : 66 : CU_ASSERT(err_blk.err_type == expected_err_type);
446 : :
447 : 66 : rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 1);
448 : 66 : CU_ASSERT(rc == 0);
449 : :
450 : 66 : _iov_free_buf(&iov);
451 : 66 : }
452 : :
453 : : static void
454 : 6 : dif_generate_and_verify_different_pi_formats_test(void)
455 : : {
456 : 6 : _dif_generate_and_verify_different_pi_format(SPDK_DIF_FLAGS_GUARD_CHECK,
457 : : SPDK_DIF_PI_FORMAT_16, SPDK_DIF_PI_FORMAT_32);
458 : 6 : _dif_generate_and_verify_different_pi_format(SPDK_DIF_FLAGS_GUARD_CHECK,
459 : : SPDK_DIF_PI_FORMAT_32, SPDK_DIF_PI_FORMAT_16);
460 : 6 : _dif_generate_and_verify_different_pi_format(SPDK_DIF_FLAGS_GUARD_CHECK,
461 : : SPDK_DIF_PI_FORMAT_16, SPDK_DIF_PI_FORMAT_64);
462 : 6 : _dif_generate_and_verify_different_pi_format(SPDK_DIF_FLAGS_GUARD_CHECK,
463 : : SPDK_DIF_PI_FORMAT_32, SPDK_DIF_PI_FORMAT_64);
464 : :
465 : 6 : _dif_generate_and_verify_different_pi_format(SPDK_DIF_FLAGS_APPTAG_CHECK,
466 : : SPDK_DIF_PI_FORMAT_16, SPDK_DIF_PI_FORMAT_32);
467 : 6 : _dif_generate_and_verify_different_pi_format(SPDK_DIF_FLAGS_APPTAG_CHECK,
468 : : SPDK_DIF_PI_FORMAT_32, SPDK_DIF_PI_FORMAT_16);
469 : 6 : _dif_generate_and_verify_different_pi_format(SPDK_DIF_FLAGS_APPTAG_CHECK,
470 : : SPDK_DIF_PI_FORMAT_16, SPDK_DIF_PI_FORMAT_64);
471 : 6 : _dif_generate_and_verify_different_pi_format(SPDK_DIF_FLAGS_APPTAG_CHECK,
472 : : SPDK_DIF_PI_FORMAT_32, SPDK_DIF_PI_FORMAT_64);
473 : :
474 : 6 : _dif_generate_and_verify_different_pi_format(SPDK_DIF_FLAGS_REFTAG_CHECK,
475 : : SPDK_DIF_PI_FORMAT_16, SPDK_DIF_PI_FORMAT_32);
476 : 6 : _dif_generate_and_verify_different_pi_format(SPDK_DIF_FLAGS_REFTAG_CHECK,
477 : : SPDK_DIF_PI_FORMAT_32, SPDK_DIF_PI_FORMAT_16);
478 : 6 : _dif_generate_and_verify_different_pi_format(SPDK_DIF_FLAGS_REFTAG_CHECK,
479 : : SPDK_DIF_PI_FORMAT_16, SPDK_DIF_PI_FORMAT_64);
480 : : /* The ref tag in 32 and 64 PI formats will partially overlap, so skip the last test */
481 : 6 : }
482 : :
483 : : static void
484 : 12 : _dif_apptag_mask_test(enum spdk_dif_pi_format dif_pi_format)
485 : : {
486 : 12 : struct spdk_dif_ctx ctx = {};
487 : : int rc;
488 : 10 : struct spdk_dif_ctx_init_ext_opts dif_opts;
489 : 10 : struct iovec iov;
490 : 12 : struct spdk_dif_error err_blk = {};
491 : : uint32_t dif_flags;
492 : :
493 : 12 : dif_flags = SPDK_DIF_FLAGS_APPTAG_CHECK;
494 : :
495 : 12 : _iov_alloc_buf(&iov, 4096 + 128);
496 : :
497 : 12 : rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1);
498 : 12 : CU_ASSERT(rc == 0);
499 : :
500 : 12 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
501 : 12 : dif_opts.dif_pi_format = dif_pi_format;
502 : 12 : rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, true, SPDK_DIF_TYPE1, dif_flags,
503 : : 0, 0xFFFF, 0x1234, 0, 0, &dif_opts);
504 : 12 : CU_ASSERT(rc == 0);
505 : :
506 : 12 : rc = spdk_dif_generate(&iov, 1, 1, &ctx);
507 : 12 : CU_ASSERT(rc == 0);
508 : :
509 : 12 : rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, true, SPDK_DIF_TYPE1, dif_flags,
510 : : 12, 0xFFFF, 0x1256, 0, 0, &dif_opts);
511 : 12 : CU_ASSERT(rc == 0);
512 : :
513 : 12 : rc = spdk_dif_verify(&iov, 1, 1, &ctx, &err_blk);
514 : 12 : CU_ASSERT(rc != 0);
515 : 12 : CU_ASSERT(err_blk.err_type == SPDK_DIF_APPTAG_ERROR);
516 : :
517 : 12 : rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, true, SPDK_DIF_TYPE1, dif_flags,
518 : : 12, 0xFF00, 0x1256, 0, 0, &dif_opts);
519 : 12 : CU_ASSERT(rc == 0);
520 : :
521 : 12 : rc = spdk_dif_verify(&iov, 1, 1, &ctx, &err_blk);
522 : 12 : CU_ASSERT(rc == 0);
523 : :
524 : 12 : rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 1);
525 : 12 : CU_ASSERT(rc == 0);
526 : :
527 : 12 : _iov_free_buf(&iov);
528 : 12 : }
529 : :
530 : : static void
531 : 6 : dif_apptag_mask_test(void)
532 : : {
533 : 6 : _dif_apptag_mask_test(SPDK_DIF_PI_FORMAT_16);
534 : 6 : _dif_apptag_mask_test(SPDK_DIF_PI_FORMAT_32);
535 : 6 : }
536 : :
537 : : static void
538 : 6 : dif_sec_512_md_0_error_test(void)
539 : : {
540 : 6 : struct spdk_dif_ctx ctx = {};
541 : : int rc;
542 : 5 : struct spdk_dif_ctx_init_ext_opts dif_opts;
543 : :
544 : 6 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
545 : 6 : dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
546 : : /* Metadata size is 0. */
547 : 6 : rc = spdk_dif_ctx_init(&ctx, 512, 0, true, false, SPDK_DIF_TYPE1, 0,
548 : : 0, 0, 0, 0, 0, &dif_opts);
549 : 6 : CU_ASSERT(rc != 0);
550 : 6 : }
551 : :
552 : : static void
553 : 12 : _dif_sec_4096_md_0_error_test(enum spdk_dif_pi_format dif_pi_format)
554 : : {
555 : 12 : struct spdk_dif_ctx ctx = {};
556 : : int rc;
557 : 10 : struct spdk_dif_ctx_init_ext_opts dif_opts;
558 : :
559 : 12 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
560 : 12 : dif_opts.dif_pi_format = dif_pi_format;
561 : : /* Metadata size is 0. */
562 : 12 : rc = spdk_dif_ctx_init(&ctx, 4096, 0, true, false, SPDK_DIF_TYPE1, 0,
563 : : 0, 0, 0, 0, 0, &dif_opts);
564 : 12 : CU_ASSERT(rc != 0);
565 : 12 : }
566 : :
567 : : static void
568 : 6 : dif_sec_4096_md_0_error_test(void)
569 : : {
570 : 6 : _dif_sec_4096_md_0_error_test(SPDK_DIF_PI_FORMAT_32);
571 : 6 : _dif_sec_4096_md_0_error_test(SPDK_DIF_PI_FORMAT_64);
572 : 6 : }
573 : :
574 : : static void
575 : 12 : _dif_sec_4100_md_128_error_test(enum spdk_dif_pi_format dif_pi_format)
576 : : {
577 : 12 : struct spdk_dif_ctx ctx = {};
578 : : int rc;
579 : 10 : struct spdk_dif_ctx_init_ext_opts dif_opts;
580 : :
581 : 12 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
582 : 12 : dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_32;
583 : : /* Block size is not multiple of 4kB, MD interleave = false */
584 : 12 : rc = spdk_dif_ctx_init(&ctx, 4100, 128, false, false, SPDK_DIF_TYPE1, 0,
585 : : 0, 0, 0, 0, 0, &dif_opts);
586 : 12 : CU_ASSERT(rc != 0);
587 : 12 : }
588 : :
589 : : static void
590 : 6 : dif_sec_4100_md_128_error_test(void)
591 : : {
592 : 6 : _dif_sec_4100_md_128_error_test(SPDK_DIF_PI_FORMAT_32);
593 : 6 : _dif_sec_4100_md_128_error_test(SPDK_DIF_PI_FORMAT_64);
594 : 6 : }
595 : :
596 : : static void
597 : 6 : _dif_guard_seed_test(uint32_t block_size, uint32_t md_size,
598 : : enum spdk_dif_pi_format dif_pi_format)
599 : : {
600 : 5 : struct iovec iov;
601 : 6 : struct spdk_dif_ctx ctx = {};
602 : 6 : struct spdk_dif_error err_blk = {};
603 : : struct spdk_dif *dif;
604 : : uint64_t guard;
605 : : int rc;
606 : 5 : struct spdk_dif_ctx_init_ext_opts dif_opts;
607 : :
608 : 6 : _iov_alloc_buf(&iov, block_size);
609 : :
610 [ - + ]: 6 : memset(iov.iov_base, 0, block_size);
611 : :
612 : 6 : dif = (struct spdk_dif *)(iov.iov_base + (block_size - md_size));
613 : :
614 : 6 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
615 : 6 : dif_opts.dif_pi_format = dif_pi_format;
616 : 6 : rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, true, SPDK_DIF_TYPE1,
617 : : SPDK_DIF_FLAGS_GUARD_CHECK,
618 : : 0, 0, 0, 0, 0, &dif_opts);
619 : 6 : CU_ASSERT(rc == 0);
620 : :
621 : 6 : rc = spdk_dif_generate(&iov, 1, 1, &ctx);
622 : 6 : CU_ASSERT(rc == 0);
623 : :
624 : : /* Guard should be zero if the block is all zero and seed is not added. */
625 : 6 : guard = _dif_get_guard(dif, ctx.dif_pi_format);
626 : 6 : CU_ASSERT(guard == 0);
627 : :
628 : 6 : rc = spdk_dif_verify(&iov, 1, 1, &ctx, &err_blk);
629 : 6 : CU_ASSERT(rc == 0);
630 : :
631 : 6 : rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, true, SPDK_DIF_TYPE1,
632 : : SPDK_DIF_FLAGS_GUARD_CHECK,
633 : : 0, 0, 0, 0, GUARD_SEED, &dif_opts);
634 : 6 : CU_ASSERT(rc == 0);
635 : :
636 : 6 : rc = spdk_dif_generate(&iov, 1, 1, &ctx);
637 : 6 : CU_ASSERT(rc == 0);
638 : :
639 : : /* Guard should not be zero if the block is all zero but seed is added. */
640 : 6 : guard = _dif_get_guard(dif, ctx.dif_pi_format);
641 : 6 : CU_ASSERT(guard != 0);
642 : :
643 : 6 : rc = spdk_dif_verify(&iov, 1, 1, &ctx, &err_blk);
644 : 6 : CU_ASSERT(rc == 0);
645 : :
646 : 6 : _iov_free_buf(&iov);
647 : 6 : }
648 : :
649 : : static void
650 : 6 : dif_guard_seed_test(void)
651 : : {
652 : 6 : _dif_guard_seed_test(512 + 8, 8, SPDK_DIF_PI_FORMAT_16);
653 : 6 : }
654 : :
655 : : static void
656 : 48 : _dif_guard_value_test(uint32_t block_size, uint32_t md_size,
657 : : enum spdk_dif_pi_format dif_pi_format, struct iovec *iov_input_data,
658 : : uint64_t expected_guard)
659 : : {
660 : 48 : struct spdk_dif_ctx ctx = {};
661 : 48 : struct spdk_dif_error err_blk = {};
662 : 40 : struct spdk_dif_ctx_init_ext_opts dif_opts;
663 : : struct spdk_dif *dif;
664 : : int rc;
665 : : uint64_t guard;
666 : :
667 : 48 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
668 : 48 : dif_opts.dif_pi_format = dif_pi_format;
669 : 48 : rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, true, SPDK_DIF_TYPE1,
670 : : SPDK_DIF_FLAGS_GUARD_CHECK,
671 : : 0, 0, 0, 0, 0, &dif_opts);
672 : 48 : CU_ASSERT(rc == 0);
673 : :
674 : 48 : dif = (struct spdk_dif *)(iov_input_data->iov_base + (block_size - md_size));
675 : :
676 : 48 : rc = spdk_dif_generate(iov_input_data, 1, 1, &ctx);
677 : 48 : CU_ASSERT(rc == 0);
678 : :
679 : 48 : guard = _dif_get_guard(dif, ctx.dif_pi_format);
680 : 48 : CU_ASSERT(guard == expected_guard);
681 : :
682 : 48 : rc = spdk_dif_verify(iov_input_data, 1, 1, &ctx, &err_blk);
683 : 48 : CU_ASSERT(rc == 0);
684 : 48 : }
685 : :
686 : : static void
687 : 6 : dif_guard_value_test(void)
688 : : {
689 : 5 : struct iovec iov;
690 : : unsigned int i, j;
691 : 6 : uint32_t block_size = 4096 + 128;
692 : 6 : uint32_t md_size = 128;
693 : :
694 : 6 : _iov_alloc_buf(&iov, block_size);
695 : :
696 : : /* All the expected CRC guard values are compliant with
697 : : * the NVM Command Set Specification 1.0c */
698 : :
699 : : /* Input buffer = 0s */
700 [ - + ]: 6 : memset(iov.iov_base, 0, block_size);
701 : 6 : _dif_guard_value_test(block_size, md_size, SPDK_DIF_PI_FORMAT_32, &iov, 0x98F94189);
702 : 6 : _dif_guard_value_test(block_size, md_size, SPDK_DIF_PI_FORMAT_64, &iov, 0x6482D367EB22B64E);
703 : :
704 : : /* Input buffer = 1s */
705 [ - + ]: 6 : memset(iov.iov_base, 0xFF, block_size);
706 : 6 : _dif_guard_value_test(block_size, md_size, SPDK_DIF_PI_FORMAT_32, &iov, 0x25C1FE13);
707 : 6 : _dif_guard_value_test(block_size, md_size, SPDK_DIF_PI_FORMAT_64, &iov, 0xC0DDBA7302ECA3AC);
708 : :
709 : : /* Input buffer = 0x00, 0x01, 0x02, ... */
710 [ - + ]: 6 : memset(iov.iov_base, 0, block_size);
711 : 6 : j = 0;
712 [ + + ]: 24582 : for (i = 0; i < block_size - md_size; i++) {
713 : 24576 : *((uint8_t *)(iov.iov_base) + i) = j;
714 [ + + ]: 24576 : if (j == 0xFF) {
715 : 96 : j = 0;
716 : : } else {
717 : 24480 : j++;
718 : : }
719 : : }
720 : 6 : _dif_guard_value_test(block_size, md_size, SPDK_DIF_PI_FORMAT_32, &iov, 0x9C71FE32);
721 : 6 : _dif_guard_value_test(block_size, md_size, SPDK_DIF_PI_FORMAT_64, &iov, 0x3E729F5F6750449C);
722 : :
723 : : /* Input buffer = 0xFF, 0xFE, 0xFD, ... */
724 [ - + ]: 6 : memset(iov.iov_base, 0, block_size);
725 : 6 : j = 0xFF;
726 [ + + ]: 24582 : for (i = 0; i < block_size - md_size ; i++) {
727 : 24576 : *((uint8_t *)(iov.iov_base) + i) = j;
728 [ + + ]: 24576 : if (j == 0) {
729 : 96 : j = 0xFF;
730 : : } else {
731 : 24480 : j--;
732 : : }
733 : : }
734 : 6 : _dif_guard_value_test(block_size, md_size, SPDK_DIF_PI_FORMAT_32, &iov, 0x214941A8);
735 : 6 : _dif_guard_value_test(block_size, md_size, SPDK_DIF_PI_FORMAT_64, &iov, 0x9A2DF64B8E9E517E);
736 : :
737 : :
738 : 6 : _iov_free_buf(&iov);
739 : 6 : }
740 : :
741 : : static void
742 : 264 : dif_generate_and_verify(struct iovec *iovs, int iovcnt,
743 : : uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
744 : : bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
745 : : enum spdk_dif_pi_format dif_pi_format,
746 : : uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag)
747 : : {
748 : 264 : struct spdk_dif_ctx ctx = {};
749 : : int rc;
750 : 220 : struct spdk_dif_ctx_init_ext_opts dif_opts;
751 : :
752 : 264 : rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks);
753 : 264 : CU_ASSERT(rc == 0);
754 : :
755 : 264 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
756 : 264 : dif_opts.dif_pi_format = dif_pi_format;
757 : 264 : rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags,
758 : : init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED, &dif_opts);
759 : 264 : CU_ASSERT(rc == 0);
760 : :
761 : 264 : rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx);
762 : 264 : CU_ASSERT(rc == 0);
763 : :
764 : 264 : rc = spdk_dif_verify(iovs, iovcnt, num_blocks, &ctx, NULL);
765 : 264 : CU_ASSERT(rc == 0);
766 : :
767 : 264 : rc = ut_data_pattern_verify(iovs, iovcnt, block_size, md_size, num_blocks);
768 : 264 : CU_ASSERT(rc == 0);
769 : 264 : }
770 : :
771 : : static void
772 : 6 : dif_disable_sec_512_md_8_single_iov_test(void)
773 : : {
774 : 5 : struct iovec iov;
775 : :
776 : 6 : _iov_alloc_buf(&iov, 512 + 8);
777 : :
778 : 6 : dif_generate_and_verify(&iov, 1, 512 + 8, 8, 1, false, SPDK_DIF_DISABLE, 0,
779 : : SPDK_DIF_PI_FORMAT_16, 0, 0, 0);
780 : :
781 : 6 : _iov_free_buf(&iov);
782 : 6 : }
783 : :
784 : : static void
785 : 6 : dif_sec_512_md_8_prchk_0_single_iov_test(void)
786 : : {
787 : 5 : struct iovec iov;
788 : :
789 : 6 : _iov_alloc_buf(&iov, 512 + 8);
790 : :
791 : 6 : dif_generate_and_verify(&iov, 1, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1, 0,
792 : : SPDK_DIF_PI_FORMAT_16, 0, 0, 0);
793 : :
794 : 6 : _iov_free_buf(&iov);
795 : 6 : }
796 : :
797 : : static void
798 : 6 : dif_sec_4096_md_128_prchk_0_single_iov_test(void)
799 : : {
800 : 5 : struct iovec iov;
801 : :
802 : 6 : _iov_alloc_buf(&iov, 4096 + 128);
803 : :
804 : 6 : dif_generate_and_verify(&iov, 1, 4096 + 128, 128, 1, false, SPDK_DIF_TYPE1, 0,
805 : : SPDK_DIF_PI_FORMAT_32, 0, 0, 0);
806 : 6 : dif_generate_and_verify(&iov, 1, 4096 + 128, 128, 1, false, SPDK_DIF_TYPE1, 0,
807 : : SPDK_DIF_PI_FORMAT_64, 0, 0, 0);
808 : :
809 : 6 : _iov_free_buf(&iov);
810 : 6 : }
811 : :
812 : : static void
813 : 6 : dif_sec_512_md_8_prchk_0_1_2_4_multi_iovs_test(void)
814 : : {
815 : 5 : struct iovec iovs[4];
816 : : int i, num_blocks;
817 : :
818 : 6 : num_blocks = 0;
819 : :
820 [ + + ]: 30 : for (i = 0; i < 4; i++) {
821 : 24 : _iov_alloc_buf(&iovs[i], (512 + 8) * (i + 1));
822 : 24 : num_blocks += i + 1;
823 : : }
824 : :
825 : 6 : dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1,
826 : : 0, SPDK_DIF_PI_FORMAT_16, 22, 0xFFFF, 0x22);
827 : :
828 : 6 : dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1,
829 : : SPDK_DIF_FLAGS_GUARD_CHECK, SPDK_DIF_PI_FORMAT_16, 22, 0xFFFF, 0x22);
830 : :
831 : 6 : dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1,
832 : : SPDK_DIF_FLAGS_APPTAG_CHECK, SPDK_DIF_PI_FORMAT_16, 22, 0xFFFF, 0x22);
833 : :
834 : 6 : dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1,
835 : : SPDK_DIF_FLAGS_REFTAG_CHECK, SPDK_DIF_PI_FORMAT_16, 22, 0xFFFF, 0x22);
836 : :
837 [ + + ]: 30 : for (i = 0; i < 4; i++) {
838 : 24 : _iov_free_buf(&iovs[i]);
839 : : }
840 : 6 : }
841 : :
842 : : static void
843 : 12 : _dif_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(enum spdk_dif_pi_format dif_pi_format)
844 : : {
845 : 10 : struct iovec iovs[4];
846 : : int i, num_blocks;
847 : :
848 : 12 : num_blocks = 0;
849 : :
850 [ + + ]: 60 : for (i = 0; i < 4; i++) {
851 : 48 : _iov_alloc_buf(&iovs[i], (4096 + 128) * (i + 1));
852 : 48 : num_blocks += i + 1;
853 : : }
854 : :
855 : 12 : dif_generate_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, false, SPDK_DIF_TYPE1,
856 : : 0, dif_pi_format, 22, 0xFFFF, 0x22);
857 : :
858 : 12 : dif_generate_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, false, SPDK_DIF_TYPE1,
859 : : SPDK_DIF_FLAGS_GUARD_CHECK, dif_pi_format, 22, 0xFFFF, 0x22);
860 : :
861 : 12 : dif_generate_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, false, SPDK_DIF_TYPE1,
862 : : SPDK_DIF_FLAGS_APPTAG_CHECK, dif_pi_format, 22, 0xFFFF, 0x22);
863 : :
864 : 12 : dif_generate_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, false, SPDK_DIF_TYPE1,
865 : : SPDK_DIF_FLAGS_REFTAG_CHECK, dif_pi_format, 22, 0xFFFF, 0x22);
866 : :
867 [ + + ]: 60 : for (i = 0; i < 4; i++) {
868 : 48 : _iov_free_buf(&iovs[i]);
869 : : }
870 : 12 : }
871 : :
872 : : static void
873 : 6 : dif_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(void)
874 : : {
875 : 6 : _dif_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(SPDK_DIF_PI_FORMAT_32);
876 : 6 : _dif_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(SPDK_DIF_PI_FORMAT_64);
877 : 6 : }
878 : :
879 : : static void
880 : 18 : _dif_sec_4096_md_128_prchk_7_multi_iovs_test(enum spdk_dif_pi_format dif_pi_format)
881 : : {
882 : 15 : struct iovec iovs[4];
883 : : int i, num_blocks;
884 : : uint32_t dif_flags;
885 : :
886 : 18 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
887 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
888 : :
889 : 18 : num_blocks = 0;
890 : :
891 [ + + ]: 90 : for (i = 0; i < 4; i++) {
892 : 72 : _iov_alloc_buf(&iovs[i], (4096 + 128) * (i + 1));
893 : 72 : num_blocks += i + 1;
894 : : }
895 : :
896 : 18 : dif_generate_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, false, SPDK_DIF_TYPE1,
897 : : dif_flags, dif_pi_format, 22, 0xFFFF, 0x22);
898 : :
899 : 18 : dif_generate_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, true, SPDK_DIF_TYPE1,
900 : : dif_flags, dif_pi_format, 22, 0xFFFF, 0x22);
901 : :
902 [ + + ]: 90 : for (i = 0; i < 4; i++) {
903 : 72 : _iov_free_buf(&iovs[i]);
904 : : }
905 : 18 : }
906 : :
907 : : static void
908 : 6 : dif_sec_4096_md_128_prchk_7_multi_iovs_test(void)
909 : : {
910 : 6 : _dif_sec_4096_md_128_prchk_7_multi_iovs_test(SPDK_DIF_PI_FORMAT_16);
911 : 6 : _dif_sec_4096_md_128_prchk_7_multi_iovs_test(SPDK_DIF_PI_FORMAT_32);
912 : 6 : _dif_sec_4096_md_128_prchk_7_multi_iovs_test(SPDK_DIF_PI_FORMAT_64);
913 : 6 : }
914 : :
915 : : static void
916 : 6 : dif_sec_512_md_8_prchk_7_multi_iovs_split_data_and_md_test(void)
917 : : {
918 : 5 : struct iovec iovs[2];
919 : : uint32_t dif_flags;
920 : :
921 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
922 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
923 : :
924 : 6 : _iov_alloc_buf(&iovs[0], 512);
925 : 6 : _iov_alloc_buf(&iovs[1], 8);
926 : :
927 : 6 : dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1,
928 : : dif_flags, SPDK_DIF_PI_FORMAT_16, 22, 0xFFFF, 0x22);
929 : :
930 : 6 : _iov_free_buf(&iovs[0]);
931 : 6 : _iov_free_buf(&iovs[1]);
932 : 6 : }
933 : :
934 : : static void
935 : 6 : dif_sec_4096_md_128_prchk_7_multi_iovs_split_data_and_md_test(void)
936 : : {
937 : 5 : struct iovec iovs[2];
938 : : uint32_t dif_flags;
939 : :
940 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
941 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
942 : :
943 : 6 : _iov_alloc_buf(&iovs[0], 4096);
944 : 6 : _iov_alloc_buf(&iovs[1], 128);
945 : :
946 : 6 : dif_generate_and_verify(iovs, 2, 4096 + 128, 128, 1, false, SPDK_DIF_TYPE1,
947 : : dif_flags, SPDK_DIF_PI_FORMAT_32, 22, 0xFFFF, 0x22);
948 : 6 : dif_generate_and_verify(iovs, 2, 4096 + 128, 128, 1, false, SPDK_DIF_TYPE1,
949 : : dif_flags, SPDK_DIF_PI_FORMAT_64, 22, 0xFFFF, 0x22);
950 : :
951 : 6 : _iov_free_buf(&iovs[0]);
952 : 6 : _iov_free_buf(&iovs[1]);
953 : 6 : }
954 : :
955 : : static void
956 : 6 : dif_sec_512_md_8_prchk_7_multi_iovs_split_data_test(void)
957 : : {
958 : 5 : struct iovec iovs[2];
959 : : uint32_t dif_flags;
960 : :
961 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
962 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
963 : :
964 : 6 : _iov_alloc_buf(&iovs[0], 256);
965 : 6 : _iov_alloc_buf(&iovs[1], 264);
966 : :
967 : 6 : dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1,
968 : : dif_flags, SPDK_DIF_PI_FORMAT_16, 22, 0xFFFF, 0x22);
969 : :
970 : 6 : _iov_free_buf(&iovs[0]);
971 : 6 : _iov_free_buf(&iovs[1]);
972 : 6 : }
973 : :
974 : : static void
975 : 6 : dif_sec_4096_md_128_prchk_7_multi_iovs_split_data_test(void)
976 : : {
977 : 5 : struct iovec iovs[2];
978 : : uint32_t dif_flags;
979 : :
980 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
981 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
982 : :
983 : 6 : _iov_alloc_buf(&iovs[0], 2048);
984 : 6 : _iov_alloc_buf(&iovs[1], 2176);
985 : :
986 : 6 : dif_generate_and_verify(iovs, 2, 4096 + 128, 128, 1, false, SPDK_DIF_TYPE1,
987 : : dif_flags, SPDK_DIF_PI_FORMAT_32, 22, 0xFFFF, 0x22);
988 : 6 : dif_generate_and_verify(iovs, 2, 4096 + 128, 128, 1, false, SPDK_DIF_TYPE1,
989 : : dif_flags, SPDK_DIF_PI_FORMAT_64, 22, 0xFFFF, 0x22);
990 : :
991 : 6 : _iov_free_buf(&iovs[0]);
992 : 6 : _iov_free_buf(&iovs[1]);
993 : 6 : }
994 : :
995 : : static void
996 : 6 : dif_sec_512_md_8_prchk_7_multi_iovs_split_guard_test(void)
997 : : {
998 : 5 : struct iovec iovs[2];
999 : : uint32_t dif_flags;
1000 : :
1001 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1002 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
1003 : :
1004 : 6 : _iov_alloc_buf(&iovs[0], 513);
1005 : 6 : _iov_alloc_buf(&iovs[1], 7);
1006 : :
1007 : 6 : dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1,
1008 : : dif_flags, SPDK_DIF_PI_FORMAT_16, 22, 0xFFFF, 0x22);
1009 : :
1010 : 6 : _iov_free_buf(&iovs[0]);
1011 : 6 : _iov_free_buf(&iovs[1]);
1012 : 6 : }
1013 : :
1014 : : static void
1015 : 6 : dif_sec_4096_md_128_prchk_7_multi_iovs_split_guard_test(void)
1016 : : {
1017 : 5 : struct iovec iovs[2];
1018 : : uint32_t dif_flags;
1019 : :
1020 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1021 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
1022 : :
1023 : 6 : _iov_alloc_buf(&iovs[0], 4097);
1024 : 6 : _iov_alloc_buf(&iovs[1], 127);
1025 : :
1026 : 6 : dif_generate_and_verify(iovs, 2, 4096 + 128, 128, 1, false, SPDK_DIF_TYPE1,
1027 : : dif_flags, SPDK_DIF_PI_FORMAT_32, 22, 0xFFFF, 0x22);
1028 : 6 : dif_generate_and_verify(iovs, 2, 4096 + 128, 128, 1, false, SPDK_DIF_TYPE1,
1029 : : dif_flags, SPDK_DIF_PI_FORMAT_64, 22, 0xFFFF, 0x22);
1030 : :
1031 : 6 : _iov_free_buf(&iovs[0]);
1032 : 6 : _iov_free_buf(&iovs[1]);
1033 : 6 : }
1034 : :
1035 : : static void
1036 : 6 : dif_sec_512_md_8_prchk_7_multi_iovs_split_apptag_test(void)
1037 : : {
1038 : 5 : struct iovec iovs[2];
1039 : : uint32_t dif_flags;
1040 : :
1041 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1042 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
1043 : :
1044 : 6 : _iov_alloc_buf(&iovs[0], 515);
1045 : 6 : _iov_alloc_buf(&iovs[1], 5);
1046 : :
1047 : 6 : dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1,
1048 : : dif_flags, SPDK_DIF_PI_FORMAT_16, 22, 0xFFFF, 0x22);
1049 : :
1050 : 6 : _iov_free_buf(&iovs[0]);
1051 : 6 : _iov_free_buf(&iovs[1]);
1052 : 6 : }
1053 : :
1054 : : static void
1055 : 6 : dif_sec_4096_md_128_prchk_7_multi_iovs_split_apptag_test(void)
1056 : : {
1057 : 5 : struct iovec iovs[2];
1058 : : uint32_t dif_flags;
1059 : :
1060 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1061 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
1062 : :
1063 : 6 : _iov_alloc_buf(&iovs[0], 4101);
1064 : 6 : _iov_alloc_buf(&iovs[1], 123);
1065 : :
1066 : 6 : dif_generate_and_verify(iovs, 2, 4096 + 128, 128, 1, false, SPDK_DIF_TYPE1,
1067 : : dif_flags, SPDK_DIF_PI_FORMAT_32, 22, 0xFFFF, 0x22);
1068 : 6 : dif_generate_and_verify(iovs, 2, 4096 + 128, 128, 1, false, SPDK_DIF_TYPE1,
1069 : : dif_flags, SPDK_DIF_PI_FORMAT_64, 22, 0xFFFF, 0x22);
1070 : :
1071 : 6 : _iov_free_buf(&iovs[0]);
1072 : 6 : _iov_free_buf(&iovs[1]);
1073 : 6 : }
1074 : :
1075 : : static void
1076 : 6 : dif_sec_512_md_8_prchk_7_multi_iovs_split_reftag_test(void)
1077 : : {
1078 : 5 : struct iovec iovs[2];
1079 : : uint32_t dif_flags;
1080 : :
1081 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1082 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
1083 : :
1084 : 6 : _iov_alloc_buf(&iovs[0], 518);
1085 : 6 : _iov_alloc_buf(&iovs[1], 2);
1086 : :
1087 : 6 : dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1,
1088 : : dif_flags, SPDK_DIF_PI_FORMAT_16, 22, 0xFFFF, 0x22);
1089 : :
1090 : 6 : _iov_free_buf(&iovs[0]);
1091 : 6 : _iov_free_buf(&iovs[1]);
1092 : 6 : }
1093 : :
1094 : : static void
1095 : 6 : dif_sec_4096_md_128_prchk_7_multi_iovs_split_reftag_test(void)
1096 : : {
1097 : 5 : struct iovec iovs[2];
1098 : : uint32_t dif_flags;
1099 : :
1100 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1101 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
1102 : :
1103 : 6 : _iov_alloc_buf(&iovs[0], 4108);
1104 : 6 : _iov_alloc_buf(&iovs[1], 116);
1105 : :
1106 : 6 : dif_generate_and_verify(iovs, 2, 4096 + 128, 128, 1, false, SPDK_DIF_TYPE1,
1107 : : dif_flags, SPDK_DIF_PI_FORMAT_32, 22, 0xFFFF, 0x22);
1108 : 6 : dif_generate_and_verify(iovs, 2, 4096 + 128, 128, 1, false, SPDK_DIF_TYPE1,
1109 : : dif_flags, SPDK_DIF_PI_FORMAT_64, 22, 0xFFFF, 0x22);
1110 : :
1111 : 6 : _iov_free_buf(&iovs[0]);
1112 : 6 : _iov_free_buf(&iovs[1]);
1113 : 6 : }
1114 : :
1115 : : static void
1116 : 6 : dif_sec_512_md_8_prchk_7_multi_iovs_complex_splits_test(void)
1117 : : {
1118 : 5 : struct iovec iovs[9];
1119 : : uint32_t dif_flags;
1120 : : int i;
1121 : :
1122 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1123 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
1124 : :
1125 : : /* data[0][255:0] */
1126 : 6 : _iov_alloc_buf(&iovs[0], 256);
1127 : :
1128 : : /* data[0][511:256], guard[0][0] */
1129 : 6 : _iov_alloc_buf(&iovs[1], 256 + 1);
1130 : :
1131 : : /* guard[0][1], apptag[0][0] */
1132 : 6 : _iov_alloc_buf(&iovs[2], 1 + 1);
1133 : :
1134 : : /* apptag[0][1], reftag[0][0] */
1135 : 6 : _iov_alloc_buf(&iovs[3], 1 + 1);
1136 : :
1137 : : /* reftag[0][3:1], data[1][255:0] */
1138 : 6 : _iov_alloc_buf(&iovs[4], 3 + 256);
1139 : :
1140 : : /* data[1][511:256], guard[1][0] */
1141 : 6 : _iov_alloc_buf(&iovs[5], 256 + 1);
1142 : :
1143 : : /* guard[1][1], apptag[1][0] */
1144 : 6 : _iov_alloc_buf(&iovs[6], 1 + 1);
1145 : :
1146 : : /* apptag[1][1], reftag[1][0] */
1147 : 6 : _iov_alloc_buf(&iovs[7], 1 + 1);
1148 : :
1149 : : /* reftag[1][3:1] */
1150 : 6 : _iov_alloc_buf(&iovs[8], 3);
1151 : :
1152 : 6 : dif_generate_and_verify(iovs, 9, 512 + 8, 8, 2, false, SPDK_DIF_TYPE1, dif_flags,
1153 : : SPDK_DIF_PI_FORMAT_16, 22, 0xFFFF, 0x22);
1154 : :
1155 [ + + ]: 60 : for (i = 0; i < 9; i++) {
1156 : 54 : _iov_free_buf(&iovs[i]);
1157 : : }
1158 : 6 : }
1159 : :
1160 : : static void
1161 : 6 : dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test(void)
1162 : : {
1163 : 5 : struct iovec iovs[11];
1164 : : uint32_t dif_flags;
1165 : : int i;
1166 : :
1167 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1168 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
1169 : :
1170 : : /* data[0][1000:0] */
1171 : 6 : _iov_alloc_buf(&iovs[0], 1000);
1172 : :
1173 : : /* data[0][3095:1000], guard[0][0] */
1174 : 6 : _iov_alloc_buf(&iovs[1], 3096 + 1);
1175 : :
1176 : : /* guard[0][1], apptag[0][0] */
1177 : 6 : _iov_alloc_buf(&iovs[2], 1 + 1);
1178 : :
1179 : : /* apptag[0][1], reftag[0][0] */
1180 : 6 : _iov_alloc_buf(&iovs[3], 1 + 1);
1181 : :
1182 : : /* reftag[0][3:1], ignore[0][59:0] */
1183 : 6 : _iov_alloc_buf(&iovs[4], 3 + 60);
1184 : :
1185 : : /* ignore[119:60], data[1][3050:0] */
1186 : 6 : _iov_alloc_buf(&iovs[5], 60 + 3051);
1187 : :
1188 : : /* data[1][4095:3050], guard[1][0] */
1189 : 6 : _iov_alloc_buf(&iovs[6], 1045 + 1);
1190 : :
1191 : : /* guard[1][1], apptag[1][0] */
1192 : 6 : _iov_alloc_buf(&iovs[7], 1 + 1);
1193 : :
1194 : : /* apptag[1][1], reftag[1][0] */
1195 : 6 : _iov_alloc_buf(&iovs[8], 1 + 1);
1196 : :
1197 : : /* reftag[1][3:1], ignore[1][9:0] */
1198 : 6 : _iov_alloc_buf(&iovs[9], 3 + 10);
1199 : :
1200 : : /* ignore[1][127:9] */
1201 : 6 : _iov_alloc_buf(&iovs[10], 118);
1202 : :
1203 : 6 : dif_generate_and_verify(iovs, 11, 4096 + 128, 128, 2, false, SPDK_DIF_TYPE1, dif_flags,
1204 : : SPDK_DIF_PI_FORMAT_16, 22, 0xFFFF, 0x22);
1205 : 6 : dif_generate_and_verify(iovs, 11, 4096 + 128, 128, 2, true, SPDK_DIF_TYPE1, dif_flags,
1206 : : SPDK_DIF_PI_FORMAT_16, 22, 0xFFFF, 0x22);
1207 : 6 : dif_generate_and_verify(iovs, 11, 4096 + 128, 128, 2, false, SPDK_DIF_TYPE1, dif_flags,
1208 : : SPDK_DIF_PI_FORMAT_32, 22, 0xFFFF, 0x22);
1209 : 6 : dif_generate_and_verify(iovs, 11, 4096 + 128, 128, 2, true, SPDK_DIF_TYPE1, dif_flags,
1210 : : SPDK_DIF_PI_FORMAT_32, 22, 0xFFFF, 0x22);
1211 : 6 : dif_generate_and_verify(iovs, 11, 4096 + 128, 128, 2, false, SPDK_DIF_TYPE1, dif_flags,
1212 : : SPDK_DIF_PI_FORMAT_64, 22, 0xFFFF, 0x22);
1213 : 6 : dif_generate_and_verify(iovs, 11, 4096 + 128, 128, 2, true, SPDK_DIF_TYPE1, dif_flags,
1214 : : SPDK_DIF_PI_FORMAT_64, 22, 0xFFFF, 0x22);
1215 : :
1216 [ + + ]: 72 : for (i = 0; i < 11; i++) {
1217 : 66 : _iov_free_buf(&iovs[i]);
1218 : : }
1219 : 6 : }
1220 : :
1221 : : static void
1222 : 864 : _dif_inject_error_and_verify(struct iovec *iovs, int iovcnt,
1223 : : uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
1224 : : uint32_t inject_flags, bool dif_loc, enum spdk_dif_pi_format dif_pi_format)
1225 : : {
1226 : 864 : struct spdk_dif_ctx ctx = {};
1227 : 864 : struct spdk_dif_error err_blk = {};
1228 : 864 : uint32_t inject_offset = 0, dif_flags;
1229 : : int rc;
1230 : 720 : struct spdk_dif_ctx_init_ext_opts dif_opts;
1231 : :
1232 : 864 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1233 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
1234 : :
1235 : 864 : rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks);
1236 : 864 : CU_ASSERT(rc == 0);
1237 : :
1238 : 864 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1239 : 864 : dif_opts.dif_pi_format = dif_pi_format;
1240 : 864 : rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc,
1241 : : SPDK_DIF_TYPE1, dif_flags,
1242 : : 88, 0xFFFF, 0x88, 0, GUARD_SEED, &dif_opts);
1243 : 864 : CU_ASSERT(rc == 0);
1244 : :
1245 : 864 : rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx);
1246 : 864 : CU_ASSERT(rc == 0);
1247 : :
1248 : 864 : rc = spdk_dif_inject_error(iovs, iovcnt, num_blocks, &ctx, inject_flags, &inject_offset);
1249 : 864 : CU_ASSERT(rc == 0);
1250 : :
1251 : 864 : rc = spdk_dif_verify(iovs, iovcnt, num_blocks, &ctx, &err_blk);
1252 : 864 : CU_ASSERT(rc != 0);
1253 [ + + ]: 864 : if (inject_flags == SPDK_DIF_DATA_ERROR) {
1254 : 216 : CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type);
1255 : : } else {
1256 : 648 : CU_ASSERT(inject_flags == err_blk.err_type);
1257 : : }
1258 : 864 : CU_ASSERT(inject_offset == err_blk.err_offset);
1259 : :
1260 : 864 : rc = ut_data_pattern_verify(iovs, iovcnt, block_size, md_size, num_blocks);
1261 [ + + - + : 864 : CU_ASSERT((rc == 0 && (inject_flags != SPDK_DIF_DATA_ERROR)) ||
+ - + - ]
1262 : : (rc != 0 && (inject_flags == SPDK_DIF_DATA_ERROR)));
1263 : 864 : }
1264 : :
1265 : : static void
1266 : 432 : dif_inject_error_and_verify(struct iovec *iovs, int iovcnt,
1267 : : uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
1268 : : uint32_t inject_flags, enum spdk_dif_pi_format dif_pi_format)
1269 : : {
1270 : : /* The case that DIF is contained in the first 8/16 bytes of metadata. */
1271 : 432 : _dif_inject_error_and_verify(iovs, iovcnt, block_size, md_size, num_blocks,
1272 : : inject_flags, true, dif_pi_format);
1273 : :
1274 : : /* The case that DIF is contained in the last 8/16 bytes of metadata. */
1275 : 432 : _dif_inject_error_and_verify(iovs, iovcnt, block_size, md_size, num_blocks,
1276 : : inject_flags, false, dif_pi_format);
1277 : 432 : }
1278 : :
1279 : : static void
1280 : 6 : dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test(void)
1281 : : {
1282 : 5 : struct iovec iovs[4];
1283 : : int i, num_blocks;
1284 : :
1285 : 6 : num_blocks = 0;
1286 : :
1287 [ + + ]: 30 : for (i = 0; i < 4; i++) {
1288 : 24 : _iov_alloc_buf(&iovs[i], (4096 + 128) * (i + 1));
1289 : 24 : num_blocks += i + 1;
1290 : : }
1291 : :
1292 : 6 : dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks,
1293 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_16);
1294 : 6 : dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks,
1295 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1296 : 6 : dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks,
1297 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1298 : 6 : dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks,
1299 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_16);
1300 : 6 : dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks,
1301 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_32);
1302 : 6 : dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks,
1303 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
1304 : 6 : dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks,
1305 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
1306 : 6 : dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks,
1307 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_32);
1308 : 6 : dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks,
1309 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_64);
1310 : 6 : dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks,
1311 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
1312 : 6 : dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks,
1313 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
1314 : 6 : dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks,
1315 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_64);
1316 : :
1317 [ + + ]: 30 : for (i = 0; i < 4; i++) {
1318 : 24 : _iov_free_buf(&iovs[i]);
1319 : : }
1320 : 6 : }
1321 : :
1322 : : static void
1323 : 6 : dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_and_md_test(void)
1324 : : {
1325 : 5 : struct iovec iovs[2];
1326 : :
1327 : 6 : _iov_alloc_buf(&iovs[0], 4096);
1328 : 6 : _iov_alloc_buf(&iovs[1], 128);
1329 : :
1330 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1331 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_16);
1332 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1333 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1334 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1335 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1336 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1337 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_16);
1338 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1339 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_32);
1340 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1341 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
1342 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1343 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
1344 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1345 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_32);
1346 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1347 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_64);
1348 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1349 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
1350 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1351 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
1352 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1353 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_64);
1354 : :
1355 : :
1356 : 6 : _iov_free_buf(&iovs[0]);
1357 : 6 : _iov_free_buf(&iovs[1]);
1358 : 6 : }
1359 : :
1360 : : static void
1361 : 6 : dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_test(void)
1362 : : {
1363 : 5 : struct iovec iovs[2];
1364 : :
1365 : 6 : _iov_alloc_buf(&iovs[0], 2048);
1366 : 6 : _iov_alloc_buf(&iovs[1], 2048 + 128);
1367 : :
1368 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1369 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_16);
1370 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1371 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1372 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1373 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1374 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1375 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_16);
1376 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1377 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_32);
1378 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1379 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
1380 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1381 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
1382 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1383 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_32);
1384 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1385 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_64);
1386 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1387 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
1388 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1389 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
1390 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1391 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_64);
1392 : :
1393 : 6 : _iov_free_buf(&iovs[0]);
1394 : 6 : _iov_free_buf(&iovs[1]);
1395 : 6 : }
1396 : :
1397 : : static void
1398 : 6 : dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_guard_test(void)
1399 : : {
1400 : 5 : struct iovec iovs[2];
1401 : :
1402 : 6 : _iov_alloc_buf(&iovs[0], 4096 + 1);
1403 : 6 : _iov_alloc_buf(&iovs[1], 127);
1404 : :
1405 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1406 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_16);
1407 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1408 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1409 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1410 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1411 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1412 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_16);
1413 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1414 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_32);
1415 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1416 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
1417 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1418 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
1419 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1420 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_32);
1421 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1422 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_64);
1423 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1424 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
1425 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1426 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
1427 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1428 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_64);
1429 : :
1430 : 6 : _iov_free_buf(&iovs[0]);
1431 : 6 : _iov_free_buf(&iovs[1]);
1432 : 6 : }
1433 : :
1434 : : static void
1435 : 6 : dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_apptag_pi_16_test(void)
1436 : : {
1437 : 5 : struct iovec iovs[2];
1438 : :
1439 : 6 : _iov_alloc_buf(&iovs[0], 4096 + 3);
1440 : 6 : _iov_alloc_buf(&iovs[1], 125);
1441 : :
1442 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1443 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_16);
1444 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1445 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1446 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1447 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1448 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1449 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_16);
1450 : :
1451 : 6 : _iov_free_buf(&iovs[0]);
1452 : 6 : _iov_free_buf(&iovs[1]);
1453 : 6 : }
1454 : :
1455 : : static void
1456 : 12 : _dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_apptag_test(
1457 : : enum spdk_dif_pi_format dif_pi_format)
1458 : : {
1459 : 10 : struct iovec iovs[2];
1460 : :
1461 : 12 : _iov_alloc_buf(&iovs[0], 4096 + 5);
1462 : 12 : _iov_alloc_buf(&iovs[1], 123);
1463 : :
1464 : 12 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1465 : : SPDK_DIF_GUARD_ERROR, dif_pi_format);
1466 : 12 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1467 : : SPDK_DIF_APPTAG_ERROR, dif_pi_format);
1468 : 12 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1469 : : SPDK_DIF_REFTAG_ERROR, dif_pi_format);
1470 : 12 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1471 : : SPDK_DIF_DATA_ERROR, dif_pi_format);
1472 : :
1473 : 12 : _iov_free_buf(&iovs[0]);
1474 : 12 : _iov_free_buf(&iovs[1]);
1475 : 12 : }
1476 : :
1477 : : static void
1478 : 6 : dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_apptag_test(void)
1479 : : {
1480 : 6 : _dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_apptag_test(SPDK_DIF_PI_FORMAT_32);
1481 : 6 : _dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_apptag_test(SPDK_DIF_PI_FORMAT_64);
1482 : 6 : }
1483 : :
1484 : : static void
1485 : 6 : dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_pi_16_test(void)
1486 : : {
1487 : 5 : struct iovec iovs[2];
1488 : :
1489 : 6 : _iov_alloc_buf(&iovs[0], 4096 + 6);
1490 : 6 : _iov_alloc_buf(&iovs[1], 122);
1491 : :
1492 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1493 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_16);
1494 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1495 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1496 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1497 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1498 : 6 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1499 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_16);
1500 : :
1501 : 6 : _iov_free_buf(&iovs[0]);
1502 : 6 : _iov_free_buf(&iovs[1]);
1503 : 6 : }
1504 : :
1505 : : static void
1506 : 12 : _dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_test(
1507 : : enum spdk_dif_pi_format dif_pi_format)
1508 : : {
1509 : 10 : struct iovec iovs[2];
1510 : :
1511 : 12 : _iov_alloc_buf(&iovs[0], 4096 + 9);
1512 : 12 : _iov_alloc_buf(&iovs[1], 119);
1513 : :
1514 : 12 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1515 : : SPDK_DIF_GUARD_ERROR, dif_pi_format);
1516 : 12 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1517 : : SPDK_DIF_APPTAG_ERROR, dif_pi_format);
1518 : 12 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1519 : : SPDK_DIF_REFTAG_ERROR, dif_pi_format);
1520 : 12 : dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1,
1521 : : SPDK_DIF_DATA_ERROR, dif_pi_format);
1522 : :
1523 : 12 : _iov_free_buf(&iovs[0]);
1524 : 12 : _iov_free_buf(&iovs[1]);
1525 : 12 : }
1526 : :
1527 : : static void
1528 : 6 : dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_test(void)
1529 : : {
1530 : 6 : _dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_test(SPDK_DIF_PI_FORMAT_32);
1531 : 6 : _dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_test(SPDK_DIF_PI_FORMAT_64);
1532 : 6 : }
1533 : :
1534 : : static void
1535 : 180 : dif_copy_gen_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
1536 : : uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
1537 : : bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
1538 : : uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag,
1539 : : enum spdk_dif_pi_format dif_pi_format)
1540 : : {
1541 : 180 : struct spdk_dif_ctx ctx = {};
1542 : : int rc;
1543 : 150 : struct spdk_dif_ctx_init_ext_opts dif_opts;
1544 : :
1545 : 180 : rc = ut_data_pattern_generate(iovs, iovcnt, block_size - md_size, 0, num_blocks);
1546 : 180 : CU_ASSERT(rc == 0);
1547 : :
1548 : 180 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1549 : 180 : dif_opts.dif_pi_format = dif_pi_format;
1550 : 180 : rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags,
1551 : : init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED, &dif_opts);
1552 : 180 : CU_ASSERT(rc == 0);
1553 : :
1554 : 180 : rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, 1, num_blocks, &ctx);
1555 : 180 : CU_ASSERT(rc == 0);
1556 : :
1557 : 180 : rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, 1, num_blocks, &ctx, NULL);
1558 : 180 : CU_ASSERT(rc == 0);
1559 : :
1560 : 180 : rc = ut_data_pattern_verify(iovs, iovcnt, block_size - md_size, 0, num_blocks);
1561 : 180 : CU_ASSERT(rc == 0);
1562 : 180 : }
1563 : :
1564 : : static void
1565 : 6 : dif_copy_sec_512_md_8_prchk_0_single_iov(void)
1566 : : {
1567 : 5 : struct iovec iov, bounce_iov;
1568 : :
1569 : 6 : _iov_alloc_buf(&iov, 512 * 4);
1570 : 6 : _iov_alloc_buf(&bounce_iov, (512 + 8) * 4);
1571 : :
1572 : 6 : dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 512 + 8, 8, 4,
1573 : : false, SPDK_DIF_TYPE1, 0, 0, 0, 0, SPDK_DIF_PI_FORMAT_16);
1574 : 6 : dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 512 + 8, 8, 4,
1575 : : true, SPDK_DIF_TYPE1, 0, 0, 0, 0, SPDK_DIF_PI_FORMAT_16);
1576 : :
1577 : 6 : _iov_free_buf(&iov);
1578 : 6 : _iov_free_buf(&bounce_iov);
1579 : 6 : }
1580 : :
1581 : : static void
1582 : 12 : _dif_copy_sec_4096_md_128_prchk_0_single_iov_test(
1583 : : enum spdk_dif_pi_format dif_pi_format)
1584 : : {
1585 : 10 : struct iovec iov, bounce_iov;
1586 : :
1587 : 12 : _iov_alloc_buf(&iov, 4096 * 4);
1588 : 12 : _iov_alloc_buf(&bounce_iov, (4096 + 128) * 4);
1589 : :
1590 : 12 : dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 4096 + 128, 128, 4,
1591 : : false, SPDK_DIF_TYPE1, 0, 0, 0, 0, dif_pi_format);
1592 : 12 : dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 4096 + 128, 128, 4,
1593 : : true, SPDK_DIF_TYPE1, 0, 0, 0, 0, dif_pi_format);
1594 : :
1595 : 12 : _iov_free_buf(&iov);
1596 : 12 : _iov_free_buf(&bounce_iov);
1597 : 12 : }
1598 : :
1599 : : static void
1600 : 6 : dif_copy_sec_4096_md_128_prchk_0_single_iov_test(void)
1601 : : {
1602 : 6 : _dif_copy_sec_4096_md_128_prchk_0_single_iov_test(SPDK_DIF_PI_FORMAT_32);
1603 : 6 : _dif_copy_sec_4096_md_128_prchk_0_single_iov_test(SPDK_DIF_PI_FORMAT_64);
1604 : 6 : }
1605 : :
1606 : : static void
1607 : 6 : dif_copy_sec_512_md_8_prchk_0_1_2_4_multi_iovs(void)
1608 : : {
1609 : 5 : struct iovec iovs[4], bounce_iov;
1610 : : int i, num_blocks;
1611 : :
1612 : 6 : num_blocks = 0;
1613 : :
1614 [ + + ]: 30 : for (i = 0; i < 4; i++) {
1615 : 24 : _iov_alloc_buf(&iovs[i], 512 * (i + 1));
1616 : 24 : num_blocks += i + 1;
1617 : : }
1618 : :
1619 : 6 : _iov_alloc_buf(&bounce_iov, (512 + 8) * num_blocks);
1620 : :
1621 : 6 : dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks,
1622 : : false, SPDK_DIF_TYPE1, 0, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
1623 : :
1624 : 6 : dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks,
1625 : : false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22,
1626 : : SPDK_DIF_PI_FORMAT_16);
1627 : :
1628 : 6 : dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks,
1629 : : false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22,
1630 : : SPDK_DIF_PI_FORMAT_16);
1631 : :
1632 : 6 : dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks,
1633 : : false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22,
1634 : : SPDK_DIF_PI_FORMAT_16);
1635 : :
1636 [ + + ]: 30 : for (i = 0; i < 4; i++) {
1637 : 24 : _iov_free_buf(&iovs[i]);
1638 : : }
1639 : 6 : _iov_free_buf(&bounce_iov);
1640 : 6 : }
1641 : :
1642 : : static void
1643 : 12 : _dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(
1644 : : enum spdk_dif_pi_format dif_pi_format)
1645 : : {
1646 : 10 : struct iovec iovs[4], bounce_iov;
1647 : : int i, num_blocks;
1648 : :
1649 : 12 : num_blocks = 0;
1650 : :
1651 [ + + ]: 60 : for (i = 0; i < 4; i++) {
1652 : 48 : _iov_alloc_buf(&iovs[i], 4096 * (i + 1));
1653 : 48 : num_blocks += i + 1;
1654 : : }
1655 : :
1656 : 12 : _iov_alloc_buf(&bounce_iov, (4096 + 128) * num_blocks);
1657 : :
1658 : 12 : dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks,
1659 : : false, SPDK_DIF_TYPE1, 0, 22, 0xFFFF, 0x22, dif_pi_format);
1660 : :
1661 : 12 : dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks,
1662 : : false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22,
1663 : : dif_pi_format);
1664 : :
1665 : 12 : dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks,
1666 : : false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22,
1667 : : dif_pi_format);
1668 : :
1669 : 12 : dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks,
1670 : : false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22,
1671 : : dif_pi_format);
1672 : :
1673 [ + + ]: 60 : for (i = 0; i < 4; i++) {
1674 : 48 : _iov_free_buf(&iovs[i]);
1675 : : }
1676 : 12 : _iov_free_buf(&bounce_iov);
1677 : 12 : }
1678 : :
1679 : : static void
1680 : 6 : dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(void)
1681 : : {
1682 : 6 : _dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(SPDK_DIF_PI_FORMAT_32);
1683 : 6 : _dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(SPDK_DIF_PI_FORMAT_64);
1684 : 6 : }
1685 : :
1686 : : static void
1687 : 6 : dif_copy_sec_4096_md_128_prchk_7_multi_iovs(void)
1688 : : {
1689 : 5 : struct iovec iovs[4], bounce_iov;
1690 : : uint32_t dif_flags;
1691 : : int i, num_blocks;
1692 : :
1693 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1694 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
1695 : :
1696 : 6 : num_blocks = 0;
1697 : :
1698 [ + + ]: 30 : for (i = 0; i < 4; i++) {
1699 : 24 : _iov_alloc_buf(&iovs[i], 4096 * (i + 1));
1700 : 24 : num_blocks += i + 1;
1701 : : }
1702 : :
1703 : 6 : _iov_alloc_buf(&bounce_iov, (4096 + 128) * num_blocks);
1704 : :
1705 : 6 : dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks,
1706 : : false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
1707 : 6 : dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks,
1708 : : true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
1709 : 6 : dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks,
1710 : : false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32);
1711 : 6 : dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks,
1712 : : true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32);
1713 : 6 : dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks,
1714 : : false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64);
1715 : 6 : dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks,
1716 : : true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64);
1717 : :
1718 [ + + ]: 30 : for (i = 0; i < 4; i++) {
1719 : 24 : _iov_free_buf(&iovs[i]);
1720 : : }
1721 : 6 : _iov_free_buf(&bounce_iov);
1722 : 6 : }
1723 : :
1724 : : static void
1725 : 6 : dif_copy_sec_512_md_8_prchk_7_multi_iovs_split_data(void)
1726 : : {
1727 : 5 : struct iovec iovs[2], bounce_iov;
1728 : : uint32_t dif_flags;
1729 : :
1730 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1731 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
1732 : :
1733 : 6 : _iov_alloc_buf(&iovs[0], 256);
1734 : 6 : _iov_alloc_buf(&iovs[1], 256);
1735 : :
1736 : 6 : _iov_alloc_buf(&bounce_iov, 512 + 8);
1737 : :
1738 : 6 : dif_copy_gen_and_verify(iovs, 2, &bounce_iov, 512 + 8, 8, 1,
1739 : : false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
1740 : :
1741 : 6 : _iov_free_buf(&iovs[0]);
1742 : 6 : _iov_free_buf(&iovs[1]);
1743 : 6 : _iov_free_buf(&bounce_iov);
1744 : 6 : }
1745 : :
1746 : : static void
1747 : 6 : dif_copy_sec_4096_md_128_prchk_7_multi_iovs_split_data_test(void)
1748 : : {
1749 : 5 : struct iovec iovs[2], bounce_iov;
1750 : : uint32_t dif_flags;
1751 : :
1752 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1753 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
1754 : :
1755 : 6 : _iov_alloc_buf(&iovs[0], 2048);
1756 : 6 : _iov_alloc_buf(&iovs[1], 2048);
1757 : :
1758 : 6 : _iov_alloc_buf(&bounce_iov, 4096 + 128);
1759 : :
1760 : 6 : dif_copy_gen_and_verify(iovs, 2, &bounce_iov, 4096 + 128, 128, 1,
1761 : : false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32);
1762 : 6 : dif_copy_gen_and_verify(iovs, 2, &bounce_iov, 4096 + 128, 128, 1,
1763 : : false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64);
1764 : :
1765 : 6 : _iov_free_buf(&iovs[0]);
1766 : 6 : _iov_free_buf(&iovs[1]);
1767 : 6 : _iov_free_buf(&bounce_iov);
1768 : 6 : }
1769 : :
1770 : : static void
1771 : 6 : dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits(void)
1772 : : {
1773 : 5 : struct iovec iovs[6], bounce_iov;
1774 : : uint32_t dif_flags;
1775 : : int i;
1776 : :
1777 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1778 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
1779 : :
1780 : : /* data[0][255:0] */
1781 : 6 : _iov_alloc_buf(&iovs[0], 256);
1782 : :
1783 : : /* data[0][511:256], data[1][255:0] */
1784 : 6 : _iov_alloc_buf(&iovs[1], 256 + 256);
1785 : :
1786 : : /* data[1][382:256] */
1787 : 6 : _iov_alloc_buf(&iovs[2], 128);
1788 : :
1789 : : /* data[1][383] */
1790 : 6 : _iov_alloc_buf(&iovs[3], 1);
1791 : :
1792 : : /* data[1][510:384] */
1793 : 6 : _iov_alloc_buf(&iovs[4], 126);
1794 : :
1795 : : /* data[1][511], data[2][511:0], data[3][511:0] */
1796 : 6 : _iov_alloc_buf(&iovs[5], 1 + 512 * 2);
1797 : :
1798 : 6 : _iov_alloc_buf(&bounce_iov, (512 + 8) * 4);
1799 : :
1800 : 6 : dif_copy_gen_and_verify(iovs, 6, &bounce_iov, 512 + 8, 8, 4,
1801 : : true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
1802 : :
1803 [ + + ]: 42 : for (i = 0; i < 6; i++) {
1804 : 36 : _iov_free_buf(&iovs[i]);
1805 : : }
1806 : 6 : _iov_free_buf(&bounce_iov);
1807 : 6 : }
1808 : :
1809 : : static void
1810 : 6 : dif_copy_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test(void)
1811 : : {
1812 : 5 : struct iovec iovs[6], bounce_iov;
1813 : : uint32_t dif_flags;
1814 : : int i;
1815 : :
1816 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1817 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
1818 : :
1819 : : /* data[0][2047:0] */
1820 : 6 : _iov_alloc_buf(&iovs[0], 2048);
1821 : :
1822 : : /* data[0][4095:2048], data[1][2047:0] */
1823 : 6 : _iov_alloc_buf(&iovs[1], 2048 + 2048);
1824 : :
1825 : : /* data[1][3071:2048] */
1826 : 6 : _iov_alloc_buf(&iovs[2], 1024);
1827 : :
1828 : : /* data[1][3072] */
1829 : 6 : _iov_alloc_buf(&iovs[3], 1);
1830 : :
1831 : : /* data[1][4094:3073] */
1832 : 6 : _iov_alloc_buf(&iovs[4], 1022);
1833 : :
1834 : : /* data[1][4095], data[2][4095:0], data[3][4095:0] */
1835 : 6 : _iov_alloc_buf(&iovs[5], 1 + 4096 * 2);
1836 : :
1837 : 6 : _iov_alloc_buf(&bounce_iov, (4096 + 128) * 4);
1838 : :
1839 : 6 : dif_copy_gen_and_verify(iovs, 6, &bounce_iov, 4096 + 128, 128, 4,
1840 : : true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32);
1841 : 6 : dif_copy_gen_and_verify(iovs, 6, &bounce_iov, 4096 + 128, 128, 4,
1842 : : true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64);
1843 : :
1844 [ + + ]: 42 : for (i = 0; i < 6; i++) {
1845 : 36 : _iov_free_buf(&iovs[i]);
1846 : : }
1847 : 6 : _iov_free_buf(&bounce_iov);
1848 : 6 : }
1849 : :
1850 : : static void
1851 : 288 : _dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
1852 : : uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
1853 : : uint32_t inject_flags, bool dif_loc, enum spdk_dif_pi_format dif_pi_format)
1854 : : {
1855 : 288 : struct spdk_dif_ctx ctx = {};
1856 : 288 : struct spdk_dif_error err_blk = {};
1857 : 288 : uint32_t inject_offset = 0, dif_flags;
1858 : : int rc;
1859 : 240 : struct spdk_dif_ctx_init_ext_opts dif_opts;
1860 : :
1861 : 288 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
1862 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
1863 : :
1864 : 288 : rc = ut_data_pattern_generate(iovs, iovcnt, block_size - md_size, 0, num_blocks);
1865 : 288 : CU_ASSERT(rc == 0);
1866 : :
1867 : 288 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
1868 : 288 : dif_opts.dif_pi_format = dif_pi_format;
1869 : 288 : rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, SPDK_DIF_TYPE1, dif_flags,
1870 : : 88, 0xFFFF, 0x88, 0, GUARD_SEED, &dif_opts);
1871 [ - + ]: 288 : SPDK_CU_ASSERT_FATAL(rc == 0);
1872 : :
1873 : 288 : rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, 1, num_blocks, &ctx);
1874 : 288 : CU_ASSERT(rc == 0);
1875 : :
1876 : 288 : rc = spdk_dif_inject_error(bounce_iov, 1, num_blocks, &ctx, inject_flags, &inject_offset);
1877 : 288 : CU_ASSERT(rc == 0);
1878 : :
1879 : 288 : rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, 1, num_blocks, &ctx, &err_blk);
1880 : 288 : CU_ASSERT(rc != 0);
1881 [ + + ]: 288 : if (inject_flags == SPDK_DIF_DATA_ERROR) {
1882 : 72 : CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type);
1883 : : } else {
1884 : 216 : CU_ASSERT(inject_flags == err_blk.err_type);
1885 : : }
1886 : 288 : CU_ASSERT(inject_offset == err_blk.err_offset);
1887 : 288 : }
1888 : :
1889 : : static void
1890 : 144 : dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
1891 : : uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
1892 : : uint32_t inject_flags, enum spdk_dif_pi_format dif_pi_format)
1893 : : {
1894 : : /* The case that DIF is contained in the first 8/16 bytes of metadata. */
1895 : 144 : _dif_copy_inject_error_and_verify(iovs, iovcnt, bounce_iov,
1896 : : block_size, md_size, num_blocks,
1897 : : inject_flags, true, dif_pi_format);
1898 : :
1899 : : /* The case that DIF is contained in the last 8/16 bytes of metadata. */
1900 : 144 : _dif_copy_inject_error_and_verify(iovs, iovcnt, bounce_iov,
1901 : : block_size, md_size, num_blocks,
1902 : : inject_flags, false, dif_pi_format);
1903 : 144 : }
1904 : :
1905 : : static void
1906 : 6 : dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test(void)
1907 : : {
1908 : 5 : struct iovec iovs[4], bounce_iov;
1909 : : int i, num_blocks;
1910 : :
1911 : 6 : num_blocks = 0;
1912 : :
1913 [ + + ]: 30 : for (i = 0; i < 4; i++) {
1914 : 24 : _iov_alloc_buf(&iovs[i], 4096 * (i + 1));
1915 : 24 : num_blocks += i + 1;
1916 : : }
1917 : :
1918 : 6 : _iov_alloc_buf(&bounce_iov, (4096 + 128) * num_blocks);
1919 : :
1920 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1921 : : num_blocks, SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_16);
1922 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1923 : : num_blocks, SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1924 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1925 : : num_blocks, SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1926 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1927 : : num_blocks, SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_16);
1928 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1929 : : num_blocks, SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_32);
1930 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1931 : : num_blocks, SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
1932 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1933 : : num_blocks, SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
1934 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1935 : : num_blocks, SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_32);
1936 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1937 : : num_blocks, SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_64);
1938 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1939 : : num_blocks, SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
1940 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1941 : : num_blocks, SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
1942 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1943 : : num_blocks, SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_64);
1944 : :
1945 [ + + ]: 30 : for (i = 0; i < 4; i++) {
1946 : 24 : _iov_free_buf(&iovs[i]);
1947 : : }
1948 : 6 : _iov_free_buf(&bounce_iov);
1949 : 6 : }
1950 : :
1951 : : static void
1952 : 6 : dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test(void)
1953 : : {
1954 : 5 : struct iovec iovs[4], bounce_iov;
1955 : : int i;
1956 : :
1957 : 6 : _iov_alloc_buf(&iovs[0], 2048);
1958 : 6 : _iov_alloc_buf(&iovs[1], 2048);
1959 : 6 : _iov_alloc_buf(&iovs[2], 1);
1960 : 6 : _iov_alloc_buf(&iovs[3], 4095);
1961 : :
1962 : 6 : _iov_alloc_buf(&bounce_iov, (4096 + 128) * 2);
1963 : :
1964 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1965 : : 2, SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_16);
1966 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1967 : : 2, SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1968 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1969 : : 2, SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
1970 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1971 : : 2, SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_16);
1972 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1973 : : 2, SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_32);
1974 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1975 : : 2, SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
1976 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1977 : : 2, SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
1978 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1979 : : 2, SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_32);
1980 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1981 : : 2, SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_64);
1982 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1983 : : 2, SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
1984 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1985 : : 2, SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
1986 : 6 : dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
1987 : : 2, SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_64);
1988 : :
1989 [ + + ]: 30 : for (i = 0; i < 4; i++) {
1990 : 24 : _iov_free_buf(&iovs[i]);
1991 : : }
1992 : 6 : _iov_free_buf(&bounce_iov);
1993 : 6 : }
1994 : :
1995 : : static void
1996 : 6 : dix_sec_512_md_0_error(void)
1997 : : {
1998 : 5 : struct spdk_dif_ctx ctx;
1999 : : int rc;
2000 : 5 : struct spdk_dif_ctx_init_ext_opts dif_opts;
2001 : :
2002 : 6 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
2003 : 6 : dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
2004 : 6 : rc = spdk_dif_ctx_init(&ctx, 512, 0, false, false, SPDK_DIF_TYPE1, 0,
2005 : : 0, 0, 0, 0, 0, &dif_opts);
2006 : 6 : CU_ASSERT(rc != 0);
2007 : 6 : }
2008 : :
2009 : : static void
2010 : 180 : dix_generate_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov,
2011 : : uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
2012 : : bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
2013 : : uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag,
2014 : : enum spdk_dif_pi_format dif_pi_format)
2015 : : {
2016 : 150 : struct spdk_dif_ctx ctx;
2017 : : int rc;
2018 : 150 : struct spdk_dif_ctx_init_ext_opts dif_opts;
2019 : :
2020 : 180 : rc = ut_data_pattern_generate(iovs, iovcnt, block_size, 0, num_blocks);
2021 : 180 : CU_ASSERT(rc == 0);
2022 : :
2023 : 180 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
2024 : 180 : dif_opts.dif_pi_format = dif_pi_format;
2025 : 180 : rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags,
2026 : : init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED, &dif_opts);
2027 : 180 : CU_ASSERT(rc == 0);
2028 : :
2029 : 180 : rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx);
2030 : 180 : CU_ASSERT(rc == 0);
2031 : :
2032 : 180 : rc = spdk_dix_verify(iovs, iovcnt, md_iov, num_blocks, &ctx, NULL);
2033 : 180 : CU_ASSERT(rc == 0);
2034 : :
2035 : 180 : rc = ut_data_pattern_verify(iovs, iovcnt, block_size, 0, num_blocks);
2036 : 180 : CU_ASSERT(rc == 0);
2037 : 180 : }
2038 : :
2039 : : static void
2040 : 6 : dix_sec_512_md_8_prchk_0_single_iov(void)
2041 : : {
2042 : 5 : struct iovec iov, md_iov;
2043 : :
2044 : 6 : _iov_alloc_buf(&iov, 512 * 4);
2045 : 6 : _iov_alloc_buf(&md_iov, 8 * 4);
2046 : :
2047 : 6 : dix_generate_and_verify(&iov, 1, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1, 0, 0, 0, 0,
2048 : : SPDK_DIF_PI_FORMAT_16);
2049 : 6 : dix_generate_and_verify(&iov, 1, &md_iov, 512, 8, 4, true, SPDK_DIF_TYPE1, 0, 0, 0, 0,
2050 : : SPDK_DIF_PI_FORMAT_16);
2051 : :
2052 : 6 : _iov_free_buf(&iov);
2053 : 6 : _iov_free_buf(&md_iov);
2054 : 6 : }
2055 : :
2056 : : static void
2057 : 12 : _dix_sec_4096_md_128_prchk_0_single_iov_test(
2058 : : enum spdk_dif_pi_format dif_pi_format)
2059 : : {
2060 : 10 : struct iovec iov, md_iov;
2061 : :
2062 : 12 : _iov_alloc_buf(&iov, 4096 * 4);
2063 : 12 : _iov_alloc_buf(&md_iov, 128 * 4);
2064 : :
2065 : 12 : dix_generate_and_verify(&iov, 1, &md_iov, 4096, 128, 4, false, SPDK_DIF_TYPE1, 0, 0, 0, 0,
2066 : : dif_pi_format);
2067 : 12 : dix_generate_and_verify(&iov, 1, &md_iov, 4096, 128, 4, true, SPDK_DIF_TYPE1, 0, 0, 0, 0,
2068 : : dif_pi_format);
2069 : :
2070 : 12 : _iov_free_buf(&iov);
2071 : 12 : _iov_free_buf(&md_iov);
2072 : 12 : }
2073 : :
2074 : : static void
2075 : 6 : dix_sec_4096_md_128_prchk_0_single_iov_test(void)
2076 : : {
2077 : 6 : _dix_sec_4096_md_128_prchk_0_single_iov_test(SPDK_DIF_PI_FORMAT_32);
2078 : 6 : _dix_sec_4096_md_128_prchk_0_single_iov_test(SPDK_DIF_PI_FORMAT_64);
2079 : 6 : }
2080 : :
2081 : : static void
2082 : 6 : dix_sec_512_md_8_prchk_0_1_2_4_multi_iovs(void)
2083 : : {
2084 : 5 : struct iovec iovs[4], md_iov;
2085 : : int i, num_blocks;
2086 : :
2087 : 6 : num_blocks = 0;
2088 : :
2089 [ + + ]: 30 : for (i = 0; i < 4; i++) {
2090 : 24 : _iov_alloc_buf(&iovs[i], 512 * (i + 1));
2091 : 24 : num_blocks += i + 1;
2092 : : }
2093 : 6 : _iov_alloc_buf(&md_iov, 8 * num_blocks);
2094 : :
2095 : 6 : dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1,
2096 : : 0, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
2097 : 6 : dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1,
2098 : : SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
2099 : 6 : dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1,
2100 : : SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
2101 : 6 : dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1,
2102 : : SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
2103 : :
2104 [ + + ]: 30 : for (i = 0; i < 4; i++) {
2105 : 24 : _iov_free_buf(&iovs[i]);
2106 : : }
2107 : 6 : _iov_free_buf(&md_iov);
2108 : 6 : }
2109 : :
2110 : : static void
2111 : 12 : _dix_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(
2112 : : enum spdk_dif_pi_format dif_pi_format)
2113 : : {
2114 : 10 : struct iovec iovs[4], md_iov;
2115 : : int i, num_blocks;
2116 : :
2117 : 12 : num_blocks = 0;
2118 : :
2119 [ + + ]: 60 : for (i = 0; i < 4; i++) {
2120 : 48 : _iov_alloc_buf(&iovs[i], 4096 * (i + 1));
2121 : 48 : num_blocks += i + 1;
2122 : : }
2123 : 12 : _iov_alloc_buf(&md_iov, 128 * num_blocks);
2124 : :
2125 : 12 : dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1,
2126 : : 0, 22, 0xFFFF, 0x22, dif_pi_format);
2127 : 12 : dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1,
2128 : : SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22, dif_pi_format);
2129 : 12 : dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1,
2130 : : SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22, dif_pi_format);
2131 : 12 : dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1,
2132 : : SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22, dif_pi_format);
2133 : :
2134 [ + + ]: 60 : for (i = 0; i < 4; i++) {
2135 : 48 : _iov_free_buf(&iovs[i]);
2136 : : }
2137 : 12 : _iov_free_buf(&md_iov);
2138 : 12 : }
2139 : :
2140 : : static void
2141 : 6 : dix_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(void)
2142 : : {
2143 : 6 : _dix_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(SPDK_DIF_PI_FORMAT_32);
2144 : 6 : _dix_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(SPDK_DIF_PI_FORMAT_64);
2145 : 6 : }
2146 : :
2147 : : /* TODO start here */
2148 : :
2149 : : static void
2150 : 6 : dix_sec_4096_md_128_prchk_7_multi_iovs(void)
2151 : : {
2152 : 5 : struct iovec iovs[4], md_iov;
2153 : : uint32_t dif_flags;
2154 : : int i, num_blocks;
2155 : :
2156 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2157 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
2158 : :
2159 : 6 : num_blocks = 0;
2160 : :
2161 [ + + ]: 30 : for (i = 0; i < 4; i++) {
2162 : 24 : _iov_alloc_buf(&iovs[i], 4096 * (i + 1));
2163 : 24 : num_blocks += i + 1;
2164 : : }
2165 : 6 : _iov_alloc_buf(&md_iov, 128 * num_blocks);
2166 : :
2167 : 6 : dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1,
2168 : : dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
2169 : 6 : dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1,
2170 : : dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
2171 : 6 : dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1,
2172 : : dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32);
2173 : 6 : dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1,
2174 : : dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32);
2175 : 6 : dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1,
2176 : : dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64);
2177 : 6 : dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1,
2178 : : dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64);
2179 : :
2180 [ + + ]: 30 : for (i = 0; i < 4; i++) {
2181 : 24 : _iov_free_buf(&iovs[i]);
2182 : : }
2183 : 6 : _iov_free_buf(&md_iov);
2184 : 6 : }
2185 : :
2186 : : static void
2187 : 6 : dix_sec_512_md_8_prchk_7_multi_iovs_split_data(void)
2188 : : {
2189 : 5 : struct iovec iovs[2], md_iov;
2190 : : uint32_t dif_flags;
2191 : :
2192 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2193 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
2194 : :
2195 : 6 : _iov_alloc_buf(&iovs[0], 256);
2196 : 6 : _iov_alloc_buf(&iovs[1], 256);
2197 : 6 : _iov_alloc_buf(&md_iov, 8);
2198 : :
2199 : 6 : dix_generate_and_verify(iovs, 2, &md_iov, 512, 8, 1, false, SPDK_DIF_TYPE1,
2200 : : dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
2201 : :
2202 : 6 : _iov_free_buf(&iovs[0]);
2203 : 6 : _iov_free_buf(&iovs[1]);
2204 : 6 : _iov_free_buf(&md_iov);
2205 : 6 : }
2206 : :
2207 : : static void
2208 : 6 : dix_sec_4096_md_128_prchk_7_multi_iovs_split_data_test(void)
2209 : : {
2210 : 5 : struct iovec iovs[2], md_iov;
2211 : : uint32_t dif_flags;
2212 : :
2213 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2214 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
2215 : :
2216 : 6 : _iov_alloc_buf(&iovs[0], 2048);
2217 : 6 : _iov_alloc_buf(&iovs[1], 2048);
2218 : 6 : _iov_alloc_buf(&md_iov, 128);
2219 : :
2220 : 6 : dix_generate_and_verify(iovs, 2, &md_iov, 4096, 128, 1, false, SPDK_DIF_TYPE1,
2221 : : dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32);
2222 : 6 : dix_generate_and_verify(iovs, 2, &md_iov, 4096, 128, 1, false, SPDK_DIF_TYPE1,
2223 : : dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64);
2224 : :
2225 : 6 : _iov_free_buf(&iovs[0]);
2226 : 6 : _iov_free_buf(&iovs[1]);
2227 : 6 : _iov_free_buf(&md_iov);
2228 : 6 : }
2229 : :
2230 : : static void
2231 : 6 : dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits(void)
2232 : : {
2233 : 5 : struct iovec iovs[6], md_iov;
2234 : : uint32_t dif_flags;
2235 : : int i;
2236 : :
2237 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2238 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
2239 : :
2240 : : /* data[0][255:0] */
2241 : 6 : _iov_alloc_buf(&iovs[0], 256);
2242 : :
2243 : : /* data[0][511:256], data[1][255:0] */
2244 : 6 : _iov_alloc_buf(&iovs[1], 256 + 256);
2245 : :
2246 : : /* data[1][382:256] */
2247 : 6 : _iov_alloc_buf(&iovs[2], 128);
2248 : :
2249 : : /* data[1][383] */
2250 : 6 : _iov_alloc_buf(&iovs[3], 1);
2251 : :
2252 : : /* data[1][510:384] */
2253 : 6 : _iov_alloc_buf(&iovs[4], 126);
2254 : :
2255 : : /* data[1][511], data[2][511:0], data[3][511:0] */
2256 : 6 : _iov_alloc_buf(&iovs[5], 1 + 512 * 2);
2257 : :
2258 : 6 : _iov_alloc_buf(&md_iov, 8 * 4);
2259 : :
2260 : 6 : dix_generate_and_verify(iovs, 6, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1,
2261 : : dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
2262 : :
2263 [ + + ]: 42 : for (i = 0; i < 6; i++) {
2264 : 36 : _iov_free_buf(&iovs[i]);
2265 : : }
2266 : 6 : _iov_free_buf(&md_iov);
2267 : 6 : }
2268 : :
2269 : : static void
2270 : 6 : dix_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test(void)
2271 : : {
2272 : 5 : struct iovec iovs[6], md_iov;
2273 : : uint32_t dif_flags;
2274 : : int i;
2275 : :
2276 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2277 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
2278 : :
2279 : : /* data[0][2047:0] */
2280 : 6 : _iov_alloc_buf(&iovs[0], 2048);
2281 : :
2282 : : /* data[0][4095:2048], data[1][2047:0] */
2283 : 6 : _iov_alloc_buf(&iovs[1], 2048 + 2048);
2284 : :
2285 : : /* data[1][3071:2048] */
2286 : 6 : _iov_alloc_buf(&iovs[2], 1024);
2287 : :
2288 : : /* data[1][3072] */
2289 : 6 : _iov_alloc_buf(&iovs[3], 1);
2290 : :
2291 : : /* data[1][4094:3073] */
2292 : 6 : _iov_alloc_buf(&iovs[4], 1022);
2293 : :
2294 : : /* data[1][4095], data[2][4095:0], data[3][4095:0] */
2295 : 6 : _iov_alloc_buf(&iovs[5], 1 + 4096 * 2);
2296 : :
2297 : 6 : _iov_alloc_buf(&md_iov, 128 * 4);
2298 : :
2299 : 6 : dix_generate_and_verify(iovs, 6, &md_iov, 4096, 128, 4, false, SPDK_DIF_TYPE1,
2300 : : dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32);
2301 : 6 : dix_generate_and_verify(iovs, 6, &md_iov, 4096, 128, 4, false, SPDK_DIF_TYPE1,
2302 : : dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64);
2303 : :
2304 [ + + ]: 42 : for (i = 0; i < 6; i++) {
2305 : 36 : _iov_free_buf(&iovs[i]);
2306 : : }
2307 : 6 : _iov_free_buf(&md_iov);
2308 : 6 : }
2309 : :
2310 : : static void
2311 : 288 : _dix_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov,
2312 : : uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
2313 : : uint32_t inject_flags, bool dif_loc, enum spdk_dif_pi_format dif_pi_format)
2314 : : {
2315 : 288 : struct spdk_dif_ctx ctx = {};
2316 : 288 : struct spdk_dif_error err_blk = {};
2317 : 288 : uint32_t inject_offset = 0, dif_flags;
2318 : : int rc;
2319 : 240 : struct spdk_dif_ctx_init_ext_opts dif_opts;
2320 : :
2321 : 288 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2322 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
2323 : :
2324 : 288 : rc = ut_data_pattern_generate(iovs, iovcnt, block_size, 0, num_blocks);
2325 : 288 : CU_ASSERT(rc == 0);
2326 : :
2327 : 288 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
2328 : 288 : dif_opts.dif_pi_format = dif_pi_format;
2329 : 288 : rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, SPDK_DIF_TYPE1, dif_flags,
2330 : : 88, 0xFFFF, 0x88, 0, GUARD_SEED, &dif_opts);
2331 : 288 : CU_ASSERT(rc == 0);
2332 : :
2333 : 288 : rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx);
2334 : 288 : CU_ASSERT(rc == 0);
2335 : :
2336 : 288 : rc = spdk_dix_inject_error(iovs, iovcnt, md_iov, num_blocks, &ctx, inject_flags, &inject_offset);
2337 : 288 : CU_ASSERT(rc == 0);
2338 : :
2339 : 288 : rc = spdk_dix_verify(iovs, iovcnt, md_iov, num_blocks, &ctx, &err_blk);
2340 : 288 : CU_ASSERT(rc != 0);
2341 : :
2342 [ + + ]: 288 : if (inject_flags == SPDK_DIF_DATA_ERROR) {
2343 : 72 : CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type);
2344 : : } else {
2345 : 216 : CU_ASSERT(inject_flags == err_blk.err_type);
2346 : : }
2347 : 288 : CU_ASSERT(inject_offset == err_blk.err_offset);
2348 : 288 : }
2349 : :
2350 : : static void
2351 : 144 : dix_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov,
2352 : : uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
2353 : : uint32_t inject_flags, enum spdk_dif_pi_format dif_pi_format)
2354 : : {
2355 : : /* The case that DIF is contained in the first 8/16 bytes of metadata. */
2356 : 144 : _dix_inject_error_and_verify(iovs, iovcnt, md_iov, block_size, md_size, num_blocks,
2357 : : inject_flags, true, dif_pi_format);
2358 : :
2359 : : /* The case that DIF is contained in the last 8/16 bytes of metadata. */
2360 : 144 : _dix_inject_error_and_verify(iovs, iovcnt, md_iov, block_size, md_size, num_blocks,
2361 : : inject_flags, false, dif_pi_format);
2362 : 144 : }
2363 : :
2364 : : static void
2365 : 6 : dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test(void)
2366 : : {
2367 : 5 : struct iovec iovs[4], md_iov;
2368 : : int i, num_blocks;
2369 : :
2370 : 6 : num_blocks = 0;
2371 : :
2372 [ + + ]: 30 : for (i = 0; i < 4; i++) {
2373 : 24 : _iov_alloc_buf(&iovs[i], 4096 * (i + 1));
2374 : 24 : num_blocks += i + 1;
2375 : : }
2376 : :
2377 : 6 : _iov_alloc_buf(&md_iov, 128 * num_blocks);
2378 : :
2379 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks,
2380 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_16);
2381 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks,
2382 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
2383 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks,
2384 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
2385 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks,
2386 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_16);
2387 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks,
2388 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_32);
2389 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks,
2390 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
2391 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks,
2392 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
2393 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks,
2394 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_32);
2395 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks,
2396 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_64);
2397 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks,
2398 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
2399 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks,
2400 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
2401 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks,
2402 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_64);
2403 : :
2404 [ + + ]: 30 : for (i = 0; i < 4; i++) {
2405 : 24 : _iov_free_buf(&iovs[i]);
2406 : : }
2407 : 6 : _iov_free_buf(&md_iov);
2408 : 6 : }
2409 : :
2410 : : static void
2411 : 6 : dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test(void)
2412 : : {
2413 : 5 : struct iovec iovs[4], md_iov;
2414 : : int i;
2415 : :
2416 : 6 : _iov_alloc_buf(&iovs[0], 2048);
2417 : 6 : _iov_alloc_buf(&iovs[1], 2048);
2418 : 6 : _iov_alloc_buf(&iovs[2], 1);
2419 : 6 : _iov_alloc_buf(&iovs[3], 4095);
2420 : :
2421 : 6 : _iov_alloc_buf(&md_iov, 128 * 2);
2422 : :
2423 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2,
2424 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_16);
2425 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2,
2426 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
2427 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2,
2428 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_16);
2429 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2,
2430 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_16);
2431 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2,
2432 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_32);
2433 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2,
2434 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
2435 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2,
2436 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_32);
2437 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2,
2438 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_32);
2439 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2,
2440 : : SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_64);
2441 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2,
2442 : : SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
2443 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2,
2444 : : SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_64);
2445 : 6 : dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2,
2446 : : SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_64);
2447 : :
2448 [ + + ]: 30 : for (i = 0; i < 4; i++) {
2449 : 24 : _iov_free_buf(&iovs[i]);
2450 : : }
2451 : 6 : _iov_free_buf(&md_iov);
2452 : 6 : }
2453 : :
2454 : : static int
2455 : 168 : ut_readv(uint32_t read_base, uint32_t read_len, struct iovec *iovs, int iovcnt)
2456 : : {
2457 : : int i;
2458 : : uint32_t j, offset;
2459 : : uint8_t *buf;
2460 : :
2461 : 168 : offset = 0;
2462 [ + + ]: 450 : for (i = 0; i < iovcnt; i++) {
2463 : 378 : buf = iovs[i].iov_base;
2464 [ + + ]: 602490 : for (j = 0; j < iovs[i].iov_len; j++, offset++) {
2465 [ + + ]: 602208 : if (offset >= read_len) {
2466 : 96 : return offset;
2467 : : }
2468 : 602112 : buf[j] = DATA_PATTERN(read_base + offset);
2469 : : }
2470 : : }
2471 : :
2472 : 72 : return offset;
2473 : : }
2474 : :
2475 : : static void
2476 : 18 : _set_md_interleave_iovs_test(enum spdk_dif_pi_format dif_pi_format)
2477 : : {
2478 : 18 : struct spdk_dif_ctx ctx = {};
2479 : 18 : struct spdk_dif_error err_blk = {};
2480 : 18 : struct iovec iov1, iov2, dif_iovs[4] = {};
2481 : 18 : uint32_t dif_check_flags, data_len, read_len, data_offset, mapped_len = 0;
2482 : : uint8_t *buf1, *buf2;
2483 : : int rc;
2484 : 15 : struct spdk_dif_ctx_init_ext_opts dif_opts;
2485 : :
2486 : 18 : dif_check_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2487 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
2488 : :
2489 : 18 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
2490 : 18 : dif_opts.dif_pi_format = dif_pi_format;
2491 : 18 : rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
2492 : : dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED, &dif_opts);
2493 : 18 : CU_ASSERT(rc == 0);
2494 : :
2495 : : /* The first data buffer:
2496 : : * - Create iovec array to Leave a space for metadata for each block
2497 : : * - Split vectored read and so creating iovec array is done before every vectored read.
2498 : : */
2499 : 18 : buf1 = calloc(1, (4096 + 128) * 4);
2500 [ - + ]: 18 : SPDK_CU_ASSERT_FATAL(buf1 != NULL);
2501 : 18 : _iov_set_buf(&iov1, buf1, (4096 + 128) * 4);
2502 : :
2503 : 18 : data_offset = 0;
2504 : 18 : data_len = 4096 * 4;
2505 : :
2506 : : /* 1st read */
2507 : 18 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
2508 : : data_offset, data_len, &mapped_len, &ctx);
2509 : 18 : CU_ASSERT(rc == 4);
2510 : 18 : CU_ASSERT(mapped_len == 4096 * 4);
2511 : 18 : CU_ASSERT(_iov_check(&dif_iovs[0], buf1, 4096) == true);
2512 : 18 : CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true);
2513 : 18 : CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true);
2514 : 18 : CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 4096) == true);
2515 : :
2516 : 18 : read_len = ut_readv(data_offset, 1024, dif_iovs, 4);
2517 : 18 : CU_ASSERT(read_len == 1024);
2518 : :
2519 : 18 : rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx);
2520 : 18 : CU_ASSERT(rc == 0);
2521 : :
2522 : 18 : data_offset += read_len;
2523 : 18 : data_len -= read_len;
2524 : :
2525 : : /* 2nd read */
2526 : 18 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
2527 : : data_offset, data_len, &mapped_len, &ctx);
2528 : 18 : CU_ASSERT(rc == 4);
2529 : 18 : CU_ASSERT(mapped_len == 3072 + 4096 * 3);
2530 : 18 : CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 1024, 3072) == true);
2531 : 18 : CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true);
2532 : 18 : CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true);
2533 : 18 : CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 4096) == true);
2534 : :
2535 : 18 : read_len = ut_readv(data_offset, 3071, dif_iovs, 4);
2536 : 18 : CU_ASSERT(read_len == 3071);
2537 : :
2538 : 18 : rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx);
2539 : 18 : CU_ASSERT(rc == 0);
2540 : :
2541 : 18 : data_offset += read_len;
2542 : 18 : data_len -= read_len;
2543 : :
2544 : : /* 3rd read */
2545 : 18 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
2546 : : data_offset, data_len, &mapped_len, &ctx);
2547 : 18 : CU_ASSERT(rc == 4);
2548 : 18 : CU_ASSERT(mapped_len == 1 + 4096 * 3);
2549 : 18 : CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 4095, 1) == true);
2550 : 18 : CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true);
2551 : 18 : CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true);
2552 : 18 : CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 4096) == true);
2553 : :
2554 : 18 : read_len = ut_readv(data_offset, 1 + 4096 * 2 + 512, dif_iovs, 4);
2555 : 18 : CU_ASSERT(read_len == 1 + 4096 * 2 + 512);
2556 : :
2557 : 18 : rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx);
2558 : 18 : CU_ASSERT(rc == 0);
2559 : :
2560 : 18 : data_offset += read_len;
2561 : 18 : data_len -= read_len;
2562 : :
2563 : : /* 4th read */
2564 : 18 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
2565 : : data_offset, data_len, &mapped_len, &ctx);
2566 : 18 : CU_ASSERT(rc == 1);
2567 : 18 : CU_ASSERT(mapped_len == 3584);
2568 : 18 : CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + (4096 + 128) * 3 + 512, 3584) == true);
2569 : :
2570 : 18 : read_len = ut_readv(data_offset, 3584, dif_iovs, 1);
2571 : 18 : CU_ASSERT(read_len == 3584);
2572 : :
2573 : 18 : rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx);
2574 : 18 : CU_ASSERT(rc == 0);
2575 : :
2576 : 18 : data_offset += read_len;
2577 : 18 : CU_ASSERT(data_offset == 4096 * 4);
2578 : 18 : data_len -= read_len;
2579 : 18 : CU_ASSERT(data_len == 0);
2580 : :
2581 : : /* The second data buffer:
2582 : : * - Set data pattern with a space for metadata for each block.
2583 : : */
2584 : 18 : buf2 = calloc(1, (4096 + 128) * 4);
2585 [ - + ]: 18 : SPDK_CU_ASSERT_FATAL(buf2 != NULL);
2586 : 18 : _iov_set_buf(&iov2, buf2, (4096 + 128) * 4);
2587 : :
2588 : 18 : rc = ut_data_pattern_generate(&iov2, 1, 4096 + 128, 128, 4);
2589 : 18 : CU_ASSERT(rc == 0);
2590 : 18 : rc = spdk_dif_generate(&iov2, 1, 4, &ctx);
2591 : 18 : CU_ASSERT(rc == 0);
2592 : :
2593 : 18 : rc = spdk_dif_verify(&iov1, 1, 4, &ctx, &err_blk);
2594 : 18 : CU_ASSERT(rc == 0);
2595 : :
2596 : 18 : rc = spdk_dif_verify(&iov2, 1, 4, &ctx, &err_blk);
2597 : 18 : CU_ASSERT(rc == 0);
2598 : :
2599 : : /* Compare the first and the second data buffer by byte. */
2600 [ - + - + ]: 18 : rc = memcmp(buf1, buf2, (4096 + 128) * 4);
2601 : 18 : CU_ASSERT(rc == 0);
2602 : :
2603 : 18 : free(buf1);
2604 : 18 : free(buf2);
2605 : 18 : }
2606 : :
2607 : : static void
2608 : 6 : set_md_interleave_iovs_test(void)
2609 : : {
2610 : 6 : _set_md_interleave_iovs_test(SPDK_DIF_PI_FORMAT_16);
2611 : 6 : _set_md_interleave_iovs_test(SPDK_DIF_PI_FORMAT_32);
2612 : 6 : _set_md_interleave_iovs_test(SPDK_DIF_PI_FORMAT_64);
2613 : 6 : }
2614 : :
2615 : : static void
2616 : 6 : set_md_interleave_iovs_split_test(void)
2617 : : {
2618 : 6 : struct spdk_dif_ctx ctx = {};
2619 : 6 : struct spdk_dif_error err_blk = {};
2620 : 6 : struct iovec iovs1[7], iovs2[7], dif_iovs[8] = {};
2621 : 6 : uint32_t dif_check_flags, data_len, read_len, data_offset, mapped_len = 0;
2622 : : int rc, i;
2623 : 5 : struct spdk_dif_ctx_init_ext_opts dif_opts;
2624 : :
2625 : 6 : dif_check_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2626 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
2627 : :
2628 : 6 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
2629 : 6 : dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
2630 : 6 : rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1,
2631 : : dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED, &dif_opts);
2632 : 6 : CU_ASSERT(rc == 0);
2633 : :
2634 : : /* The first SGL data buffer:
2635 : : * - Create iovec array to leave a space for metadata for each block
2636 : : * - Split vectored read and so creating iovec array is done before every vectored read.
2637 : : */
2638 : 6 : _iov_alloc_buf(&iovs1[0], 512 + 8 + 128);
2639 : 6 : _iov_alloc_buf(&iovs1[1], 128);
2640 : 6 : _iov_alloc_buf(&iovs1[2], 256 + 8);
2641 : 6 : _iov_alloc_buf(&iovs1[3], 100);
2642 : 6 : _iov_alloc_buf(&iovs1[4], 412 + 5);
2643 : 6 : _iov_alloc_buf(&iovs1[5], 3 + 300);
2644 : 6 : _iov_alloc_buf(&iovs1[6], 212 + 8);
2645 : :
2646 : 6 : data_offset = 0;
2647 : 6 : data_len = 512 * 4;
2648 : :
2649 : : /* 1st read */
2650 : 6 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7,
2651 : : data_offset, data_len, &mapped_len, &ctx);
2652 : 6 : CU_ASSERT(rc == 8);
2653 : 6 : CU_ASSERT(mapped_len == 512 * 4);
2654 : 6 : CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base, 512) == true);
2655 : 6 : CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true);
2656 : 6 : CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true);
2657 : 6 : CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true);
2658 : 6 : CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true);
2659 : 6 : CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true);
2660 : 6 : CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true);
2661 : 6 : CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true);
2662 : :
2663 : 6 : read_len = ut_readv(data_offset, 128, dif_iovs, 8);
2664 : 6 : CU_ASSERT(read_len == 128);
2665 : :
2666 : 6 : rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx);
2667 : 6 : CU_ASSERT(rc == 0);
2668 : :
2669 : 6 : data_offset += read_len;
2670 : 6 : data_len -= read_len;
2671 : :
2672 : : /* 2nd read */
2673 : 6 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7,
2674 : : data_offset, data_len, &mapped_len, &ctx);
2675 : 6 : CU_ASSERT(rc == 8);
2676 : 6 : CU_ASSERT(mapped_len == 384 + 512 * 3);
2677 : 6 : CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base + 128, 384) == true);
2678 : 6 : CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true);
2679 : 6 : CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true);
2680 : 6 : CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true);
2681 : 6 : CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true);
2682 : 6 : CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true);
2683 : 6 : CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true);
2684 : 6 : CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true);
2685 : :
2686 : 6 : read_len = ut_readv(data_offset, 383, dif_iovs, 8);
2687 : 6 : CU_ASSERT(read_len == 383);
2688 : :
2689 : 6 : rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx);
2690 : 6 : CU_ASSERT(rc == 0);
2691 : :
2692 : 6 : data_offset += read_len;
2693 : 6 : data_len -= read_len;
2694 : :
2695 : : /* 3rd read */
2696 : 6 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7,
2697 : : data_offset, data_len, &mapped_len, &ctx);
2698 : 6 : CU_ASSERT(rc == 8);
2699 : 6 : CU_ASSERT(mapped_len == 1 + 512 * 3);
2700 : 6 : CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base + 511, 1) == true);
2701 : 6 : CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true);
2702 : 6 : CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true);
2703 : 6 : CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true);
2704 : 6 : CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true);
2705 : 6 : CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true);
2706 : 6 : CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true);
2707 : 6 : CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true);
2708 : :
2709 : 6 : read_len = ut_readv(data_offset, 1 + 512 * 2 + 128, dif_iovs, 8);
2710 : 6 : CU_ASSERT(read_len == 1 + 512 * 2 + 128);
2711 : :
2712 : 6 : rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx);
2713 : 6 : CU_ASSERT(rc == 0);
2714 : :
2715 : 6 : data_offset += read_len;
2716 : 6 : data_len -= read_len;
2717 : :
2718 : : /* 4th read */
2719 : 6 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7,
2720 : : data_offset, data_len, &mapped_len, &ctx);
2721 : 6 : CU_ASSERT(rc == 2);
2722 : 6 : CU_ASSERT(mapped_len == 384);
2723 : 6 : CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[5].iov_base + 3 + 128, 172) == true);
2724 : 6 : CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[6].iov_base, 212) == true);
2725 : :
2726 : 6 : read_len = ut_readv(data_offset, 384, dif_iovs, 8);
2727 : 6 : CU_ASSERT(read_len == 384);
2728 : :
2729 : 6 : rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx);
2730 : 6 : CU_ASSERT(rc == 0);
2731 : :
2732 : 6 : data_offset += read_len;
2733 : 6 : CU_ASSERT(data_offset == 512 * 4);
2734 : 6 : data_len -= read_len;
2735 : 6 : CU_ASSERT(data_len == 0);
2736 : :
2737 : : /* The second SGL data buffer:
2738 : : * - Set data pattern with a space for metadata for each block.
2739 : : */
2740 : 6 : _iov_alloc_buf(&iovs2[0], 512 + 8 + 128);
2741 : 6 : _iov_alloc_buf(&iovs2[1], 128);
2742 : 6 : _iov_alloc_buf(&iovs2[2], 256 + 8);
2743 : 6 : _iov_alloc_buf(&iovs2[3], 100);
2744 : 6 : _iov_alloc_buf(&iovs2[4], 412 + 5);
2745 : 6 : _iov_alloc_buf(&iovs2[5], 3 + 300);
2746 : 6 : _iov_alloc_buf(&iovs2[6], 212 + 8);
2747 : :
2748 : 6 : rc = ut_data_pattern_generate(iovs2, 7, 512 + 8, 8, 4);
2749 : 6 : CU_ASSERT(rc == 0);
2750 : 6 : rc = spdk_dif_generate(iovs2, 7, 4, &ctx);
2751 : 6 : CU_ASSERT(rc == 0);
2752 : :
2753 : 6 : rc = spdk_dif_verify(iovs1, 7, 4, &ctx, &err_blk);
2754 : 6 : CU_ASSERT(rc == 0);
2755 : :
2756 : 6 : rc = spdk_dif_verify(iovs2, 7, 4, &ctx, &err_blk);
2757 : 6 : CU_ASSERT(rc == 0);
2758 : :
2759 : : /* Compare the first and the second SGL data buffer by byte. */
2760 [ + + ]: 48 : for (i = 0; i < 7; i++) {
2761 [ - + - + ]: 42 : rc = memcmp(iovs1[i].iov_base, iovs2[i].iov_base,
2762 : 28 : iovs1[i].iov_len);
2763 : 42 : CU_ASSERT(rc == 0);
2764 : : }
2765 : :
2766 [ + + ]: 48 : for (i = 0; i < 7; i++) {
2767 : 42 : _iov_free_buf(&iovs1[i]);
2768 : 42 : _iov_free_buf(&iovs2[i]);
2769 : : }
2770 : 6 : }
2771 : :
2772 : : static void
2773 : 6 : dif_generate_stream_pi_16_test(void)
2774 : : {
2775 : 5 : struct iovec iov;
2776 : 5 : struct spdk_dif_ctx ctx;
2777 : 5 : struct spdk_dif_error err_blk;
2778 : : uint32_t dif_flags;
2779 : : int rc;
2780 : 5 : struct spdk_dif_ctx_init_ext_opts dif_opts;
2781 : :
2782 : 6 : _iov_alloc_buf(&iov, (512 + 8) * 5);
2783 : :
2784 : 6 : rc = ut_data_pattern_generate(&iov, 1, 512 + 8, 8, 5);
2785 : 6 : CU_ASSERT(rc == 0);
2786 : :
2787 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2788 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
2789 : :
2790 : 6 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
2791 : 6 : dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
2792 : 6 : rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, dif_flags,
2793 : : 22, 0xFFFF, 0x22, 0, GUARD_SEED, &dif_opts);
2794 : 6 : CU_ASSERT(rc == 0);
2795 : :
2796 : 6 : rc = spdk_dif_generate_stream(&iov, 1, 0, 511, &ctx);
2797 : 6 : CU_ASSERT(rc == 0);
2798 : :
2799 : 6 : rc = spdk_dif_generate_stream(&iov, 1, 511, 1, &ctx);
2800 : 6 : CU_ASSERT(rc == 0);
2801 : :
2802 : 6 : rc = spdk_dif_generate_stream(&iov, 1, 512, 256, &ctx);
2803 : 6 : CU_ASSERT(rc == 0);
2804 : :
2805 : 6 : rc = spdk_dif_generate_stream(&iov, 1, 768, 512, &ctx);
2806 : 6 : CU_ASSERT(rc == 0);
2807 : :
2808 : 6 : rc = spdk_dif_generate_stream(&iov, 1, 1280, 1024, &ctx);
2809 : 6 : CU_ASSERT(rc == 0);
2810 : :
2811 : 6 : rc = spdk_dif_generate_stream(&iov, 1, 2304, 256, &ctx);
2812 : 6 : CU_ASSERT(rc == 0);
2813 : :
2814 : 6 : rc = spdk_dif_generate_stream(&iov, 1, 2560, 512, &ctx);
2815 : 6 : CU_ASSERT(rc == -ERANGE);
2816 : :
2817 : 6 : rc = spdk_dif_verify(&iov, 1, 5, &ctx, &err_blk);
2818 : 6 : CU_ASSERT(rc == 0);
2819 : :
2820 : 6 : rc = ut_data_pattern_verify(&iov, 1, 512 + 8, 8, 5);
2821 : 6 : CU_ASSERT(rc == 0);
2822 : :
2823 : 6 : _iov_free_buf(&iov);
2824 : 6 : }
2825 : :
2826 : : static void
2827 : 12 : _dif_generate_stream_test(enum spdk_dif_pi_format dif_pi_format)
2828 : : {
2829 : 10 : struct iovec iov;
2830 : 10 : struct spdk_dif_ctx ctx;
2831 : 10 : struct spdk_dif_error err_blk;
2832 : : uint32_t dif_flags;
2833 : : int rc;
2834 : 10 : struct spdk_dif_ctx_init_ext_opts dif_opts;
2835 : :
2836 : 12 : _iov_alloc_buf(&iov, (4096 + 128) * 5);
2837 : :
2838 : 12 : rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 5);
2839 : 12 : CU_ASSERT(rc == 0);
2840 : :
2841 : 12 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2842 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
2843 : :
2844 : 12 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
2845 : 12 : dif_opts.dif_pi_format = dif_pi_format;
2846 : 12 : rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, dif_flags,
2847 : : 22, 0xFFFF, 0x22, 0, GUARD_SEED, &dif_opts);
2848 : 12 : CU_ASSERT(rc == 0);
2849 : :
2850 : 12 : rc = spdk_dif_generate_stream(&iov, 1, 0, 4095, &ctx);
2851 : 12 : CU_ASSERT(rc == 0);
2852 : :
2853 : 12 : rc = spdk_dif_generate_stream(&iov, 1, 4095, 1, &ctx);
2854 : 12 : CU_ASSERT(rc == 0);
2855 : :
2856 : 12 : rc = spdk_dif_generate_stream(&iov, 1, 4096, 2048, &ctx);
2857 : 12 : CU_ASSERT(rc == 0);
2858 : :
2859 : 12 : rc = spdk_dif_generate_stream(&iov, 1, 6144, 4096, &ctx);
2860 : 12 : CU_ASSERT(rc == 0);
2861 : :
2862 : 12 : rc = spdk_dif_generate_stream(&iov, 1, 10240, 8192, &ctx);
2863 : 12 : CU_ASSERT(rc == 0);
2864 : :
2865 : 12 : rc = spdk_dif_generate_stream(&iov, 1, 18432, 2048, &ctx);
2866 : 12 : CU_ASSERT(rc == 0);
2867 : :
2868 : 12 : rc = spdk_dif_generate_stream(&iov, 1, 20480, 4096, &ctx);
2869 : 12 : CU_ASSERT(rc == -ERANGE);
2870 : :
2871 : 12 : rc = spdk_dif_verify(&iov, 1, 5, &ctx, &err_blk);
2872 : 12 : CU_ASSERT(rc == 0);
2873 : :
2874 : 12 : rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 5);
2875 : 12 : CU_ASSERT(rc == 0);
2876 : :
2877 : 12 : _iov_free_buf(&iov);
2878 : 12 : }
2879 : :
2880 : : static void
2881 : 6 : dif_generate_stream_test(void)
2882 : : {
2883 : 6 : _dif_generate_stream_test(SPDK_DIF_PI_FORMAT_32);
2884 : 6 : _dif_generate_stream_test(SPDK_DIF_PI_FORMAT_64);
2885 : 6 : }
2886 : :
2887 : : static void
2888 : 6 : set_md_interleave_iovs_alignment_test(void)
2889 : : {
2890 : 6 : struct iovec iovs[3], dif_iovs[5] = {};
2891 : 6 : uint32_t mapped_len = 0;
2892 : : int rc;
2893 : 5 : struct spdk_dif_ctx ctx;
2894 : 5 : struct spdk_dif_ctx_init_ext_opts dif_opts;
2895 : :
2896 : 6 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
2897 : 6 : dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
2898 : 6 : rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1,
2899 : : 0, 0, 0, 0, 0, 0, &dif_opts);
2900 : 6 : CU_ASSERT(rc == 0);
2901 : :
2902 : : /* The case that buffer size is smaller than necessary. */
2903 : 6 : _iov_set_buf(&iovs[0], (uint8_t *)0xDEADBEEF, 1024);
2904 : 6 : _iov_set_buf(&iovs[1], (uint8_t *)0xFEEDBEEF, 1024);
2905 : 6 : _iov_set_buf(&iovs[2], (uint8_t *)0xC0FFEE, 24);
2906 : :
2907 : 6 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 0, 2048, &mapped_len, &ctx);
2908 : 6 : CU_ASSERT(rc == -ERANGE);
2909 : :
2910 : : /* The following are the normal cases. */
2911 : 6 : _iov_set_buf(&iovs[2], (uint8_t *)0xC0FFEE, 32);
2912 : :
2913 : : /* data length is less than a data block size. */
2914 : 6 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 0, 500, &mapped_len, &ctx);
2915 : 6 : CU_ASSERT(rc == 1);
2916 : 6 : CU_ASSERT(mapped_len == 500);
2917 : 6 : CU_ASSERT(_iov_check(&dif_iovs[0], (void *)0xDEADBEEF, 500) == true);
2918 : :
2919 : : /* Pass enough number of iovecs */
2920 : 6 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 500, 1000, &mapped_len, &ctx);
2921 : 6 : CU_ASSERT(rc == 4);
2922 : 6 : CU_ASSERT(mapped_len == 1000);
2923 : 6 : CU_ASSERT(_iov_check(&dif_iovs[0], (void *)(0xDEADBEEF + 500), 12) == true);
2924 : 6 : CU_ASSERT(_iov_check(&dif_iovs[1], (void *)(0xDEADBEEF + 520), 504) == true);
2925 : 6 : CU_ASSERT(_iov_check(&dif_iovs[2], (void *)0xFEEDBEEF, 8) == true);
2926 : 6 : CU_ASSERT(_iov_check(&dif_iovs[3], (void *)(0xFEEDBEEF + 16), 476) == true);
2927 : :
2928 : : /* Pass iovecs smaller than necessary */
2929 : 6 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 3, iovs, 3, 500, 1000, &mapped_len, &ctx);
2930 : 6 : CU_ASSERT(rc == 3);
2931 : 6 : CU_ASSERT(mapped_len == 524);
2932 : 6 : CU_ASSERT(_iov_check(&dif_iovs[0], (void *)(0xDEADBEEF + 500), 12) == true);
2933 : 6 : CU_ASSERT(_iov_check(&dif_iovs[1], (void *)(0xDEADBEEF + 520), 504) == true);
2934 : 6 : CU_ASSERT(_iov_check(&dif_iovs[2], (void *)0xFEEDBEEF, 8) == true);
2935 : :
2936 : 6 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 1500, 500, &mapped_len, &ctx);
2937 : 6 : CU_ASSERT(rc == 2);
2938 : 6 : CU_ASSERT(mapped_len == 500);
2939 : 6 : CU_ASSERT(_iov_check(&dif_iovs[0], (void *)(0xFEEDBEEF + 492), 36) == true);
2940 : 6 : CU_ASSERT(_iov_check(&dif_iovs[1], (void *)(0xFEEDBEEF + 536), 464) == true);
2941 : :
2942 : 6 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 2000, 48, &mapped_len, &ctx);
2943 : 6 : CU_ASSERT(rc == 2);
2944 : 6 : CU_ASSERT(mapped_len == 48);
2945 : 6 : CU_ASSERT(_iov_check(&dif_iovs[0], (void *)0xFEEDBEEF + 1000, 24) == true);
2946 : 6 : CU_ASSERT(_iov_check(&dif_iovs[1], (void *)0xC0FFEE, 24) == true);
2947 : 6 : }
2948 : :
2949 : : static void
2950 : 18 : _dif_generate_split_test(enum spdk_dif_pi_format dif_pi_format)
2951 : : {
2952 : 18 : struct spdk_dif_ctx ctx = {};
2953 : 15 : struct iovec iov;
2954 : : uint8_t *buf1, *buf2;
2955 : 15 : struct _dif_sgl sgl;
2956 : 18 : uint64_t guard = 0, prev_guard;
2957 : : uint32_t dif_flags;
2958 : : int rc;
2959 : 15 : struct spdk_dif_ctx_init_ext_opts dif_opts;
2960 : :
2961 : 18 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
2962 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
2963 : :
2964 : 18 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
2965 : 18 : dif_opts.dif_pi_format = dif_pi_format;
2966 : 18 : rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
2967 : : dif_flags, 0, 0, 0, 0, GUARD_SEED, &dif_opts);
2968 : 18 : CU_ASSERT(rc == 0);
2969 : :
2970 : 18 : buf1 = calloc(1, 4096 + 128);
2971 [ - + ]: 18 : SPDK_CU_ASSERT_FATAL(buf1 != NULL);
2972 : 18 : _iov_set_buf(&iov, buf1, 4096 + 128);
2973 : :
2974 : 18 : rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1);
2975 : 18 : CU_ASSERT(rc == 0);
2976 : :
2977 : 18 : _dif_sgl_init(&sgl, &iov, 1);
2978 : :
2979 : 18 : guard = GUARD_SEED;
2980 : 18 : prev_guard = GUARD_SEED;
2981 : :
2982 : 18 : guard = _dif_generate_split(&sgl, 0, 1000, guard, 0, &ctx);
2983 : 18 : CU_ASSERT(sgl.iov_offset == 1000);
2984 : 18 : CU_ASSERT(guard == _generate_guard(prev_guard, buf1, 1000, dif_pi_format));
2985 : :
2986 : 18 : prev_guard = guard;
2987 : :
2988 : 18 : guard = _dif_generate_split(&sgl, 1000, 3000, guard, 0, &ctx);
2989 : 18 : CU_ASSERT(sgl.iov_offset == 4000);
2990 : 18 : CU_ASSERT(guard == _generate_guard(prev_guard, buf1 + 1000, 3000, dif_pi_format));
2991 : :
2992 : 18 : guard = _dif_generate_split(&sgl, 4000, 96 + 128, guard, 0, &ctx);
2993 : 18 : CU_ASSERT(guard == GUARD_SEED);
2994 : 18 : CU_ASSERT(sgl.iov_offset == 0);
2995 : 18 : CU_ASSERT(sgl.iovcnt == 0);
2996 : :
2997 : 18 : rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 1);
2998 : 18 : CU_ASSERT(rc == 0);
2999 : :
3000 : 18 : _dif_sgl_init(&sgl, &iov, 1);
3001 : :
3002 : 18 : rc = dif_verify(&sgl, 1, &ctx, NULL);
3003 : 18 : CU_ASSERT(rc == 0);
3004 : :
3005 : 18 : buf2 = calloc(1, 4096 + 128);
3006 [ - + ]: 18 : SPDK_CU_ASSERT_FATAL(buf2 != NULL);
3007 : 18 : _iov_set_buf(&iov, buf2, 4096 + 128);
3008 : :
3009 : 18 : rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1);
3010 : 18 : CU_ASSERT(rc == 0);
3011 : :
3012 : 18 : _dif_sgl_init(&sgl, &iov, 1);
3013 : :
3014 : 18 : dif_generate(&sgl, 1, &ctx);
3015 : :
3016 : 18 : rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 1);
3017 : 18 : CU_ASSERT(rc == 0);
3018 : :
3019 : 18 : _dif_sgl_init(&sgl, &iov, 1);
3020 : :
3021 : 18 : rc = dif_verify(&sgl, 1, &ctx, NULL);
3022 : 18 : CU_ASSERT(rc == 0);
3023 : :
3024 [ - + - + ]: 18 : rc = memcmp(buf1, buf2, 4096 + 128);
3025 : 18 : CU_ASSERT(rc == 0);
3026 : :
3027 : 18 : free(buf1);
3028 : 18 : free(buf2);
3029 : 18 : }
3030 : :
3031 : : static void
3032 : 6 : dif_generate_split_test(void)
3033 : : {
3034 : 6 : _dif_generate_split_test(SPDK_DIF_PI_FORMAT_16);
3035 : 6 : _dif_generate_split_test(SPDK_DIF_PI_FORMAT_32);
3036 : 6 : _dif_generate_split_test(SPDK_DIF_PI_FORMAT_64);
3037 : 6 : }
3038 : :
3039 : : static void
3040 : 18 : _set_md_interleave_iovs_multi_segments_test(enum spdk_dif_pi_format dif_pi_format)
3041 : : {
3042 : 18 : struct spdk_dif_ctx ctx = {};
3043 : 18 : struct spdk_dif_error err_blk = {};
3044 : 18 : struct iovec iov1 = {}, iov2 = {}, dif_iovs[4] = {};
3045 : 18 : uint32_t dif_check_flags, data_len, read_len, data_offset, read_offset, mapped_len = 0;
3046 : : uint8_t *buf1, *buf2;
3047 : : int rc;
3048 : 15 : struct spdk_dif_ctx_init_ext_opts dif_opts;
3049 : :
3050 : 18 : dif_check_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
3051 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
3052 : :
3053 : 18 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
3054 : 18 : dif_opts.dif_pi_format = dif_pi_format;
3055 : 18 : rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
3056 : : dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED, &dif_opts);
3057 : 18 : CU_ASSERT(rc == 0);
3058 : :
3059 : : /* The first data buffer:
3060 : : * - Data buffer is split into multi data segments
3061 : : * - For each data segment,
3062 : : * - Create iovec array to Leave a space for metadata for each block
3063 : : * - Split vectored read and so creating iovec array is done before every vectored read.
3064 : : */
3065 : 18 : buf1 = calloc(1, (4096 + 128) * 4);
3066 [ - + ]: 18 : SPDK_CU_ASSERT_FATAL(buf1 != NULL);
3067 : 18 : _iov_set_buf(&iov1, buf1, (4096 + 128) * 4);
3068 : :
3069 : : /* 1st data segment */
3070 : 18 : data_offset = 0;
3071 : 18 : data_len = 1024;
3072 : :
3073 : 18 : spdk_dif_ctx_set_data_offset(&ctx, data_offset);
3074 : :
3075 : 18 : read_offset = 0;
3076 : :
3077 : : /* 1st read in 1st data segment */
3078 : 18 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
3079 : : read_offset, data_len - read_offset,
3080 : : &mapped_len, &ctx);
3081 : 18 : CU_ASSERT(rc == 1);
3082 : 18 : CU_ASSERT(mapped_len == 1024);
3083 : 18 : CU_ASSERT(_iov_check(&dif_iovs[0], buf1, 1024) == true);
3084 : :
3085 : 18 : read_len = ut_readv(data_offset + read_offset, 1024, dif_iovs, 4);
3086 : 18 : CU_ASSERT(read_len == 1024);
3087 : :
3088 : 18 : rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx);
3089 : 18 : CU_ASSERT(rc == 0);
3090 : :
3091 : 18 : read_offset += read_len;
3092 : 18 : CU_ASSERT(read_offset == data_len);
3093 : :
3094 : : /* 2nd data segment */
3095 : 18 : data_offset += data_len;
3096 : 18 : data_len = 3072 + 4096 * 2 + 512;
3097 : :
3098 : 18 : spdk_dif_ctx_set_data_offset(&ctx, data_offset);
3099 : 18 : _iov_set_buf(&iov1, buf1 + 1024, 3072 + 128 + (4096 + 128) * 3 + 512);
3100 : :
3101 : 18 : read_offset = 0;
3102 : :
3103 : : /* 1st read in 2nd data segment */
3104 : 18 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
3105 : : read_offset, data_len - read_offset,
3106 : : &mapped_len, &ctx);
3107 : 18 : CU_ASSERT(rc == 4);
3108 : 18 : CU_ASSERT(mapped_len == 3072 + 4096 * 2 + 512);
3109 : 18 : CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 1024, 3072) == true);
3110 : 18 : CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true);
3111 : 18 : CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true);
3112 : 18 : CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 512) == true);
3113 : :
3114 : 18 : read_len = ut_readv(data_offset + read_offset, 3071, dif_iovs, 4);
3115 : 18 : CU_ASSERT(read_len == 3071);
3116 : :
3117 : 18 : rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx);
3118 : 18 : CU_ASSERT(rc == 0);
3119 : :
3120 : 18 : read_offset += read_len;
3121 : :
3122 : : /* 2nd read in 2nd data segment */
3123 : 18 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
3124 : : read_offset, data_len - read_offset,
3125 : : &mapped_len, &ctx);
3126 : 18 : CU_ASSERT(rc == 4);
3127 : 18 : CU_ASSERT(mapped_len == 1 + 4096 * 2 + 512);
3128 : 18 : CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 4095, 1) == true);
3129 : 18 : CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true);
3130 : 18 : CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true);
3131 : 18 : CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 512) == true);
3132 : :
3133 : 18 : read_len = ut_readv(data_offset + read_offset, 1 + 4096 * 2 + 512, dif_iovs, 4);
3134 : 18 : CU_ASSERT(read_len == 1 + 4096 * 2 + 512);
3135 : :
3136 : 18 : rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx);
3137 : 18 : CU_ASSERT(rc == 0);
3138 : :
3139 : 18 : read_offset += read_len;
3140 : 18 : CU_ASSERT(read_offset == data_len);
3141 : :
3142 : : /* 3rd data segment */
3143 : 18 : data_offset += data_len;
3144 : 18 : data_len = 3584;
3145 : :
3146 : 18 : spdk_dif_ctx_set_data_offset(&ctx, data_offset);
3147 : 18 : _iov_set_buf(&iov1, buf1 + (4096 + 128) * 3 + 512, 3584 + 128);
3148 : :
3149 : 18 : read_offset = 0;
3150 : :
3151 : : /* 1st read in 3rd data segment */
3152 : 18 : rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
3153 : : read_offset, data_len - read_offset,
3154 : : &mapped_len, &ctx);
3155 : 18 : CU_ASSERT(rc == 1);
3156 : 18 : CU_ASSERT(mapped_len == 3584);
3157 : 18 : CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + (4096 + 128) * 3 + 512, 3584) == true);
3158 : :
3159 : 18 : read_len = ut_readv(data_offset + read_offset, 3584, dif_iovs, 1);
3160 : 18 : CU_ASSERT(read_len == 3584);
3161 : :
3162 : 18 : rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx);
3163 : 18 : CU_ASSERT(rc == 0);
3164 : :
3165 : 18 : read_offset += read_len;
3166 : 18 : CU_ASSERT(read_offset == data_len);
3167 : 18 : data_offset += data_len;
3168 : 18 : CU_ASSERT(data_offset == 4096 * 4);
3169 : :
3170 : 18 : spdk_dif_ctx_set_data_offset(&ctx, 0);
3171 : 18 : _iov_set_buf(&iov1, buf1, (4096 + 128) * 4);
3172 : :
3173 : : /* The second data buffer:
3174 : : * - Set data pattern with a space for metadata for each block.
3175 : : */
3176 : 18 : buf2 = calloc(1, (4096 + 128) * 4);
3177 [ - + ]: 18 : SPDK_CU_ASSERT_FATAL(buf2 != NULL);
3178 : 18 : _iov_set_buf(&iov2, buf2, (4096 + 128) * 4);
3179 : :
3180 : 18 : rc = ut_data_pattern_generate(&iov2, 1, 4096 + 128, 128, 4);
3181 : 18 : CU_ASSERT(rc == 0);
3182 : :
3183 : 18 : rc = spdk_dif_generate(&iov2, 1, 4, &ctx);
3184 : 18 : CU_ASSERT(rc == 0);
3185 : :
3186 : 18 : rc = spdk_dif_verify(&iov1, 1, 4, &ctx, &err_blk);
3187 : 18 : CU_ASSERT(rc == 0);
3188 : :
3189 : 18 : rc = spdk_dif_verify(&iov2, 1, 4, &ctx, &err_blk);
3190 : 18 : CU_ASSERT(rc == 0);
3191 : :
3192 : : /* Compare the first and the second data buffer by byte. */
3193 [ - + - + ]: 18 : rc = memcmp(buf1, buf2, (4096 + 128) * 4);
3194 : 18 : CU_ASSERT(rc == 0);
3195 : :
3196 : 18 : free(buf1);
3197 : 18 : free(buf2);
3198 : 18 : }
3199 : :
3200 : : static void
3201 : 6 : set_md_interleave_iovs_multi_segments_test(void)
3202 : : {
3203 : 6 : _set_md_interleave_iovs_multi_segments_test(SPDK_DIF_PI_FORMAT_16);
3204 : 6 : _set_md_interleave_iovs_multi_segments_test(SPDK_DIF_PI_FORMAT_32);
3205 : 6 : _set_md_interleave_iovs_multi_segments_test(SPDK_DIF_PI_FORMAT_64);
3206 : 6 : }
3207 : :
3208 : : static void
3209 : 18 : _dif_verify_split_test(enum spdk_dif_pi_format dif_pi_format)
3210 : : {
3211 : 18 : struct spdk_dif_ctx ctx = {};
3212 : 18 : struct spdk_dif_error err_blk = {};
3213 : 15 : struct iovec iov;
3214 : : uint8_t *buf;
3215 : 15 : struct _dif_sgl sgl;
3216 : 18 : uint64_t guard = 0, prev_guard = 0;
3217 : : uint32_t dif_flags;
3218 : : int rc;
3219 : 15 : struct spdk_dif_ctx_init_ext_opts dif_opts;
3220 : :
3221 : 18 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
3222 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
3223 : :
3224 : 18 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
3225 : 18 : dif_opts.dif_pi_format = dif_pi_format;
3226 : 18 : rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
3227 : : dif_flags, 0, 0, 0, 0, GUARD_SEED, &dif_opts);
3228 : 18 : CU_ASSERT(rc == 0);
3229 : :
3230 : 18 : buf = calloc(1, 4096 + 128);
3231 [ - + ]: 18 : SPDK_CU_ASSERT_FATAL(buf != NULL);
3232 : 18 : _iov_set_buf(&iov, buf, 4096 + 128);
3233 : :
3234 : 18 : rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1);
3235 : 18 : CU_ASSERT(rc == 0);
3236 : :
3237 : 18 : _dif_sgl_init(&sgl, &iov, 1);
3238 : :
3239 : 18 : dif_generate(&sgl, 1, &ctx);
3240 : :
3241 : 18 : _dif_sgl_init(&sgl, &iov, 1);
3242 : :
3243 : 18 : guard = GUARD_SEED;
3244 : 18 : prev_guard = GUARD_SEED;
3245 : :
3246 : 18 : rc = _dif_verify_split(&sgl, 0, 1000, &guard, 0, &ctx, &err_blk);
3247 : 18 : CU_ASSERT(rc == 0);
3248 : 18 : CU_ASSERT(guard == _generate_guard(prev_guard, buf, 1000, dif_pi_format));
3249 : 18 : CU_ASSERT(sgl.iov_offset == 1000);
3250 : :
3251 : 18 : prev_guard = guard;
3252 : :
3253 : 18 : rc = _dif_verify_split(&sgl, 1000, 3000, &guard, 0, &ctx, &err_blk);
3254 : 18 : CU_ASSERT(rc == 0);
3255 : 18 : CU_ASSERT(guard == _generate_guard(prev_guard, buf + 1000, 3000, dif_pi_format));
3256 : 18 : CU_ASSERT(sgl.iov_offset == 4000);
3257 : :
3258 : 18 : rc = _dif_verify_split(&sgl, 4000, 96 + 128, &guard, 0, &ctx, &err_blk);
3259 : 18 : CU_ASSERT(rc == 0);
3260 : 18 : CU_ASSERT(guard == GUARD_SEED);
3261 : 18 : CU_ASSERT(sgl.iov_offset == 0);
3262 : 18 : CU_ASSERT(sgl.iovcnt == 0);
3263 : :
3264 : 18 : _dif_sgl_init(&sgl, &iov, 1);
3265 : :
3266 : 18 : rc = dif_verify(&sgl, 1, &ctx, &err_blk);
3267 : 18 : CU_ASSERT(rc == 0);
3268 : :
3269 : 18 : rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 1);
3270 : 18 : CU_ASSERT(rc == 0);
3271 : :
3272 : 18 : free(buf);
3273 : 18 : }
3274 : :
3275 : : static void
3276 : 6 : dif_verify_split_test(void)
3277 : : {
3278 : 6 : _dif_verify_split_test(SPDK_DIF_PI_FORMAT_16);
3279 : 6 : _dif_verify_split_test(SPDK_DIF_PI_FORMAT_32);
3280 : 6 : _dif_verify_split_test(SPDK_DIF_PI_FORMAT_64);
3281 : 6 : }
3282 : :
3283 : : static void
3284 : 18 : _dif_verify_stream_multi_segments_test(enum spdk_dif_pi_format dif_pi_format)
3285 : : {
3286 : 18 : struct spdk_dif_ctx ctx = {};
3287 : 18 : struct spdk_dif_error err_blk = {};
3288 : 18 : struct iovec iov = {};
3289 : : uint8_t *buf;
3290 : : uint32_t dif_flags;
3291 : : int rc;
3292 : 15 : struct spdk_dif_ctx_init_ext_opts dif_opts;
3293 : :
3294 : 18 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
3295 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
3296 : :
3297 : 18 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
3298 : 18 : dif_opts.dif_pi_format = dif_pi_format;
3299 : 18 : rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
3300 : : dif_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED, &dif_opts);
3301 : 18 : CU_ASSERT(rc == 0);
3302 : :
3303 : 18 : buf = calloc(1, (4096 + 128) * 4);
3304 [ - + ]: 18 : SPDK_CU_ASSERT_FATAL(buf != NULL);
3305 : 18 : _iov_set_buf(&iov, buf, (4096 + 128) * 4);
3306 : :
3307 : 18 : rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 4);
3308 : 18 : CU_ASSERT(rc == 0);
3309 : :
3310 : 18 : rc = spdk_dif_generate(&iov, 1, 4, &ctx);
3311 : 18 : CU_ASSERT(rc == 0);
3312 : :
3313 : : /* 1st data segment */
3314 : 18 : _iov_set_buf(&iov, buf, 1024);
3315 : 18 : spdk_dif_ctx_set_data_offset(&ctx, 0);
3316 : :
3317 : 18 : rc = spdk_dif_verify_stream(&iov, 1, 0, 1024, &ctx, &err_blk);
3318 : 18 : CU_ASSERT(rc == 0);
3319 : :
3320 : : /* 2nd data segment */
3321 : 18 : _iov_set_buf(&iov, buf + 1024, (3072 + 128) + (4096 + 128) * 2 + 512);
3322 : 18 : spdk_dif_ctx_set_data_offset(&ctx, 1024);
3323 : :
3324 : 18 : rc = spdk_dif_verify_stream(&iov, 1, 0, 3072 + 4096 * 2 + 512, &ctx, &err_blk);
3325 : 18 : CU_ASSERT(rc == 0);
3326 : :
3327 : : /* 3rd data segment */
3328 : 18 : _iov_set_buf(&iov, buf + (4096 + 128) * 3 + 512, 3584 + 128);
3329 : 18 : spdk_dif_ctx_set_data_offset(&ctx, 4096 * 3);
3330 : :
3331 : 18 : rc = spdk_dif_verify_stream(&iov, 1, 0, 3584, &ctx, &err_blk);
3332 : 18 : CU_ASSERT(rc == 0);
3333 : :
3334 : : /* verify all data segments once */
3335 : 18 : _iov_set_buf(&iov, buf, (4096 + 128) * 4);
3336 : 18 : spdk_dif_ctx_set_data_offset(&ctx, 0);
3337 : :
3338 : 18 : rc = spdk_dif_verify(&iov, 1, 4, &ctx, &err_blk);
3339 : 18 : CU_ASSERT(rc == 0);
3340 : :
3341 : 18 : rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 4);
3342 : 18 : CU_ASSERT(rc == 0);
3343 : :
3344 : 18 : free(buf);
3345 : 18 : }
3346 : :
3347 : : static void
3348 : 6 : dif_verify_stream_multi_segments_test(void)
3349 : : {
3350 : 6 : _dif_verify_stream_multi_segments_test(SPDK_DIF_PI_FORMAT_16);
3351 : 6 : _dif_verify_stream_multi_segments_test(SPDK_DIF_PI_FORMAT_32);
3352 : 6 : _dif_verify_stream_multi_segments_test(SPDK_DIF_PI_FORMAT_64);
3353 : 6 : }
3354 : :
3355 : : #define UT_CRC32C_XOR 0xffffffffUL
3356 : :
3357 : : static void
3358 : 6 : update_crc32c_pi_16_test(void)
3359 : : {
3360 : 6 : struct spdk_dif_ctx ctx = {};
3361 : 5 : struct iovec iovs[7];
3362 : 5 : uint32_t crc32c1, crc32c2, crc32c3, crc32c4;
3363 : : uint32_t dif_flags;
3364 : : int i, rc;
3365 : 5 : struct spdk_dif_ctx_init_ext_opts dif_opts;
3366 : :
3367 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
3368 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
3369 : :
3370 : 6 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
3371 : 6 : dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
3372 : 6 : rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1,
3373 : : dif_flags, 0, 0, 0, 0, 0, &dif_opts);
3374 : 6 : CU_ASSERT(rc == 0);
3375 : :
3376 : : /* data[0][255:0] */
3377 : 6 : _iov_alloc_buf(&iovs[0], 256);
3378 : :
3379 : : /* data[0][511:256], md[0][0] */
3380 : 6 : _iov_alloc_buf(&iovs[1], 256 + 1);
3381 : :
3382 : : /* md[0][4:1] */
3383 : 6 : _iov_alloc_buf(&iovs[2], 4);
3384 : :
3385 : : /* md[0][7:5], data[1][122:0] */
3386 : 6 : _iov_alloc_buf(&iovs[3], 3 + 123);
3387 : :
3388 : : /* data[1][511:123], md[1][5:0] */
3389 : 6 : _iov_alloc_buf(&iovs[4], 389 + 6);
3390 : :
3391 : : /* md[1][7:6], data[2][511:0], md[2][7:0], data[3][431:0] */
3392 : 6 : _iov_alloc_buf(&iovs[5], 2 + 512 + 8 + 432);
3393 : :
3394 : : /* data[3][511:432], md[3][7:0] */
3395 : 6 : _iov_alloc_buf(&iovs[6], 80 + 8);
3396 : :
3397 : 6 : rc = ut_data_pattern_generate(iovs, 7, 512 + 8, 8, 4);
3398 : 6 : CU_ASSERT(rc == 0);
3399 : :
3400 : 6 : crc32c1 = UT_CRC32C_XOR;
3401 : :
3402 : 6 : rc = spdk_dif_update_crc32c(iovs, 7, 4, &crc32c1, &ctx);
3403 : 6 : CU_ASSERT(rc == 0);
3404 : :
3405 : : /* Test if DIF doesn't affect CRC for split case. */
3406 : 6 : rc = spdk_dif_generate(iovs, 7, 4, &ctx);
3407 : 6 : CU_ASSERT(rc == 0);
3408 : :
3409 : 6 : crc32c2 = UT_CRC32C_XOR;
3410 : :
3411 : 6 : rc = spdk_dif_update_crc32c(iovs, 7, 4, &crc32c2, &ctx);
3412 : 6 : CU_ASSERT(rc == 0);
3413 : :
3414 : 6 : CU_ASSERT(crc32c1 == crc32c2);
3415 : :
3416 [ + + ]: 48 : for (i = 0; i < 7; i++) {
3417 : 42 : _iov_free_buf(&iovs[i]);
3418 : : }
3419 : :
3420 : : /* Test if CRC is same regardless of splitting. */
3421 [ + + ]: 30 : for (i = 0; i < 4; i++) {
3422 : 24 : _iov_alloc_buf(&iovs[i], 512 + 8);
3423 : : }
3424 : :
3425 : 6 : rc = ut_data_pattern_generate(iovs, 4, 512 + 8, 8, 4);
3426 : 6 : CU_ASSERT(rc == 0);
3427 : :
3428 : 6 : crc32c3 = UT_CRC32C_XOR;
3429 : :
3430 : 6 : rc = spdk_dif_update_crc32c(iovs, 4, 4, &crc32c3, &ctx);
3431 : 6 : CU_ASSERT(rc == 0);
3432 : :
3433 : 6 : CU_ASSERT(crc32c1 == crc32c3);
3434 : :
3435 : : /* Test if DIF doesn't affect CRC for non-split case. */
3436 : 6 : rc = spdk_dif_generate(iovs, 4, 4, &ctx);
3437 : 6 : CU_ASSERT(rc == 0);
3438 : :
3439 : 6 : crc32c4 = UT_CRC32C_XOR;
3440 : :
3441 : 6 : rc = spdk_dif_update_crc32c(iovs, 4, 4, &crc32c4, &ctx);
3442 : 6 : CU_ASSERT(rc == 0);
3443 : :
3444 : 6 : CU_ASSERT(crc32c1 == crc32c4);
3445 : :
3446 [ + + ]: 30 : for (i = 0; i < 4; i++) {
3447 : 24 : _iov_free_buf(&iovs[i]);
3448 : : }
3449 : 6 : }
3450 : :
3451 : : static void
3452 : 12 : _update_crc32c_test(enum spdk_dif_pi_format dif_pi_format)
3453 : : {
3454 : 12 : struct spdk_dif_ctx ctx = {};
3455 : 10 : struct iovec iovs[7];
3456 : 10 : uint32_t crc32c1, crc32c2, crc32c3, crc32c4;
3457 : : uint32_t dif_flags;
3458 : : int i, rc;
3459 : 10 : struct spdk_dif_ctx_init_ext_opts dif_opts;
3460 : :
3461 : 12 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
3462 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
3463 : :
3464 : 12 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
3465 : 12 : dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_32;
3466 : 12 : rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
3467 : : dif_flags, 0, 0, 0, 0, 0, &dif_opts);
3468 : 12 : CU_ASSERT(rc == 0);
3469 : :
3470 : : /* data[0][2047:0] */
3471 : 12 : _iov_alloc_buf(&iovs[0], 2048);
3472 : :
3473 : : /* data[0][4095:2048], md[0][0] */
3474 : 12 : _iov_alloc_buf(&iovs[1], 2048 + 1);
3475 : :
3476 : : /* md[0][4:1] */
3477 : 12 : _iov_alloc_buf(&iovs[2], 4);
3478 : :
3479 : : /* md[0][127:5], data[1][122:0] */
3480 : 12 : _iov_alloc_buf(&iovs[3], 123 + 123);
3481 : :
3482 : : /* data[1][4095:123], md[1][5:0] */
3483 : 12 : _iov_alloc_buf(&iovs[4], 3973 + 6);
3484 : :
3485 : : /* md[1][127:6], data[2][4095:0], md[2][127:0], data[3][431:0] */
3486 : 12 : _iov_alloc_buf(&iovs[5], 122 + 4096 + 128 + 432);
3487 : :
3488 : : /* data[3][511:432], md[3][127:0] */
3489 : 12 : _iov_alloc_buf(&iovs[6], 3665 + 128);
3490 : :
3491 : 12 : rc = ut_data_pattern_generate(iovs, 7, 4096 + 128, 128, 4);
3492 : 12 : CU_ASSERT(rc == 0);
3493 : :
3494 : 12 : crc32c1 = UT_CRC32C_XOR;
3495 : :
3496 : 12 : rc = spdk_dif_update_crc32c(iovs, 7, 4, &crc32c1, &ctx);
3497 : 12 : CU_ASSERT(rc == 0);
3498 : :
3499 : : /* Test if DIF doesn't affect CRC for split case. */
3500 : 12 : rc = spdk_dif_generate(iovs, 7, 4, &ctx);
3501 : 12 : CU_ASSERT(rc == 0);
3502 : :
3503 : 12 : crc32c2 = UT_CRC32C_XOR;
3504 : :
3505 : 12 : rc = spdk_dif_update_crc32c(iovs, 7, 4, &crc32c2, &ctx);
3506 : 12 : CU_ASSERT(rc == 0);
3507 : :
3508 : 12 : CU_ASSERT(crc32c1 == crc32c2);
3509 : :
3510 [ + + ]: 96 : for (i = 0; i < 7; i++) {
3511 : 84 : _iov_free_buf(&iovs[i]);
3512 : : }
3513 : :
3514 : : /* Test if CRC is same regardless of splitting. */
3515 [ + + ]: 60 : for (i = 0; i < 4; i++) {
3516 : 48 : _iov_alloc_buf(&iovs[i], 4096 + 128);
3517 : : }
3518 : :
3519 : 12 : rc = ut_data_pattern_generate(iovs, 4, 4096 + 128, 128, 4);
3520 : 12 : CU_ASSERT(rc == 0);
3521 : :
3522 : 12 : crc32c3 = UT_CRC32C_XOR;
3523 : :
3524 : 12 : rc = spdk_dif_update_crc32c(iovs, 4, 4, &crc32c3, &ctx);
3525 : 12 : CU_ASSERT(rc == 0);
3526 : :
3527 : 12 : CU_ASSERT(crc32c1 == crc32c3);
3528 : :
3529 : : /* Test if DIF doesn't affect CRC for non-split case. */
3530 : 12 : rc = spdk_dif_generate(iovs, 4, 4, &ctx);
3531 : 12 : CU_ASSERT(rc == 0);
3532 : :
3533 : 12 : crc32c4 = UT_CRC32C_XOR;
3534 : :
3535 : 12 : rc = spdk_dif_update_crc32c(iovs, 4, 4, &crc32c4, &ctx);
3536 : 12 : CU_ASSERT(rc == 0);
3537 : :
3538 : 12 : CU_ASSERT(crc32c1 == crc32c4);
3539 : :
3540 [ + + ]: 60 : for (i = 0; i < 4; i++) {
3541 : 48 : _iov_free_buf(&iovs[i]);
3542 : : }
3543 : 12 : }
3544 : :
3545 : : static void
3546 : 6 : update_crc32c_test(void)
3547 : : {
3548 : 6 : _update_crc32c_test(SPDK_DIF_PI_FORMAT_32);
3549 : 6 : _update_crc32c_test(SPDK_DIF_PI_FORMAT_64);
3550 : 6 : }
3551 : :
3552 : : static void
3553 : 18 : _dif_update_crc32c_split_test(enum spdk_dif_pi_format dif_pi_format)
3554 : : {
3555 : 18 : struct spdk_dif_ctx ctx = {};
3556 : 15 : struct iovec iov;
3557 : : uint8_t *buf;
3558 : 15 : struct _dif_sgl sgl;
3559 : : uint32_t dif_flags, crc32c, prev_crc32c;
3560 : : int rc;
3561 : 15 : struct spdk_dif_ctx_init_ext_opts dif_opts;
3562 : :
3563 : 18 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
3564 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
3565 : :
3566 : 18 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
3567 : 18 : dif_opts.dif_pi_format = dif_pi_format;
3568 : 18 : rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
3569 : : dif_flags, 0, 0, 0, 0, GUARD_SEED, &dif_opts);
3570 : 18 : CU_ASSERT(rc == 0);
3571 : :
3572 : 18 : buf = calloc(1, 4096 + 128);
3573 [ - + ]: 18 : SPDK_CU_ASSERT_FATAL(buf != NULL);
3574 : 18 : _iov_set_buf(&iov, buf, 4096 + 128);
3575 : :
3576 : 18 : rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1);
3577 : 18 : CU_ASSERT(rc == 0);
3578 : :
3579 : 18 : _dif_sgl_init(&sgl, &iov, 1);
3580 : :
3581 : 18 : dif_generate(&sgl, 1, &ctx);
3582 : :
3583 : 18 : _dif_sgl_init(&sgl, &iov, 1);
3584 : :
3585 : 18 : crc32c = _dif_update_crc32c_split(&sgl, 0, 1000, UT_CRC32C_XOR, &ctx);
3586 : 18 : CU_ASSERT(crc32c == spdk_crc32c_update(buf, 1000, UT_CRC32C_XOR));
3587 : :
3588 : 18 : prev_crc32c = crc32c;
3589 : :
3590 : 18 : crc32c = _dif_update_crc32c_split(&sgl, 1000, 3000, prev_crc32c, &ctx);
3591 : 18 : CU_ASSERT(crc32c == spdk_crc32c_update(buf + 1000, 3000, prev_crc32c));
3592 : :
3593 : 18 : prev_crc32c = crc32c;
3594 : :
3595 : 18 : crc32c = _dif_update_crc32c_split(&sgl, 4000, 96 + 128, prev_crc32c, &ctx);
3596 : 18 : CU_ASSERT(crc32c == spdk_crc32c_update(buf + 4000, 96, prev_crc32c));
3597 : :
3598 : 18 : CU_ASSERT(crc32c == spdk_crc32c_update(buf, 4096, UT_CRC32C_XOR));
3599 : :
3600 : 18 : free(buf);
3601 : 18 : }
3602 : :
3603 : : static void
3604 : 6 : dif_update_crc32c_split_test(void)
3605 : : {
3606 : 6 : _dif_update_crc32c_split_test(SPDK_DIF_PI_FORMAT_16);
3607 : 6 : _dif_update_crc32c_split_test(SPDK_DIF_PI_FORMAT_32);
3608 : 6 : _dif_update_crc32c_split_test(SPDK_DIF_PI_FORMAT_64);
3609 : 6 : }
3610 : :
3611 : : static void
3612 : 18 : _dif_update_crc32c_stream_multi_segments_test(enum spdk_dif_pi_format dif_pi_format)
3613 : : {
3614 : 18 : struct spdk_dif_ctx ctx = {};
3615 : 18 : struct iovec iov = {};
3616 : : uint8_t *buf;
3617 : 15 : uint32_t dif_flags, crc32c1, crc32c2;
3618 : : int rc;
3619 : 15 : struct spdk_dif_ctx_init_ext_opts dif_opts;
3620 : :
3621 : 18 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
3622 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
3623 : :
3624 : 18 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
3625 : 18 : dif_opts.dif_pi_format = dif_pi_format;
3626 : 18 : rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
3627 : : dif_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED, &dif_opts);
3628 : 18 : CU_ASSERT(rc == 0);
3629 : :
3630 : 18 : buf = calloc(1, (4096 + 128) * 4);
3631 [ - + ]: 18 : SPDK_CU_ASSERT_FATAL(buf != NULL);
3632 : 18 : _iov_set_buf(&iov, buf, (4096 + 128) * 4);
3633 : :
3634 : 18 : rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 4);
3635 : 18 : CU_ASSERT(rc == 0);
3636 : :
3637 : 18 : rc = spdk_dif_generate(&iov, 1, 4, &ctx);
3638 : 18 : CU_ASSERT(rc == 0);
3639 : :
3640 : 18 : crc32c1 = UT_CRC32C_XOR;
3641 : 18 : crc32c2 = UT_CRC32C_XOR;
3642 : :
3643 : : /* 1st data segment */
3644 : 18 : _iov_set_buf(&iov, buf, 1024);
3645 : 18 : spdk_dif_ctx_set_data_offset(&ctx, 0);
3646 : :
3647 : 18 : rc = spdk_dif_update_crc32c_stream(&iov, 1, 0, 1024, &crc32c1, &ctx);
3648 : 18 : CU_ASSERT(rc == 0);
3649 : :
3650 : : /* 2nd data segment */
3651 : 18 : _iov_set_buf(&iov, buf + 1024, (3072 + 128) + (4096 + 128) * 2 + 512);
3652 : 18 : spdk_dif_ctx_set_data_offset(&ctx, 1024);
3653 : :
3654 : 18 : rc = spdk_dif_update_crc32c_stream(&iov, 1, 0, 3072 + 4096 * 2 + 512, &crc32c1, &ctx);
3655 : 18 : CU_ASSERT(rc == 0);
3656 : :
3657 : : /* 3rd data segment */
3658 : 18 : _iov_set_buf(&iov, buf + (4096 + 128) * 3 + 512, 3584 + 128);
3659 : 18 : spdk_dif_ctx_set_data_offset(&ctx, 4096 * 3);
3660 : :
3661 : 18 : rc = spdk_dif_update_crc32c_stream(&iov, 1, 0, 3584, &crc32c1, &ctx);
3662 : 18 : CU_ASSERT(rc == 0);
3663 : :
3664 : : /* Update CRC32C for all data segments once */
3665 : 18 : _iov_set_buf(&iov, buf, (4096 + 128) * 4);
3666 : 18 : spdk_dif_ctx_set_data_offset(&ctx, 0);
3667 : :
3668 : 18 : rc = spdk_dif_update_crc32c(&iov, 1, 4, &crc32c2, &ctx);
3669 : 18 : CU_ASSERT(rc == 0);
3670 : :
3671 : 18 : CU_ASSERT(crc32c1 == crc32c2);
3672 : :
3673 : 18 : free(buf);
3674 : 18 : }
3675 : :
3676 : : static void
3677 : 6 : dif_update_crc32c_stream_multi_segments_test(void)
3678 : : {
3679 : 6 : _dif_update_crc32c_stream_multi_segments_test(SPDK_DIF_PI_FORMAT_16);
3680 : 6 : _dif_update_crc32c_stream_multi_segments_test(SPDK_DIF_PI_FORMAT_32);
3681 : 6 : _dif_update_crc32c_stream_multi_segments_test(SPDK_DIF_PI_FORMAT_64);
3682 : 6 : }
3683 : :
3684 : : static void
3685 : 6 : get_range_with_md_test(void)
3686 : : {
3687 : 6 : struct spdk_dif_ctx ctx = {};
3688 : 5 : uint32_t buf_offset, buf_len;
3689 : : int rc;
3690 : 5 : struct spdk_dif_ctx_init_ext_opts dif_opts;
3691 : :
3692 : 6 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
3693 : 6 : dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
3694 : 6 : rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, 0, 0,
3695 : : 0, 0, 0, 0, 0, &dif_opts);
3696 : 6 : CU_ASSERT(rc == 0);
3697 : :
3698 : 6 : spdk_dif_get_range_with_md(0, 2048, &buf_offset, &buf_len, &ctx);
3699 : 6 : CU_ASSERT(buf_offset == 0);
3700 : 6 : CU_ASSERT(buf_len == 2048);
3701 : :
3702 : 6 : spdk_dif_get_range_with_md(2048, 4096, &buf_offset, &buf_len, &ctx);
3703 : 6 : CU_ASSERT(buf_offset == 2048);
3704 : 6 : CU_ASSERT(buf_len == 4096 + 128);
3705 : :
3706 : 6 : spdk_dif_get_range_with_md(4096, 10240, &buf_offset, &buf_len, &ctx);
3707 : 6 : CU_ASSERT(buf_offset == 4096 + 128);
3708 : 6 : CU_ASSERT(buf_len == 10240 + 256);
3709 : :
3710 : 6 : spdk_dif_get_range_with_md(10240, 2048, &buf_offset, &buf_len, &ctx);
3711 : 6 : CU_ASSERT(buf_offset == 10240 + 256);
3712 : 6 : CU_ASSERT(buf_len == 2048 + 128);
3713 : :
3714 : 6 : buf_len = spdk_dif_get_length_with_md(6144, &ctx);
3715 : 6 : CU_ASSERT(buf_len == 6144 + 128);
3716 : 6 : }
3717 : :
3718 : : static void
3719 : 72 : dif_generate_remap_and_verify(struct iovec *iovs, int iovcnt,
3720 : : uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
3721 : : bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
3722 : : uint32_t init_ref_tag, uint32_t remapped_init_ref_tag,
3723 : : uint16_t apptag_mask, uint16_t app_tag,
3724 : : enum spdk_dif_pi_format dif_pi_format)
3725 : : {
3726 : 72 : struct spdk_dif_ctx ctx = {};
3727 : : int rc;
3728 : 60 : struct spdk_dif_ctx_init_ext_opts dif_opts;
3729 : :
3730 : 72 : rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks);
3731 : 72 : CU_ASSERT(rc == 0);
3732 : :
3733 : 72 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
3734 : 72 : dif_opts.dif_pi_format = dif_pi_format;
3735 : 72 : rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags,
3736 : : init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED, &dif_opts);
3737 : 72 : CU_ASSERT(rc == 0);
3738 : :
3739 : 72 : rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx);
3740 : 72 : CU_ASSERT(rc == 0);
3741 : :
3742 : 72 : spdk_dif_ctx_set_remapped_init_ref_tag(&ctx, remapped_init_ref_tag);
3743 : :
3744 : 72 : rc = spdk_dif_remap_ref_tag(iovs, iovcnt, num_blocks, &ctx, NULL, true);
3745 : 72 : CU_ASSERT(rc == 0);
3746 : :
3747 : 72 : rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags,
3748 : : remapped_init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED, &dif_opts);
3749 : 72 : CU_ASSERT(rc == 0);
3750 : :
3751 : 72 : rc = spdk_dif_verify(iovs, iovcnt, num_blocks, &ctx, NULL);
3752 : 72 : CU_ASSERT(rc == 0);
3753 : :
3754 : 72 : rc = ut_data_pattern_verify(iovs, iovcnt, block_size, md_size, num_blocks);
3755 : 72 : CU_ASSERT(rc == 0);
3756 : 72 : }
3757 : :
3758 : : static void
3759 : 6 : dif_sec_512_md_8_prchk_7_multi_iovs_remap_pi_16_test(void)
3760 : : {
3761 : 5 : struct iovec iovs[4];
3762 : : int i, num_blocks;
3763 : : uint32_t dif_flags;
3764 : :
3765 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
3766 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
3767 : :
3768 : 6 : num_blocks = 0;
3769 : :
3770 [ + + ]: 30 : for (i = 0; i < 4; i++) {
3771 : 24 : _iov_alloc_buf(&iovs[i], (512 + 8) * (i + 1));
3772 : 24 : num_blocks += i + 1;
3773 : : }
3774 : :
3775 : 6 : dif_generate_remap_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1,
3776 : : dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
3777 : :
3778 : 6 : dif_generate_remap_and_verify(iovs, 4, 512 + 8, 8, num_blocks, true, SPDK_DIF_TYPE1,
3779 : : dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
3780 : :
3781 [ + + ]: 30 : for (i = 0; i < 4; i++) {
3782 : 24 : _iov_free_buf(&iovs[i]);
3783 : : }
3784 : 6 : }
3785 : :
3786 : : static void
3787 : 6 : dif_sec_4096_md_128_prchk_7_multi_iovs_remap_test(void)
3788 : : {
3789 : 5 : struct iovec iovs[4];
3790 : : int i, num_blocks;
3791 : : uint32_t dif_flags;
3792 : :
3793 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
3794 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
3795 : :
3796 : 6 : num_blocks = 0;
3797 : :
3798 [ + + ]: 30 : for (i = 0; i < 4; i++) {
3799 : 24 : _iov_alloc_buf(&iovs[i], (4096 + 128) * (i + 1));
3800 : 24 : num_blocks += i + 1;
3801 : : }
3802 : :
3803 : 6 : dif_generate_remap_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, false, SPDK_DIF_TYPE1,
3804 : : dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32);
3805 : 6 : dif_generate_remap_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, true, SPDK_DIF_TYPE1,
3806 : : dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32);
3807 : 6 : dif_generate_remap_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, false, SPDK_DIF_TYPE1,
3808 : : dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64);
3809 : 6 : dif_generate_remap_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, true, SPDK_DIF_TYPE1,
3810 : : dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64);
3811 : :
3812 [ + + ]: 30 : for (i = 0; i < 4; i++) {
3813 : 24 : _iov_free_buf(&iovs[i]);
3814 : : }
3815 : 6 : }
3816 : :
3817 : : static void
3818 : 6 : dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_remap_test(void)
3819 : : {
3820 : 5 : struct iovec iovs[11];
3821 : : uint32_t dif_flags;
3822 : : int i;
3823 : :
3824 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
3825 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
3826 : :
3827 : : /* data[0][1000:0] */
3828 : 6 : _iov_alloc_buf(&iovs[0], 1000);
3829 : :
3830 : : /* data[0][3095:1000], guard[0][0] */
3831 : 6 : _iov_alloc_buf(&iovs[1], 3096 + 1);
3832 : :
3833 : : /* guard[0][1], apptag[0][0] */
3834 : 6 : _iov_alloc_buf(&iovs[2], 1 + 1);
3835 : :
3836 : : /* apptag[0][1], reftag[0][0] */
3837 : 6 : _iov_alloc_buf(&iovs[3], 1 + 1);
3838 : :
3839 : : /* reftag[0][3:1], ignore[0][59:0] */
3840 : 6 : _iov_alloc_buf(&iovs[4], 3 + 60);
3841 : :
3842 : : /* ignore[119:60], data[1][3050:0] */
3843 : 6 : _iov_alloc_buf(&iovs[5], 60 + 3051);
3844 : :
3845 : : /* data[1][4095:3050], guard[1][0] */
3846 : 6 : _iov_alloc_buf(&iovs[6], 1045 + 1);
3847 : :
3848 : : /* guard[1][1], apptag[1][0] */
3849 : 6 : _iov_alloc_buf(&iovs[7], 1 + 1);
3850 : :
3851 : : /* apptag[1][1], reftag[1][0] */
3852 : 6 : _iov_alloc_buf(&iovs[8], 1 + 1);
3853 : :
3854 : : /* reftag[1][3:1], ignore[1][9:0] */
3855 : 6 : _iov_alloc_buf(&iovs[9], 3 + 10);
3856 : :
3857 : : /* ignore[1][127:9] */
3858 : 6 : _iov_alloc_buf(&iovs[10], 118);
3859 : :
3860 : 6 : dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, false, SPDK_DIF_TYPE1, dif_flags,
3861 : : 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
3862 : 6 : dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, true, SPDK_DIF_TYPE1, dif_flags,
3863 : : 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
3864 : 6 : dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, false, SPDK_DIF_TYPE1, dif_flags,
3865 : : 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32);
3866 : 6 : dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, true, SPDK_DIF_TYPE1, dif_flags,
3867 : : 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32);
3868 : 6 : dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, false, SPDK_DIF_TYPE1, dif_flags,
3869 : : 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64);
3870 : 6 : dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, true, SPDK_DIF_TYPE1, dif_flags,
3871 : : 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64);
3872 : :
3873 [ + + ]: 72 : for (i = 0; i < 11; i++) {
3874 : 66 : _iov_free_buf(&iovs[i]);
3875 : : }
3876 : 6 : }
3877 : :
3878 : : static void
3879 : 54 : dix_generate_remap_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov,
3880 : : uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
3881 : : bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags,
3882 : : uint32_t init_ref_tag, uint32_t remapped_init_ref_tag,
3883 : : uint16_t apptag_mask, uint16_t app_tag,
3884 : : enum spdk_dif_pi_format dif_pi_format)
3885 : : {
3886 : 45 : struct spdk_dif_ctx ctx;
3887 : : int rc;
3888 : 45 : struct spdk_dif_ctx_init_ext_opts dif_opts;
3889 : :
3890 : 54 : rc = ut_data_pattern_generate(iovs, iovcnt, block_size, 0, num_blocks);
3891 : 54 : CU_ASSERT(rc == 0);
3892 : :
3893 : 54 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
3894 : 54 : dif_opts.dif_pi_format = dif_pi_format;
3895 : 54 : rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags,
3896 : : init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED, &dif_opts);
3897 : 54 : CU_ASSERT(rc == 0);
3898 : :
3899 : 54 : rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx);
3900 : 54 : CU_ASSERT(rc == 0);
3901 : :
3902 : 54 : spdk_dif_ctx_set_remapped_init_ref_tag(&ctx, remapped_init_ref_tag);
3903 : :
3904 : 54 : rc = spdk_dix_remap_ref_tag(md_iov, num_blocks, &ctx, NULL, true);
3905 : 54 : CU_ASSERT(rc == 0);
3906 : :
3907 : 54 : rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags,
3908 : : remapped_init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED, &dif_opts);
3909 : 54 : CU_ASSERT(rc == 0);
3910 : :
3911 : 54 : rc = spdk_dix_verify(iovs, iovcnt, md_iov, num_blocks, &ctx, NULL);
3912 : 54 : CU_ASSERT(rc == 0);
3913 : :
3914 : 54 : rc = ut_data_pattern_verify(iovs, iovcnt, block_size, 0, num_blocks);
3915 : 54 : CU_ASSERT(rc == 0);
3916 : 54 : }
3917 : :
3918 : : static void
3919 : 6 : dix_sec_4096_md_128_prchk_7_multi_iovs_remap(void)
3920 : : {
3921 : 5 : struct iovec iovs[4], md_iov;
3922 : : uint32_t dif_flags;
3923 : : int i, num_blocks;
3924 : :
3925 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
3926 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
3927 : :
3928 : 6 : num_blocks = 0;
3929 : :
3930 [ + + ]: 30 : for (i = 0; i < 4; i++) {
3931 : 24 : _iov_alloc_buf(&iovs[i], 4096 * (i + 1));
3932 : 24 : num_blocks += i + 1;
3933 : : }
3934 : 6 : _iov_alloc_buf(&md_iov, 128 * num_blocks);
3935 : :
3936 : 6 : dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1,
3937 : : dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
3938 : 6 : dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1,
3939 : : dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
3940 : 6 : dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1,
3941 : : dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32);
3942 : 6 : dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1,
3943 : : dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32);
3944 : 6 : dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1,
3945 : : dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64);
3946 : 6 : dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1,
3947 : : dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64);
3948 : :
3949 [ + + ]: 30 : for (i = 0; i < 4; i++) {
3950 : 24 : _iov_free_buf(&iovs[i]);
3951 : : }
3952 : 6 : _iov_free_buf(&md_iov);
3953 : 6 : }
3954 : :
3955 : : static void
3956 : 6 : dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits_remap_pi_16_test(void)
3957 : : {
3958 : 5 : struct iovec iovs[6], md_iov;
3959 : : uint32_t dif_flags;
3960 : : int i;
3961 : :
3962 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
3963 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
3964 : :
3965 : : /* data[0][255:0] */
3966 : 6 : _iov_alloc_buf(&iovs[0], 256);
3967 : :
3968 : : /* data[0][511:256], data[1][255:0] */
3969 : 6 : _iov_alloc_buf(&iovs[1], 256 + 256);
3970 : :
3971 : : /* data[1][382:256] */
3972 : 6 : _iov_alloc_buf(&iovs[2], 128);
3973 : :
3974 : : /* data[1][383] */
3975 : 6 : _iov_alloc_buf(&iovs[3], 1);
3976 : :
3977 : : /* data[1][510:384] */
3978 : 6 : _iov_alloc_buf(&iovs[4], 126);
3979 : :
3980 : : /* data[1][511], data[2][511:0], data[3][511:0] */
3981 : 6 : _iov_alloc_buf(&iovs[5], 1 + 512 * 2);
3982 : :
3983 : 6 : _iov_alloc_buf(&md_iov, 8 * 4);
3984 : :
3985 : 6 : dix_generate_remap_and_verify(iovs, 6, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1,
3986 : : dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16);
3987 : :
3988 [ + + ]: 42 : for (i = 0; i < 6; i++) {
3989 : 36 : _iov_free_buf(&iovs[i]);
3990 : : }
3991 : 6 : _iov_free_buf(&md_iov);
3992 : 6 : }
3993 : :
3994 : : static void
3995 : 6 : dix_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_remap_test(void)
3996 : : {
3997 : 5 : struct iovec iovs[6], md_iov;
3998 : : uint32_t dif_flags;
3999 : : int i;
4000 : :
4001 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
4002 : : SPDK_DIF_FLAGS_REFTAG_CHECK;
4003 : :
4004 : : /* data[0][2047:0] */
4005 : 6 : _iov_alloc_buf(&iovs[0], 2048);
4006 : :
4007 : : /* data[0][4095:2048], data[1][2047:0] */
4008 : 6 : _iov_alloc_buf(&iovs[1], 2048 + 2048);
4009 : :
4010 : : /* data[1][3071:2048] */
4011 : 6 : _iov_alloc_buf(&iovs[2], 1024);
4012 : :
4013 : : /* data[1][3072] */
4014 : 6 : _iov_alloc_buf(&iovs[3], 1);
4015 : :
4016 : : /* data[1][4094:3073] */
4017 : 6 : _iov_alloc_buf(&iovs[4], 1022);
4018 : :
4019 : : /* data[1][4095], data[2][4095:0], data[3][4095:0] */
4020 : 6 : _iov_alloc_buf(&iovs[5], 1 + 4096 * 2);
4021 : :
4022 : 6 : _iov_alloc_buf(&md_iov, 128 * 4);
4023 : :
4024 : 6 : dix_generate_remap_and_verify(iovs, 6, &md_iov, 4096, 128, 4, false, SPDK_DIF_TYPE1,
4025 : : dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32);
4026 : 6 : dix_generate_remap_and_verify(iovs, 6, &md_iov, 4096, 128, 4, false, SPDK_DIF_TYPE1,
4027 : : dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64);
4028 : :
4029 [ + + ]: 42 : for (i = 0; i < 6; i++) {
4030 : 36 : _iov_free_buf(&iovs[i]);
4031 : : }
4032 : 6 : _iov_free_buf(&md_iov);
4033 : 6 : }
4034 : :
4035 : : static void
4036 : 6 : dif_generate_and_verify_unmap_test(void)
4037 : : {
4038 : 5 : struct iovec iov;
4039 : 6 : struct spdk_dif_ctx ctx = {};
4040 : : int rc;
4041 : 5 : struct spdk_dif_ctx_init_ext_opts dif_opts;
4042 : : uint32_t dif_flags;
4043 : : struct spdk_dif *dif;
4044 : :
4045 : 6 : _iov_alloc_buf(&iov, 4096 + 128);
4046 : :
4047 : 6 : dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
4048 : 6 : dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
4049 : 6 : dif = (struct spdk_dif *)(iov.iov_base + 4096);
4050 : :
4051 : : /* Case 1 for TYPE1 */
4052 [ - + ]: 6 : memset(iov.iov_base, 0, 4096 + 128);
4053 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | SPDK_DIF_FLAGS_REFTAG_CHECK;
4054 : 6 : rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, true, SPDK_DIF_TYPE1, dif_flags,
4055 : : 0x100, 0xFFFF, SPDK_DIF_APPTAG_IGNORE, 0, 0, &dif_opts);
4056 : 6 : CU_ASSERT(rc == 0);
4057 : :
4058 : 6 : rc = spdk_dif_generate(&iov, 1, 1, &ctx);
4059 : 6 : CU_ASSERT(rc == 0);
4060 : :
4061 : 6 : rc = spdk_dif_verify(&iov, 1, 1, &ctx, NULL);
4062 : 6 : CU_ASSERT(rc == 0);
4063 : :
4064 : 6 : CU_ASSERT(_dif_get_apptag(dif, ctx.dif_pi_format) == SPDK_DIF_APPTAG_IGNORE);
4065 : 6 : CU_ASSERT(_dif_get_reftag(dif, ctx.dif_pi_format) == 0x100);
4066 : :
4067 : : /* Case 2 for TYPE3 */
4068 [ - + ]: 6 : memset(iov.iov_base, 0, 4096 + 128);
4069 : :
4070 : 6 : dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | SPDK_DIF_FLAGS_REFTAG_CHECK;
4071 : 6 : rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, true, SPDK_DIF_TYPE3, dif_flags,
4072 : : SPDK_DIF_REFTAG_IGNORE, 0xFFFF, SPDK_DIF_APPTAG_IGNORE, 0, 0, &dif_opts);
4073 : 6 : CU_ASSERT(rc == 0);
4074 : :
4075 : 6 : rc = spdk_dif_generate(&iov, 1, 1, &ctx);
4076 : 6 : CU_ASSERT(rc == 0);
4077 : :
4078 : 6 : rc = spdk_dif_verify(&iov, 1, 1, &ctx, NULL);
4079 : 6 : CU_ASSERT(rc == 0);
4080 : :
4081 : 6 : CU_ASSERT(_dif_get_apptag(dif, ctx.dif_pi_format) == SPDK_DIF_APPTAG_IGNORE);
4082 : 6 : CU_ASSERT(_dif_get_reftag(dif, ctx.dif_pi_format) == REFTAG_MASK_16);
4083 : :
4084 : 6 : _iov_free_buf(&iov);
4085 : 6 : }
4086 : :
4087 : : int
4088 : 6 : main(int argc, char **argv)
4089 : : {
4090 : 6 : CU_pSuite suite = NULL;
4091 : : unsigned int num_failures;
4092 : :
4093 : 6 : CU_initialize_registry();
4094 : :
4095 : 6 : suite = CU_add_suite("dif", NULL, NULL);
4096 : :
4097 : 6 : CU_ADD_TEST(suite, dif_generate_and_verify_test);
4098 : 6 : CU_ADD_TEST(suite, dif_disable_check_test);
4099 : 6 : CU_ADD_TEST(suite, dif_generate_and_verify_different_pi_formats_test);
4100 : 6 : CU_ADD_TEST(suite, dif_apptag_mask_test);
4101 : 6 : CU_ADD_TEST(suite, dif_sec_512_md_0_error_test);
4102 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_0_error_test);
4103 : 6 : CU_ADD_TEST(suite, dif_sec_4100_md_128_error_test);
4104 : 6 : CU_ADD_TEST(suite, dif_guard_seed_test);
4105 : 6 : CU_ADD_TEST(suite, dif_guard_value_test);
4106 : 6 : CU_ADD_TEST(suite, dif_disable_sec_512_md_8_single_iov_test);
4107 : 6 : CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_0_single_iov_test);
4108 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_0_single_iov_test);
4109 : 6 : CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_0_1_2_4_multi_iovs_test);
4110 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test);
4111 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_test);
4112 : 6 : CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_data_and_md_test);
4113 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_split_data_and_md_test);
4114 : 6 : CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_data_test);
4115 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_split_data_test);
4116 : 6 : CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_guard_test);
4117 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_split_guard_test);
4118 : 6 : CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_apptag_test);
4119 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_split_apptag_test);
4120 : 6 : CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_reftag_test);
4121 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_split_reftag_test);
4122 : 6 : CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_complex_splits_test);
4123 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test);
4124 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test);
4125 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_and_md_test);
4126 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_test);
4127 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_guard_test);
4128 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_apptag_pi_16_test);
4129 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_apptag_test);
4130 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_pi_16_test);
4131 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_test);
4132 : 6 : CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_0_single_iov);
4133 : 6 : CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_0_single_iov_test);
4134 : 6 : CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_0_1_2_4_multi_iovs);
4135 : 6 : CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test);
4136 : 6 : CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_7_multi_iovs);
4137 : 6 : CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_7_multi_iovs_split_data);
4138 : 6 : CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_7_multi_iovs_split_data_test);
4139 : 6 : CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits);
4140 : 6 : CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test);
4141 : 6 : CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test);
4142 : 6 : CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test);
4143 : 6 : CU_ADD_TEST(suite, dix_sec_512_md_0_error);
4144 : 6 : CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_0_single_iov);
4145 : 6 : CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_0_single_iov_test);
4146 : 6 : CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_0_1_2_4_multi_iovs);
4147 : 6 : CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test);
4148 : 6 : CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs);
4149 : 6 : CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_7_multi_iovs_split_data);
4150 : 6 : CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs_split_data_test);
4151 : 6 : CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits);
4152 : 6 : CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test);
4153 : 6 : CU_ADD_TEST(suite, dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test);
4154 : 6 : CU_ADD_TEST(suite, dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test);
4155 : 6 : CU_ADD_TEST(suite, set_md_interleave_iovs_test);
4156 : 6 : CU_ADD_TEST(suite, set_md_interleave_iovs_split_test);
4157 : 6 : CU_ADD_TEST(suite, dif_generate_stream_pi_16_test);
4158 : 6 : CU_ADD_TEST(suite, dif_generate_stream_test);
4159 : 6 : CU_ADD_TEST(suite, set_md_interleave_iovs_alignment_test);
4160 : 6 : CU_ADD_TEST(suite, dif_generate_split_test);
4161 : 6 : CU_ADD_TEST(suite, set_md_interleave_iovs_multi_segments_test);
4162 : 6 : CU_ADD_TEST(suite, dif_verify_split_test);
4163 : 6 : CU_ADD_TEST(suite, dif_verify_stream_multi_segments_test);
4164 : 6 : CU_ADD_TEST(suite, update_crc32c_pi_16_test);
4165 : 6 : CU_ADD_TEST(suite, update_crc32c_test);
4166 : 6 : CU_ADD_TEST(suite, dif_update_crc32c_split_test);
4167 : 6 : CU_ADD_TEST(suite, dif_update_crc32c_stream_multi_segments_test);
4168 : 6 : CU_ADD_TEST(suite, get_range_with_md_test);
4169 : 6 : CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_remap_pi_16_test);
4170 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_remap_test);
4171 : 6 : CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_remap_test);
4172 : 6 : CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs_remap);
4173 : 6 : CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits_remap_pi_16_test);
4174 : 6 : CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_remap_test);
4175 : 6 : CU_ADD_TEST(suite, dif_generate_and_verify_unmap_test);
4176 : :
4177 : :
4178 : 6 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
4179 : :
4180 : 6 : CU_cleanup_registry();
4181 : :
4182 : 6 : return num_failures;
4183 : : }
|