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