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_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 void 127 _dif_generate_and_verify(struct iovec *iov, 128 uint32_t block_size, uint32_t md_size, bool dif_loc, 129 enum spdk_dif_type dif_type, uint32_t dif_flags, 130 uint32_t ref_tag, uint32_t e_ref_tag, 131 uint16_t app_tag, uint16_t apptag_mask, uint16_t e_app_tag, 132 bool expect_pass) 133 { 134 struct spdk_dif_ctx ctx = {}; 135 uint32_t guard_interval; 136 uint16_t guard = 0; 137 int rc; 138 139 rc = ut_data_pattern_generate(iov, 1, block_size, md_size, 1); 140 CU_ASSERT(rc == 0); 141 142 guard_interval = _get_guard_interval(block_size, md_size, dif_loc, true); 143 144 ctx.dif_type = dif_type; 145 ctx.dif_flags = dif_flags; 146 ctx.init_ref_tag = ref_tag; 147 ctx.app_tag = app_tag; 148 149 if (dif_flags & SPDK_DIF_FLAGS_GUARD_CHECK) { 150 guard = spdk_crc16_t10dif(0, iov->iov_base, guard_interval); 151 } 152 153 _dif_generate(iov->iov_base + guard_interval, guard, 0, &ctx); 154 155 ctx.init_ref_tag = e_ref_tag; 156 ctx.apptag_mask = apptag_mask; 157 ctx.app_tag = e_app_tag; 158 159 rc = _dif_verify(iov->iov_base + guard_interval, guard, 0, &ctx, NULL); 160 CU_ASSERT((expect_pass && rc == 0) || (!expect_pass && rc != 0)); 161 162 rc = ut_data_pattern_verify(iov, 1, block_size, md_size, 1); 163 CU_ASSERT(rc == 0); 164 } 165 166 static void 167 dif_generate_and_verify_test(void) 168 { 169 struct iovec iov; 170 uint32_t dif_flags; 171 172 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 173 SPDK_DIF_FLAGS_REFTAG_CHECK; 174 175 _iov_alloc_buf(&iov, 4096 + 128); 176 177 /* Positive cases */ 178 179 /* The case that DIF is contained in the first 8 bytes of metadata. */ 180 _dif_generate_and_verify(&iov, 181 4096 + 128, 128, true, 182 SPDK_DIF_TYPE1, dif_flags, 183 22, 22, 184 0x22, 0xFFFF, 0x22, 185 true); 186 187 /* The case that DIF is contained in the last 8 bytes of metadata. */ 188 _dif_generate_and_verify(&iov, 189 4096 + 128, 128, false, 190 SPDK_DIF_TYPE1, dif_flags, 191 22, 22, 192 0x22, 0xFFFF, 0x22, 193 true); 194 195 /* Negative cases */ 196 197 /* Reference tag doesn't match. */ 198 _dif_generate_and_verify(&iov, 199 4096 + 128, 128, false, 200 SPDK_DIF_TYPE1, dif_flags, 201 22, 23, 202 0x22, 0xFFFF, 0x22, 203 false); 204 205 /* Application tag doesn't match. */ 206 _dif_generate_and_verify(&iov, 207 4096 + 128, 128, false, 208 SPDK_DIF_TYPE1, dif_flags, 209 22, 22, 210 0x22, 0xFFFF, 0x23, 211 false); 212 213 _iov_free_buf(&iov); 214 } 215 216 static void 217 dif_disable_check_test(void) 218 { 219 struct iovec iov; 220 uint32_t dif_flags; 221 222 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 223 SPDK_DIF_FLAGS_REFTAG_CHECK; 224 225 _iov_alloc_buf(&iov, 4096 + 128); 226 227 /* The case that DIF check is disabled when the Application Tag is 0xFFFF for 228 * Type 1. DIF check is disabled and pass is expected. 229 */ 230 _dif_generate_and_verify(&iov, 231 4096 + 128, 128, false, 232 SPDK_DIF_TYPE1, dif_flags, 233 22, 22, 234 0xFFFF, 0xFFFF, 0x22, 235 true); 236 237 /* The case that DIF check is not disabled when the Application Tag is 0xFFFF but 238 * the Reference Tag is not 0xFFFFFFFF for Type 3. DIF check is not disabled and 239 * fail is expected. 240 */ 241 _dif_generate_and_verify(&iov, 242 4096 + 128, 128, false, 243 SPDK_DIF_TYPE3, dif_flags, 244 22, 22, 245 0xFFFF, 0xFFFF, 0x22, 246 false); 247 248 /* The case that DIF check is disabled when the Application Tag is 0xFFFF and 249 * the Reference Tag is 0xFFFFFFFF for Type 3. DIF check is disabled and 250 * pass is expected. 251 */ 252 _dif_generate_and_verify(&iov, 253 4096 + 128, 128, false, 254 SPDK_DIF_TYPE3, dif_flags, 255 0xFFFFFFFF, 22, 256 0xFFFF, 0xFFFF, 0x22, 257 true); 258 259 _iov_free_buf(&iov); 260 } 261 262 static void 263 dif_sec_512_md_0_error_test(void) 264 { 265 struct spdk_dif_ctx ctx = {}; 266 int rc; 267 268 /* Metadata size is 0. */ 269 rc = spdk_dif_ctx_init(&ctx, 512, 0, true, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 0, 0); 270 CU_ASSERT(rc != 0); 271 } 272 273 static void 274 dif_guard_seed_test(void) 275 { 276 struct iovec iov; 277 struct spdk_dif_ctx ctx = {}; 278 struct spdk_dif_error err_blk = {}; 279 struct spdk_dif *dif; 280 uint16_t guard; 281 int rc; 282 283 _iov_alloc_buf(&iov, 512 + 8); 284 285 memset(iov.iov_base, 0, 512 + 8); 286 287 dif = (struct spdk_dif *)(iov.iov_base + 512); 288 289 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, 290 SPDK_DIF_FLAGS_GUARD_CHECK, 0, 0, 0, 0, 0); 291 CU_ASSERT(rc == 0); 292 293 rc = spdk_dif_generate(&iov, 1, 1, &ctx); 294 CU_ASSERT(rc == 0); 295 296 /* Guard should be zero if the block is all zero and seed is not added. */ 297 guard = from_be16(&dif->guard); 298 CU_ASSERT(guard == 0); 299 300 rc = spdk_dif_verify(&iov, 1, 1, &ctx, &err_blk); 301 CU_ASSERT(rc == 0); 302 303 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, 304 SPDK_DIF_FLAGS_GUARD_CHECK, 0, 0, 0, 0, GUARD_SEED); 305 CU_ASSERT(rc == 0); 306 307 rc = spdk_dif_generate(&iov, 1, 1, &ctx); 308 CU_ASSERT(rc == 0); 309 310 /* Guard should not be zero if the block is all zero but seed is added. */ 311 guard = from_be16(&dif->guard); 312 CU_ASSERT(guard != 0); 313 314 rc = spdk_dif_verify(&iov, 1, 1, &ctx, &err_blk); 315 CU_ASSERT(rc == 0); 316 317 _iov_free_buf(&iov); 318 } 319 320 static void 321 dif_generate_and_verify(struct iovec *iovs, int iovcnt, 322 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 323 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, 324 uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag) 325 { 326 struct spdk_dif_ctx ctx = {}; 327 int rc; 328 329 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks); 330 CU_ASSERT(rc == 0); 331 332 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags, 333 init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED); 334 CU_ASSERT(rc == 0); 335 336 rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx); 337 CU_ASSERT(rc == 0); 338 339 rc = spdk_dif_verify(iovs, iovcnt, num_blocks, &ctx, NULL); 340 CU_ASSERT(rc == 0); 341 342 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, md_size, num_blocks); 343 CU_ASSERT(rc == 0); 344 } 345 346 static void 347 dif_disable_sec_512_md_8_single_iov_test(void) 348 { 349 struct iovec iov; 350 351 _iov_alloc_buf(&iov, 512 + 8); 352 353 dif_generate_and_verify(&iov, 1, 512 + 8, 8, 1, false, SPDK_DIF_DISABLE, 0, 0, 0, 0); 354 355 _iov_free_buf(&iov); 356 } 357 358 static void 359 dif_sec_512_md_8_prchk_0_single_iov_test(void) 360 { 361 struct iovec iov; 362 363 _iov_alloc_buf(&iov, 512 + 8); 364 365 dif_generate_and_verify(&iov, 1, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1, 0, 0, 0, 0); 366 367 _iov_free_buf(&iov); 368 } 369 370 static void 371 dif_sec_512_md_8_prchk_0_1_2_4_multi_iovs_test(void) 372 { 373 struct iovec iovs[4]; 374 int i, num_blocks; 375 376 num_blocks = 0; 377 378 for (i = 0; i < 4; i++) { 379 _iov_alloc_buf(&iovs[i], (512 + 8) * (i + 1)); 380 num_blocks += i + 1; 381 } 382 383 dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1, 384 0, 22, 0xFFFF, 0x22); 385 386 dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1, 387 SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22); 388 389 dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1, 390 SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22); 391 392 dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1, 393 SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22); 394 395 for (i = 0; i < 4; i++) { 396 _iov_free_buf(&iovs[i]); 397 } 398 } 399 400 static void 401 dif_sec_4096_md_128_prchk_7_multi_iovs_test(void) 402 { 403 struct iovec iovs[4]; 404 int i, num_blocks; 405 uint32_t dif_flags; 406 407 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 408 SPDK_DIF_FLAGS_REFTAG_CHECK; 409 410 num_blocks = 0; 411 412 for (i = 0; i < 4; i++) { 413 _iov_alloc_buf(&iovs[i], (4096 + 128) * (i + 1)); 414 num_blocks += i + 1; 415 } 416 417 dif_generate_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, false, SPDK_DIF_TYPE1, 418 dif_flags, 22, 0xFFFF, 0x22); 419 420 dif_generate_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, true, SPDK_DIF_TYPE1, 421 dif_flags, 22, 0xFFFF, 0x22); 422 423 for (i = 0; i < 4; i++) { 424 _iov_free_buf(&iovs[i]); 425 } 426 } 427 428 static void 429 dif_sec_512_md_8_prchk_7_multi_iovs_split_data_and_md_test(void) 430 { 431 struct iovec iovs[2]; 432 uint32_t dif_flags; 433 434 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 435 SPDK_DIF_FLAGS_REFTAG_CHECK; 436 437 _iov_alloc_buf(&iovs[0], 512); 438 _iov_alloc_buf(&iovs[1], 8); 439 440 dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1, 441 dif_flags, 22, 0xFFFF, 0x22); 442 443 _iov_free_buf(&iovs[0]); 444 _iov_free_buf(&iovs[1]); 445 } 446 447 static void 448 dif_sec_512_md_8_prchk_7_multi_iovs_split_data_test(void) 449 { 450 struct iovec iovs[2]; 451 uint32_t dif_flags; 452 453 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 454 SPDK_DIF_FLAGS_REFTAG_CHECK; 455 456 _iov_alloc_buf(&iovs[0], 256); 457 _iov_alloc_buf(&iovs[1], 264); 458 459 dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1, 460 dif_flags, 22, 0xFFFF, 0x22); 461 462 _iov_free_buf(&iovs[0]); 463 _iov_free_buf(&iovs[1]); 464 } 465 466 static void 467 dif_sec_512_md_8_prchk_7_multi_iovs_split_guard_test(void) 468 { 469 struct iovec iovs[2]; 470 uint32_t dif_flags; 471 472 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 473 SPDK_DIF_FLAGS_REFTAG_CHECK; 474 475 _iov_alloc_buf(&iovs[0], 513); 476 _iov_alloc_buf(&iovs[1], 7); 477 478 dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1, 479 dif_flags, 22, 0xFFFF, 0x22); 480 481 _iov_free_buf(&iovs[0]); 482 _iov_free_buf(&iovs[1]); 483 } 484 485 static void 486 dif_sec_512_md_8_prchk_7_multi_iovs_split_apptag_test(void) 487 { 488 struct iovec iovs[2]; 489 uint32_t dif_flags; 490 491 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 492 SPDK_DIF_FLAGS_REFTAG_CHECK; 493 494 _iov_alloc_buf(&iovs[0], 515); 495 _iov_alloc_buf(&iovs[1], 5); 496 497 dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1, 498 dif_flags, 22, 0xFFFF, 0x22); 499 500 _iov_free_buf(&iovs[0]); 501 _iov_free_buf(&iovs[1]); 502 } 503 504 static void 505 dif_sec_512_md_8_prchk_7_multi_iovs_split_reftag_test(void) 506 { 507 struct iovec iovs[2]; 508 uint32_t dif_flags; 509 510 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 511 SPDK_DIF_FLAGS_REFTAG_CHECK; 512 513 _iov_alloc_buf(&iovs[0], 518); 514 _iov_alloc_buf(&iovs[1], 2); 515 516 dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1, 517 dif_flags, 22, 0xFFFF, 0x22); 518 519 _iov_free_buf(&iovs[0]); 520 _iov_free_buf(&iovs[1]); 521 } 522 523 static void 524 dif_sec_512_md_8_prchk_7_multi_iovs_complex_splits_test(void) 525 { 526 struct iovec iovs[9]; 527 uint32_t dif_flags; 528 int i; 529 530 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 531 SPDK_DIF_FLAGS_REFTAG_CHECK; 532 533 /* data[0][255:0] */ 534 _iov_alloc_buf(&iovs[0], 256); 535 536 /* data[0][511:256], guard[0][0] */ 537 _iov_alloc_buf(&iovs[1], 256 + 1); 538 539 /* guard[0][1], apptag[0][0] */ 540 _iov_alloc_buf(&iovs[2], 1 + 1); 541 542 /* apptag[0][1], reftag[0][0] */ 543 _iov_alloc_buf(&iovs[3], 1 + 1); 544 545 /* reftag[0][3:1], data[1][255:0] */ 546 _iov_alloc_buf(&iovs[4], 3 + 256); 547 548 /* data[1][511:256], guard[1][0] */ 549 _iov_alloc_buf(&iovs[5], 256 + 1); 550 551 /* guard[1][1], apptag[1][0] */ 552 _iov_alloc_buf(&iovs[6], 1 + 1); 553 554 /* apptag[1][1], reftag[1][0] */ 555 _iov_alloc_buf(&iovs[7], 1 + 1); 556 557 /* reftag[1][3:1] */ 558 _iov_alloc_buf(&iovs[8], 3); 559 560 dif_generate_and_verify(iovs, 9, 512 + 8, 8, 2, false, SPDK_DIF_TYPE1, dif_flags, 561 22, 0xFFFF, 0x22); 562 563 for (i = 0; i < 9; i++) { 564 _iov_free_buf(&iovs[i]); 565 } 566 } 567 568 static void 569 dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test(void) 570 { 571 struct iovec iovs[11]; 572 uint32_t dif_flags; 573 int i; 574 575 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 576 SPDK_DIF_FLAGS_REFTAG_CHECK; 577 578 /* data[0][1000:0] */ 579 _iov_alloc_buf(&iovs[0], 1000); 580 581 /* data[0][3095:1000], guard[0][0] */ 582 _iov_alloc_buf(&iovs[1], 3096 + 1); 583 584 /* guard[0][1], apptag[0][0] */ 585 _iov_alloc_buf(&iovs[2], 1 + 1); 586 587 /* apptag[0][1], reftag[0][0] */ 588 _iov_alloc_buf(&iovs[3], 1 + 1); 589 590 /* reftag[0][3:1], ignore[0][59:0] */ 591 _iov_alloc_buf(&iovs[4], 3 + 60); 592 593 /* ignore[119:60], data[1][3050:0] */ 594 _iov_alloc_buf(&iovs[5], 60 + 3051); 595 596 /* data[1][4095:3050], guard[1][0] */ 597 _iov_alloc_buf(&iovs[6], 1045 + 1); 598 599 /* guard[1][1], apptag[1][0] */ 600 _iov_alloc_buf(&iovs[7], 1 + 1); 601 602 /* apptag[1][1], reftag[1][0] */ 603 _iov_alloc_buf(&iovs[8], 1 + 1); 604 605 /* reftag[1][3:1], ignore[1][9:0] */ 606 _iov_alloc_buf(&iovs[9], 3 + 10); 607 608 /* ignore[1][127:9] */ 609 _iov_alloc_buf(&iovs[10], 118); 610 611 dif_generate_and_verify(iovs, 11, 4096 + 128, 128, 2, false, SPDK_DIF_TYPE1, dif_flags, 612 22, 0xFFFF, 0x22); 613 dif_generate_and_verify(iovs, 11, 4096 + 128, 128, 2, true, SPDK_DIF_TYPE1, dif_flags, 614 22, 0xFFFF, 0x22); 615 616 for (i = 0; i < 11; i++) { 617 _iov_free_buf(&iovs[i]); 618 } 619 } 620 621 static void 622 _dif_inject_error_and_verify(struct iovec *iovs, int iovcnt, 623 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 624 uint32_t inject_flags, bool dif_loc) 625 { 626 struct spdk_dif_ctx ctx = {}; 627 struct spdk_dif_error err_blk = {}; 628 uint32_t inject_offset = 0, dif_flags; 629 int rc; 630 631 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 632 SPDK_DIF_FLAGS_REFTAG_CHECK; 633 634 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks); 635 CU_ASSERT(rc == 0); 636 637 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, 638 SPDK_DIF_TYPE1, dif_flags, 88, 0xFFFF, 0x88, 0, GUARD_SEED); 639 CU_ASSERT(rc == 0); 640 641 rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx); 642 CU_ASSERT(rc == 0); 643 644 rc = spdk_dif_inject_error(iovs, iovcnt, num_blocks, &ctx, inject_flags, &inject_offset); 645 CU_ASSERT(rc == 0); 646 647 rc = spdk_dif_verify(iovs, iovcnt, num_blocks, &ctx, &err_blk); 648 CU_ASSERT(rc != 0); 649 if (inject_flags == SPDK_DIF_DATA_ERROR) { 650 CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type); 651 } else { 652 CU_ASSERT(inject_flags == err_blk.err_type); 653 } 654 CU_ASSERT(inject_offset == err_blk.err_offset); 655 656 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, md_size, num_blocks); 657 CU_ASSERT((rc == 0 && (inject_flags != SPDK_DIF_DATA_ERROR)) || 658 (rc != 0 && (inject_flags == SPDK_DIF_DATA_ERROR))); 659 } 660 661 static void 662 dif_inject_error_and_verify(struct iovec *iovs, int iovcnt, 663 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 664 uint32_t inject_flags) 665 { 666 /* The case that DIF is contained in the first 8 bytes of metadata. */ 667 _dif_inject_error_and_verify(iovs, iovcnt, block_size, md_size, num_blocks, 668 inject_flags, true); 669 670 /* The case that DIF is contained in the last 8 bytes of metadata. */ 671 _dif_inject_error_and_verify(iovs, iovcnt, block_size, md_size, num_blocks, 672 inject_flags, false); 673 } 674 675 static void 676 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test(void) 677 { 678 struct iovec iovs[4]; 679 int i, num_blocks; 680 681 num_blocks = 0; 682 683 for (i = 0; i < 4; i++) { 684 _iov_alloc_buf(&iovs[i], (4096 + 128) * (i + 1)); 685 num_blocks += i + 1; 686 } 687 688 dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, SPDK_DIF_GUARD_ERROR); 689 dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, SPDK_DIF_APPTAG_ERROR); 690 dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, SPDK_DIF_REFTAG_ERROR); 691 dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, SPDK_DIF_DATA_ERROR); 692 693 for (i = 0; i < 4; i++) { 694 _iov_free_buf(&iovs[i]); 695 } 696 } 697 698 static void 699 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_and_md_test(void) 700 { 701 struct iovec iovs[2]; 702 703 _iov_alloc_buf(&iovs[0], 4096); 704 _iov_alloc_buf(&iovs[1], 128); 705 706 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_GUARD_ERROR); 707 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_APPTAG_ERROR); 708 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_REFTAG_ERROR); 709 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_DATA_ERROR); 710 711 _iov_free_buf(&iovs[0]); 712 _iov_free_buf(&iovs[1]); 713 } 714 715 static void 716 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_test(void) 717 { 718 struct iovec iovs[2]; 719 720 _iov_alloc_buf(&iovs[0], 2048); 721 _iov_alloc_buf(&iovs[1], 2048 + 128); 722 723 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_GUARD_ERROR); 724 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_APPTAG_ERROR); 725 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_REFTAG_ERROR); 726 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_DATA_ERROR); 727 728 _iov_free_buf(&iovs[0]); 729 _iov_free_buf(&iovs[1]); 730 } 731 732 static void 733 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_guard_test(void) 734 { 735 struct iovec iovs[2]; 736 737 _iov_alloc_buf(&iovs[0], 4096 + 1); 738 _iov_alloc_buf(&iovs[1], 127); 739 740 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_GUARD_ERROR); 741 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_APPTAG_ERROR); 742 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_REFTAG_ERROR); 743 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_DATA_ERROR); 744 745 _iov_free_buf(&iovs[0]); 746 _iov_free_buf(&iovs[1]); 747 } 748 749 static void 750 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_apptag_test(void) 751 { 752 struct iovec iovs[2]; 753 754 _iov_alloc_buf(&iovs[0], 4096 + 3); 755 _iov_alloc_buf(&iovs[1], 125); 756 757 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_GUARD_ERROR); 758 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_APPTAG_ERROR); 759 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_REFTAG_ERROR); 760 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_DATA_ERROR); 761 762 _iov_free_buf(&iovs[0]); 763 _iov_free_buf(&iovs[1]); 764 } 765 766 static void 767 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_test(void) 768 { 769 struct iovec iovs[2]; 770 771 _iov_alloc_buf(&iovs[0], 4096 + 6); 772 _iov_alloc_buf(&iovs[1], 122); 773 774 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_GUARD_ERROR); 775 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_APPTAG_ERROR); 776 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_REFTAG_ERROR); 777 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_DATA_ERROR); 778 779 _iov_free_buf(&iovs[0]); 780 _iov_free_buf(&iovs[1]); 781 } 782 783 static void 784 dif_copy_gen_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov, 785 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 786 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, 787 uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag) 788 { 789 struct spdk_dif_ctx ctx = {}; 790 int rc; 791 792 rc = ut_data_pattern_generate(iovs, iovcnt, block_size - md_size, 0, num_blocks); 793 CU_ASSERT(rc == 0); 794 795 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags, 796 init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED); 797 CU_ASSERT(rc == 0); 798 799 rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, 1, num_blocks, &ctx); 800 CU_ASSERT(rc == 0); 801 802 rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, 1, num_blocks, &ctx, NULL); 803 CU_ASSERT(rc == 0); 804 805 rc = ut_data_pattern_verify(iovs, iovcnt, block_size - md_size, 0, num_blocks); 806 CU_ASSERT(rc == 0); 807 } 808 809 static void 810 dif_copy_sec_512_md_8_prchk_0_single_iov(void) 811 { 812 struct iovec iov, bounce_iov; 813 814 _iov_alloc_buf(&iov, 512 * 4); 815 _iov_alloc_buf(&bounce_iov, (512 + 8) * 4); 816 817 dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 512 + 8, 8, 4, 818 false, SPDK_DIF_TYPE1, 0, 0, 0, 0); 819 dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 512 + 8, 8, 4, 820 true, SPDK_DIF_TYPE1, 0, 0, 0, 0); 821 822 _iov_free_buf(&iov); 823 _iov_free_buf(&bounce_iov); 824 } 825 826 static void 827 dif_copy_sec_512_md_8_prchk_0_1_2_4_multi_iovs(void) 828 { 829 struct iovec iovs[4], bounce_iov; 830 int i, num_blocks; 831 832 num_blocks = 0; 833 834 for (i = 0; i < 4; i++) { 835 _iov_alloc_buf(&iovs[i], 512 * (i + 1)); 836 num_blocks += i + 1; 837 } 838 839 _iov_alloc_buf(&bounce_iov, (512 + 8) * num_blocks); 840 841 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks, 842 false, SPDK_DIF_TYPE1, 0, 22, 0xFFFF, 0x22); 843 844 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks, 845 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22); 846 847 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks, 848 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22); 849 850 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks, 851 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22); 852 853 for (i = 0; i < 4; i++) { 854 _iov_free_buf(&iovs[i]); 855 } 856 _iov_free_buf(&bounce_iov); 857 } 858 859 static void 860 dif_copy_sec_4096_md_128_prchk_7_multi_iovs(void) 861 { 862 struct iovec iovs[4], bounce_iov; 863 uint32_t dif_flags; 864 int i, num_blocks; 865 866 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 867 SPDK_DIF_FLAGS_REFTAG_CHECK; 868 869 num_blocks = 0; 870 871 for (i = 0; i < 4; i++) { 872 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 873 num_blocks += i + 1; 874 } 875 876 _iov_alloc_buf(&bounce_iov, (4096 + 128) * num_blocks); 877 878 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks, 879 false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22); 880 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks, 881 true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22); 882 883 for (i = 0; i < 4; i++) { 884 _iov_free_buf(&iovs[i]); 885 } 886 _iov_free_buf(&bounce_iov); 887 } 888 889 static void 890 dif_copy_sec_512_md_8_prchk_7_multi_iovs_split_data(void) 891 { 892 struct iovec iovs[2], bounce_iov; 893 uint32_t dif_flags; 894 895 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 896 SPDK_DIF_FLAGS_REFTAG_CHECK; 897 898 _iov_alloc_buf(&iovs[0], 256); 899 _iov_alloc_buf(&iovs[1], 256); 900 901 _iov_alloc_buf(&bounce_iov, 512 + 8); 902 903 dif_copy_gen_and_verify(iovs, 2, &bounce_iov, 512 + 8, 8, 1, 904 false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22); 905 906 _iov_free_buf(&iovs[0]); 907 _iov_free_buf(&iovs[1]); 908 _iov_free_buf(&bounce_iov); 909 } 910 911 static void 912 dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits(void) 913 { 914 struct iovec iovs[6], bounce_iov; 915 uint32_t dif_flags; 916 int i; 917 918 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 919 SPDK_DIF_FLAGS_REFTAG_CHECK; 920 921 /* data[0][255:0] */ 922 _iov_alloc_buf(&iovs[0], 256); 923 924 /* data[0][511:256], data[1][255:0] */ 925 _iov_alloc_buf(&iovs[1], 256 + 256); 926 927 /* data[1][382:256] */ 928 _iov_alloc_buf(&iovs[2], 128); 929 930 /* data[1][383] */ 931 _iov_alloc_buf(&iovs[3], 1); 932 933 /* data[1][510:384] */ 934 _iov_alloc_buf(&iovs[4], 126); 935 936 /* data[1][511], data[2][511:0], data[3][511:0] */ 937 _iov_alloc_buf(&iovs[5], 1 + 512 * 2); 938 939 _iov_alloc_buf(&bounce_iov, (512 + 8) * 4); 940 941 dif_copy_gen_and_verify(iovs, 6, &bounce_iov, 512 + 8, 8, 4, 942 true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22); 943 944 for (i = 0; i < 6; i++) { 945 _iov_free_buf(&iovs[i]); 946 } 947 _iov_free_buf(&bounce_iov); 948 } 949 950 static void 951 _dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov, 952 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 953 uint32_t inject_flags, bool dif_loc) 954 { 955 struct spdk_dif_ctx ctx = {}; 956 struct spdk_dif_error err_blk = {}; 957 uint32_t inject_offset = 0, dif_flags; 958 int rc; 959 960 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 961 SPDK_DIF_FLAGS_REFTAG_CHECK; 962 963 rc = ut_data_pattern_generate(iovs, iovcnt, block_size - md_size, 0, num_blocks); 964 CU_ASSERT(rc == 0); 965 966 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, SPDK_DIF_TYPE1, dif_flags, 967 88, 0xFFFF, 0x88, 0, GUARD_SEED); 968 SPDK_CU_ASSERT_FATAL(rc == 0); 969 970 rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, 1, num_blocks, &ctx); 971 CU_ASSERT(rc == 0); 972 973 rc = spdk_dif_inject_error(bounce_iov, 1, num_blocks, &ctx, inject_flags, &inject_offset); 974 CU_ASSERT(rc == 0); 975 976 rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, 1, num_blocks, &ctx, &err_blk); 977 CU_ASSERT(rc != 0); 978 if (inject_flags == SPDK_DIF_DATA_ERROR) { 979 CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type); 980 } else { 981 CU_ASSERT(inject_flags == err_blk.err_type); 982 } 983 CU_ASSERT(inject_offset == err_blk.err_offset); 984 } 985 986 static void 987 dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov, 988 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 989 uint32_t inject_flags) 990 { 991 /* The case that DIF is contained in the first 8 bytes of metadata. */ 992 _dif_copy_inject_error_and_verify(iovs, iovcnt, bounce_iov, 993 block_size, md_size, num_blocks, 994 inject_flags, true); 995 996 /* The case that DIF is contained in the last 8 bytes of metadata. */ 997 _dif_copy_inject_error_and_verify(iovs, iovcnt, bounce_iov, 998 block_size, md_size, num_blocks, 999 inject_flags, false); 1000 } 1001 1002 static void 1003 dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test(void) 1004 { 1005 struct iovec iovs[4], bounce_iov; 1006 int i, num_blocks; 1007 1008 num_blocks = 0; 1009 1010 for (i = 0; i < 4; i++) { 1011 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 1012 num_blocks += i + 1; 1013 } 1014 1015 _iov_alloc_buf(&bounce_iov, (4096 + 128) * num_blocks); 1016 1017 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1018 num_blocks, SPDK_DIF_GUARD_ERROR); 1019 1020 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1021 num_blocks, SPDK_DIF_APPTAG_ERROR); 1022 1023 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1024 num_blocks, SPDK_DIF_REFTAG_ERROR); 1025 1026 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1027 num_blocks, SPDK_DIF_DATA_ERROR); 1028 1029 for (i = 0; i < 4; i++) { 1030 _iov_free_buf(&iovs[i]); 1031 } 1032 _iov_free_buf(&bounce_iov); 1033 } 1034 1035 static void 1036 dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test(void) 1037 { 1038 struct iovec iovs[4], bounce_iov; 1039 int i; 1040 1041 _iov_alloc_buf(&iovs[0], 2048); 1042 _iov_alloc_buf(&iovs[1], 2048); 1043 _iov_alloc_buf(&iovs[2], 1); 1044 _iov_alloc_buf(&iovs[3], 4095); 1045 1046 _iov_alloc_buf(&bounce_iov, (4096 + 128) * 2); 1047 1048 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1049 2, SPDK_DIF_GUARD_ERROR); 1050 1051 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1052 2, SPDK_DIF_APPTAG_ERROR); 1053 1054 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1055 2, SPDK_DIF_REFTAG_ERROR); 1056 1057 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1058 2, SPDK_DIF_DATA_ERROR); 1059 1060 for (i = 0; i < 4; i++) { 1061 _iov_free_buf(&iovs[i]); 1062 } 1063 _iov_free_buf(&bounce_iov); 1064 } 1065 1066 static void 1067 dix_sec_512_md_0_error(void) 1068 { 1069 struct spdk_dif_ctx ctx; 1070 int rc; 1071 1072 rc = spdk_dif_ctx_init(&ctx, 512, 0, false, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 0, 0); 1073 CU_ASSERT(rc != 0); 1074 } 1075 1076 static void 1077 dix_generate_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, 1078 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 1079 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, 1080 uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag) 1081 { 1082 struct spdk_dif_ctx ctx; 1083 int rc; 1084 1085 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, 0, num_blocks); 1086 CU_ASSERT(rc == 0); 1087 1088 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags, 1089 init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED); 1090 CU_ASSERT(rc == 0); 1091 1092 rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx); 1093 CU_ASSERT(rc == 0); 1094 1095 rc = spdk_dix_verify(iovs, iovcnt, md_iov, num_blocks, &ctx, NULL); 1096 CU_ASSERT(rc == 0); 1097 1098 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, 0, num_blocks); 1099 CU_ASSERT(rc == 0); 1100 } 1101 1102 static void 1103 dix_sec_512_md_8_prchk_0_single_iov(void) 1104 { 1105 struct iovec iov, md_iov; 1106 1107 _iov_alloc_buf(&iov, 512 * 4); 1108 _iov_alloc_buf(&md_iov, 8 * 4); 1109 1110 dix_generate_and_verify(&iov, 1, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1, 0, 0, 0, 0); 1111 dix_generate_and_verify(&iov, 1, &md_iov, 512, 8, 4, true, SPDK_DIF_TYPE1, 0, 0, 0, 0); 1112 1113 _iov_free_buf(&iov); 1114 _iov_free_buf(&md_iov); 1115 } 1116 1117 static void 1118 dix_sec_512_md_8_prchk_0_1_2_4_multi_iovs(void) 1119 { 1120 struct iovec iovs[4], md_iov; 1121 int i, num_blocks; 1122 1123 num_blocks = 0; 1124 1125 for (i = 0; i < 4; i++) { 1126 _iov_alloc_buf(&iovs[i], 512 * (i + 1)); 1127 num_blocks += i + 1; 1128 } 1129 _iov_alloc_buf(&md_iov, 8 * num_blocks); 1130 1131 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, 1132 0, 22, 0xFFFF, 0x22); 1133 1134 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, 1135 SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22); 1136 1137 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, 1138 SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22); 1139 1140 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, 1141 SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22); 1142 1143 for (i = 0; i < 4; i++) { 1144 _iov_free_buf(&iovs[i]); 1145 } 1146 _iov_free_buf(&md_iov); 1147 } 1148 1149 static void 1150 dix_sec_4096_md_128_prchk_7_multi_iovs(void) 1151 { 1152 struct iovec iovs[4], md_iov; 1153 uint32_t dif_flags; 1154 int i, num_blocks; 1155 1156 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1157 SPDK_DIF_FLAGS_REFTAG_CHECK; 1158 1159 num_blocks = 0; 1160 1161 for (i = 0; i < 4; i++) { 1162 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 1163 num_blocks += i + 1; 1164 } 1165 _iov_alloc_buf(&md_iov, 128 * num_blocks); 1166 1167 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1, 1168 dif_flags, 22, 0xFFFF, 0x22); 1169 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1, 1170 dif_flags, 22, 0xFFFF, 0x22); 1171 1172 for (i = 0; i < 4; i++) { 1173 _iov_free_buf(&iovs[i]); 1174 } 1175 _iov_free_buf(&md_iov); 1176 } 1177 1178 static void 1179 dix_sec_512_md_8_prchk_7_multi_iovs_split_data(void) 1180 { 1181 struct iovec iovs[2], md_iov; 1182 uint32_t dif_flags; 1183 1184 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1185 SPDK_DIF_FLAGS_REFTAG_CHECK; 1186 1187 _iov_alloc_buf(&iovs[0], 256); 1188 _iov_alloc_buf(&iovs[1], 256); 1189 _iov_alloc_buf(&md_iov, 8); 1190 1191 dix_generate_and_verify(iovs, 2, &md_iov, 512, 8, 1, false, SPDK_DIF_TYPE1, 1192 dif_flags, 22, 0xFFFF, 0x22); 1193 1194 _iov_free_buf(&iovs[0]); 1195 _iov_free_buf(&iovs[1]); 1196 _iov_free_buf(&md_iov); 1197 } 1198 1199 static void 1200 dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits(void) 1201 { 1202 struct iovec iovs[6], md_iov; 1203 uint32_t dif_flags; 1204 int i; 1205 1206 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1207 SPDK_DIF_FLAGS_REFTAG_CHECK; 1208 1209 /* data[0][255:0] */ 1210 _iov_alloc_buf(&iovs[0], 256); 1211 1212 /* data[0][511:256], data[1][255:0] */ 1213 _iov_alloc_buf(&iovs[1], 256 + 256); 1214 1215 /* data[1][382:256] */ 1216 _iov_alloc_buf(&iovs[2], 128); 1217 1218 /* data[1][383] */ 1219 _iov_alloc_buf(&iovs[3], 1); 1220 1221 /* data[1][510:384] */ 1222 _iov_alloc_buf(&iovs[4], 126); 1223 1224 /* data[1][511], data[2][511:0], data[3][511:0] */ 1225 _iov_alloc_buf(&iovs[5], 1 + 512 * 2); 1226 1227 _iov_alloc_buf(&md_iov, 8 * 4); 1228 1229 dix_generate_and_verify(iovs, 6, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1, 1230 dif_flags, 22, 0xFFFF, 0x22); 1231 1232 for (i = 0; i < 6; i++) { 1233 _iov_free_buf(&iovs[i]); 1234 } 1235 _iov_free_buf(&md_iov); 1236 } 1237 1238 static void 1239 _dix_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, 1240 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 1241 uint32_t inject_flags, bool dif_loc) 1242 { 1243 struct spdk_dif_ctx ctx = {}; 1244 struct spdk_dif_error err_blk = {}; 1245 uint32_t inject_offset = 0, dif_flags; 1246 int rc; 1247 1248 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1249 SPDK_DIF_FLAGS_REFTAG_CHECK; 1250 1251 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, 0, num_blocks); 1252 CU_ASSERT(rc == 0); 1253 1254 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, SPDK_DIF_TYPE1, dif_flags, 1255 88, 0xFFFF, 0x88, 0, GUARD_SEED); 1256 CU_ASSERT(rc == 0); 1257 1258 rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx); 1259 CU_ASSERT(rc == 0); 1260 1261 rc = spdk_dix_inject_error(iovs, iovcnt, md_iov, num_blocks, &ctx, inject_flags, &inject_offset); 1262 CU_ASSERT(rc == 0); 1263 1264 rc = spdk_dix_verify(iovs, iovcnt, md_iov, num_blocks, &ctx, &err_blk); 1265 CU_ASSERT(rc != 0); 1266 1267 if (inject_flags == SPDK_DIF_DATA_ERROR) { 1268 CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type); 1269 } else { 1270 CU_ASSERT(inject_flags == err_blk.err_type); 1271 } 1272 CU_ASSERT(inject_offset == err_blk.err_offset); 1273 } 1274 1275 static void 1276 dix_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, 1277 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 1278 uint32_t inject_flags) 1279 { 1280 /* The case that DIF is contained in the first 8 bytes of metadata. */ 1281 _dix_inject_error_and_verify(iovs, iovcnt, md_iov, block_size, md_size, num_blocks, 1282 inject_flags, true); 1283 1284 /* The case that DIF is contained in the last 8 bytes of metadata. */ 1285 _dix_inject_error_and_verify(iovs, iovcnt, md_iov, block_size, md_size, num_blocks, 1286 inject_flags, false); 1287 } 1288 1289 static void 1290 dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test(void) 1291 { 1292 struct iovec iovs[4], md_iov; 1293 int i, num_blocks; 1294 1295 num_blocks = 0; 1296 1297 for (i = 0; i < 4; i++) { 1298 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 1299 num_blocks += i + 1; 1300 } 1301 1302 _iov_alloc_buf(&md_iov, 128 * num_blocks); 1303 1304 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, SPDK_DIF_GUARD_ERROR); 1305 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, SPDK_DIF_APPTAG_ERROR); 1306 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, SPDK_DIF_REFTAG_ERROR); 1307 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, SPDK_DIF_DATA_ERROR); 1308 1309 for (i = 0; i < 4; i++) { 1310 _iov_free_buf(&iovs[i]); 1311 } 1312 _iov_free_buf(&md_iov); 1313 } 1314 1315 static void 1316 dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test(void) 1317 { 1318 struct iovec iovs[4], md_iov; 1319 int i; 1320 1321 _iov_alloc_buf(&iovs[0], 2048); 1322 _iov_alloc_buf(&iovs[1], 2048); 1323 _iov_alloc_buf(&iovs[2], 1); 1324 _iov_alloc_buf(&iovs[3], 4095); 1325 1326 _iov_alloc_buf(&md_iov, 128 * 2); 1327 1328 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, SPDK_DIF_GUARD_ERROR); 1329 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, SPDK_DIF_APPTAG_ERROR); 1330 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, SPDK_DIF_REFTAG_ERROR); 1331 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, SPDK_DIF_DATA_ERROR); 1332 1333 for (i = 0; i < 4; i++) { 1334 _iov_free_buf(&iovs[i]); 1335 } 1336 _iov_free_buf(&md_iov); 1337 } 1338 1339 static int 1340 ut_readv(uint32_t read_base, uint32_t read_len, struct iovec *iovs, int iovcnt) 1341 { 1342 int i; 1343 uint32_t j, offset; 1344 uint8_t *buf; 1345 1346 offset = 0; 1347 for (i = 0; i < iovcnt; i++) { 1348 buf = iovs[i].iov_base; 1349 for (j = 0; j < iovs[i].iov_len; j++, offset++) { 1350 if (offset >= read_len) { 1351 return offset; 1352 } 1353 buf[j] = DATA_PATTERN(read_base + offset); 1354 } 1355 } 1356 1357 return offset; 1358 } 1359 1360 static void 1361 set_md_interleave_iovs_test(void) 1362 { 1363 struct spdk_dif_ctx ctx = {}; 1364 struct spdk_dif_error err_blk = {}; 1365 struct iovec iov1, iov2, dif_iovs[4] = {}; 1366 uint32_t dif_check_flags, data_len, read_len, data_offset, mapped_len = 0; 1367 uint8_t *buf1, *buf2; 1368 int rc; 1369 1370 dif_check_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1371 SPDK_DIF_FLAGS_REFTAG_CHECK; 1372 1373 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 1374 dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED); 1375 CU_ASSERT(rc == 0); 1376 1377 /* The first data buffer: 1378 * - Create iovec array to Leave a space for metadata for each block 1379 * - Split vectored read and so creating iovec array is done before every vectored read. 1380 */ 1381 buf1 = calloc(1, (4096 + 128) * 4); 1382 SPDK_CU_ASSERT_FATAL(buf1 != NULL); 1383 _iov_set_buf(&iov1, buf1, (4096 + 128) * 4); 1384 1385 data_offset = 0; 1386 data_len = 4096 * 4; 1387 1388 /* 1st read */ 1389 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 1390 data_offset, data_len, &mapped_len, &ctx); 1391 CU_ASSERT(rc == 4); 1392 CU_ASSERT(mapped_len == 4096 * 4); 1393 CU_ASSERT(_iov_check(&dif_iovs[0], buf1, 4096) == true); 1394 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true); 1395 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true); 1396 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 4096) == true); 1397 1398 read_len = ut_readv(data_offset, 1024, dif_iovs, 4); 1399 CU_ASSERT(read_len == 1024); 1400 1401 rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx); 1402 CU_ASSERT(rc == 0); 1403 1404 data_offset += read_len; 1405 data_len -= read_len; 1406 1407 /* 2nd read */ 1408 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 1409 data_offset, data_len, &mapped_len, &ctx); 1410 CU_ASSERT(rc == 4); 1411 CU_ASSERT(mapped_len == 3072 + 4096 * 3); 1412 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 1024, 3072) == true); 1413 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true); 1414 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true); 1415 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 4096) == true); 1416 1417 read_len = ut_readv(data_offset, 3071, dif_iovs, 4); 1418 CU_ASSERT(read_len == 3071); 1419 1420 rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx); 1421 CU_ASSERT(rc == 0); 1422 1423 data_offset += read_len; 1424 data_len -= read_len; 1425 1426 /* 3rd read */ 1427 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 1428 data_offset, data_len, &mapped_len, &ctx); 1429 CU_ASSERT(rc == 4); 1430 CU_ASSERT(mapped_len == 1 + 4096 * 3); 1431 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 4095, 1) == true); 1432 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true); 1433 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true); 1434 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 4096) == true); 1435 1436 read_len = ut_readv(data_offset, 1 + 4096 * 2 + 512, dif_iovs, 4); 1437 CU_ASSERT(read_len == 1 + 4096 * 2 + 512); 1438 1439 rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx); 1440 CU_ASSERT(rc == 0); 1441 1442 data_offset += read_len; 1443 data_len -= read_len; 1444 1445 /* 4th read */ 1446 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 1447 data_offset, data_len, &mapped_len, &ctx); 1448 CU_ASSERT(rc == 1); 1449 CU_ASSERT(mapped_len == 3584); 1450 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + (4096 + 128) * 3 + 512, 3584) == true); 1451 1452 read_len = ut_readv(data_offset, 3584, dif_iovs, 1); 1453 CU_ASSERT(read_len == 3584); 1454 1455 rc = spdk_dif_generate_stream(&iov1, 1, data_offset, read_len, &ctx); 1456 CU_ASSERT(rc == 0); 1457 1458 data_offset += read_len; 1459 CU_ASSERT(data_offset == 4096 * 4); 1460 data_len -= read_len; 1461 CU_ASSERT(data_len == 0); 1462 1463 /* The second data buffer: 1464 * - Set data pattern with a space for metadata for each block. 1465 */ 1466 buf2 = calloc(1, (4096 + 128) * 4); 1467 SPDK_CU_ASSERT_FATAL(buf2 != NULL); 1468 _iov_set_buf(&iov2, buf2, (4096 + 128) * 4); 1469 1470 rc = ut_data_pattern_generate(&iov2, 1, 4096 + 128, 128, 4); 1471 CU_ASSERT(rc == 0); 1472 rc = spdk_dif_generate(&iov2, 1, 4, &ctx); 1473 CU_ASSERT(rc == 0); 1474 1475 rc = spdk_dif_verify(&iov1, 1, 4, &ctx, &err_blk); 1476 CU_ASSERT(rc == 0); 1477 1478 rc = spdk_dif_verify(&iov2, 1, 4, &ctx, &err_blk); 1479 CU_ASSERT(rc == 0); 1480 1481 /* Compare the first and the second data buffer by byte. */ 1482 rc = memcmp(buf1, buf2, (4096 + 128) * 4); 1483 CU_ASSERT(rc == 0); 1484 1485 free(buf1); 1486 free(buf2); 1487 } 1488 1489 static void 1490 set_md_interleave_iovs_split_test(void) 1491 { 1492 struct spdk_dif_ctx ctx = {}; 1493 struct spdk_dif_error err_blk = {}; 1494 struct iovec iovs1[7], iovs2[7], dif_iovs[8] = {}; 1495 uint32_t dif_check_flags, data_len, read_len, data_offset, mapped_len = 0; 1496 int rc, i; 1497 1498 dif_check_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1499 SPDK_DIF_FLAGS_REFTAG_CHECK; 1500 1501 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, 1502 dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED); 1503 CU_ASSERT(rc == 0); 1504 1505 /* The first SGL data buffer: 1506 * - Create iovec array to leave a space for metadata for each block 1507 * - Split vectored read and so creating iovec array is done before every vectored read. 1508 */ 1509 _iov_alloc_buf(&iovs1[0], 512 + 8 + 128); 1510 _iov_alloc_buf(&iovs1[1], 128); 1511 _iov_alloc_buf(&iovs1[2], 256 + 8); 1512 _iov_alloc_buf(&iovs1[3], 100); 1513 _iov_alloc_buf(&iovs1[4], 412 + 5); 1514 _iov_alloc_buf(&iovs1[5], 3 + 300); 1515 _iov_alloc_buf(&iovs1[6], 212 + 8); 1516 1517 data_offset = 0; 1518 data_len = 512 * 4; 1519 1520 /* 1st read */ 1521 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7, 1522 data_offset, data_len, &mapped_len, &ctx); 1523 CU_ASSERT(rc == 8); 1524 CU_ASSERT(mapped_len == 512 * 4); 1525 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base, 512) == true); 1526 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true); 1527 CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true); 1528 CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true); 1529 CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true); 1530 CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true); 1531 CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true); 1532 CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true); 1533 1534 read_len = ut_readv(data_offset, 128, dif_iovs, 8); 1535 CU_ASSERT(read_len == 128); 1536 1537 rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx); 1538 CU_ASSERT(rc == 0); 1539 1540 data_offset += read_len; 1541 data_len -= read_len; 1542 1543 /* 2nd read */ 1544 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7, 1545 data_offset, data_len, &mapped_len, &ctx); 1546 CU_ASSERT(rc == 8); 1547 CU_ASSERT(mapped_len == 384 + 512 * 3); 1548 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base + 128, 384) == true); 1549 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true); 1550 CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true); 1551 CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true); 1552 CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true); 1553 CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true); 1554 CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true); 1555 CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true); 1556 1557 read_len = ut_readv(data_offset, 383, dif_iovs, 8); 1558 CU_ASSERT(read_len == 383); 1559 1560 rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx); 1561 CU_ASSERT(rc == 0); 1562 1563 data_offset += read_len; 1564 data_len -= read_len; 1565 1566 /* 3rd read */ 1567 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7, 1568 data_offset, data_len, &mapped_len, &ctx); 1569 CU_ASSERT(rc == 8); 1570 CU_ASSERT(mapped_len == 1 + 512 * 3); 1571 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base + 511, 1) == true); 1572 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true); 1573 CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true); 1574 CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true); 1575 CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true); 1576 CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true); 1577 CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true); 1578 CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true); 1579 1580 read_len = ut_readv(data_offset, 1 + 512 * 2 + 128, dif_iovs, 8); 1581 CU_ASSERT(read_len == 1 + 512 * 2 + 128); 1582 1583 rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx); 1584 CU_ASSERT(rc == 0); 1585 1586 data_offset += read_len; 1587 data_len -= read_len; 1588 1589 /* 4th read */ 1590 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7, 1591 data_offset, data_len, &mapped_len, &ctx); 1592 CU_ASSERT(rc == 2); 1593 CU_ASSERT(mapped_len == 384); 1594 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[5].iov_base + 3 + 128, 172) == true); 1595 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[6].iov_base, 212) == true); 1596 1597 read_len = ut_readv(data_offset, 384, dif_iovs, 8); 1598 CU_ASSERT(read_len == 384); 1599 1600 rc = spdk_dif_generate_stream(iovs1, 7, data_offset, read_len, &ctx); 1601 CU_ASSERT(rc == 0); 1602 1603 data_offset += read_len; 1604 CU_ASSERT(data_offset == 512 * 4); 1605 data_len -= read_len; 1606 CU_ASSERT(data_len == 0); 1607 1608 /* The second SGL data buffer: 1609 * - Set data pattern with a space for metadata for each block. 1610 */ 1611 _iov_alloc_buf(&iovs2[0], 512 + 8 + 128); 1612 _iov_alloc_buf(&iovs2[1], 128); 1613 _iov_alloc_buf(&iovs2[2], 256 + 8); 1614 _iov_alloc_buf(&iovs2[3], 100); 1615 _iov_alloc_buf(&iovs2[4], 412 + 5); 1616 _iov_alloc_buf(&iovs2[5], 3 + 300); 1617 _iov_alloc_buf(&iovs2[6], 212 + 8); 1618 1619 rc = ut_data_pattern_generate(iovs2, 7, 512 + 8, 8, 4); 1620 CU_ASSERT(rc == 0); 1621 rc = spdk_dif_generate(iovs2, 7, 4, &ctx); 1622 CU_ASSERT(rc == 0); 1623 1624 rc = spdk_dif_verify(iovs1, 7, 4, &ctx, &err_blk); 1625 CU_ASSERT(rc == 0); 1626 1627 rc = spdk_dif_verify(iovs2, 7, 4, &ctx, &err_blk); 1628 CU_ASSERT(rc == 0); 1629 1630 /* Compare the first and the second SGL data buffer by byte. */ 1631 for (i = 0; i < 7; i++) { 1632 rc = memcmp(iovs1[i].iov_base, iovs2[i].iov_base, 1633 iovs1[i].iov_len); 1634 CU_ASSERT(rc == 0); 1635 } 1636 1637 for (i = 0; i < 7; i++) { 1638 _iov_free_buf(&iovs1[i]); 1639 _iov_free_buf(&iovs2[i]); 1640 } 1641 } 1642 1643 static void 1644 dif_generate_stream_test(void) 1645 { 1646 struct iovec iov; 1647 struct spdk_dif_ctx ctx; 1648 struct spdk_dif_error err_blk; 1649 uint32_t dif_flags; 1650 int rc; 1651 1652 _iov_alloc_buf(&iov, (512 + 8) * 5); 1653 1654 rc = ut_data_pattern_generate(&iov, 1, 512 + 8, 8, 5); 1655 CU_ASSERT(rc == 0); 1656 1657 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1658 SPDK_DIF_FLAGS_REFTAG_CHECK; 1659 1660 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, dif_flags, 1661 22, 0xFFFF, 0x22, 0, GUARD_SEED); 1662 CU_ASSERT(rc == 0); 1663 1664 rc = spdk_dif_generate_stream(&iov, 1, 0, 511, &ctx); 1665 CU_ASSERT(rc == 0); 1666 1667 rc = spdk_dif_generate_stream(&iov, 1, 511, 1, &ctx); 1668 CU_ASSERT(rc == 0); 1669 1670 rc = spdk_dif_generate_stream(&iov, 1, 512, 256, &ctx); 1671 CU_ASSERT(rc == 0); 1672 1673 rc = spdk_dif_generate_stream(&iov, 1, 768, 512, &ctx); 1674 CU_ASSERT(rc == 0); 1675 1676 rc = spdk_dif_generate_stream(&iov, 1, 1280, 1024, &ctx); 1677 CU_ASSERT(rc == 0); 1678 1679 rc = spdk_dif_generate_stream(&iov, 1, 2304, 256, &ctx); 1680 CU_ASSERT(rc == 0); 1681 1682 rc = spdk_dif_generate_stream(&iov, 1, 2560, 512, &ctx); 1683 CU_ASSERT(rc == -ERANGE); 1684 1685 rc = spdk_dif_verify(&iov, 1, 5, &ctx, &err_blk); 1686 CU_ASSERT(rc == 0); 1687 1688 rc = ut_data_pattern_verify(&iov, 1, 512 + 8, 8, 5); 1689 CU_ASSERT(rc == 0); 1690 1691 _iov_free_buf(&iov); 1692 } 1693 1694 static void 1695 set_md_interleave_iovs_alignment_test(void) 1696 { 1697 struct iovec iovs[3], dif_iovs[5] = {}; 1698 uint32_t mapped_len = 0; 1699 int rc; 1700 struct spdk_dif_ctx ctx; 1701 1702 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, 1703 0, 0, 0, 0, 0, 0); 1704 CU_ASSERT(rc == 0); 1705 1706 /* The case that buffer size is smaller than necessary. */ 1707 _iov_set_buf(&iovs[0], (uint8_t *)0xDEADBEEF, 1024); 1708 _iov_set_buf(&iovs[1], (uint8_t *)0xFEEDBEEF, 1024); 1709 _iov_set_buf(&iovs[2], (uint8_t *)0xC0FFEE, 24); 1710 1711 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 0, 2048, &mapped_len, &ctx); 1712 CU_ASSERT(rc == -ERANGE); 1713 1714 /* The following are the normal cases. */ 1715 _iov_set_buf(&iovs[2], (uint8_t *)0xC0FFEE, 32); 1716 1717 /* data length is less than a data block size. */ 1718 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 0, 500, &mapped_len, &ctx); 1719 CU_ASSERT(rc == 1); 1720 CU_ASSERT(mapped_len == 500); 1721 CU_ASSERT(_iov_check(&dif_iovs[0], (void *)0xDEADBEEF, 500) == true); 1722 1723 /* Pass enough number of iovecs */ 1724 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 500, 1000, &mapped_len, &ctx); 1725 CU_ASSERT(rc == 4); 1726 CU_ASSERT(mapped_len == 1000); 1727 CU_ASSERT(_iov_check(&dif_iovs[0], (void *)(0xDEADBEEF + 500), 12) == true); 1728 CU_ASSERT(_iov_check(&dif_iovs[1], (void *)(0xDEADBEEF + 520), 504) == true); 1729 CU_ASSERT(_iov_check(&dif_iovs[2], (void *)0xFEEDBEEF, 8) == true); 1730 CU_ASSERT(_iov_check(&dif_iovs[3], (void *)(0xFEEDBEEF + 16), 476) == true); 1731 1732 /* Pass iovecs smaller than necessary */ 1733 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 3, iovs, 3, 500, 1000, &mapped_len, &ctx); 1734 CU_ASSERT(rc == 3); 1735 CU_ASSERT(mapped_len == 524); 1736 CU_ASSERT(_iov_check(&dif_iovs[0], (void *)(0xDEADBEEF + 500), 12) == true); 1737 CU_ASSERT(_iov_check(&dif_iovs[1], (void *)(0xDEADBEEF + 520), 504) == true); 1738 CU_ASSERT(_iov_check(&dif_iovs[2], (void *)0xFEEDBEEF, 8) == true); 1739 1740 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 1500, 500, &mapped_len, &ctx); 1741 CU_ASSERT(rc == 2); 1742 CU_ASSERT(mapped_len == 500); 1743 CU_ASSERT(_iov_check(&dif_iovs[0], (void *)(0xFEEDBEEF + 492), 36) == true); 1744 CU_ASSERT(_iov_check(&dif_iovs[1], (void *)(0xFEEDBEEF + 536), 464) == true); 1745 1746 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 5, iovs, 3, 2000, 48, &mapped_len, &ctx); 1747 CU_ASSERT(rc == 2); 1748 CU_ASSERT(mapped_len == 48); 1749 CU_ASSERT(_iov_check(&dif_iovs[0], (void *)0xFEEDBEEF + 1000, 24) == true); 1750 CU_ASSERT(_iov_check(&dif_iovs[1], (void *)0xC0FFEE, 24) == true); 1751 } 1752 1753 static void 1754 _dif_generate_split_test(void) 1755 { 1756 struct spdk_dif_ctx ctx = {}; 1757 struct iovec iov; 1758 uint8_t *buf1, *buf2; 1759 struct _dif_sgl sgl; 1760 uint16_t guard = 0, prev_guard; 1761 uint32_t dif_flags; 1762 int rc; 1763 1764 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1765 SPDK_DIF_FLAGS_REFTAG_CHECK; 1766 1767 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 1768 dif_flags, 0, 0, 0, 0, GUARD_SEED); 1769 CU_ASSERT(rc == 0); 1770 1771 buf1 = calloc(1, 4096 + 128); 1772 SPDK_CU_ASSERT_FATAL(buf1 != NULL); 1773 _iov_set_buf(&iov, buf1, 4096 + 128); 1774 1775 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1); 1776 CU_ASSERT(rc == 0); 1777 1778 _dif_sgl_init(&sgl, &iov, 1); 1779 1780 guard = GUARD_SEED; 1781 prev_guard = GUARD_SEED; 1782 1783 guard = _dif_generate_split(&sgl, 0, 1000, guard, 0, &ctx); 1784 CU_ASSERT(sgl.iov_offset == 1000); 1785 CU_ASSERT(guard == spdk_crc16_t10dif(prev_guard, buf1, 1000)); 1786 1787 prev_guard = guard; 1788 1789 guard = _dif_generate_split(&sgl, 1000, 3000, guard, 0, &ctx); 1790 CU_ASSERT(sgl.iov_offset == 4000); 1791 CU_ASSERT(guard == spdk_crc16_t10dif(prev_guard, buf1 + 1000, 3000)); 1792 1793 guard = _dif_generate_split(&sgl, 4000, 96 + 128, guard, 0, &ctx); 1794 CU_ASSERT(guard == GUARD_SEED); 1795 CU_ASSERT(sgl.iov_offset == 0); 1796 CU_ASSERT(sgl.iovcnt == 0); 1797 1798 rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 1); 1799 CU_ASSERT(rc == 0); 1800 1801 _dif_sgl_init(&sgl, &iov, 1); 1802 1803 rc = dif_verify(&sgl, 1, &ctx, NULL); 1804 CU_ASSERT(rc == 0); 1805 1806 buf2 = calloc(1, 4096 + 128); 1807 SPDK_CU_ASSERT_FATAL(buf2 != NULL); 1808 _iov_set_buf(&iov, buf2, 4096 + 128); 1809 1810 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1); 1811 CU_ASSERT(rc == 0); 1812 1813 _dif_sgl_init(&sgl, &iov, 1); 1814 1815 dif_generate(&sgl, 1, &ctx); 1816 1817 rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 1); 1818 CU_ASSERT(rc == 0); 1819 1820 _dif_sgl_init(&sgl, &iov, 1); 1821 1822 rc = dif_verify(&sgl, 1, &ctx, NULL); 1823 CU_ASSERT(rc == 0); 1824 1825 rc = memcmp(buf1, buf2, 4096 + 128); 1826 CU_ASSERT(rc == 0); 1827 1828 free(buf1); 1829 free(buf2); 1830 } 1831 1832 static void 1833 set_md_interleave_iovs_multi_segments_test(void) 1834 { 1835 struct spdk_dif_ctx ctx = {}; 1836 struct spdk_dif_error err_blk = {}; 1837 struct iovec iov1 = {}, iov2 = {}, dif_iovs[4] = {}; 1838 uint32_t dif_check_flags, data_len, read_len, data_offset, read_offset, mapped_len = 0; 1839 uint8_t *buf1, *buf2; 1840 int rc; 1841 1842 dif_check_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1843 SPDK_DIF_FLAGS_REFTAG_CHECK; 1844 1845 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 1846 dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED); 1847 CU_ASSERT(rc == 0); 1848 1849 /* The first data buffer: 1850 * - Data buffer is split into multi data segments 1851 * - For each data segment, 1852 * - Create iovec array to Leave a space for metadata for each block 1853 * - Split vectored read and so creating iovec array is done before every vectored read. 1854 */ 1855 buf1 = calloc(1, (4096 + 128) * 4); 1856 SPDK_CU_ASSERT_FATAL(buf1 != NULL); 1857 _iov_set_buf(&iov1, buf1, (4096 + 128) * 4); 1858 1859 /* 1st data segment */ 1860 data_offset = 0; 1861 data_len = 1024; 1862 1863 spdk_dif_ctx_set_data_offset(&ctx, data_offset); 1864 1865 read_offset = 0; 1866 1867 /* 1st read in 1st data segment */ 1868 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 1869 read_offset, data_len - read_offset, 1870 &mapped_len, &ctx); 1871 CU_ASSERT(rc == 1); 1872 CU_ASSERT(mapped_len == 1024); 1873 CU_ASSERT(_iov_check(&dif_iovs[0], buf1, 1024) == true); 1874 1875 read_len = ut_readv(data_offset + read_offset, 1024, dif_iovs, 4); 1876 CU_ASSERT(read_len == 1024); 1877 1878 rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx); 1879 CU_ASSERT(rc == 0); 1880 1881 read_offset += read_len; 1882 CU_ASSERT(read_offset == data_len); 1883 1884 /* 2nd data segment */ 1885 data_offset += data_len; 1886 data_len = 3072 + 4096 * 2 + 512; 1887 1888 spdk_dif_ctx_set_data_offset(&ctx, data_offset); 1889 _iov_set_buf(&iov1, buf1 + 1024, 3072 + 128 + (4096 + 128) * 3 + 512); 1890 1891 read_offset = 0; 1892 1893 /* 1st read in 2nd data segment */ 1894 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 1895 read_offset, data_len - read_offset, 1896 &mapped_len, &ctx); 1897 CU_ASSERT(rc == 4); 1898 CU_ASSERT(mapped_len == 3072 + 4096 * 2 + 512); 1899 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 1024, 3072) == true); 1900 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true); 1901 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true); 1902 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 512) == true); 1903 1904 read_len = ut_readv(data_offset + read_offset, 3071, dif_iovs, 4); 1905 CU_ASSERT(read_len == 3071); 1906 1907 rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx); 1908 CU_ASSERT(rc == 0); 1909 1910 read_offset += read_len; 1911 1912 /* 2nd read in 2nd data segment */ 1913 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 1914 read_offset, data_len - read_offset, 1915 &mapped_len, &ctx); 1916 CU_ASSERT(rc == 4); 1917 CU_ASSERT(mapped_len == 1 + 4096 * 2 + 512); 1918 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 4095, 1) == true); 1919 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true); 1920 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true); 1921 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 512) == true); 1922 1923 read_len = ut_readv(data_offset + read_offset, 1 + 4096 * 2 + 512, dif_iovs, 4); 1924 CU_ASSERT(read_len == 1 + 4096 * 2 + 512); 1925 1926 rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx); 1927 CU_ASSERT(rc == 0); 1928 1929 read_offset += read_len; 1930 CU_ASSERT(read_offset == data_len); 1931 1932 /* 3rd data segment */ 1933 data_offset += data_len; 1934 data_len = 3584; 1935 1936 spdk_dif_ctx_set_data_offset(&ctx, data_offset); 1937 _iov_set_buf(&iov1, buf1 + (4096 + 128) * 3 + 512, 3584 + 128); 1938 1939 read_offset = 0; 1940 1941 /* 1st read in 3rd data segment */ 1942 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 1943 read_offset, data_len - read_offset, 1944 &mapped_len, &ctx); 1945 CU_ASSERT(rc == 1); 1946 CU_ASSERT(mapped_len == 3584); 1947 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + (4096 + 128) * 3 + 512, 3584) == true); 1948 1949 read_len = ut_readv(data_offset + read_offset, 3584, dif_iovs, 1); 1950 CU_ASSERT(read_len == 3584); 1951 1952 rc = spdk_dif_generate_stream(&iov1, 1, read_offset, read_len, &ctx); 1953 CU_ASSERT(rc == 0); 1954 1955 read_offset += read_len; 1956 CU_ASSERT(read_offset == data_len); 1957 data_offset += data_len; 1958 CU_ASSERT(data_offset == 4096 * 4); 1959 1960 spdk_dif_ctx_set_data_offset(&ctx, 0); 1961 _iov_set_buf(&iov1, buf1, (4096 + 128) * 4); 1962 1963 /* The second data buffer: 1964 * - Set data pattern with a space for metadata for each block. 1965 */ 1966 buf2 = calloc(1, (4096 + 128) * 4); 1967 SPDK_CU_ASSERT_FATAL(buf2 != NULL); 1968 _iov_set_buf(&iov2, buf2, (4096 + 128) * 4); 1969 1970 rc = ut_data_pattern_generate(&iov2, 1, 4096 + 128, 128, 4); 1971 CU_ASSERT(rc == 0); 1972 1973 rc = spdk_dif_generate(&iov2, 1, 4, &ctx); 1974 CU_ASSERT(rc == 0); 1975 1976 rc = spdk_dif_verify(&iov1, 1, 4, &ctx, &err_blk); 1977 CU_ASSERT(rc == 0); 1978 1979 rc = spdk_dif_verify(&iov2, 1, 4, &ctx, &err_blk); 1980 CU_ASSERT(rc == 0); 1981 1982 /* Compare the first and the second data buffer by byte. */ 1983 rc = memcmp(buf1, buf2, (4096 + 128) * 4); 1984 CU_ASSERT(rc == 0); 1985 1986 free(buf1); 1987 free(buf2); 1988 } 1989 1990 static void 1991 _dif_verify_split_test(void) 1992 { 1993 struct spdk_dif_ctx ctx = {}; 1994 struct spdk_dif_error err_blk = {}; 1995 struct iovec iov; 1996 uint8_t *buf; 1997 struct _dif_sgl sgl; 1998 uint16_t guard = 0, prev_guard = 0; 1999 uint32_t dif_flags; 2000 int rc; 2001 2002 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2003 SPDK_DIF_FLAGS_REFTAG_CHECK; 2004 2005 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 2006 dif_flags, 0, 0, 0, 0, GUARD_SEED); 2007 CU_ASSERT(rc == 0); 2008 2009 buf = calloc(1, 4096 + 128); 2010 SPDK_CU_ASSERT_FATAL(buf != NULL); 2011 _iov_set_buf(&iov, buf, 4096 + 128); 2012 2013 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1); 2014 CU_ASSERT(rc == 0); 2015 2016 _dif_sgl_init(&sgl, &iov, 1); 2017 2018 dif_generate(&sgl, 1, &ctx); 2019 2020 _dif_sgl_init(&sgl, &iov, 1); 2021 2022 guard = GUARD_SEED; 2023 prev_guard = GUARD_SEED; 2024 2025 rc = _dif_verify_split(&sgl, 0, 1000, &guard, 0, &ctx, &err_blk); 2026 CU_ASSERT(rc == 0); 2027 CU_ASSERT(guard == spdk_crc16_t10dif(prev_guard, buf, 1000)); 2028 CU_ASSERT(sgl.iov_offset == 1000); 2029 2030 prev_guard = guard; 2031 2032 rc = _dif_verify_split(&sgl, 1000, 3000, &guard, 0, &ctx, &err_blk); 2033 CU_ASSERT(rc == 0); 2034 CU_ASSERT(guard == spdk_crc16_t10dif(prev_guard, buf + 1000, 3000)); 2035 CU_ASSERT(sgl.iov_offset == 4000); 2036 2037 rc = _dif_verify_split(&sgl, 4000, 96 + 128, &guard, 0, &ctx, &err_blk); 2038 CU_ASSERT(rc == 0); 2039 CU_ASSERT(guard == GUARD_SEED); 2040 CU_ASSERT(sgl.iov_offset == 0); 2041 CU_ASSERT(sgl.iovcnt == 0); 2042 2043 _dif_sgl_init(&sgl, &iov, 1); 2044 2045 rc = dif_verify(&sgl, 1, &ctx, &err_blk); 2046 CU_ASSERT(rc == 0); 2047 2048 rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 1); 2049 CU_ASSERT(rc == 0); 2050 2051 free(buf); 2052 } 2053 2054 static void 2055 dif_verify_stream_multi_segments_test(void) 2056 { 2057 struct spdk_dif_ctx ctx = {}; 2058 struct spdk_dif_error err_blk = {}; 2059 struct iovec iov = {}; 2060 uint8_t *buf; 2061 uint32_t dif_flags; 2062 int rc; 2063 2064 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2065 SPDK_DIF_FLAGS_REFTAG_CHECK; 2066 2067 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 2068 dif_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED); 2069 CU_ASSERT(rc == 0); 2070 2071 buf = calloc(1, (4096 + 128) * 4); 2072 SPDK_CU_ASSERT_FATAL(buf != NULL); 2073 _iov_set_buf(&iov, buf, (4096 + 128) * 4); 2074 2075 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 4); 2076 CU_ASSERT(rc == 0); 2077 2078 rc = spdk_dif_generate(&iov, 1, 4, &ctx); 2079 CU_ASSERT(rc == 0); 2080 2081 /* 1st data segment */ 2082 _iov_set_buf(&iov, buf, 1024); 2083 spdk_dif_ctx_set_data_offset(&ctx, 0); 2084 2085 rc = spdk_dif_verify_stream(&iov, 1, 0, 1024, &ctx, &err_blk); 2086 CU_ASSERT(rc == 0); 2087 2088 /* 2nd data segment */ 2089 _iov_set_buf(&iov, buf + 1024, (3072 + 128) + (4096 + 128) * 2 + 512); 2090 spdk_dif_ctx_set_data_offset(&ctx, 1024); 2091 2092 rc = spdk_dif_verify_stream(&iov, 1, 0, 3072 + 4096 * 2 + 512, &ctx, &err_blk); 2093 CU_ASSERT(rc == 0); 2094 2095 /* 3rd data segment */ 2096 _iov_set_buf(&iov, buf + (4096 + 128) * 3 + 512, 3584 + 128); 2097 spdk_dif_ctx_set_data_offset(&ctx, 4096 * 3); 2098 2099 rc = spdk_dif_verify_stream(&iov, 1, 0, 3584, &ctx, &err_blk); 2100 CU_ASSERT(rc == 0); 2101 2102 /* verify all data segments once */ 2103 _iov_set_buf(&iov, buf, (4096 + 128) * 4); 2104 spdk_dif_ctx_set_data_offset(&ctx, 0); 2105 2106 rc = spdk_dif_verify(&iov, 1, 4, &ctx, &err_blk); 2107 CU_ASSERT(rc == 0); 2108 2109 rc = ut_data_pattern_verify(&iov, 1, 4096 + 128, 128, 4); 2110 CU_ASSERT(rc == 0); 2111 2112 free(buf); 2113 } 2114 2115 #define UT_CRC32C_XOR 0xffffffffUL 2116 2117 static void 2118 update_crc32c_test(void) 2119 { 2120 struct spdk_dif_ctx ctx = {}; 2121 struct iovec iovs[7]; 2122 uint32_t crc32c1, crc32c2, crc32c3, crc32c4; 2123 uint32_t dif_flags; 2124 int i, rc; 2125 2126 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2127 SPDK_DIF_FLAGS_REFTAG_CHECK; 2128 2129 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, 2130 dif_flags, 0, 0, 0, 0, 0); 2131 CU_ASSERT(rc == 0); 2132 2133 /* data[0][255:0] */ 2134 _iov_alloc_buf(&iovs[0], 256); 2135 2136 /* data[0][511:256], md[0][0] */ 2137 _iov_alloc_buf(&iovs[1], 256 + 1); 2138 2139 /* md[0][4:1] */ 2140 _iov_alloc_buf(&iovs[2], 4); 2141 2142 /* md[0][7:5], data[1][122:0] */ 2143 _iov_alloc_buf(&iovs[3], 3 + 123); 2144 2145 /* data[1][511:123], md[1][5:0] */ 2146 _iov_alloc_buf(&iovs[4], 389 + 6); 2147 2148 /* md[1][7:6], data[2][511:0], md[2][7:0], data[3][431:0] */ 2149 _iov_alloc_buf(&iovs[5], 2 + 512 + 8 + 432); 2150 2151 /* data[3][511:432], md[3][7:0] */ 2152 _iov_alloc_buf(&iovs[6], 80 + 8); 2153 2154 rc = ut_data_pattern_generate(iovs, 7, 512 + 8, 8, 4); 2155 CU_ASSERT(rc == 0); 2156 2157 crc32c1 = UT_CRC32C_XOR; 2158 2159 rc = spdk_dif_update_crc32c(iovs, 7, 4, &crc32c1, &ctx); 2160 CU_ASSERT(rc == 0); 2161 2162 /* Test if DIF doesn't affect CRC for split case. */ 2163 rc = spdk_dif_generate(iovs, 7, 4, &ctx); 2164 CU_ASSERT(rc == 0); 2165 2166 crc32c2 = UT_CRC32C_XOR; 2167 2168 rc = spdk_dif_update_crc32c(iovs, 7, 4, &crc32c2, &ctx); 2169 CU_ASSERT(rc == 0); 2170 2171 CU_ASSERT(crc32c1 == crc32c2); 2172 2173 for (i = 0; i < 7; i++) { 2174 _iov_free_buf(&iovs[i]); 2175 } 2176 2177 /* Test if CRC is same regardless of splitting. */ 2178 for (i = 0; i < 4; i++) { 2179 _iov_alloc_buf(&iovs[i], 512 + 8); 2180 } 2181 2182 rc = ut_data_pattern_generate(iovs, 4, 512 + 8, 8, 4); 2183 CU_ASSERT(rc == 0); 2184 2185 crc32c3 = UT_CRC32C_XOR; 2186 2187 rc = spdk_dif_update_crc32c(iovs, 4, 4, &crc32c3, &ctx); 2188 CU_ASSERT(rc == 0); 2189 2190 CU_ASSERT(crc32c1 == crc32c3); 2191 2192 /* Test if DIF doesn't affect CRC for non-split case. */ 2193 rc = spdk_dif_generate(iovs, 4, 4, &ctx); 2194 CU_ASSERT(rc == 0); 2195 2196 crc32c4 = UT_CRC32C_XOR; 2197 2198 rc = spdk_dif_update_crc32c(iovs, 4, 4, &crc32c4, &ctx); 2199 CU_ASSERT(rc == 0); 2200 2201 CU_ASSERT(crc32c1 == crc32c4); 2202 2203 for (i = 0; i < 4; i++) { 2204 _iov_free_buf(&iovs[i]); 2205 } 2206 } 2207 2208 static void 2209 _dif_update_crc32c_split_test(void) 2210 { 2211 struct spdk_dif_ctx ctx = {}; 2212 struct iovec iov; 2213 uint8_t *buf; 2214 struct _dif_sgl sgl; 2215 uint32_t dif_flags, crc32c, prev_crc32c; 2216 int rc; 2217 2218 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2219 SPDK_DIF_FLAGS_REFTAG_CHECK; 2220 2221 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 2222 dif_flags, 0, 0, 0, 0, GUARD_SEED); 2223 CU_ASSERT(rc == 0); 2224 2225 buf = calloc(1, 4096 + 128); 2226 SPDK_CU_ASSERT_FATAL(buf != NULL); 2227 _iov_set_buf(&iov, buf, 4096 + 128); 2228 2229 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 1); 2230 CU_ASSERT(rc == 0); 2231 2232 _dif_sgl_init(&sgl, &iov, 1); 2233 2234 dif_generate(&sgl, 1, &ctx); 2235 2236 _dif_sgl_init(&sgl, &iov, 1); 2237 2238 crc32c = _dif_update_crc32c_split(&sgl, 0, 1000, UT_CRC32C_XOR, &ctx); 2239 CU_ASSERT(crc32c == spdk_crc32c_update(buf, 1000, UT_CRC32C_XOR)); 2240 2241 prev_crc32c = crc32c; 2242 2243 crc32c = _dif_update_crc32c_split(&sgl, 1000, 3000, prev_crc32c, &ctx); 2244 CU_ASSERT(crc32c == spdk_crc32c_update(buf + 1000, 3000, prev_crc32c)); 2245 2246 prev_crc32c = crc32c; 2247 2248 crc32c = _dif_update_crc32c_split(&sgl, 4000, 96 + 128, prev_crc32c, &ctx); 2249 CU_ASSERT(crc32c == spdk_crc32c_update(buf + 4000, 96, prev_crc32c)); 2250 2251 CU_ASSERT(crc32c == spdk_crc32c_update(buf, 4096, UT_CRC32C_XOR)); 2252 2253 free(buf); 2254 } 2255 2256 static void 2257 dif_update_crc32c_stream_multi_segments_test(void) 2258 { 2259 struct spdk_dif_ctx ctx = {}; 2260 struct iovec iov = {}; 2261 uint8_t *buf; 2262 uint32_t dif_flags, crc32c1, crc32c2; 2263 int rc; 2264 2265 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2266 SPDK_DIF_FLAGS_REFTAG_CHECK; 2267 2268 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 2269 dif_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED); 2270 CU_ASSERT(rc == 0); 2271 2272 buf = calloc(1, (4096 + 128) * 4); 2273 SPDK_CU_ASSERT_FATAL(buf != NULL); 2274 _iov_set_buf(&iov, buf, (4096 + 128) * 4); 2275 2276 rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 4); 2277 CU_ASSERT(rc == 0); 2278 2279 rc = spdk_dif_generate(&iov, 1, 4, &ctx); 2280 CU_ASSERT(rc == 0); 2281 2282 crc32c1 = UT_CRC32C_XOR; 2283 crc32c2 = UT_CRC32C_XOR; 2284 2285 /* 1st data segment */ 2286 _iov_set_buf(&iov, buf, 1024); 2287 spdk_dif_ctx_set_data_offset(&ctx, 0); 2288 2289 rc = spdk_dif_update_crc32c_stream(&iov, 1, 0, 1024, &crc32c1, &ctx); 2290 CU_ASSERT(rc == 0); 2291 2292 /* 2nd data segment */ 2293 _iov_set_buf(&iov, buf + 1024, (3072 + 128) + (4096 + 128) * 2 + 512); 2294 spdk_dif_ctx_set_data_offset(&ctx, 1024); 2295 2296 rc = spdk_dif_update_crc32c_stream(&iov, 1, 0, 3072 + 4096 * 2 + 512, &crc32c1, &ctx); 2297 CU_ASSERT(rc == 0); 2298 2299 /* 3rd data segment */ 2300 _iov_set_buf(&iov, buf + (4096 + 128) * 3 + 512, 3584 + 128); 2301 spdk_dif_ctx_set_data_offset(&ctx, 4096 * 3); 2302 2303 rc = spdk_dif_update_crc32c_stream(&iov, 1, 0, 3584, &crc32c1, &ctx); 2304 CU_ASSERT(rc == 0); 2305 2306 /* Update CRC32C for all data segments once */ 2307 _iov_set_buf(&iov, buf, (4096 + 128) * 4); 2308 spdk_dif_ctx_set_data_offset(&ctx, 0); 2309 2310 rc = spdk_dif_update_crc32c(&iov, 1, 4, &crc32c2, &ctx); 2311 CU_ASSERT(rc == 0); 2312 2313 CU_ASSERT(crc32c1 == crc32c2); 2314 2315 free(buf); 2316 } 2317 2318 static void 2319 get_range_with_md_test(void) 2320 { 2321 struct spdk_dif_ctx ctx = {}; 2322 uint32_t buf_offset, buf_len; 2323 int rc; 2324 2325 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, 0, 0, 0, 0, 0, 0, 0); 2326 CU_ASSERT(rc == 0); 2327 2328 spdk_dif_get_range_with_md(0, 2048, &buf_offset, &buf_len, &ctx); 2329 CU_ASSERT(buf_offset == 0); 2330 CU_ASSERT(buf_len == 2048); 2331 2332 spdk_dif_get_range_with_md(2048, 4096, &buf_offset, &buf_len, &ctx); 2333 CU_ASSERT(buf_offset == 2048); 2334 CU_ASSERT(buf_len == 4096 + 128); 2335 2336 spdk_dif_get_range_with_md(4096, 10240, &buf_offset, &buf_len, &ctx); 2337 CU_ASSERT(buf_offset == 4096 + 128); 2338 CU_ASSERT(buf_len == 10240 + 256); 2339 2340 spdk_dif_get_range_with_md(10240, 2048, &buf_offset, &buf_len, &ctx); 2341 CU_ASSERT(buf_offset == 10240 + 256); 2342 CU_ASSERT(buf_len == 2048 + 128); 2343 2344 buf_len = spdk_dif_get_length_with_md(6144, &ctx); 2345 CU_ASSERT(buf_len == 6144 + 128); 2346 } 2347 2348 static void 2349 dif_generate_remap_and_verify(struct iovec *iovs, int iovcnt, 2350 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 2351 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, 2352 uint32_t init_ref_tag, uint32_t remapped_init_ref_tag, 2353 uint16_t apptag_mask, uint16_t app_tag) 2354 { 2355 struct spdk_dif_ctx ctx = {}; 2356 int rc; 2357 2358 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks); 2359 CU_ASSERT(rc == 0); 2360 2361 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags, 2362 init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED); 2363 CU_ASSERT(rc == 0); 2364 2365 rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx); 2366 CU_ASSERT(rc == 0); 2367 2368 spdk_dif_ctx_set_remapped_init_ref_tag(&ctx, remapped_init_ref_tag); 2369 2370 rc = spdk_dif_remap_ref_tag(iovs, iovcnt, num_blocks, &ctx, NULL); 2371 CU_ASSERT(rc == 0); 2372 2373 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags, 2374 remapped_init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED); 2375 CU_ASSERT(rc == 0); 2376 2377 rc = spdk_dif_verify(iovs, iovcnt, num_blocks, &ctx, NULL); 2378 CU_ASSERT(rc == 0); 2379 2380 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, md_size, num_blocks); 2381 CU_ASSERT(rc == 0); 2382 } 2383 2384 static void 2385 dif_sec_4096_md_128_prchk_7_multi_iovs_remap_test(void) 2386 { 2387 struct iovec iovs[4]; 2388 int i, num_blocks; 2389 uint32_t dif_flags; 2390 2391 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2392 SPDK_DIF_FLAGS_REFTAG_CHECK; 2393 2394 num_blocks = 0; 2395 2396 for (i = 0; i < 4; i++) { 2397 _iov_alloc_buf(&iovs[i], (512 + 8) * (i + 1)); 2398 num_blocks += i + 1; 2399 } 2400 2401 dif_generate_remap_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1, 2402 dif_flags, 22, 99, 0xFFFF, 0x22); 2403 2404 dif_generate_remap_and_verify(iovs, 4, 512 + 8, 8, num_blocks, true, SPDK_DIF_TYPE1, 2405 dif_flags, 22, 99, 0xFFFF, 0x22); 2406 2407 for (i = 0; i < 4; i++) { 2408 _iov_free_buf(&iovs[i]); 2409 } 2410 } 2411 2412 static void 2413 dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_remap_test(void) 2414 { 2415 struct iovec iovs[11]; 2416 uint32_t dif_flags; 2417 int i; 2418 2419 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2420 SPDK_DIF_FLAGS_REFTAG_CHECK; 2421 2422 /* data[0][1000:0] */ 2423 _iov_alloc_buf(&iovs[0], 1000); 2424 2425 /* data[0][3095:1000], guard[0][0] */ 2426 _iov_alloc_buf(&iovs[1], 3096 + 1); 2427 2428 /* guard[0][1], apptag[0][0] */ 2429 _iov_alloc_buf(&iovs[2], 1 + 1); 2430 2431 /* apptag[0][1], reftag[0][0] */ 2432 _iov_alloc_buf(&iovs[3], 1 + 1); 2433 2434 /* reftag[0][3:1], ignore[0][59:0] */ 2435 _iov_alloc_buf(&iovs[4], 3 + 60); 2436 2437 /* ignore[119:60], data[1][3050:0] */ 2438 _iov_alloc_buf(&iovs[5], 60 + 3051); 2439 2440 /* data[1][4095:3050], guard[1][0] */ 2441 _iov_alloc_buf(&iovs[6], 1045 + 1); 2442 2443 /* guard[1][1], apptag[1][0] */ 2444 _iov_alloc_buf(&iovs[7], 1 + 1); 2445 2446 /* apptag[1][1], reftag[1][0] */ 2447 _iov_alloc_buf(&iovs[8], 1 + 1); 2448 2449 /* reftag[1][3:1], ignore[1][9:0] */ 2450 _iov_alloc_buf(&iovs[9], 3 + 10); 2451 2452 /* ignore[1][127:9] */ 2453 _iov_alloc_buf(&iovs[10], 118); 2454 2455 dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, false, SPDK_DIF_TYPE1, dif_flags, 2456 22, 99, 0xFFFF, 0x22); 2457 dif_generate_remap_and_verify(iovs, 11, 4096 + 128, 128, 2, true, SPDK_DIF_TYPE1, dif_flags, 2458 22, 99, 0xFFFF, 0x22); 2459 2460 for (i = 0; i < 11; i++) { 2461 _iov_free_buf(&iovs[i]); 2462 } 2463 } 2464 2465 static void 2466 dix_generate_remap_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, 2467 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 2468 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, 2469 uint32_t init_ref_tag, uint32_t remapped_init_ref_tag, 2470 uint16_t apptag_mask, uint16_t app_tag) 2471 { 2472 struct spdk_dif_ctx ctx; 2473 int rc; 2474 2475 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, 0, num_blocks); 2476 CU_ASSERT(rc == 0); 2477 2478 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags, 2479 init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED); 2480 CU_ASSERT(rc == 0); 2481 2482 rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx); 2483 CU_ASSERT(rc == 0); 2484 2485 spdk_dif_ctx_set_remapped_init_ref_tag(&ctx, remapped_init_ref_tag); 2486 2487 rc = spdk_dix_remap_ref_tag(md_iov, num_blocks, &ctx, NULL); 2488 CU_ASSERT(rc == 0); 2489 2490 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags, 2491 remapped_init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED); 2492 CU_ASSERT(rc == 0); 2493 2494 rc = spdk_dix_verify(iovs, iovcnt, md_iov, num_blocks, &ctx, NULL); 2495 CU_ASSERT(rc == 0); 2496 2497 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, 0, num_blocks); 2498 CU_ASSERT(rc == 0); 2499 } 2500 2501 static void 2502 dix_sec_4096_md_128_prchk_7_multi_iovs_remap(void) 2503 { 2504 struct iovec iovs[4], md_iov; 2505 uint32_t dif_flags; 2506 int i, num_blocks; 2507 2508 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2509 SPDK_DIF_FLAGS_REFTAG_CHECK; 2510 2511 num_blocks = 0; 2512 2513 for (i = 0; i < 4; i++) { 2514 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 2515 num_blocks += i + 1; 2516 } 2517 _iov_alloc_buf(&md_iov, 128 * num_blocks); 2518 2519 dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1, 2520 dif_flags, 22, 99, 0xFFFF, 0x22); 2521 dix_generate_remap_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1, 2522 dif_flags, 22, 99, 0xFFFF, 0x22); 2523 2524 for (i = 0; i < 4; i++) { 2525 _iov_free_buf(&iovs[i]); 2526 } 2527 _iov_free_buf(&md_iov); 2528 } 2529 2530 static void 2531 dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits_remap(void) 2532 { 2533 struct iovec iovs[6], md_iov; 2534 uint32_t dif_flags; 2535 int i; 2536 2537 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 2538 SPDK_DIF_FLAGS_REFTAG_CHECK; 2539 2540 /* data[0][255:0] */ 2541 _iov_alloc_buf(&iovs[0], 256); 2542 2543 /* data[0][511:256], data[1][255:0] */ 2544 _iov_alloc_buf(&iovs[1], 256 + 256); 2545 2546 /* data[1][382:256] */ 2547 _iov_alloc_buf(&iovs[2], 128); 2548 2549 /* data[1][383] */ 2550 _iov_alloc_buf(&iovs[3], 1); 2551 2552 /* data[1][510:384] */ 2553 _iov_alloc_buf(&iovs[4], 126); 2554 2555 /* data[1][511], data[2][511:0], data[3][511:0] */ 2556 _iov_alloc_buf(&iovs[5], 1 + 512 * 2); 2557 2558 _iov_alloc_buf(&md_iov, 8 * 4); 2559 2560 dix_generate_remap_and_verify(iovs, 6, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1, 2561 dif_flags, 22, 99, 0xFFFF, 0x22); 2562 2563 for (i = 0; i < 6; i++) { 2564 _iov_free_buf(&iovs[i]); 2565 } 2566 _iov_free_buf(&md_iov); 2567 } 2568 2569 int 2570 main(int argc, char **argv) 2571 { 2572 CU_pSuite suite = NULL; 2573 unsigned int num_failures; 2574 2575 CU_set_error_action(CUEA_ABORT); 2576 CU_initialize_registry(); 2577 2578 suite = CU_add_suite("dif", NULL, NULL); 2579 2580 CU_ADD_TEST(suite, dif_generate_and_verify_test); 2581 CU_ADD_TEST(suite, dif_disable_check_test); 2582 CU_ADD_TEST(suite, dif_sec_512_md_0_error_test); 2583 CU_ADD_TEST(suite, dif_guard_seed_test); 2584 CU_ADD_TEST(suite, dif_disable_sec_512_md_8_single_iov_test); 2585 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_0_single_iov_test); 2586 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_0_1_2_4_multi_iovs_test); 2587 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_test); 2588 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_data_and_md_test); 2589 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_data_test); 2590 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_guard_test); 2591 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_apptag_test); 2592 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_split_reftag_test); 2593 CU_ADD_TEST(suite, dif_sec_512_md_8_prchk_7_multi_iovs_complex_splits_test); 2594 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test); 2595 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test); 2596 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_and_md_test); 2597 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_test); 2598 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_guard_test); 2599 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_apptag_test); 2600 CU_ADD_TEST(suite, dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_test); 2601 CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_0_single_iov); 2602 CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_0_1_2_4_multi_iovs); 2603 CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_prchk_7_multi_iovs); 2604 CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_7_multi_iovs_split_data); 2605 CU_ADD_TEST(suite, dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits); 2606 CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test); 2607 CU_ADD_TEST(suite, dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test); 2608 CU_ADD_TEST(suite, dix_sec_512_md_0_error); 2609 CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_0_single_iov); 2610 CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_0_1_2_4_multi_iovs); 2611 CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs); 2612 CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_7_multi_iovs_split_data); 2613 CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits); 2614 CU_ADD_TEST(suite, dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test); 2615 CU_ADD_TEST(suite, dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test); 2616 CU_ADD_TEST(suite, set_md_interleave_iovs_test); 2617 CU_ADD_TEST(suite, set_md_interleave_iovs_split_test); 2618 CU_ADD_TEST(suite, dif_generate_stream_test); 2619 CU_ADD_TEST(suite, set_md_interleave_iovs_alignment_test); 2620 CU_ADD_TEST(suite, _dif_generate_split_test); 2621 CU_ADD_TEST(suite, set_md_interleave_iovs_multi_segments_test); 2622 CU_ADD_TEST(suite, _dif_verify_split_test); 2623 CU_ADD_TEST(suite, dif_verify_stream_multi_segments_test); 2624 CU_ADD_TEST(suite, update_crc32c_test); 2625 CU_ADD_TEST(suite, _dif_update_crc32c_split_test); 2626 CU_ADD_TEST(suite, dif_update_crc32c_stream_multi_segments_test); 2627 CU_ADD_TEST(suite, get_range_with_md_test); 2628 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_remap_test); 2629 CU_ADD_TEST(suite, dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_remap_test); 2630 CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs_remap); 2631 CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits_remap); 2632 2633 CU_basic_set_mode(CU_BRM_VERBOSE); 2634 2635 CU_basic_run_tests(); 2636 2637 num_failures = CU_get_number_of_failures(); 2638 CU_cleanup_registry(); 2639 2640 return num_failures; 2641 } 2642