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