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_512_md_8_dif_disable_single_iov(void) 1628 { 1629 struct iovec iov, bounce_iov; 1630 1631 _iov_alloc_buf(&iov, 512 * 4); 1632 _iov_alloc_buf(&bounce_iov, (512 + 8) * 4); 1633 1634 dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 1, 512 + 8, 8, 4, 1635 false, SPDK_DIF_DISABLE, 0, 0, 0, 0, SPDK_DIF_PI_FORMAT_16); 1636 dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 1, 512 + 8, 8, 4, 1637 true, SPDK_DIF_DISABLE, 0, 0, 0, 0, SPDK_DIF_PI_FORMAT_16); 1638 1639 _iov_free_buf(&iov); 1640 _iov_free_buf(&bounce_iov); 1641 } 1642 1643 static void 1644 _dif_copy_sec_4096_md_128_prchk_0_single_iov_test( 1645 enum spdk_dif_pi_format dif_pi_format) 1646 { 1647 struct iovec iov, bounce_iov; 1648 1649 _iov_alloc_buf(&iov, 4096 * 4); 1650 _iov_alloc_buf(&bounce_iov, (4096 + 128) * 4); 1651 1652 dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 1, 4096 + 128, 128, 4, 1653 false, SPDK_DIF_TYPE1, 0, 0, 0, 0, dif_pi_format); 1654 dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 1, 4096 + 128, 128, 4, 1655 true, SPDK_DIF_TYPE1, 0, 0, 0, 0, dif_pi_format); 1656 1657 _iov_free_buf(&iov); 1658 _iov_free_buf(&bounce_iov); 1659 } 1660 1661 static void 1662 dif_copy_sec_4096_md_128_prchk_0_single_iov_test(void) 1663 { 1664 _dif_copy_sec_4096_md_128_prchk_0_single_iov_test(SPDK_DIF_PI_FORMAT_32); 1665 _dif_copy_sec_4096_md_128_prchk_0_single_iov_test(SPDK_DIF_PI_FORMAT_64); 1666 } 1667 1668 static void 1669 dif_copy_sec_512_md_8_prchk_0_1_2_4_multi_iovs(void) 1670 { 1671 struct iovec iovs[4], bounce_iov; 1672 int i, num_blocks; 1673 1674 num_blocks = 0; 1675 1676 for (i = 0; i < 4; i++) { 1677 _iov_alloc_buf(&iovs[i], 512 * (i + 1)); 1678 num_blocks += i + 1; 1679 } 1680 1681 _iov_alloc_buf(&bounce_iov, (512 + 8) * num_blocks); 1682 1683 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 1, 512 + 8, 8, num_blocks, 1684 false, SPDK_DIF_TYPE1, 0, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 1685 1686 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 1, 512 + 8, 8, num_blocks, 1687 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22, 1688 SPDK_DIF_PI_FORMAT_16); 1689 1690 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 1, 512 + 8, 8, num_blocks, 1691 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22, 1692 SPDK_DIF_PI_FORMAT_16); 1693 1694 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 1, 512 + 8, 8, num_blocks, 1695 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22, 1696 SPDK_DIF_PI_FORMAT_16); 1697 1698 for (i = 0; i < 4; i++) { 1699 _iov_free_buf(&iovs[i]); 1700 } 1701 _iov_free_buf(&bounce_iov); 1702 } 1703 1704 static void 1705 _dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test( 1706 enum spdk_dif_pi_format dif_pi_format) 1707 { 1708 struct iovec iovs[4], bounce_iov; 1709 int i, num_blocks; 1710 1711 num_blocks = 0; 1712 1713 for (i = 0; i < 4; i++) { 1714 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 1715 num_blocks += i + 1; 1716 } 1717 1718 _iov_alloc_buf(&bounce_iov, (4096 + 128) * num_blocks); 1719 1720 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 1, 4096 + 128, 128, num_blocks, 1721 false, SPDK_DIF_TYPE1, 0, 22, 0xFFFF, 0x22, dif_pi_format); 1722 1723 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 1, 4096 + 128, 128, num_blocks, 1724 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22, 1725 dif_pi_format); 1726 1727 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 1, 4096 + 128, 128, num_blocks, 1728 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22, 1729 dif_pi_format); 1730 1731 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 1, 4096 + 128, 128, num_blocks, 1732 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22, 1733 dif_pi_format); 1734 1735 for (i = 0; i < 4; i++) { 1736 _iov_free_buf(&iovs[i]); 1737 } 1738 _iov_free_buf(&bounce_iov); 1739 } 1740 1741 static void 1742 dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(void) 1743 { 1744 _dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(SPDK_DIF_PI_FORMAT_32); 1745 _dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(SPDK_DIF_PI_FORMAT_64); 1746 } 1747 1748 static void 1749 _dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_bounce_iovs_test( 1750 enum spdk_dif_pi_format dif_pi_format) 1751 { 1752 struct iovec iovs[4], bounce_iovs[2]; 1753 int i, num_blocks; 1754 1755 num_blocks = 0; 1756 1757 for (i = 0; i < 4; i++) { 1758 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 1759 num_blocks += i + 1; 1760 } 1761 1762 num_blocks = 0; 1763 1764 for (i = 0; i < 2; i++) { 1765 _iov_alloc_buf(&bounce_iovs[i], (4096 + 128) * 2 * (i + 1)); 1766 num_blocks += 2 * (i + 1); 1767 } 1768 1769 dif_copy_gen_and_verify(iovs, 4, bounce_iovs, 2, 4096 + 128, 128, num_blocks, 1770 false, SPDK_DIF_TYPE1, 0, 22, 0xFFFF, 0x22, dif_pi_format); 1771 1772 dif_copy_gen_and_verify(iovs, 4, bounce_iovs, 2, 4096 + 128, 128, num_blocks, 1773 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22, 1774 dif_pi_format); 1775 1776 dif_copy_gen_and_verify(iovs, 4, bounce_iovs, 2, 4096 + 128, 128, num_blocks, 1777 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22, 1778 dif_pi_format); 1779 1780 dif_copy_gen_and_verify(iovs, 4, bounce_iovs, 2, 4096 + 128, 128, num_blocks, 1781 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22, 1782 dif_pi_format); 1783 1784 for (i = 0; i < 4; i++) { 1785 _iov_free_buf(&iovs[i]); 1786 } 1787 1788 for (i = 0; i < 2; i++) { 1789 _iov_free_buf(&bounce_iovs[i]); 1790 } 1791 } 1792 1793 static void 1794 dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_bounce_iovs_test(void) 1795 { 1796 _dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_bounce_iovs_test(SPDK_DIF_PI_FORMAT_32); 1797 _dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_bounce_iovs_test(SPDK_DIF_PI_FORMAT_64); 1798 } 1799 1800 static void 1801 dif_copy_sec_4096_md_128_prchk_7_multi_iovs(void) 1802 { 1803 struct iovec iovs[4], bounce_iov; 1804 uint32_t dif_flags; 1805 int i, num_blocks; 1806 1807 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1808 SPDK_DIF_FLAGS_REFTAG_CHECK; 1809 1810 num_blocks = 0; 1811 1812 for (i = 0; i < 4; i++) { 1813 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 1814 num_blocks += i + 1; 1815 } 1816 1817 _iov_alloc_buf(&bounce_iov, (4096 + 128) * num_blocks); 1818 1819 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 1, 4096 + 128, 128, num_blocks, 1820 false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 1821 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 1, 4096 + 128, 128, num_blocks, 1822 true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 1823 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 1, 4096 + 128, 128, num_blocks, 1824 false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32); 1825 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 1, 4096 + 128, 128, num_blocks, 1826 true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32); 1827 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 1, 4096 + 128, 128, num_blocks, 1828 false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64); 1829 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 1, 4096 + 128, 128, num_blocks, 1830 true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64); 1831 1832 for (i = 0; i < 4; i++) { 1833 _iov_free_buf(&iovs[i]); 1834 } 1835 _iov_free_buf(&bounce_iov); 1836 } 1837 1838 static void 1839 dif_copy_sec_512_md_8_prchk_7_multi_iovs_split_data(void) 1840 { 1841 struct iovec iovs[2], bounce_iov; 1842 uint32_t dif_flags; 1843 1844 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1845 SPDK_DIF_FLAGS_REFTAG_CHECK; 1846 1847 _iov_alloc_buf(&iovs[0], 256); 1848 _iov_alloc_buf(&iovs[1], 256); 1849 1850 _iov_alloc_buf(&bounce_iov, 512 + 8); 1851 1852 dif_copy_gen_and_verify(iovs, 2, &bounce_iov, 1, 512 + 8, 8, 1, 1853 false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 1854 1855 _iov_free_buf(&iovs[0]); 1856 _iov_free_buf(&iovs[1]); 1857 _iov_free_buf(&bounce_iov); 1858 } 1859 1860 static void 1861 dif_copy_sec_4096_md_128_prchk_7_multi_iovs_split_data_test(void) 1862 { 1863 struct iovec iovs[2], bounce_iov; 1864 uint32_t dif_flags; 1865 1866 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1867 SPDK_DIF_FLAGS_REFTAG_CHECK; 1868 1869 _iov_alloc_buf(&iovs[0], 2048); 1870 _iov_alloc_buf(&iovs[1], 2048); 1871 1872 _iov_alloc_buf(&bounce_iov, 4096 + 128); 1873 1874 dif_copy_gen_and_verify(iovs, 2, &bounce_iov, 1, 4096 + 128, 128, 1, 1875 false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32); 1876 dif_copy_gen_and_verify(iovs, 2, &bounce_iov, 1, 4096 + 128, 128, 1, 1877 false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64); 1878 1879 _iov_free_buf(&iovs[0]); 1880 _iov_free_buf(&iovs[1]); 1881 _iov_free_buf(&bounce_iov); 1882 } 1883 1884 static void 1885 dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits(void) 1886 { 1887 struct iovec iovs[6], bounce_iov; 1888 uint32_t dif_flags; 1889 int i; 1890 1891 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1892 SPDK_DIF_FLAGS_REFTAG_CHECK; 1893 1894 /* data[0][255:0] */ 1895 _iov_alloc_buf(&iovs[0], 256); 1896 1897 /* data[0][511:256], data[1][255:0] */ 1898 _iov_alloc_buf(&iovs[1], 256 + 256); 1899 1900 /* data[1][382:256] */ 1901 _iov_alloc_buf(&iovs[2], 128); 1902 1903 /* data[1][383] */ 1904 _iov_alloc_buf(&iovs[3], 1); 1905 1906 /* data[1][510:384] */ 1907 _iov_alloc_buf(&iovs[4], 126); 1908 1909 /* data[1][511], data[2][511:0], data[3][511:0] */ 1910 _iov_alloc_buf(&iovs[5], 1 + 512 * 2); 1911 1912 _iov_alloc_buf(&bounce_iov, (512 + 8) * 4); 1913 1914 dif_copy_gen_and_verify(iovs, 6, &bounce_iov, 1, 512 + 8, 8, 4, 1915 true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 1916 1917 for (i = 0; i < 6; i++) { 1918 _iov_free_buf(&iovs[i]); 1919 } 1920 _iov_free_buf(&bounce_iov); 1921 } 1922 1923 static void 1924 dif_copy_sec_512_md_8_prchk_7_multi_bounce_iovs_complex_splits(void) 1925 { 1926 struct iovec iovs[6], bounce_iovs[7]; 1927 uint32_t dif_flags; 1928 int i; 1929 1930 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1931 SPDK_DIF_FLAGS_REFTAG_CHECK; 1932 1933 /* src_data[0][255:0] */ 1934 _iov_alloc_buf(&iovs[0], 256); 1935 1936 /* src_data[0][511:256], src_data[1][255:0] */ 1937 _iov_alloc_buf(&iovs[1], 256 + 256); 1938 1939 /* src_data[1][382:256] */ 1940 _iov_alloc_buf(&iovs[2], 128); 1941 1942 /* src_data[1][383] */ 1943 _iov_alloc_buf(&iovs[3], 1); 1944 1945 /* src_data[1][510:384] */ 1946 _iov_alloc_buf(&iovs[4], 126); 1947 1948 /* src_data[1][511], src_data[2][511:0], src_data[3][511:0] */ 1949 _iov_alloc_buf(&iovs[5], 1 + 512 * 2); 1950 1951 /* dst_data[0][516:0] */ 1952 _iov_alloc_buf(&bounce_iovs[0], 517); 1953 1954 /* dst_data[0][519:517], dst_data[1][260:0] */ 1955 _iov_alloc_buf(&bounce_iovs[1], 3 + 261); 1956 1957 /* dst_data[1][399:261] */ 1958 _iov_alloc_buf(&bounce_iovs[2], 139); 1959 1960 /* dst_data[1][511:400] */ 1961 _iov_alloc_buf(&bounce_iovs[3], 112); 1962 1963 /* dst_data[1][515:512] */ 1964 _iov_alloc_buf(&bounce_iovs[4], 4); 1965 1966 /* dst_data[1][519:516], dst_data[2][11:0] */ 1967 _iov_alloc_buf(&bounce_iovs[5], 21); 1968 1969 /* dst_data[1][519:12], dst_data[2][519:0], dst_data[3][519:0] */ 1970 _iov_alloc_buf(&bounce_iovs[6], 507 + 520 + 520); 1971 1972 dif_copy_gen_and_verify(iovs, 6, bounce_iovs, 7, 512 + 8, 8, 4, 1973 true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 1974 1975 for (i = 0; i < 6; i++) { 1976 _iov_free_buf(&iovs[i]); 1977 } 1978 1979 for (i = 0; i < 7; i++) { 1980 _iov_free_buf(&bounce_iovs[i]); 1981 } 1982 } 1983 1984 static void 1985 dif_copy_sec_512_md_8_dif_disable_multi_bounce_iovs_complex_splits(void) 1986 { 1987 struct iovec iovs[6], bounce_iovs[7]; 1988 int i; 1989 1990 /* 1991 * src_data is made of 4 blocks and its block size is 512. 1992 * dst_data is made of 4 blocks and its block size is 520. 1993 * 1994 * The first dimension of src_data[][] and dst_data[][] represents the 1995 * number of blocks, and the second dimension represents the bytes range. 1996 * 1997 * Test the case these data is split with arbitrary boundary. 1998 */ 1999 2000 /* src_data[0][255:0] */ 2001 _iov_alloc_buf(&iovs[0], 256); 2002 2003 /* src_data[0][511:256], src_data[1][255:0] */ 2004 _iov_alloc_buf(&iovs[1], 256 + 256); 2005 2006 /* src_data[1][382:256] */ 2007 _iov_alloc_buf(&iovs[2], 128); 2008 2009 /* src_data[1][383] */ 2010 _iov_alloc_buf(&iovs[3], 1); 2011 2012 /* src_data[1][510:384] */ 2013 _iov_alloc_buf(&iovs[4], 126); 2014 2015 /* src_data[1][511], src_data[2][511:0], src_data[3][511:0] */ 2016 _iov_alloc_buf(&iovs[5], 1 + 512 * 2); 2017 2018 /* dst_data[0][516:0] */ 2019 _iov_alloc_buf(&bounce_iovs[0], 517); 2020 2021 /* dst_data[0][519:517], dst_data[1][260:0] */ 2022 _iov_alloc_buf(&bounce_iovs[1], 3 + 261); 2023 2024 /* dst_data[1][399:261] */ 2025 _iov_alloc_buf(&bounce_iovs[2], 139); 2026 2027 /* dst_data[1][511:400] */ 2028 _iov_alloc_buf(&bounce_iovs[3], 112); 2029 2030 /* dst_data[1][515:512] */ 2031 _iov_alloc_buf(&bounce_iovs[4], 4); 2032 2033 /* dst_data[1][519:516], dst_data[2][11:0] */ 2034 _iov_alloc_buf(&bounce_iovs[5], 21); 2035 2036 /* dst_data[1][519:12], dst_data[2][519:0], dst_data[3][519:0] */ 2037 _iov_alloc_buf(&bounce_iovs[6], 507 + 520 + 520); 2038 2039 dif_copy_gen_and_verify(iovs, 6, bounce_iovs, 7, 512 + 8, 8, 4, 2040 true, SPDK_DIF_DISABLE, 0, 0, 0, 0, SPDK_DIF_PI_FORMAT_16); 2041 2042 for (i = 0; i < 6; i++) { 2043 _iov_free_buf(&iovs[i]); 2044 } 2045 2046 for (i = 0; i < 7; i++) { 2047 _iov_free_buf(&bounce_iovs[i]); 2048 } 2049 } 2050 2051 static void 2052 dif_copy_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test(void) 2053 { 2054 struct iovec iovs[6], bounce_iov; 2055 uint32_t dif_flags; 2056 int i; 2057 2058 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2059 SPDK_DIF_FLAGS_REFTAG_CHECK; 2060 2061 /* data[0][2047:0] */ 2062 _iov_alloc_buf(&iovs[0], 2048); 2063 2064 /* data[0][4095:2048], data[1][2047:0] */ 2065 _iov_alloc_buf(&iovs[1], 2048 + 2048); 2066 2067 /* data[1][3071:2048] */ 2068 _iov_alloc_buf(&iovs[2], 1024); 2069 2070 /* data[1][3072] */ 2071 _iov_alloc_buf(&iovs[3], 1); 2072 2073 /* data[1][4094:3073] */ 2074 _iov_alloc_buf(&iovs[4], 1022); 2075 2076 /* data[1][4095], data[2][4095:0], data[3][4095:0] */ 2077 _iov_alloc_buf(&iovs[5], 1 + 4096 * 2); 2078 2079 _iov_alloc_buf(&bounce_iov, (4096 + 128) * 4); 2080 2081 dif_copy_gen_and_verify(iovs, 6, &bounce_iov, 1, 4096 + 128, 128, 4, 2082 true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32); 2083 dif_copy_gen_and_verify(iovs, 6, &bounce_iov, 1, 4096 + 128, 128, 4, 2084 true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64); 2085 2086 for (i = 0; i < 6; i++) { 2087 _iov_free_buf(&iovs[i]); 2088 } 2089 _iov_free_buf(&bounce_iov); 2090 } 2091 2092 static void 2093 _dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov, 2094 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 2095 uint32_t inject_flags, bool dif_loc, enum spdk_dif_pi_format dif_pi_format) 2096 { 2097 struct spdk_dif_ctx ctx = {}; 2098 struct spdk_dif_error err_blk = {}; 2099 uint32_t inject_offset = 0, dif_flags; 2100 int rc; 2101 struct spdk_dif_ctx_init_ext_opts dif_opts; 2102 2103 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2104 SPDK_DIF_FLAGS_REFTAG_CHECK; 2105 2106 rc = ut_data_pattern_generate(iovs, iovcnt, block_size - md_size, 0, num_blocks); 2107 CU_ASSERT(rc == 0); 2108 2109 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 2110 dif_opts.dif_pi_format = dif_pi_format; 2111 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, SPDK_DIF_TYPE1, dif_flags, 2112 88, 0xFFFF, 0x88, 0, GUARD_SEED, &dif_opts); 2113 SPDK_CU_ASSERT_FATAL(rc == 0); 2114 2115 rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, 1, num_blocks, &ctx); 2116 CU_ASSERT(rc == 0); 2117 2118 rc = spdk_dif_inject_error(bounce_iov, 1, num_blocks, &ctx, inject_flags, &inject_offset); 2119 CU_ASSERT(rc == 0); 2120 2121 rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, 1, num_blocks, &ctx, &err_blk); 2122 CU_ASSERT(rc != 0); 2123 if (inject_flags == SPDK_DIF_DATA_ERROR) { 2124 CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type); 2125 } else { 2126 CU_ASSERT(inject_flags == err_blk.err_type); 2127 } 2128 CU_ASSERT(inject_offset == err_blk.err_offset); 2129 } 2130 2131 static void 2132 dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov, 2133 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 2134 uint32_t inject_flags, enum spdk_dif_pi_format dif_pi_format) 2135 { 2136 /* The case that DIF is contained in the first 8/16 bytes of metadata. */ 2137 _dif_copy_inject_error_and_verify(iovs, iovcnt, bounce_iov, 2138 block_size, md_size, num_blocks, 2139 inject_flags, true, dif_pi_format); 2140 2141 /* The case that DIF is contained in the last 8/16 bytes of metadata. */ 2142 _dif_copy_inject_error_and_verify(iovs, iovcnt, bounce_iov, 2143 block_size, md_size, num_blocks, 2144 inject_flags, false, dif_pi_format); 2145 } 2146 2147 static void 2148 dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test(void) 2149 { 2150 struct iovec iovs[4], bounce_iov; 2151 int i, num_blocks; 2152 2153 num_blocks = 0; 2154 2155 for (i = 0; i < 4; i++) { 2156 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 2157 num_blocks += i + 1; 2158 } 2159 2160 _iov_alloc_buf(&bounce_iov, (4096 + 128) * num_blocks); 2161 2162 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2163 num_blocks, SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_16); 2164 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2165 num_blocks, SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_16); 2166 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2167 num_blocks, SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_16); 2168 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2169 num_blocks, SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_16); 2170 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2171 num_blocks, SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_32); 2172 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2173 num_blocks, SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_32); 2174 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2175 num_blocks, SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_32); 2176 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2177 num_blocks, SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_32); 2178 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2179 num_blocks, SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_64); 2180 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2181 num_blocks, SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_64); 2182 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2183 num_blocks, SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_64); 2184 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2185 num_blocks, SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_64); 2186 2187 for (i = 0; i < 4; i++) { 2188 _iov_free_buf(&iovs[i]); 2189 } 2190 _iov_free_buf(&bounce_iov); 2191 } 2192 2193 static void 2194 dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test(void) 2195 { 2196 struct iovec iovs[4], bounce_iov; 2197 int i; 2198 2199 _iov_alloc_buf(&iovs[0], 2048); 2200 _iov_alloc_buf(&iovs[1], 2048); 2201 _iov_alloc_buf(&iovs[2], 1); 2202 _iov_alloc_buf(&iovs[3], 4095); 2203 2204 _iov_alloc_buf(&bounce_iov, (4096 + 128) * 2); 2205 2206 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2207 2, SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_16); 2208 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2209 2, SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_16); 2210 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2211 2, SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_16); 2212 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2213 2, SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_16); 2214 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2215 2, SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_32); 2216 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2217 2, SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_32); 2218 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2219 2, SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_32); 2220 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2221 2, SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_32); 2222 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2223 2, SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_64); 2224 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2225 2, SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_64); 2226 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2227 2, SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_64); 2228 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 2229 2, SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_64); 2230 2231 for (i = 0; i < 4; i++) { 2232 _iov_free_buf(&iovs[i]); 2233 } 2234 _iov_free_buf(&bounce_iov); 2235 } 2236 2237 static void 2238 dix_sec_0_md_8_error(void) 2239 { 2240 struct spdk_dif_ctx ctx; 2241 int rc; 2242 struct spdk_dif_ctx_init_ext_opts dif_opts; 2243 2244 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 2245 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 2246 rc = spdk_dif_ctx_init(&ctx, 0, 8, false, false, SPDK_DIF_TYPE1, 0, 2247 0, 0, 0, 0, 0, &dif_opts); 2248 CU_ASSERT(rc != 0); 2249 } 2250 2251 static void 2252 dix_sec_512_md_0_error(void) 2253 { 2254 struct spdk_dif_ctx ctx; 2255 int rc; 2256 struct spdk_dif_ctx_init_ext_opts dif_opts; 2257 2258 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 2259 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 2260 rc = spdk_dif_ctx_init(&ctx, 512, 0, false, false, SPDK_DIF_TYPE1, 0, 2261 0, 0, 0, 0, 0, &dif_opts); 2262 CU_ASSERT(rc != 0); 2263 } 2264 2265 static void 2266 _dix_sec_512_md_16_error(enum spdk_dif_pi_format dif_pi_format) 2267 { 2268 struct spdk_dif_ctx ctx; 2269 int rc; 2270 struct spdk_dif_ctx_init_ext_opts dif_opts; 2271 2272 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 2273 dif_opts.dif_pi_format = dif_pi_format; 2274 rc = spdk_dif_ctx_init(&ctx, 512, 16, false, false, SPDK_DIF_TYPE1, 0, 2275 0, 0, 0, 0, 0, &dif_opts); 2276 CU_ASSERT(rc != 0); 2277 } 2278 2279 static void 2280 dix_sec_512_md_16_error(void) 2281 { 2282 _dix_sec_512_md_16_error(SPDK_DIF_PI_FORMAT_32); 2283 _dix_sec_512_md_16_error(SPDK_DIF_PI_FORMAT_64); 2284 } 2285 2286 static void 2287 _dix_sec_4096_md_0_8_error(enum spdk_dif_pi_format dif_pi_format) 2288 { 2289 struct spdk_dif_ctx ctx = {}; 2290 int rc; 2291 struct spdk_dif_ctx_init_ext_opts dif_opts; 2292 2293 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 2294 dif_opts.dif_pi_format = dif_pi_format; 2295 /* Metadata size is 0. */ 2296 rc = spdk_dif_ctx_init(&ctx, 4096, 0, true, false, SPDK_DIF_TYPE1, 0, 2297 0, 0, 0, 0, 0, &dif_opts); 2298 CU_ASSERT(rc != 0); 2299 2300 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 2301 dif_opts.dif_pi_format = dif_pi_format; 2302 /* Metadata size is 0. */ 2303 rc = spdk_dif_ctx_init(&ctx, 4096, 8, true, false, SPDK_DIF_TYPE1, 0, 2304 0, 0, 0, 0, 0, &dif_opts); 2305 CU_ASSERT(rc != 0); 2306 } 2307 2308 static void 2309 dix_sec_4096_md_0_8_error(void) 2310 { 2311 _dix_sec_4096_md_0_8_error(SPDK_DIF_PI_FORMAT_32); 2312 _dix_sec_4096_md_0_8_error(SPDK_DIF_PI_FORMAT_64); 2313 } 2314 2315 static void 2316 dix_generate_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, 2317 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 2318 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, 2319 uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag, 2320 enum spdk_dif_pi_format dif_pi_format) 2321 { 2322 struct spdk_dif_ctx ctx; 2323 int rc; 2324 struct spdk_dif_ctx_init_ext_opts dif_opts; 2325 2326 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, 0, num_blocks); 2327 CU_ASSERT(rc == 0); 2328 2329 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 2330 dif_opts.dif_pi_format = dif_pi_format; 2331 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags, 2332 init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED, &dif_opts); 2333 CU_ASSERT(rc == 0); 2334 2335 rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx); 2336 CU_ASSERT(rc == 0); 2337 2338 rc = spdk_dix_verify(iovs, iovcnt, md_iov, num_blocks, &ctx, NULL); 2339 CU_ASSERT(rc == 0); 2340 2341 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, 0, num_blocks); 2342 CU_ASSERT(rc == 0); 2343 } 2344 2345 static void 2346 dix_sec_512_md_8_prchk_0_single_iov(void) 2347 { 2348 struct iovec iov, md_iov; 2349 2350 _iov_alloc_buf(&iov, 512 * 4); 2351 _iov_alloc_buf(&md_iov, 8 * 4); 2352 2353 dix_generate_and_verify(&iov, 1, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 2354 SPDK_DIF_PI_FORMAT_16); 2355 dix_generate_and_verify(&iov, 1, &md_iov, 512, 8, 4, true, SPDK_DIF_TYPE1, 0, 0, 0, 0, 2356 SPDK_DIF_PI_FORMAT_16); 2357 2358 _iov_free_buf(&iov); 2359 _iov_free_buf(&md_iov); 2360 } 2361 2362 static void 2363 _dix_sec_4096_md_128_prchk_0_single_iov_test( 2364 enum spdk_dif_pi_format dif_pi_format) 2365 { 2366 struct iovec iov, md_iov; 2367 2368 _iov_alloc_buf(&iov, 4096 * 4); 2369 _iov_alloc_buf(&md_iov, 128 * 4); 2370 2371 dix_generate_and_verify(&iov, 1, &md_iov, 4096, 128, 4, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 2372 dif_pi_format); 2373 dix_generate_and_verify(&iov, 1, &md_iov, 4096, 128, 4, true, SPDK_DIF_TYPE1, 0, 0, 0, 0, 2374 dif_pi_format); 2375 2376 _iov_free_buf(&iov); 2377 _iov_free_buf(&md_iov); 2378 } 2379 2380 static void 2381 dix_sec_4096_md_128_prchk_0_single_iov_test(void) 2382 { 2383 _dix_sec_4096_md_128_prchk_0_single_iov_test(SPDK_DIF_PI_FORMAT_32); 2384 _dix_sec_4096_md_128_prchk_0_single_iov_test(SPDK_DIF_PI_FORMAT_64); 2385 } 2386 2387 static void 2388 dix_sec_512_md_8_prchk_0_1_2_4_multi_iovs(void) 2389 { 2390 struct iovec iovs[4], md_iov; 2391 int i, num_blocks; 2392 2393 num_blocks = 0; 2394 2395 for (i = 0; i < 4; i++) { 2396 _iov_alloc_buf(&iovs[i], 512 * (i + 1)); 2397 num_blocks += i + 1; 2398 } 2399 _iov_alloc_buf(&md_iov, 8 * num_blocks); 2400 2401 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, 2402 0, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 2403 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, 2404 SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 2405 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, 2406 SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 2407 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, 2408 SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 2409 2410 for (i = 0; i < 4; i++) { 2411 _iov_free_buf(&iovs[i]); 2412 } 2413 _iov_free_buf(&md_iov); 2414 } 2415 2416 static void 2417 _dix_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test( 2418 enum spdk_dif_pi_format dif_pi_format) 2419 { 2420 struct iovec iovs[4], md_iov; 2421 int i, num_blocks; 2422 2423 num_blocks = 0; 2424 2425 for (i = 0; i < 4; i++) { 2426 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 2427 num_blocks += i + 1; 2428 } 2429 _iov_alloc_buf(&md_iov, 128 * num_blocks); 2430 2431 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1, 2432 0, 22, 0xFFFF, 0x22, dif_pi_format); 2433 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1, 2434 SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22, dif_pi_format); 2435 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1, 2436 SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22, dif_pi_format); 2437 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1, 2438 SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22, dif_pi_format); 2439 2440 for (i = 0; i < 4; i++) { 2441 _iov_free_buf(&iovs[i]); 2442 } 2443 _iov_free_buf(&md_iov); 2444 } 2445 2446 static void 2447 dix_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(void) 2448 { 2449 _dix_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(SPDK_DIF_PI_FORMAT_32); 2450 _dix_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test(SPDK_DIF_PI_FORMAT_64); 2451 } 2452 2453 /* TODO start here */ 2454 2455 static void 2456 dix_sec_4096_md_128_prchk_7_multi_iovs(void) 2457 { 2458 struct iovec iovs[4], md_iov; 2459 uint32_t dif_flags; 2460 int i, num_blocks; 2461 2462 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2463 SPDK_DIF_FLAGS_REFTAG_CHECK; 2464 2465 num_blocks = 0; 2466 2467 for (i = 0; i < 4; i++) { 2468 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 2469 num_blocks += i + 1; 2470 } 2471 _iov_alloc_buf(&md_iov, 128 * num_blocks); 2472 2473 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1, 2474 dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 2475 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1, 2476 dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 2477 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1, 2478 dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32); 2479 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1, 2480 dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32); 2481 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1, 2482 dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64); 2483 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1, 2484 dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64); 2485 2486 for (i = 0; i < 4; i++) { 2487 _iov_free_buf(&iovs[i]); 2488 } 2489 _iov_free_buf(&md_iov); 2490 } 2491 2492 static void 2493 dix_sec_512_md_8_prchk_7_multi_iovs_split_data(void) 2494 { 2495 struct iovec iovs[2], md_iov; 2496 uint32_t dif_flags; 2497 2498 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2499 SPDK_DIF_FLAGS_REFTAG_CHECK; 2500 2501 _iov_alloc_buf(&iovs[0], 256); 2502 _iov_alloc_buf(&iovs[1], 256); 2503 _iov_alloc_buf(&md_iov, 8); 2504 2505 dix_generate_and_verify(iovs, 2, &md_iov, 512, 8, 1, false, SPDK_DIF_TYPE1, 2506 dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 2507 2508 _iov_free_buf(&iovs[0]); 2509 _iov_free_buf(&iovs[1]); 2510 _iov_free_buf(&md_iov); 2511 } 2512 2513 static void 2514 dix_sec_4096_md_128_prchk_7_multi_iovs_split_data_test(void) 2515 { 2516 struct iovec iovs[2], md_iov; 2517 uint32_t dif_flags; 2518 2519 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2520 SPDK_DIF_FLAGS_REFTAG_CHECK; 2521 2522 _iov_alloc_buf(&iovs[0], 2048); 2523 _iov_alloc_buf(&iovs[1], 2048); 2524 _iov_alloc_buf(&md_iov, 128); 2525 2526 dix_generate_and_verify(iovs, 2, &md_iov, 4096, 128, 1, false, SPDK_DIF_TYPE1, 2527 dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32); 2528 dix_generate_and_verify(iovs, 2, &md_iov, 4096, 128, 1, false, SPDK_DIF_TYPE1, 2529 dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64); 2530 2531 _iov_free_buf(&iovs[0]); 2532 _iov_free_buf(&iovs[1]); 2533 _iov_free_buf(&md_iov); 2534 } 2535 2536 static void 2537 dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits(void) 2538 { 2539 struct iovec iovs[6], md_iov; 2540 uint32_t dif_flags; 2541 int i; 2542 2543 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2544 SPDK_DIF_FLAGS_REFTAG_CHECK; 2545 2546 /* data[0][255:0] */ 2547 _iov_alloc_buf(&iovs[0], 256); 2548 2549 /* data[0][511:256], data[1][255:0] */ 2550 _iov_alloc_buf(&iovs[1], 256 + 256); 2551 2552 /* data[1][382:256] */ 2553 _iov_alloc_buf(&iovs[2], 128); 2554 2555 /* data[1][383] */ 2556 _iov_alloc_buf(&iovs[3], 1); 2557 2558 /* data[1][510:384] */ 2559 _iov_alloc_buf(&iovs[4], 126); 2560 2561 /* data[1][511], data[2][511:0], data[3][511:0] */ 2562 _iov_alloc_buf(&iovs[5], 1 + 512 * 2); 2563 2564 _iov_alloc_buf(&md_iov, 8 * 4); 2565 2566 dix_generate_and_verify(iovs, 6, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1, 2567 dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 2568 2569 for (i = 0; i < 6; i++) { 2570 _iov_free_buf(&iovs[i]); 2571 } 2572 _iov_free_buf(&md_iov); 2573 } 2574 2575 static void 2576 dix_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test(void) 2577 { 2578 struct iovec iovs[6], md_iov; 2579 uint32_t dif_flags; 2580 int i; 2581 2582 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2583 SPDK_DIF_FLAGS_REFTAG_CHECK; 2584 2585 /* data[0][2047:0] */ 2586 _iov_alloc_buf(&iovs[0], 2048); 2587 2588 /* data[0][4095:2048], data[1][2047:0] */ 2589 _iov_alloc_buf(&iovs[1], 2048 + 2048); 2590 2591 /* data[1][3071:2048] */ 2592 _iov_alloc_buf(&iovs[2], 1024); 2593 2594 /* data[1][3072] */ 2595 _iov_alloc_buf(&iovs[3], 1); 2596 2597 /* data[1][4094:3073] */ 2598 _iov_alloc_buf(&iovs[4], 1022); 2599 2600 /* data[1][4095], data[2][4095:0], data[3][4095:0] */ 2601 _iov_alloc_buf(&iovs[5], 1 + 4096 * 2); 2602 2603 _iov_alloc_buf(&md_iov, 128 * 4); 2604 2605 dix_generate_and_verify(iovs, 6, &md_iov, 4096, 128, 4, false, SPDK_DIF_TYPE1, 2606 dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32); 2607 dix_generate_and_verify(iovs, 6, &md_iov, 4096, 128, 4, false, SPDK_DIF_TYPE1, 2608 dif_flags, 22, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64); 2609 2610 for (i = 0; i < 6; i++) { 2611 _iov_free_buf(&iovs[i]); 2612 } 2613 _iov_free_buf(&md_iov); 2614 } 2615 2616 static void 2617 _dix_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, 2618 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 2619 uint32_t inject_flags, bool dif_loc, enum spdk_dif_pi_format dif_pi_format) 2620 { 2621 struct spdk_dif_ctx ctx = {}; 2622 struct spdk_dif_error err_blk = {}; 2623 uint32_t inject_offset = 0, dif_flags; 2624 int rc; 2625 struct spdk_dif_ctx_init_ext_opts dif_opts; 2626 2627 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2628 SPDK_DIF_FLAGS_REFTAG_CHECK; 2629 2630 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, 0, num_blocks); 2631 CU_ASSERT(rc == 0); 2632 2633 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 2634 dif_opts.dif_pi_format = dif_pi_format; 2635 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, SPDK_DIF_TYPE1, dif_flags, 2636 88, 0xFFFF, 0x88, 0, GUARD_SEED, &dif_opts); 2637 CU_ASSERT(rc == 0); 2638 2639 rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx); 2640 CU_ASSERT(rc == 0); 2641 2642 rc = spdk_dix_inject_error(iovs, iovcnt, md_iov, num_blocks, &ctx, inject_flags, &inject_offset); 2643 CU_ASSERT(rc == 0); 2644 2645 rc = spdk_dix_verify(iovs, iovcnt, md_iov, num_blocks, &ctx, &err_blk); 2646 CU_ASSERT(rc != 0); 2647 2648 if (inject_flags == SPDK_DIF_DATA_ERROR) { 2649 CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type); 2650 } else { 2651 CU_ASSERT(inject_flags == err_blk.err_type); 2652 } 2653 CU_ASSERT(inject_offset == err_blk.err_offset); 2654 } 2655 2656 static void 2657 dix_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, 2658 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 2659 uint32_t inject_flags, enum spdk_dif_pi_format dif_pi_format) 2660 { 2661 /* The case that DIF is contained in the first 8/16 bytes of metadata. */ 2662 _dix_inject_error_and_verify(iovs, iovcnt, md_iov, block_size, md_size, num_blocks, 2663 inject_flags, true, dif_pi_format); 2664 2665 /* The case that DIF is contained in the last 8/16 bytes of metadata. */ 2666 _dix_inject_error_and_verify(iovs, iovcnt, md_iov, block_size, md_size, num_blocks, 2667 inject_flags, false, dif_pi_format); 2668 } 2669 2670 static void 2671 dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test(void) 2672 { 2673 struct iovec iovs[4], md_iov; 2674 int i, num_blocks; 2675 2676 num_blocks = 0; 2677 2678 for (i = 0; i < 4; i++) { 2679 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 2680 num_blocks += i + 1; 2681 } 2682 2683 _iov_alloc_buf(&md_iov, 128 * num_blocks); 2684 2685 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, 2686 SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_16); 2687 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, 2688 SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_16); 2689 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, 2690 SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_16); 2691 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, 2692 SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_16); 2693 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, 2694 SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_32); 2695 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, 2696 SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_32); 2697 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, 2698 SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_32); 2699 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, 2700 SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_32); 2701 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, 2702 SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_64); 2703 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, 2704 SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_64); 2705 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, 2706 SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_64); 2707 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, 2708 SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_64); 2709 2710 for (i = 0; i < 4; i++) { 2711 _iov_free_buf(&iovs[i]); 2712 } 2713 _iov_free_buf(&md_iov); 2714 } 2715 2716 static void 2717 dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test(void) 2718 { 2719 struct iovec iovs[4], md_iov; 2720 int i; 2721 2722 _iov_alloc_buf(&iovs[0], 2048); 2723 _iov_alloc_buf(&iovs[1], 2048); 2724 _iov_alloc_buf(&iovs[2], 1); 2725 _iov_alloc_buf(&iovs[3], 4095); 2726 2727 _iov_alloc_buf(&md_iov, 128 * 2); 2728 2729 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, 2730 SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_16); 2731 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, 2732 SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_16); 2733 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, 2734 SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_16); 2735 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, 2736 SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_16); 2737 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, 2738 SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_32); 2739 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, 2740 SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_32); 2741 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, 2742 SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_32); 2743 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, 2744 SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_32); 2745 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, 2746 SPDK_DIF_GUARD_ERROR, SPDK_DIF_PI_FORMAT_64); 2747 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, 2748 SPDK_DIF_APPTAG_ERROR, SPDK_DIF_PI_FORMAT_64); 2749 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, 2750 SPDK_DIF_REFTAG_ERROR, SPDK_DIF_PI_FORMAT_64); 2751 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, 2752 SPDK_DIF_DATA_ERROR, SPDK_DIF_PI_FORMAT_64); 2753 2754 for (i = 0; i < 4; i++) { 2755 _iov_free_buf(&iovs[i]); 2756 } 2757 _iov_free_buf(&md_iov); 2758 } 2759 2760 static int 2761 ut_readv(uint32_t read_base, uint32_t read_len, struct iovec *iovs, int iovcnt) 2762 { 2763 int i; 2764 uint32_t j, offset; 2765 uint8_t *buf; 2766 2767 offset = 0; 2768 for (i = 0; i < iovcnt; i++) { 2769 buf = iovs[i].iov_base; 2770 for (j = 0; j < iovs[i].iov_len; j++, offset++) { 2771 if (offset >= read_len) { 2772 return offset; 2773 } 2774 buf[j] = DATA_PATTERN(read_base + offset); 2775 } 2776 } 2777 2778 return offset; 2779 } 2780 2781 static void 2782 _set_md_interleave_iovs_test(enum spdk_dif_pi_format dif_pi_format) 2783 { 2784 struct spdk_dif_ctx ctx = {}; 2785 struct spdk_dif_error err_blk = {}; 2786 struct iovec iov1, iov2, dif_iovs[4] = {}; 2787 uint32_t dif_check_flags, data_len, read_len, data_offset, mapped_len = 0; 2788 uint8_t *buf1, *buf2; 2789 int rc; 2790 struct spdk_dif_ctx_init_ext_opts dif_opts; 2791 2792 dif_check_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2793 SPDK_DIF_FLAGS_REFTAG_CHECK; 2794 2795 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 2796 dif_opts.dif_pi_format = dif_pi_format; 2797 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 2798 dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED, &dif_opts); 2799 CU_ASSERT(rc == 0); 2800 2801 /* The first data buffer: 2802 * - Create iovec array to Leave a space for metadata for each block 2803 * - Split vectored read and so creating iovec array is done before every vectored read. 2804 */ 2805 buf1 = calloc(1, (4096 + 128) * 4); 2806 SPDK_CU_ASSERT_FATAL(buf1 != NULL); 2807 _iov_set_buf(&iov1, buf1, (4096 + 128) * 4); 2808 2809 data_offset = 0; 2810 data_len = 4096 * 4; 2811 2812 /* 1st read */ 2813 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 2814 data_offset, data_len, &mapped_len, &ctx); 2815 CU_ASSERT(rc == 4); 2816 CU_ASSERT(mapped_len == 4096 * 4); 2817 CU_ASSERT(_iov_check(&dif_iovs[0], buf1, 4096) == true); 2818 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true); 2819 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true); 2820 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 4096) == true); 2821 2822 read_len = ut_readv(data_offset, 1024, dif_iovs, 4); 2823 CU_ASSERT(read_len == 1024); 2824 2825 rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx); 2826 CU_ASSERT(rc == 0); 2827 2828 data_offset += read_len; 2829 data_len -= read_len; 2830 2831 /* 2nd read */ 2832 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 2833 data_offset, data_len, &mapped_len, &ctx); 2834 CU_ASSERT(rc == 4); 2835 CU_ASSERT(mapped_len == 3072 + 4096 * 3); 2836 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 1024, 3072) == true); 2837 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true); 2838 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true); 2839 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 4096) == true); 2840 2841 read_len = ut_readv(data_offset, 3071, dif_iovs, 4); 2842 CU_ASSERT(read_len == 3071); 2843 2844 rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx); 2845 CU_ASSERT(rc == 0); 2846 2847 data_offset += read_len; 2848 data_len -= read_len; 2849 2850 /* 3rd read */ 2851 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 2852 data_offset, data_len, &mapped_len, &ctx); 2853 CU_ASSERT(rc == 4); 2854 CU_ASSERT(mapped_len == 1 + 4096 * 3); 2855 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 4095, 1) == true); 2856 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true); 2857 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true); 2858 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 4096) == true); 2859 2860 read_len = ut_readv(data_offset, 1 + 4096 * 2 + 512, dif_iovs, 4); 2861 CU_ASSERT(read_len == 1 + 4096 * 2 + 512); 2862 2863 rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx); 2864 CU_ASSERT(rc == 0); 2865 2866 data_offset += read_len; 2867 data_len -= read_len; 2868 2869 /* 4th read */ 2870 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 2871 data_offset, data_len, &mapped_len, &ctx); 2872 CU_ASSERT(rc == 1); 2873 CU_ASSERT(mapped_len == 3584); 2874 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + (4096 + 128) * 3 + 512, 3584) == true); 2875 2876 read_len = ut_readv(data_offset, 3584, dif_iovs, 1); 2877 CU_ASSERT(read_len == 3584); 2878 2879 rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx); 2880 CU_ASSERT(rc == 0); 2881 2882 data_offset += read_len; 2883 CU_ASSERT(data_offset == 4096 * 4); 2884 data_len -= read_len; 2885 CU_ASSERT(data_len == 0); 2886 2887 /* The second data buffer: 2888 * - Set data pattern with a space for metadata for each block. 2889 */ 2890 buf2 = calloc(1, (4096 + 128) * 4); 2891 SPDK_CU_ASSERT_FATAL(buf2 != NULL); 2892 _iov_set_buf(&iov2, buf2, (4096 + 128) * 4); 2893 2894 rc = ut_data_pattern_generate(&iov2, 1, 4096 + 128, 128, 4); 2895 CU_ASSERT(rc == 0); 2896 rc = spdk_dif_generate(&iov2, 1, 4, &ctx); 2897 CU_ASSERT(rc == 0); 2898 2899 rc = spdk_dif_verify(&iov1, 1, 4, &ctx, &err_blk); 2900 CU_ASSERT(rc == 0); 2901 2902 rc = spdk_dif_verify(&iov2, 1, 4, &ctx, &err_blk); 2903 CU_ASSERT(rc == 0); 2904 2905 /* Compare the first and the second data buffer by byte. */ 2906 rc = memcmp(buf1, buf2, (4096 + 128) * 4); 2907 CU_ASSERT(rc == 0); 2908 2909 free(buf1); 2910 free(buf2); 2911 } 2912 2913 static void 2914 set_md_interleave_iovs_test(void) 2915 { 2916 _set_md_interleave_iovs_test(SPDK_DIF_PI_FORMAT_16); 2917 _set_md_interleave_iovs_test(SPDK_DIF_PI_FORMAT_32); 2918 _set_md_interleave_iovs_test(SPDK_DIF_PI_FORMAT_64); 2919 } 2920 2921 static void 2922 set_md_interleave_iovs_split_test(void) 2923 { 2924 struct spdk_dif_ctx ctx = {}; 2925 struct spdk_dif_error err_blk = {}; 2926 struct iovec iovs1[7], iovs2[7], dif_iovs[8] = {}; 2927 uint32_t dif_check_flags, data_len, read_len, data_offset, mapped_len = 0; 2928 int rc, i; 2929 struct spdk_dif_ctx_init_ext_opts dif_opts; 2930 2931 dif_check_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2932 SPDK_DIF_FLAGS_REFTAG_CHECK; 2933 2934 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 2935 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 2936 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, 2937 dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED, &dif_opts); 2938 CU_ASSERT(rc == 0); 2939 2940 /* The first SGL data buffer: 2941 * - Create iovec array to leave a space for metadata for each block 2942 * - Split vectored read and so creating iovec array is done before every vectored read. 2943 */ 2944 _iov_alloc_buf(&iovs1[0], 512 + 8 + 128); 2945 _iov_alloc_buf(&iovs1[1], 128); 2946 _iov_alloc_buf(&iovs1[2], 256 + 8); 2947 _iov_alloc_buf(&iovs1[3], 100); 2948 _iov_alloc_buf(&iovs1[4], 412 + 5); 2949 _iov_alloc_buf(&iovs1[5], 3 + 300); 2950 _iov_alloc_buf(&iovs1[6], 212 + 8); 2951 2952 data_offset = 0; 2953 data_len = 512 * 4; 2954 2955 /* 1st read */ 2956 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7, 2957 data_offset, data_len, &mapped_len, &ctx); 2958 CU_ASSERT(rc == 8); 2959 CU_ASSERT(mapped_len == 512 * 4); 2960 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base, 512) == true); 2961 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true); 2962 CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true); 2963 CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true); 2964 CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true); 2965 CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true); 2966 CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true); 2967 CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true); 2968 2969 read_len = ut_readv(data_offset, 128, dif_iovs, 8); 2970 CU_ASSERT(read_len == 128); 2971 2972 rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx); 2973 CU_ASSERT(rc == 0); 2974 2975 data_offset += read_len; 2976 data_len -= read_len; 2977 2978 /* 2nd read */ 2979 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7, 2980 data_offset, data_len, &mapped_len, &ctx); 2981 CU_ASSERT(rc == 8); 2982 CU_ASSERT(mapped_len == 384 + 512 * 3); 2983 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base + 128, 384) == true); 2984 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true); 2985 CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true); 2986 CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true); 2987 CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true); 2988 CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true); 2989 CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true); 2990 CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true); 2991 2992 read_len = ut_readv(data_offset, 383, dif_iovs, 8); 2993 CU_ASSERT(read_len == 383); 2994 2995 rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx); 2996 CU_ASSERT(rc == 0); 2997 2998 data_offset += read_len; 2999 data_len -= read_len; 3000 3001 /* 3rd read */ 3002 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7, 3003 data_offset, data_len, &mapped_len, &ctx); 3004 CU_ASSERT(rc == 8); 3005 CU_ASSERT(mapped_len == 1 + 512 * 3); 3006 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base + 511, 1) == true); 3007 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true); 3008 CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true); 3009 CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true); 3010 CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true); 3011 CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true); 3012 CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true); 3013 CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true); 3014 3015 read_len = ut_readv(data_offset, 1 + 512 * 2 + 128, dif_iovs, 8); 3016 CU_ASSERT(read_len == 1 + 512 * 2 + 128); 3017 3018 rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx); 3019 CU_ASSERT(rc == 0); 3020 3021 data_offset += read_len; 3022 data_len -= read_len; 3023 3024 /* 4th read */ 3025 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7, 3026 data_offset, data_len, &mapped_len, &ctx); 3027 CU_ASSERT(rc == 2); 3028 CU_ASSERT(mapped_len == 384); 3029 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[5].iov_base + 3 + 128, 172) == true); 3030 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[6].iov_base, 212) == true); 3031 3032 read_len = ut_readv(data_offset, 384, dif_iovs, 8); 3033 CU_ASSERT(read_len == 384); 3034 3035 rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx); 3036 CU_ASSERT(rc == 0); 3037 3038 data_offset += read_len; 3039 CU_ASSERT(data_offset == 512 * 4); 3040 data_len -= read_len; 3041 CU_ASSERT(data_len == 0); 3042 3043 /* The second SGL data buffer: 3044 * - Set data pattern with a space for metadata for each block. 3045 */ 3046 _iov_alloc_buf(&iovs2[0], 512 + 8 + 128); 3047 _iov_alloc_buf(&iovs2[1], 128); 3048 _iov_alloc_buf(&iovs2[2], 256 + 8); 3049 _iov_alloc_buf(&iovs2[3], 100); 3050 _iov_alloc_buf(&iovs2[4], 412 + 5); 3051 _iov_alloc_buf(&iovs2[5], 3 + 300); 3052 _iov_alloc_buf(&iovs2[6], 212 + 8); 3053 3054 rc = ut_data_pattern_generate(iovs2, 7, 512 + 8, 8, 4); 3055 CU_ASSERT(rc == 0); 3056 rc = spdk_dif_generate(iovs2, 7, 4, &ctx); 3057 CU_ASSERT(rc == 0); 3058 3059 rc = spdk_dif_verify(iovs1, 7, 4, &ctx, &err_blk); 3060 CU_ASSERT(rc == 0); 3061 3062 rc = spdk_dif_verify(iovs2, 7, 4, &ctx, &err_blk); 3063 CU_ASSERT(rc == 0); 3064 3065 /* Compare the first and the second SGL data buffer by byte. */ 3066 for (i = 0; i < 7; i++) { 3067 rc = memcmp(iovs1[i].iov_base, iovs2[i].iov_base, 3068 iovs1[i].iov_len); 3069 CU_ASSERT(rc == 0); 3070 } 3071 3072 for (i = 0; i < 7; i++) { 3073 _iov_free_buf(&iovs1[i]); 3074 _iov_free_buf(&iovs2[i]); 3075 } 3076 } 3077 3078 static void 3079 dif_generate_stream_pi_16_test(void) 3080 { 3081 struct iovec iov; 3082 struct spdk_dif_ctx ctx; 3083 struct spdk_dif_error err_blk; 3084 uint32_t dif_flags; 3085 int rc; 3086 struct spdk_dif_ctx_init_ext_opts dif_opts; 3087 3088 _iov_alloc_buf(&iov, (512 + 8) * 5); 3089 3090 rc = ut_data_pattern_generate(&iov, 1, 512 + 8, 8, 5); 3091 CU_ASSERT(rc == 0); 3092 3093 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 3094 SPDK_DIF_FLAGS_REFTAG_CHECK; 3095 3096 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 3097 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 3098 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, dif_flags, 3099 22, 0xFFFF, 0x22, 0, GUARD_SEED, &dif_opts); 3100 CU_ASSERT(rc == 0); 3101 3102 rc = spdk_dif_generate_stream(&iov, 1, 0, 511, &ctx); 3103 CU_ASSERT(rc == 0); 3104 3105 rc = spdk_dif_generate_stream(&iov, 1, 511, 1, &ctx); 3106 CU_ASSERT(rc == 0); 3107 3108 rc = spdk_dif_generate_stream(&iov, 1, 512, 256, &ctx); 3109 CU_ASSERT(rc == 0); 3110 3111 rc = spdk_dif_generate_stream(&iov, 1, 768, 512, &ctx); 3112 CU_ASSERT(rc == 0); 3113 3114 rc = spdk_dif_generate_stream(&iov, 1, 1280, 1024, &ctx); 3115 CU_ASSERT(rc == 0); 3116 3117 rc = spdk_dif_generate_stream(&iov, 1, 2304, 256, &ctx); 3118 CU_ASSERT(rc == 0); 3119 3120 rc = spdk_dif_generate_stream(&iov, 1, 2560, 512, &ctx); 3121 CU_ASSERT(rc == -ERANGE); 3122 3123 rc = spdk_dif_verify(&iov, 1, 5, &ctx, &err_blk); 3124 CU_ASSERT(rc == 0); 3125 3126 rc = ut_data_pattern_verify(&iov, 1, 512 + 8, 8, 5); 3127 CU_ASSERT(rc == 0); 3128 3129 _iov_free_buf(&iov); 3130 } 3131 3132 static void 3133 _dif_generate_stream_test(enum spdk_dif_pi_format dif_pi_format) 3134 { 3135 struct iovec iov; 3136 struct spdk_dif_ctx ctx; 3137 struct spdk_dif_error err_blk; 3138 uint32_t dif_flags; 3139 int rc; 3140 struct spdk_dif_ctx_init_ext_opts dif_opts; 3141 3142 _iov_alloc_buf(&iov, (4096 + 128) * 5); 3143 3144 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 5); 3145 CU_ASSERT(rc == 0); 3146 3147 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 3148 SPDK_DIF_FLAGS_REFTAG_CHECK; 3149 3150 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 3151 dif_opts.dif_pi_format = dif_pi_format; 3152 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, dif_flags, 3153 22, 0xFFFF, 0x22, 0, GUARD_SEED, &dif_opts); 3154 CU_ASSERT(rc == 0); 3155 3156 rc = spdk_dif_generate_stream(&iov, 1, 0, 4095, &ctx); 3157 CU_ASSERT(rc == 0); 3158 3159 rc = spdk_dif_generate_stream(&iov, 1, 4095, 1, &ctx); 3160 CU_ASSERT(rc == 0); 3161 3162 rc = spdk_dif_generate_stream(&iov, 1, 4096, 2048, &ctx); 3163 CU_ASSERT(rc == 0); 3164 3165 rc = spdk_dif_generate_stream(&iov, 1, 6144, 4096, &ctx); 3166 CU_ASSERT(rc == 0); 3167 3168 rc = spdk_dif_generate_stream(&iov, 1, 10240, 8192, &ctx); 3169 CU_ASSERT(rc == 0); 3170 3171 rc = spdk_dif_generate_stream(&iov, 1, 18432, 2048, &ctx); 3172 CU_ASSERT(rc == 0); 3173 3174 rc = spdk_dif_generate_stream(&iov, 1, 20480, 4096, &ctx); 3175 CU_ASSERT(rc == -ERANGE); 3176 3177 rc = spdk_dif_verify(&iov, 1, 5, &ctx, &err_blk); 3178 CU_ASSERT(rc == 0); 3179 3180 rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 5); 3181 CU_ASSERT(rc == 0); 3182 3183 _iov_free_buf(&iov); 3184 } 3185 3186 static void 3187 dif_generate_stream_test(void) 3188 { 3189 _dif_generate_stream_test(SPDK_DIF_PI_FORMAT_32); 3190 _dif_generate_stream_test(SPDK_DIF_PI_FORMAT_64); 3191 } 3192 3193 static void 3194 set_md_interleave_iovs_alignment_test(void) 3195 { 3196 struct iovec iovs[3], dif_iovs[5] = {}; 3197 uint32_t mapped_len = 0; 3198 int rc; 3199 struct spdk_dif_ctx ctx; 3200 struct spdk_dif_ctx_init_ext_opts dif_opts; 3201 3202 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 3203 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 3204 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, 3205 0, 0, 0, 0, 0, 0, &dif_opts); 3206 CU_ASSERT(rc == 0); 3207 3208 /* The case that buffer size is smaller than necessary. */ 3209 _iov_set_buf(&iovs[0], (uint8_t *)0xDEADBEEF, 1024); 3210 _iov_set_buf(&iovs[1], (uint8_t *)0xFEEDBEEF, 1024); 3211 _iov_set_buf(&iovs[2], (uint8_t *)0xC0FFEE, 24); 3212 3213 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 0, 2048, &mapped_len, &ctx); 3214 CU_ASSERT(rc == -ERANGE); 3215 3216 /* The following are the normal cases. */ 3217 _iov_set_buf(&iovs[2], (uint8_t *)0xC0FFEE, 32); 3218 3219 /* data length is less than a data block size. */ 3220 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 0, 500, &mapped_len, &ctx); 3221 CU_ASSERT(rc == 1); 3222 CU_ASSERT(mapped_len == 500); 3223 CU_ASSERT(_iov_check(&dif_iovs[0], (void *)0xDEADBEEF, 500) == true); 3224 3225 /* Pass enough number of iovecs */ 3226 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 500, 1000, &mapped_len, &ctx); 3227 CU_ASSERT(rc == 4); 3228 CU_ASSERT(mapped_len == 1000); 3229 CU_ASSERT(_iov_check(&dif_iovs[0], (void *)(0xDEADBEEF + 500), 12) == true); 3230 CU_ASSERT(_iov_check(&dif_iovs[1], (void *)(0xDEADBEEF + 520), 504) == true); 3231 CU_ASSERT(_iov_check(&dif_iovs[2], (void *)0xFEEDBEEF, 8) == true); 3232 CU_ASSERT(_iov_check(&dif_iovs[3], (void *)(0xFEEDBEEF + 16), 476) == true); 3233 3234 /* Pass iovecs smaller than necessary */ 3235 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 3, iovs, 3, 500, 1000, &mapped_len, &ctx); 3236 CU_ASSERT(rc == 3); 3237 CU_ASSERT(mapped_len == 524); 3238 CU_ASSERT(_iov_check(&dif_iovs[0], (void *)(0xDEADBEEF + 500), 12) == true); 3239 CU_ASSERT(_iov_check(&dif_iovs[1], (void *)(0xDEADBEEF + 520), 504) == true); 3240 CU_ASSERT(_iov_check(&dif_iovs[2], (void *)0xFEEDBEEF, 8) == true); 3241 3242 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 1500, 500, &mapped_len, &ctx); 3243 CU_ASSERT(rc == 2); 3244 CU_ASSERT(mapped_len == 500); 3245 CU_ASSERT(_iov_check(&dif_iovs[0], (void *)(0xFEEDBEEF + 492), 36) == true); 3246 CU_ASSERT(_iov_check(&dif_iovs[1], (void *)(0xFEEDBEEF + 536), 464) == true); 3247 3248 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 2000, 48, &mapped_len, &ctx); 3249 CU_ASSERT(rc == 2); 3250 CU_ASSERT(mapped_len == 48); 3251 CU_ASSERT(_iov_check(&dif_iovs[0], (void *)0xFEEDBEEF + 1000, 24) == true); 3252 CU_ASSERT(_iov_check(&dif_iovs[1], (void *)0xC0FFEE, 24) == true); 3253 } 3254 3255 static void 3256 _dif_generate_split_test(enum spdk_dif_pi_format dif_pi_format) 3257 { 3258 struct spdk_dif_ctx ctx = {}; 3259 struct iovec iov; 3260 uint8_t *buf1, *buf2; 3261 struct _dif_sgl sgl; 3262 uint64_t guard = 0, prev_guard; 3263 uint32_t dif_flags; 3264 int rc; 3265 struct spdk_dif_ctx_init_ext_opts dif_opts; 3266 3267 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 3268 SPDK_DIF_FLAGS_REFTAG_CHECK; 3269 3270 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 3271 dif_opts.dif_pi_format = dif_pi_format; 3272 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 3273 dif_flags, 0, 0, 0, 0, GUARD_SEED, &dif_opts); 3274 CU_ASSERT(rc == 0); 3275 3276 buf1 = calloc(1, 4096 + 128); 3277 SPDK_CU_ASSERT_FATAL(buf1 != NULL); 3278 _iov_set_buf(&iov, buf1, 4096 + 128); 3279 3280 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1); 3281 CU_ASSERT(rc == 0); 3282 3283 _dif_sgl_init(&sgl, &iov, 1); 3284 3285 guard = GUARD_SEED; 3286 prev_guard = GUARD_SEED; 3287 3288 guard = _dif_generate_split(&sgl, 0, 1000, guard, 0, &ctx); 3289 CU_ASSERT(sgl.iov_offset == 1000); 3290 CU_ASSERT(guard == _generate_guard(prev_guard, buf1, 1000, dif_pi_format)); 3291 3292 prev_guard = guard; 3293 3294 guard = _dif_generate_split(&sgl, 1000, 3000, guard, 0, &ctx); 3295 CU_ASSERT(sgl.iov_offset == 4000); 3296 CU_ASSERT(guard == _generate_guard(prev_guard, buf1 + 1000, 3000, dif_pi_format)); 3297 3298 guard = _dif_generate_split(&sgl, 4000, 96 + 128, guard, 0, &ctx); 3299 CU_ASSERT(guard == GUARD_SEED); 3300 CU_ASSERT(sgl.iov_offset == 0); 3301 CU_ASSERT(sgl.iovcnt == 0); 3302 3303 rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 1); 3304 CU_ASSERT(rc == 0); 3305 3306 _dif_sgl_init(&sgl, &iov, 1); 3307 3308 rc = dif_verify(&sgl, 1, &ctx, NULL); 3309 CU_ASSERT(rc == 0); 3310 3311 buf2 = calloc(1, 4096 + 128); 3312 SPDK_CU_ASSERT_FATAL(buf2 != NULL); 3313 _iov_set_buf(&iov, buf2, 4096 + 128); 3314 3315 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1); 3316 CU_ASSERT(rc == 0); 3317 3318 _dif_sgl_init(&sgl, &iov, 1); 3319 3320 dif_generate(&sgl, 1, &ctx); 3321 3322 rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 1); 3323 CU_ASSERT(rc == 0); 3324 3325 _dif_sgl_init(&sgl, &iov, 1); 3326 3327 rc = dif_verify(&sgl, 1, &ctx, NULL); 3328 CU_ASSERT(rc == 0); 3329 3330 rc = memcmp(buf1, buf2, 4096 + 128); 3331 CU_ASSERT(rc == 0); 3332 3333 free(buf1); 3334 free(buf2); 3335 } 3336 3337 static void 3338 dif_generate_split_test(void) 3339 { 3340 _dif_generate_split_test(SPDK_DIF_PI_FORMAT_16); 3341 _dif_generate_split_test(SPDK_DIF_PI_FORMAT_32); 3342 _dif_generate_split_test(SPDK_DIF_PI_FORMAT_64); 3343 } 3344 3345 static void 3346 _set_md_interleave_iovs_multi_segments_test(enum spdk_dif_pi_format dif_pi_format) 3347 { 3348 struct spdk_dif_ctx ctx = {}; 3349 struct spdk_dif_error err_blk = {}; 3350 struct iovec iov1 = {}, iov2 = {}, dif_iovs[4] = {}; 3351 uint32_t dif_check_flags, data_len, read_len, data_offset, read_offset, mapped_len = 0; 3352 uint8_t *buf1, *buf2; 3353 int rc; 3354 struct spdk_dif_ctx_init_ext_opts dif_opts; 3355 3356 dif_check_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 3357 SPDK_DIF_FLAGS_REFTAG_CHECK; 3358 3359 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 3360 dif_opts.dif_pi_format = dif_pi_format; 3361 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 3362 dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED, &dif_opts); 3363 CU_ASSERT(rc == 0); 3364 3365 /* The first data buffer: 3366 * - Data buffer is split into multi data segments 3367 * - For each data segment, 3368 * - Create iovec array to Leave a space for metadata for each block 3369 * - Split vectored read and so creating iovec array is done before every vectored read. 3370 */ 3371 buf1 = calloc(1, (4096 + 128) * 4); 3372 SPDK_CU_ASSERT_FATAL(buf1 != NULL); 3373 _iov_set_buf(&iov1, buf1, (4096 + 128) * 4); 3374 3375 /* 1st data segment */ 3376 data_offset = 0; 3377 data_len = 1024; 3378 3379 spdk_dif_ctx_set_data_offset(&ctx, data_offset); 3380 3381 read_offset = 0; 3382 3383 /* 1st read in 1st data segment */ 3384 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 3385 read_offset, data_len - read_offset, 3386 &mapped_len, &ctx); 3387 CU_ASSERT(rc == 1); 3388 CU_ASSERT(mapped_len == 1024); 3389 CU_ASSERT(_iov_check(&dif_iovs[0], buf1, 1024) == true); 3390 3391 read_len = ut_readv(data_offset + read_offset, 1024, dif_iovs, 4); 3392 CU_ASSERT(read_len == 1024); 3393 3394 rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx); 3395 CU_ASSERT(rc == 0); 3396 3397 read_offset += read_len; 3398 CU_ASSERT(read_offset == data_len); 3399 3400 /* 2nd data segment */ 3401 data_offset += data_len; 3402 data_len = 3072 + 4096 * 2 + 512; 3403 3404 spdk_dif_ctx_set_data_offset(&ctx, data_offset); 3405 _iov_set_buf(&iov1, buf1 + 1024, 3072 + 128 + (4096 + 128) * 3 + 512); 3406 3407 read_offset = 0; 3408 3409 /* 1st read in 2nd data segment */ 3410 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 3411 read_offset, data_len - read_offset, 3412 &mapped_len, &ctx); 3413 CU_ASSERT(rc == 4); 3414 CU_ASSERT(mapped_len == 3072 + 4096 * 2 + 512); 3415 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 1024, 3072) == true); 3416 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true); 3417 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true); 3418 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 512) == true); 3419 3420 read_len = ut_readv(data_offset + read_offset, 3071, dif_iovs, 4); 3421 CU_ASSERT(read_len == 3071); 3422 3423 rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx); 3424 CU_ASSERT(rc == 0); 3425 3426 read_offset += read_len; 3427 3428 /* 2nd read in 2nd data segment */ 3429 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 3430 read_offset, data_len - read_offset, 3431 &mapped_len, &ctx); 3432 CU_ASSERT(rc == 4); 3433 CU_ASSERT(mapped_len == 1 + 4096 * 2 + 512); 3434 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 4095, 1) == true); 3435 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true); 3436 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true); 3437 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 512) == true); 3438 3439 read_len = ut_readv(data_offset + read_offset, 1 + 4096 * 2 + 512, dif_iovs, 4); 3440 CU_ASSERT(read_len == 1 + 4096 * 2 + 512); 3441 3442 rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx); 3443 CU_ASSERT(rc == 0); 3444 3445 read_offset += read_len; 3446 CU_ASSERT(read_offset == data_len); 3447 3448 /* 3rd data segment */ 3449 data_offset += data_len; 3450 data_len = 3584; 3451 3452 spdk_dif_ctx_set_data_offset(&ctx, data_offset); 3453 _iov_set_buf(&iov1, buf1 + (4096 + 128) * 3 + 512, 3584 + 128); 3454 3455 read_offset = 0; 3456 3457 /* 1st read in 3rd data segment */ 3458 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 3459 read_offset, data_len - read_offset, 3460 &mapped_len, &ctx); 3461 CU_ASSERT(rc == 1); 3462 CU_ASSERT(mapped_len == 3584); 3463 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + (4096 + 128) * 3 + 512, 3584) == true); 3464 3465 read_len = ut_readv(data_offset + read_offset, 3584, dif_iovs, 1); 3466 CU_ASSERT(read_len == 3584); 3467 3468 rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx); 3469 CU_ASSERT(rc == 0); 3470 3471 read_offset += read_len; 3472 CU_ASSERT(read_offset == data_len); 3473 data_offset += data_len; 3474 CU_ASSERT(data_offset == 4096 * 4); 3475 3476 spdk_dif_ctx_set_data_offset(&ctx, 0); 3477 _iov_set_buf(&iov1, buf1, (4096 + 128) * 4); 3478 3479 /* The second data buffer: 3480 * - Set data pattern with a space for metadata for each block. 3481 */ 3482 buf2 = calloc(1, (4096 + 128) * 4); 3483 SPDK_CU_ASSERT_FATAL(buf2 != NULL); 3484 _iov_set_buf(&iov2, buf2, (4096 + 128) * 4); 3485 3486 rc = ut_data_pattern_generate(&iov2, 1, 4096 + 128, 128, 4); 3487 CU_ASSERT(rc == 0); 3488 3489 rc = spdk_dif_generate(&iov2, 1, 4, &ctx); 3490 CU_ASSERT(rc == 0); 3491 3492 rc = spdk_dif_verify(&iov1, 1, 4, &ctx, &err_blk); 3493 CU_ASSERT(rc == 0); 3494 3495 rc = spdk_dif_verify(&iov2, 1, 4, &ctx, &err_blk); 3496 CU_ASSERT(rc == 0); 3497 3498 /* Compare the first and the second data buffer by byte. */ 3499 rc = memcmp(buf1, buf2, (4096 + 128) * 4); 3500 CU_ASSERT(rc == 0); 3501 3502 free(buf1); 3503 free(buf2); 3504 } 3505 3506 static void 3507 set_md_interleave_iovs_multi_segments_test(void) 3508 { 3509 _set_md_interleave_iovs_multi_segments_test(SPDK_DIF_PI_FORMAT_16); 3510 _set_md_interleave_iovs_multi_segments_test(SPDK_DIF_PI_FORMAT_32); 3511 _set_md_interleave_iovs_multi_segments_test(SPDK_DIF_PI_FORMAT_64); 3512 } 3513 3514 static void 3515 _dif_verify_split_test(enum spdk_dif_pi_format dif_pi_format) 3516 { 3517 struct spdk_dif_ctx ctx = {}; 3518 struct spdk_dif_error err_blk = {}; 3519 struct iovec iov; 3520 uint8_t *buf; 3521 struct _dif_sgl sgl; 3522 uint64_t guard = 0, prev_guard = 0; 3523 uint32_t dif_flags; 3524 int rc; 3525 struct spdk_dif_ctx_init_ext_opts dif_opts; 3526 3527 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 3528 SPDK_DIF_FLAGS_REFTAG_CHECK; 3529 3530 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 3531 dif_opts.dif_pi_format = dif_pi_format; 3532 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 3533 dif_flags, 0, 0, 0, 0, GUARD_SEED, &dif_opts); 3534 CU_ASSERT(rc == 0); 3535 3536 buf = calloc(1, 4096 + 128); 3537 SPDK_CU_ASSERT_FATAL(buf != NULL); 3538 _iov_set_buf(&iov, buf, 4096 + 128); 3539 3540 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1); 3541 CU_ASSERT(rc == 0); 3542 3543 _dif_sgl_init(&sgl, &iov, 1); 3544 3545 dif_generate(&sgl, 1, &ctx); 3546 3547 _dif_sgl_init(&sgl, &iov, 1); 3548 3549 guard = GUARD_SEED; 3550 prev_guard = GUARD_SEED; 3551 3552 rc = _dif_verify_split(&sgl, 0, 1000, &guard, 0, &ctx, &err_blk); 3553 CU_ASSERT(rc == 0); 3554 CU_ASSERT(guard == _generate_guard(prev_guard, buf, 1000, dif_pi_format)); 3555 CU_ASSERT(sgl.iov_offset == 1000); 3556 3557 prev_guard = guard; 3558 3559 rc = _dif_verify_split(&sgl, 1000, 3000, &guard, 0, &ctx, &err_blk); 3560 CU_ASSERT(rc == 0); 3561 CU_ASSERT(guard == _generate_guard(prev_guard, buf + 1000, 3000, dif_pi_format)); 3562 CU_ASSERT(sgl.iov_offset == 4000); 3563 3564 rc = _dif_verify_split(&sgl, 4000, 96 + 128, &guard, 0, &ctx, &err_blk); 3565 CU_ASSERT(rc == 0); 3566 CU_ASSERT(guard == GUARD_SEED); 3567 CU_ASSERT(sgl.iov_offset == 0); 3568 CU_ASSERT(sgl.iovcnt == 0); 3569 3570 _dif_sgl_init(&sgl, &iov, 1); 3571 3572 rc = dif_verify(&sgl, 1, &ctx, &err_blk); 3573 CU_ASSERT(rc == 0); 3574 3575 rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 1); 3576 CU_ASSERT(rc == 0); 3577 3578 free(buf); 3579 } 3580 3581 static void 3582 dif_verify_split_test(void) 3583 { 3584 _dif_verify_split_test(SPDK_DIF_PI_FORMAT_16); 3585 _dif_verify_split_test(SPDK_DIF_PI_FORMAT_32); 3586 _dif_verify_split_test(SPDK_DIF_PI_FORMAT_64); 3587 } 3588 3589 static void 3590 _dif_verify_stream_multi_segments_test(enum spdk_dif_pi_format dif_pi_format) 3591 { 3592 struct spdk_dif_ctx ctx = {}; 3593 struct spdk_dif_error err_blk = {}; 3594 struct iovec iov = {}; 3595 uint8_t *buf; 3596 uint32_t dif_flags; 3597 int rc; 3598 struct spdk_dif_ctx_init_ext_opts dif_opts; 3599 3600 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 3601 SPDK_DIF_FLAGS_REFTAG_CHECK; 3602 3603 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 3604 dif_opts.dif_pi_format = dif_pi_format; 3605 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 3606 dif_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED, &dif_opts); 3607 CU_ASSERT(rc == 0); 3608 3609 buf = calloc(1, (4096 + 128) * 4); 3610 SPDK_CU_ASSERT_FATAL(buf != NULL); 3611 _iov_set_buf(&iov, buf, (4096 + 128) * 4); 3612 3613 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 4); 3614 CU_ASSERT(rc == 0); 3615 3616 rc = spdk_dif_generate(&iov, 1, 4, &ctx); 3617 CU_ASSERT(rc == 0); 3618 3619 /* 1st data segment */ 3620 _iov_set_buf(&iov, buf, 1024); 3621 spdk_dif_ctx_set_data_offset(&ctx, 0); 3622 3623 rc = spdk_dif_verify_stream(&iov, 1, 0, 1024, &ctx, &err_blk); 3624 CU_ASSERT(rc == 0); 3625 3626 /* 2nd data segment */ 3627 _iov_set_buf(&iov, buf + 1024, (3072 + 128) + (4096 + 128) * 2 + 512); 3628 spdk_dif_ctx_set_data_offset(&ctx, 1024); 3629 3630 rc = spdk_dif_verify_stream(&iov, 1, 0, 3072 + 4096 * 2 + 512, &ctx, &err_blk); 3631 CU_ASSERT(rc == 0); 3632 3633 /* 3rd data segment */ 3634 _iov_set_buf(&iov, buf + (4096 + 128) * 3 + 512, 3584 + 128); 3635 spdk_dif_ctx_set_data_offset(&ctx, 4096 * 3); 3636 3637 rc = spdk_dif_verify_stream(&iov, 1, 0, 3584, &ctx, &err_blk); 3638 CU_ASSERT(rc == 0); 3639 3640 /* verify all data segments once */ 3641 _iov_set_buf(&iov, buf, (4096 + 128) * 4); 3642 spdk_dif_ctx_set_data_offset(&ctx, 0); 3643 3644 rc = spdk_dif_verify(&iov, 1, 4, &ctx, &err_blk); 3645 CU_ASSERT(rc == 0); 3646 3647 rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 4); 3648 CU_ASSERT(rc == 0); 3649 3650 free(buf); 3651 } 3652 3653 static void 3654 dif_verify_stream_multi_segments_test(void) 3655 { 3656 _dif_verify_stream_multi_segments_test(SPDK_DIF_PI_FORMAT_16); 3657 _dif_verify_stream_multi_segments_test(SPDK_DIF_PI_FORMAT_32); 3658 _dif_verify_stream_multi_segments_test(SPDK_DIF_PI_FORMAT_64); 3659 } 3660 3661 #define UT_CRC32C_XOR 0xffffffffUL 3662 3663 static void 3664 update_crc32c_pi_16_test(void) 3665 { 3666 struct spdk_dif_ctx ctx = {}; 3667 struct iovec iovs[7]; 3668 uint32_t crc32c1, crc32c2, crc32c3, crc32c4; 3669 uint32_t dif_flags; 3670 int i, rc; 3671 struct spdk_dif_ctx_init_ext_opts dif_opts; 3672 3673 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 3674 SPDK_DIF_FLAGS_REFTAG_CHECK; 3675 3676 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 3677 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 3678 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, 3679 dif_flags, 0, 0, 0, 0, 0, &dif_opts); 3680 CU_ASSERT(rc == 0); 3681 3682 /* data[0][255:0] */ 3683 _iov_alloc_buf(&iovs[0], 256); 3684 3685 /* data[0][511:256], md[0][0] */ 3686 _iov_alloc_buf(&iovs[1], 256 + 1); 3687 3688 /* md[0][4:1] */ 3689 _iov_alloc_buf(&iovs[2], 4); 3690 3691 /* md[0][7:5], data[1][122:0] */ 3692 _iov_alloc_buf(&iovs[3], 3 + 123); 3693 3694 /* data[1][511:123], md[1][5:0] */ 3695 _iov_alloc_buf(&iovs[4], 389 + 6); 3696 3697 /* md[1][7:6], data[2][511:0], md[2][7:0], data[3][431:0] */ 3698 _iov_alloc_buf(&iovs[5], 2 + 512 + 8 + 432); 3699 3700 /* data[3][511:432], md[3][7:0] */ 3701 _iov_alloc_buf(&iovs[6], 80 + 8); 3702 3703 rc = ut_data_pattern_generate(iovs, 7, 512 + 8, 8, 4); 3704 CU_ASSERT(rc == 0); 3705 3706 crc32c1 = UT_CRC32C_XOR; 3707 3708 rc = spdk_dif_update_crc32c(iovs, 7, 4, &crc32c1, &ctx); 3709 CU_ASSERT(rc == 0); 3710 3711 /* Test if DIF doesn't affect CRC for split case. */ 3712 rc = spdk_dif_generate(iovs, 7, 4, &ctx); 3713 CU_ASSERT(rc == 0); 3714 3715 crc32c2 = UT_CRC32C_XOR; 3716 3717 rc = spdk_dif_update_crc32c(iovs, 7, 4, &crc32c2, &ctx); 3718 CU_ASSERT(rc == 0); 3719 3720 CU_ASSERT(crc32c1 == crc32c2); 3721 3722 for (i = 0; i < 7; i++) { 3723 _iov_free_buf(&iovs[i]); 3724 } 3725 3726 /* Test if CRC is same regardless of splitting. */ 3727 for (i = 0; i < 4; i++) { 3728 _iov_alloc_buf(&iovs[i], 512 + 8); 3729 } 3730 3731 rc = ut_data_pattern_generate(iovs, 4, 512 + 8, 8, 4); 3732 CU_ASSERT(rc == 0); 3733 3734 crc32c3 = UT_CRC32C_XOR; 3735 3736 rc = spdk_dif_update_crc32c(iovs, 4, 4, &crc32c3, &ctx); 3737 CU_ASSERT(rc == 0); 3738 3739 CU_ASSERT(crc32c1 == crc32c3); 3740 3741 /* Test if DIF doesn't affect CRC for non-split case. */ 3742 rc = spdk_dif_generate(iovs, 4, 4, &ctx); 3743 CU_ASSERT(rc == 0); 3744 3745 crc32c4 = UT_CRC32C_XOR; 3746 3747 rc = spdk_dif_update_crc32c(iovs, 4, 4, &crc32c4, &ctx); 3748 CU_ASSERT(rc == 0); 3749 3750 CU_ASSERT(crc32c1 == crc32c4); 3751 3752 for (i = 0; i < 4; i++) { 3753 _iov_free_buf(&iovs[i]); 3754 } 3755 } 3756 3757 static void 3758 _update_crc32c_test(enum spdk_dif_pi_format dif_pi_format) 3759 { 3760 struct spdk_dif_ctx ctx = {}; 3761 struct iovec iovs[7]; 3762 uint32_t crc32c1, crc32c2, crc32c3, crc32c4; 3763 uint32_t dif_flags; 3764 int i, rc; 3765 struct spdk_dif_ctx_init_ext_opts dif_opts; 3766 3767 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 3768 SPDK_DIF_FLAGS_REFTAG_CHECK; 3769 3770 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 3771 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_32; 3772 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 3773 dif_flags, 0, 0, 0, 0, 0, &dif_opts); 3774 CU_ASSERT(rc == 0); 3775 3776 /* data[0][2047:0] */ 3777 _iov_alloc_buf(&iovs[0], 2048); 3778 3779 /* data[0][4095:2048], md[0][0] */ 3780 _iov_alloc_buf(&iovs[1], 2048 + 1); 3781 3782 /* md[0][4:1] */ 3783 _iov_alloc_buf(&iovs[2], 4); 3784 3785 /* md[0][127:5], data[1][122:0] */ 3786 _iov_alloc_buf(&iovs[3], 123 + 123); 3787 3788 /* data[1][4095:123], md[1][5:0] */ 3789 _iov_alloc_buf(&iovs[4], 3973 + 6); 3790 3791 /* md[1][127:6], data[2][4095:0], md[2][127:0], data[3][431:0] */ 3792 _iov_alloc_buf(&iovs[5], 122 + 4096 + 128 + 432); 3793 3794 /* data[3][511:432], md[3][127:0] */ 3795 _iov_alloc_buf(&iovs[6], 3665 + 128); 3796 3797 rc = ut_data_pattern_generate(iovs, 7, 4096 + 128, 128, 4); 3798 CU_ASSERT(rc == 0); 3799 3800 crc32c1 = UT_CRC32C_XOR; 3801 3802 rc = spdk_dif_update_crc32c(iovs, 7, 4, &crc32c1, &ctx); 3803 CU_ASSERT(rc == 0); 3804 3805 /* Test if DIF doesn't affect CRC for split case. */ 3806 rc = spdk_dif_generate(iovs, 7, 4, &ctx); 3807 CU_ASSERT(rc == 0); 3808 3809 crc32c2 = UT_CRC32C_XOR; 3810 3811 rc = spdk_dif_update_crc32c(iovs, 7, 4, &crc32c2, &ctx); 3812 CU_ASSERT(rc == 0); 3813 3814 CU_ASSERT(crc32c1 == crc32c2); 3815 3816 for (i = 0; i < 7; i++) { 3817 _iov_free_buf(&iovs[i]); 3818 } 3819 3820 /* Test if CRC is same regardless of splitting. */ 3821 for (i = 0; i < 4; i++) { 3822 _iov_alloc_buf(&iovs[i], 4096 + 128); 3823 } 3824 3825 rc = ut_data_pattern_generate(iovs, 4, 4096 + 128, 128, 4); 3826 CU_ASSERT(rc == 0); 3827 3828 crc32c3 = UT_CRC32C_XOR; 3829 3830 rc = spdk_dif_update_crc32c(iovs, 4, 4, &crc32c3, &ctx); 3831 CU_ASSERT(rc == 0); 3832 3833 CU_ASSERT(crc32c1 == crc32c3); 3834 3835 /* Test if DIF doesn't affect CRC for non-split case. */ 3836 rc = spdk_dif_generate(iovs, 4, 4, &ctx); 3837 CU_ASSERT(rc == 0); 3838 3839 crc32c4 = UT_CRC32C_XOR; 3840 3841 rc = spdk_dif_update_crc32c(iovs, 4, 4, &crc32c4, &ctx); 3842 CU_ASSERT(rc == 0); 3843 3844 CU_ASSERT(crc32c1 == crc32c4); 3845 3846 for (i = 0; i < 4; i++) { 3847 _iov_free_buf(&iovs[i]); 3848 } 3849 } 3850 3851 static void 3852 update_crc32c_test(void) 3853 { 3854 _update_crc32c_test(SPDK_DIF_PI_FORMAT_32); 3855 _update_crc32c_test(SPDK_DIF_PI_FORMAT_64); 3856 } 3857 3858 static void 3859 _dif_update_crc32c_split_test(enum spdk_dif_pi_format dif_pi_format) 3860 { 3861 struct spdk_dif_ctx ctx = {}; 3862 struct iovec iov; 3863 uint8_t *buf; 3864 struct _dif_sgl sgl; 3865 uint32_t dif_flags, crc32c, prev_crc32c; 3866 int rc; 3867 struct spdk_dif_ctx_init_ext_opts dif_opts; 3868 3869 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 3870 SPDK_DIF_FLAGS_REFTAG_CHECK; 3871 3872 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 3873 dif_opts.dif_pi_format = dif_pi_format; 3874 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 3875 dif_flags, 0, 0, 0, 0, GUARD_SEED, &dif_opts); 3876 CU_ASSERT(rc == 0); 3877 3878 buf = calloc(1, 4096 + 128); 3879 SPDK_CU_ASSERT_FATAL(buf != NULL); 3880 _iov_set_buf(&iov, buf, 4096 + 128); 3881 3882 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1); 3883 CU_ASSERT(rc == 0); 3884 3885 _dif_sgl_init(&sgl, &iov, 1); 3886 3887 dif_generate(&sgl, 1, &ctx); 3888 3889 _dif_sgl_init(&sgl, &iov, 1); 3890 3891 crc32c = _dif_update_crc32c_split(&sgl, 0, 1000, UT_CRC32C_XOR, &ctx); 3892 CU_ASSERT(crc32c == spdk_crc32c_update(buf, 1000, UT_CRC32C_XOR)); 3893 3894 prev_crc32c = crc32c; 3895 3896 crc32c = _dif_update_crc32c_split(&sgl, 1000, 3000, prev_crc32c, &ctx); 3897 CU_ASSERT(crc32c == spdk_crc32c_update(buf + 1000, 3000, prev_crc32c)); 3898 3899 prev_crc32c = crc32c; 3900 3901 crc32c = _dif_update_crc32c_split(&sgl, 4000, 96 + 128, prev_crc32c, &ctx); 3902 CU_ASSERT(crc32c == spdk_crc32c_update(buf + 4000, 96, prev_crc32c)); 3903 3904 CU_ASSERT(crc32c == spdk_crc32c_update(buf, 4096, UT_CRC32C_XOR)); 3905 3906 free(buf); 3907 } 3908 3909 static void 3910 dif_update_crc32c_split_test(void) 3911 { 3912 _dif_update_crc32c_split_test(SPDK_DIF_PI_FORMAT_16); 3913 _dif_update_crc32c_split_test(SPDK_DIF_PI_FORMAT_32); 3914 _dif_update_crc32c_split_test(SPDK_DIF_PI_FORMAT_64); 3915 } 3916 3917 static void 3918 _dif_update_crc32c_stream_multi_segments_test(enum spdk_dif_pi_format dif_pi_format) 3919 { 3920 struct spdk_dif_ctx ctx = {}; 3921 struct iovec iov = {}; 3922 uint8_t *buf; 3923 uint32_t dif_flags, crc32c1, crc32c2; 3924 int rc; 3925 struct spdk_dif_ctx_init_ext_opts dif_opts; 3926 3927 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 3928 SPDK_DIF_FLAGS_REFTAG_CHECK; 3929 3930 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 3931 dif_opts.dif_pi_format = dif_pi_format; 3932 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 3933 dif_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED, &dif_opts); 3934 CU_ASSERT(rc == 0); 3935 3936 buf = calloc(1, (4096 + 128) * 4); 3937 SPDK_CU_ASSERT_FATAL(buf != NULL); 3938 _iov_set_buf(&iov, buf, (4096 + 128) * 4); 3939 3940 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 4); 3941 CU_ASSERT(rc == 0); 3942 3943 rc = spdk_dif_generate(&iov, 1, 4, &ctx); 3944 CU_ASSERT(rc == 0); 3945 3946 crc32c1 = UT_CRC32C_XOR; 3947 crc32c2 = UT_CRC32C_XOR; 3948 3949 /* 1st data segment */ 3950 _iov_set_buf(&iov, buf, 1024); 3951 spdk_dif_ctx_set_data_offset(&ctx, 0); 3952 3953 rc = spdk_dif_update_crc32c_stream(&iov, 1, 0, 1024, &crc32c1, &ctx); 3954 CU_ASSERT(rc == 0); 3955 3956 /* 2nd data segment */ 3957 _iov_set_buf(&iov, buf + 1024, (3072 + 128) + (4096 + 128) * 2 + 512); 3958 spdk_dif_ctx_set_data_offset(&ctx, 1024); 3959 3960 rc = spdk_dif_update_crc32c_stream(&iov, 1, 0, 3072 + 4096 * 2 + 512, &crc32c1, &ctx); 3961 CU_ASSERT(rc == 0); 3962 3963 /* 3rd data segment */ 3964 _iov_set_buf(&iov, buf + (4096 + 128) * 3 + 512, 3584 + 128); 3965 spdk_dif_ctx_set_data_offset(&ctx, 4096 * 3); 3966 3967 rc = spdk_dif_update_crc32c_stream(&iov, 1, 0, 3584, &crc32c1, &ctx); 3968 CU_ASSERT(rc == 0); 3969 3970 /* Update CRC32C for all data segments once */ 3971 _iov_set_buf(&iov, buf, (4096 + 128) * 4); 3972 spdk_dif_ctx_set_data_offset(&ctx, 0); 3973 3974 rc = spdk_dif_update_crc32c(&iov, 1, 4, &crc32c2, &ctx); 3975 CU_ASSERT(rc == 0); 3976 3977 CU_ASSERT(crc32c1 == crc32c2); 3978 3979 free(buf); 3980 } 3981 3982 static void 3983 dif_update_crc32c_stream_multi_segments_test(void) 3984 { 3985 _dif_update_crc32c_stream_multi_segments_test(SPDK_DIF_PI_FORMAT_16); 3986 _dif_update_crc32c_stream_multi_segments_test(SPDK_DIF_PI_FORMAT_32); 3987 _dif_update_crc32c_stream_multi_segments_test(SPDK_DIF_PI_FORMAT_64); 3988 } 3989 3990 static void 3991 get_range_with_md_test(void) 3992 { 3993 struct spdk_dif_ctx ctx = {}; 3994 uint32_t buf_offset, buf_len; 3995 int rc; 3996 struct spdk_dif_ctx_init_ext_opts dif_opts; 3997 3998 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 3999 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 4000 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, 0, 0, 4001 0, 0, 0, 0, 0, &dif_opts); 4002 CU_ASSERT(rc == 0); 4003 4004 spdk_dif_get_range_with_md(0, 2048, &buf_offset, &buf_len, &ctx); 4005 CU_ASSERT(buf_offset == 0); 4006 CU_ASSERT(buf_len == 2048); 4007 4008 spdk_dif_get_range_with_md(2048, 4096, &buf_offset, &buf_len, &ctx); 4009 CU_ASSERT(buf_offset == 2048); 4010 CU_ASSERT(buf_len == 4096 + 128); 4011 4012 spdk_dif_get_range_with_md(4096, 10240, &buf_offset, &buf_len, &ctx); 4013 CU_ASSERT(buf_offset == 4096 + 128); 4014 CU_ASSERT(buf_len == 10240 + 256); 4015 4016 spdk_dif_get_range_with_md(10240, 2048, &buf_offset, &buf_len, &ctx); 4017 CU_ASSERT(buf_offset == 10240 + 256); 4018 CU_ASSERT(buf_len == 2048 + 128); 4019 4020 buf_len = spdk_dif_get_length_with_md(6144, &ctx); 4021 CU_ASSERT(buf_len == 6144 + 128); 4022 } 4023 4024 static void 4025 dif_generate_remap_and_verify(struct iovec *iovs, int iovcnt, 4026 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 4027 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, 4028 uint32_t init_ref_tag, uint32_t remapped_init_ref_tag, 4029 uint16_t apptag_mask, uint16_t app_tag, 4030 enum spdk_dif_pi_format dif_pi_format) 4031 { 4032 struct spdk_dif_ctx ctx = {}; 4033 int rc; 4034 struct spdk_dif_ctx_init_ext_opts dif_opts; 4035 4036 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks); 4037 CU_ASSERT(rc == 0); 4038 4039 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 4040 dif_opts.dif_pi_format = dif_pi_format; 4041 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags, 4042 init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED, &dif_opts); 4043 CU_ASSERT(rc == 0); 4044 4045 rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx); 4046 CU_ASSERT(rc == 0); 4047 4048 spdk_dif_ctx_set_remapped_init_ref_tag(&ctx, remapped_init_ref_tag); 4049 4050 rc = spdk_dif_remap_ref_tag(iovs, iovcnt, num_blocks, &ctx, NULL, true); 4051 CU_ASSERT(rc == 0); 4052 4053 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags, 4054 remapped_init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED, &dif_opts); 4055 CU_ASSERT(rc == 0); 4056 4057 rc = spdk_dif_verify(iovs, iovcnt, num_blocks, &ctx, NULL); 4058 CU_ASSERT(rc == 0); 4059 4060 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, md_size, num_blocks); 4061 CU_ASSERT(rc == 0); 4062 } 4063 4064 static void 4065 dif_sec_512_md_8_prchk_7_multi_iovs_remap_pi_16_test(void) 4066 { 4067 struct iovec iovs[4]; 4068 int i, num_blocks; 4069 uint32_t dif_flags; 4070 4071 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 4072 SPDK_DIF_FLAGS_REFTAG_CHECK; 4073 4074 num_blocks = 0; 4075 4076 for (i = 0; i < 4; i++) { 4077 _iov_alloc_buf(&iovs[i], (512 + 8) * (i + 1)); 4078 num_blocks += i + 1; 4079 } 4080 4081 dif_generate_remap_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1, 4082 dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 4083 4084 dif_generate_remap_and_verify(iovs, 4, 512 + 8, 8, num_blocks, true, SPDK_DIF_TYPE1, 4085 dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 4086 4087 for (i = 0; i < 4; i++) { 4088 _iov_free_buf(&iovs[i]); 4089 } 4090 } 4091 4092 static void 4093 dif_sec_4096_md_128_prchk_7_multi_iovs_remap_test(void) 4094 { 4095 struct iovec iovs[4]; 4096 int i, num_blocks; 4097 uint32_t dif_flags; 4098 4099 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 4100 SPDK_DIF_FLAGS_REFTAG_CHECK; 4101 4102 num_blocks = 0; 4103 4104 for (i = 0; i < 4; i++) { 4105 _iov_alloc_buf(&iovs[i], (4096 + 128) * (i + 1)); 4106 num_blocks += i + 1; 4107 } 4108 4109 dif_generate_remap_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, false, SPDK_DIF_TYPE1, 4110 dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32); 4111 dif_generate_remap_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, true, SPDK_DIF_TYPE1, 4112 dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32); 4113 dif_generate_remap_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, false, SPDK_DIF_TYPE1, 4114 dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64); 4115 dif_generate_remap_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, true, SPDK_DIF_TYPE1, 4116 dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64); 4117 4118 for (i = 0; i < 4; i++) { 4119 _iov_free_buf(&iovs[i]); 4120 } 4121 } 4122 4123 static void 4124 dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_remap_test(void) 4125 { 4126 struct iovec iovs[11]; 4127 uint32_t dif_flags; 4128 int i; 4129 4130 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 4131 SPDK_DIF_FLAGS_REFTAG_CHECK; 4132 4133 /* data[0][1000:0] */ 4134 _iov_alloc_buf(&iovs[0], 1000); 4135 4136 /* data[0][3095:1000], guard[0][0] */ 4137 _iov_alloc_buf(&iovs[1], 3096 + 1); 4138 4139 /* guard[0][1], apptag[0][0] */ 4140 _iov_alloc_buf(&iovs[2], 1 + 1); 4141 4142 /* apptag[0][1], reftag[0][0] */ 4143 _iov_alloc_buf(&iovs[3], 1 + 1); 4144 4145 /* reftag[0][3:1], ignore[0][59:0] */ 4146 _iov_alloc_buf(&iovs[4], 3 + 60); 4147 4148 /* ignore[119:60], data[1][3050:0] */ 4149 _iov_alloc_buf(&iovs[5], 60 + 3051); 4150 4151 /* data[1][4095:3050], guard[1][0] */ 4152 _iov_alloc_buf(&iovs[6], 1045 + 1); 4153 4154 /* guard[1][1], apptag[1][0] */ 4155 _iov_alloc_buf(&iovs[7], 1 + 1); 4156 4157 /* apptag[1][1], reftag[1][0] */ 4158 _iov_alloc_buf(&iovs[8], 1 + 1); 4159 4160 /* reftag[1][3:1], ignore[1][9:0] */ 4161 _iov_alloc_buf(&iovs[9], 3 + 10); 4162 4163 /* ignore[1][127:9] */ 4164 _iov_alloc_buf(&iovs[10], 118); 4165 4166 dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, false, SPDK_DIF_TYPE1, dif_flags, 4167 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 4168 dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, true, SPDK_DIF_TYPE1, dif_flags, 4169 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 4170 dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, false, SPDK_DIF_TYPE1, dif_flags, 4171 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32); 4172 dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, true, SPDK_DIF_TYPE1, dif_flags, 4173 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32); 4174 dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, false, SPDK_DIF_TYPE1, dif_flags, 4175 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64); 4176 dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, true, SPDK_DIF_TYPE1, dif_flags, 4177 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64); 4178 4179 for (i = 0; i < 11; i++) { 4180 _iov_free_buf(&iovs[i]); 4181 } 4182 } 4183 4184 static void 4185 dix_generate_remap_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, 4186 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 4187 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, 4188 uint32_t init_ref_tag, uint32_t remapped_init_ref_tag, 4189 uint16_t apptag_mask, uint16_t app_tag, 4190 enum spdk_dif_pi_format dif_pi_format) 4191 { 4192 struct spdk_dif_ctx ctx; 4193 int rc; 4194 struct spdk_dif_ctx_init_ext_opts dif_opts; 4195 4196 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, 0, num_blocks); 4197 CU_ASSERT(rc == 0); 4198 4199 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 4200 dif_opts.dif_pi_format = dif_pi_format; 4201 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags, 4202 init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED, &dif_opts); 4203 CU_ASSERT(rc == 0); 4204 4205 rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx); 4206 CU_ASSERT(rc == 0); 4207 4208 spdk_dif_ctx_set_remapped_init_ref_tag(&ctx, remapped_init_ref_tag); 4209 4210 rc = spdk_dix_remap_ref_tag(md_iov, num_blocks, &ctx, NULL, true); 4211 CU_ASSERT(rc == 0); 4212 4213 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags, 4214 remapped_init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED, &dif_opts); 4215 CU_ASSERT(rc == 0); 4216 4217 rc = spdk_dix_verify(iovs, iovcnt, md_iov, num_blocks, &ctx, NULL); 4218 CU_ASSERT(rc == 0); 4219 4220 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, 0, num_blocks); 4221 CU_ASSERT(rc == 0); 4222 } 4223 4224 static void 4225 dix_sec_4096_md_128_prchk_7_multi_iovs_remap(void) 4226 { 4227 struct iovec iovs[4], md_iov; 4228 uint32_t dif_flags; 4229 int i, num_blocks; 4230 4231 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 4232 SPDK_DIF_FLAGS_REFTAG_CHECK; 4233 4234 num_blocks = 0; 4235 4236 for (i = 0; i < 4; i++) { 4237 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 4238 num_blocks += i + 1; 4239 } 4240 _iov_alloc_buf(&md_iov, 128 * num_blocks); 4241 4242 dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1, 4243 dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 4244 dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1, 4245 dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 4246 dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1, 4247 dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32); 4248 dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1, 4249 dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32); 4250 dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1, 4251 dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64); 4252 dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1, 4253 dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64); 4254 4255 for (i = 0; i < 4; i++) { 4256 _iov_free_buf(&iovs[i]); 4257 } 4258 _iov_free_buf(&md_iov); 4259 } 4260 4261 static void 4262 dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits_remap_pi_16_test(void) 4263 { 4264 struct iovec iovs[6], md_iov; 4265 uint32_t dif_flags; 4266 int i; 4267 4268 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 4269 SPDK_DIF_FLAGS_REFTAG_CHECK; 4270 4271 /* data[0][255:0] */ 4272 _iov_alloc_buf(&iovs[0], 256); 4273 4274 /* data[0][511:256], data[1][255:0] */ 4275 _iov_alloc_buf(&iovs[1], 256 + 256); 4276 4277 /* data[1][382:256] */ 4278 _iov_alloc_buf(&iovs[2], 128); 4279 4280 /* data[1][383] */ 4281 _iov_alloc_buf(&iovs[3], 1); 4282 4283 /* data[1][510:384] */ 4284 _iov_alloc_buf(&iovs[4], 126); 4285 4286 /* data[1][511], data[2][511:0], data[3][511:0] */ 4287 _iov_alloc_buf(&iovs[5], 1 + 512 * 2); 4288 4289 _iov_alloc_buf(&md_iov, 8 * 4); 4290 4291 dix_generate_remap_and_verify(iovs, 6, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1, 4292 dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_16); 4293 4294 for (i = 0; i < 6; i++) { 4295 _iov_free_buf(&iovs[i]); 4296 } 4297 _iov_free_buf(&md_iov); 4298 } 4299 4300 static void 4301 dix_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_remap_test(void) 4302 { 4303 struct iovec iovs[6], md_iov; 4304 uint32_t dif_flags; 4305 int i; 4306 4307 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 4308 SPDK_DIF_FLAGS_REFTAG_CHECK; 4309 4310 /* data[0][2047:0] */ 4311 _iov_alloc_buf(&iovs[0], 2048); 4312 4313 /* data[0][4095:2048], data[1][2047:0] */ 4314 _iov_alloc_buf(&iovs[1], 2048 + 2048); 4315 4316 /* data[1][3071:2048] */ 4317 _iov_alloc_buf(&iovs[2], 1024); 4318 4319 /* data[1][3072] */ 4320 _iov_alloc_buf(&iovs[3], 1); 4321 4322 /* data[1][4094:3073] */ 4323 _iov_alloc_buf(&iovs[4], 1022); 4324 4325 /* data[1][4095], data[2][4095:0], data[3][4095:0] */ 4326 _iov_alloc_buf(&iovs[5], 1 + 4096 * 2); 4327 4328 _iov_alloc_buf(&md_iov, 128 * 4); 4329 4330 dix_generate_remap_and_verify(iovs, 6, &md_iov, 4096, 128, 4, false, SPDK_DIF_TYPE1, 4331 dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_32); 4332 dix_generate_remap_and_verify(iovs, 6, &md_iov, 4096, 128, 4, false, SPDK_DIF_TYPE1, 4333 dif_flags, 22, 99, 0xFFFF, 0x22, SPDK_DIF_PI_FORMAT_64); 4334 4335 for (i = 0; i < 6; i++) { 4336 _iov_free_buf(&iovs[i]); 4337 } 4338 _iov_free_buf(&md_iov); 4339 } 4340 4341 static void 4342 dif_generate_and_verify_unmap_test(void) 4343 { 4344 struct iovec iov; 4345 struct spdk_dif_ctx ctx = {}; 4346 int rc; 4347 struct spdk_dif_ctx_init_ext_opts dif_opts; 4348 uint32_t dif_flags; 4349 struct spdk_dif *dif; 4350 4351 _iov_alloc_buf(&iov, 4096 + 128); 4352 4353 dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format); 4354 dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16; 4355 dif = (struct spdk_dif *)(iov.iov_base + 4096); 4356 4357 /* Case 1 for TYPE1 */ 4358 memset(iov.iov_base, 0, 4096 + 128); 4359 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | SPDK_DIF_FLAGS_REFTAG_CHECK; 4360 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, true, SPDK_DIF_TYPE1, dif_flags, 4361 0x100, 0xFFFF, SPDK_DIF_APPTAG_IGNORE, 0, 0, &dif_opts); 4362 CU_ASSERT(rc == 0); 4363 4364 rc = spdk_dif_generate(&iov, 1, 1, &ctx); 4365 CU_ASSERT(rc == 0); 4366 4367 rc = spdk_dif_verify(&iov, 1, 1, &ctx, NULL); 4368 CU_ASSERT(rc == 0); 4369 4370 CU_ASSERT(_dif_get_apptag(dif, ctx.dif_pi_format) == SPDK_DIF_APPTAG_IGNORE); 4371 CU_ASSERT(_dif_get_reftag(dif, ctx.dif_pi_format) == 0x100); 4372 4373 /* Case 2 for TYPE3 */ 4374 memset(iov.iov_base, 0, 4096 + 128); 4375 4376 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | SPDK_DIF_FLAGS_REFTAG_CHECK; 4377 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, true, SPDK_DIF_TYPE3, dif_flags, 4378 SPDK_DIF_REFTAG_IGNORE, 0xFFFF, SPDK_DIF_APPTAG_IGNORE, 0, 0, &dif_opts); 4379 CU_ASSERT(rc == 0); 4380 4381 rc = spdk_dif_generate(&iov, 1, 1, &ctx); 4382 CU_ASSERT(rc == 0); 4383 4384 rc = spdk_dif_verify(&iov, 1, 1, &ctx, NULL); 4385 CU_ASSERT(rc == 0); 4386 4387 CU_ASSERT(_dif_get_apptag(dif, ctx.dif_pi_format) == SPDK_DIF_APPTAG_IGNORE); 4388 CU_ASSERT(_dif_get_reftag(dif, ctx.dif_pi_format) == REFTAG_MASK_16); 4389 4390 _iov_free_buf(&iov); 4391 } 4392 4393 static void 4394 dif_pi_format_check_test(void) 4395 { 4396 CU_ASSERT(_dif_pi_format_is_valid(SPDK_DIF_PI_FORMAT_16) == true); 4397 CU_ASSERT(_dif_pi_format_is_valid(SPDK_DIF_PI_FORMAT_32) == true); 4398 CU_ASSERT(_dif_pi_format_is_valid(SPDK_DIF_PI_FORMAT_64) == true); 4399 CU_ASSERT(_dif_pi_format_is_valid(SPDK_DIF_PI_FORMAT_64 + 1) == false); 4400 } 4401 4402 static void 4403 dif_type_check_test(void) 4404 { 4405 CU_ASSERT(_dif_type_is_valid(SPDK_DIF_DISABLE) == true); 4406 CU_ASSERT(_dif_type_is_valid(SPDK_DIF_TYPE1) == true); 4407 CU_ASSERT(_dif_type_is_valid(SPDK_DIF_TYPE2) == true); 4408 CU_ASSERT(_dif_type_is_valid(SPDK_DIF_TYPE3) == true); 4409 CU_ASSERT(_dif_type_is_valid(SPDK_DIF_TYPE3 + 1) == false); 4410 } 4411 4412 int 4413 main(int argc, char **argv) 4414 { 4415 CU_pSuite suite = NULL; 4416 unsigned int num_failures; 4417 4418 CU_initialize_registry(); 4419 4420 suite = CU_add_suite("dif", NULL, NULL); 4421 4422 CU_ADD_TEST(suite, dif_generate_and_verify_test); 4423 CU_ADD_TEST(suite, dif_disable_check_test); 4424 CU_ADD_TEST(suite, dif_generate_and_verify_different_pi_formats_test); 4425 CU_ADD_TEST(suite, dif_apptag_mask_test); 4426 CU_ADD_TEST(suite, dif_sec_8_md_8_error_test); 4427 CU_ADD_TEST(suite, dif_sec_512_md_0_error_test); 4428 CU_ADD_TEST(suite, dif_sec_512_md_16_error_test); 4429 CU_ADD_TEST(suite, dif_sec_4096_md_0_8_error_test); 4430 CU_ADD_TEST(suite, dif_sec_4100_md_128_error_test); 4431 CU_ADD_TEST(suite, dif_guard_seed_test); 4432 CU_ADD_TEST(suite, dif_guard_value_test); 4433 CU_ADD_TEST(suite, dif_disable_sec_512_md_8_single_iov_test); 4434 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_0_single_iov_test); 4435 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_0_single_iov_test); 4436 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_0_1_2_4_multi_iovs_test); 4437 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test); 4438 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_test); 4439 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_data_and_md_test); 4440 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_split_data_and_md_test); 4441 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_data_test); 4442 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_split_data_test); 4443 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_guard_test); 4444 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_split_guard_test); 4445 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_apptag_test); 4446 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_split_apptag_test); 4447 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_reftag_test); 4448 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_split_reftag_test); 4449 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_complex_splits_test); 4450 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test); 4451 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test); 4452 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_and_md_test); 4453 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_test); 4454 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_guard_test); 4455 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_apptag_pi_16_test); 4456 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_apptag_test); 4457 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_pi_16_test); 4458 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_test); 4459 CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_0_single_iov); 4460 CU_ADD_TEST(suite, dif_copy_sec_512_md_8_dif_disable_single_iov); 4461 CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_0_single_iov_test); 4462 CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_0_1_2_4_multi_iovs); 4463 CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test); 4464 CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_0_1_2_4_multi_bounce_iovs_test); 4465 CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_7_multi_iovs); 4466 CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_7_multi_iovs_split_data); 4467 CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_7_multi_iovs_split_data_test); 4468 CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits); 4469 CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_7_multi_bounce_iovs_complex_splits); 4470 CU_ADD_TEST(suite, dif_copy_sec_512_md_8_dif_disable_multi_bounce_iovs_complex_splits); 4471 CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test); 4472 CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test); 4473 CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test); 4474 CU_ADD_TEST(suite, dix_sec_0_md_8_error); 4475 CU_ADD_TEST(suite, dix_sec_512_md_0_error); 4476 CU_ADD_TEST(suite, dix_sec_512_md_16_error); 4477 CU_ADD_TEST(suite, dix_sec_4096_md_0_8_error); 4478 CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_0_single_iov); 4479 CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_0_single_iov_test); 4480 CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_0_1_2_4_multi_iovs); 4481 CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_0_1_2_4_multi_iovs_test); 4482 CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs); 4483 CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_7_multi_iovs_split_data); 4484 CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs_split_data_test); 4485 CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits); 4486 CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test); 4487 CU_ADD_TEST(suite, dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test); 4488 CU_ADD_TEST(suite, dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test); 4489 CU_ADD_TEST(suite, set_md_interleave_iovs_test); 4490 CU_ADD_TEST(suite, set_md_interleave_iovs_split_test); 4491 CU_ADD_TEST(suite, dif_generate_stream_pi_16_test); 4492 CU_ADD_TEST(suite, dif_generate_stream_test); 4493 CU_ADD_TEST(suite, set_md_interleave_iovs_alignment_test); 4494 CU_ADD_TEST(suite, dif_generate_split_test); 4495 CU_ADD_TEST(suite, set_md_interleave_iovs_multi_segments_test); 4496 CU_ADD_TEST(suite, dif_verify_split_test); 4497 CU_ADD_TEST(suite, dif_verify_stream_multi_segments_test); 4498 CU_ADD_TEST(suite, update_crc32c_pi_16_test); 4499 CU_ADD_TEST(suite, update_crc32c_test); 4500 CU_ADD_TEST(suite, dif_update_crc32c_split_test); 4501 CU_ADD_TEST(suite, dif_update_crc32c_stream_multi_segments_test); 4502 CU_ADD_TEST(suite, get_range_with_md_test); 4503 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_remap_pi_16_test); 4504 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_remap_test); 4505 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_remap_test); 4506 CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs_remap); 4507 CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits_remap_pi_16_test); 4508 CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_remap_test); 4509 CU_ADD_TEST(suite, dif_generate_and_verify_unmap_test); 4510 CU_ADD_TEST(suite, dif_pi_format_check_test); 4511 CU_ADD_TEST(suite, dif_type_check_test); 4512 4513 num_failures = spdk_ut_run_tests(argc, argv, NULL); 4514 4515 CU_cleanup_registry(); 4516 4517 return num_failures; 4518 } 4519