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