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