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