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