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