[Accel-config] [PATCH v1 7/9] accel-config/test: add 4 dif operations support
Tony Zhu <tony.zhu at intel.com> Fri, 11 Feb 2022 21:16:31 +0800
| Newsgroups | dev.linux.lists.accel-config |
|---|---|
| Message-ID | <[email protected]> |
Add Data Integrity Field (DIF) check, insert, strip, and update while transferring data.
Signed-off-by: Tony Zhu <tony.zhu(a)intel.com>
---
test/dsa.c | 473 ++++++++++++++++++++++++++++++++++++++++++++++++
test/dsa.h | 17 ++
test/dsa_test.c | 104 +++++++++++
test/prep.c | 189 +++++++++++++++++++
4 files changed, 783 insertions(+)
diff --git a/test/dsa.c b/test/dsa.c
index 5e617a9..eead318 100644
--- a/test/dsa.c
+++ b/test/dsa.c
@@ -1445,6 +1445,158 @@ int dsa_crc_copy_multi_task_nodes(struct dsa_context *ctx)
return ret;
}
+int dsa_dif_check_multi_task_nodes(struct dsa_context *ctx)
+{
+ struct task_node *tsk_node = ctx->multi_task_node;
+ int ret = DSA_STATUS_OK;
+
+ while (tsk_node) {
+ tsk_node->tsk->dflags = IDXD_OP_FLAG_CRAV | IDXD_OP_FLAG_RCR;
+ if ((tsk_node->tsk->test_flags & TEST_FLAGS_BOF) && ctx->bof)
+ tsk_node->tsk->dflags |= IDXD_OP_FLAG_BOF;
+
+ dsa_prep_dif_check(tsk_node->tsk);
+ tsk_node = tsk_node->next;
+ }
+
+ tsk_node = ctx->multi_task_node;
+ while (tsk_node) {
+ dsa_desc_submit(ctx, tsk_node->tsk->desc);
+ tsk_node = tsk_node->next;
+ }
+
+ info("Submitted all dif check jobs\n");
+ tsk_node = ctx->multi_task_node;
+ while (tsk_node) {
+ ret = dsa_wait_dif(ctx, tsk_node->tsk);
+ if (ret != DSA_STATUS_OK)
+ info("Desc: %p failed with ret: %d\n", tsk_node->tsk->desc,
+ tsk_node->tsk->comp->status);
+ tsk_node = tsk_node->next;
+ }
+ return ret;
+}
+
+int dsa_dif_ins_multi_task_nodes(struct dsa_context *ctx)
+{
+ struct task_node *tsk_node = ctx->multi_task_node;
+ int ret = DSA_STATUS_OK;
+
+ while (tsk_node) {
+ tsk_node->tsk->dflags = IDXD_OP_FLAG_CRAV | IDXD_OP_FLAG_RCR;
+ if ((tsk_node->tsk->test_flags & TEST_FLAGS_BOF) && ctx->bof)
+ tsk_node->tsk->dflags |= IDXD_OP_FLAG_BOF;
+
+ dsa_prep_dif_insert(tsk_node->tsk);
+ tsk_node = tsk_node->next;
+ }
+
+ tsk_node = ctx->multi_task_node;
+ while (tsk_node) {
+ dsa_desc_submit(ctx, tsk_node->tsk->desc);
+ tsk_node = tsk_node->next;
+ }
+ tsk_node = ctx->multi_task_node;
+ info("Submitted all dif insert jobs\n");
+ while (tsk_node) {
+ ret = dsa_wait_dif(ctx, tsk_node->tsk);
+ if (ret != DSA_STATUS_OK)
+ info("Desc: %p failed with ret: %d\n", tsk_node->tsk->desc,
+ tsk_node->tsk->comp->status);
+ tsk_node = tsk_node->next;
+ }
+ return ret;
+}
+
+int dsa_dif_strp_multi_task_nodes(struct dsa_context *ctx)
+{
+ struct task_node *tsk_node = ctx->multi_task_node;
+ int ret = DSA_STATUS_OK;
+
+ while (tsk_node) {
+ tsk_node->tsk->dflags = IDXD_OP_FLAG_CRAV | IDXD_OP_FLAG_RCR;
+ if ((tsk_node->tsk->test_flags & TEST_FLAGS_BOF) && ctx->bof)
+ tsk_node->tsk->dflags |= IDXD_OP_FLAG_BOF;
+
+ dsa_prep_dif_strip(tsk_node->tsk);
+ tsk_node = tsk_node->next;
+ }
+
+ tsk_node = ctx->multi_task_node;
+ while (tsk_node) {
+ dsa_desc_submit(ctx, tsk_node->tsk->desc);
+ tsk_node = tsk_node->next;
+ }
+
+ info("Submitted all dif strp jobs\n");
+ tsk_node = ctx->multi_task_node;
+ while (tsk_node) {
+ ret = dsa_wait_dif(ctx, tsk_node->tsk);
+ if (ret != DSA_STATUS_OK)
+ info("Desc: %p failed with ret: %d\n", tsk_node->tsk->desc,
+ tsk_node->tsk->comp->status);
+ tsk_node = tsk_node->next;
+ }
+
+ return ret;
+}
+
+int dsa_dif_updt_multi_task_nodes(struct dsa_context *ctx)
+{
+ struct task_node *tsk_node = ctx->multi_task_node;
+ int ret = DSA_STATUS_OK;
+
+ while (tsk_node) {
+ tsk_node->tsk->dflags = IDXD_OP_FLAG_CRAV | IDXD_OP_FLAG_RCR;
+ if ((tsk_node->tsk->test_flags & TEST_FLAGS_BOF) && ctx->bof)
+ tsk_node->tsk->dflags |= IDXD_OP_FLAG_BOF;
+
+ dsa_prep_dif_update(tsk_node->tsk);
+ tsk_node = tsk_node->next;
+ }
+
+ tsk_node = ctx->multi_task_node;
+ while (tsk_node) {
+ dsa_desc_submit(ctx, tsk_node->tsk->desc);
+ tsk_node = tsk_node->next;
+ }
+ tsk_node = ctx->multi_task_node;
+
+ info("Submitted all dif update jobs\n");
+ while (tsk_node) {
+ ret = dsa_wait_dif(ctx, tsk_node->tsk);
+ if (ret != DSA_STATUS_OK)
+ info("Desc: %p failed with ret: %d\n", tsk_node->tsk->desc,
+ tsk_node->tsk->comp->status);
+ tsk_node = tsk_node->next;
+ }
+ return ret;
+}
+
+int dsa_wait_dif(struct dsa_context *ctx, struct task *tsk)
+{
+ struct dsa_hw_desc *desc = tsk->desc;
+ struct dsa_completion_record *comp = tsk->comp;
+ int rc;
+
+again:
+ rc = dsa_wait_on_desc_timeout(comp, ms_timeout);
+ if (rc < 0) {
+ err("DIF desc timeout\n");
+ return DSA_STATUS_TIMEOUT;
+ }
+
+ /* re-submit if PAGE_FAULT reported by HW && BOF is off */
+ if (stat_val(comp->status) == DSA_COMP_PAGE_FAULT_NOBOF &&
+ !(desc->flags & IDXD_OP_FLAG_BOF)) {
+ task_result_verify(tsk, 0);
+ dsa_reprep_dif(ctx, tsk);
+ goto again;
+ }
+
+ return DSA_STATUS_OK;
+}
+
/* mismatch_expected: expect mismatched buffer with success status 0x1 */
int task_result_verify(struct task *tsk, int mismatch_expected)
{
@@ -1483,6 +1635,19 @@ int task_result_verify(struct task *tsk, int mismatch_expected)
case DSA_OPCODE_COPY_CRC:
rc = task_result_verify_crc_copy(tsk, mismatch_expected);
return rc;
+ case DSA_OPCODE_DIF_INS:
+ rc = task_result_verify_dif(tsk, tsk->xfer_size, mismatch_expected);
+ rc = task_result_verify_dif_tags(tsk, tsk->xfer_size);
+ return rc;
+ case DSA_OPCODE_DIF_STRP:
+ rc = task_result_verify_dif(tsk, tsk->xfer_size - 8 * tsk->blks,
+ mismatch_expected);
+ return rc;
+ case DSA_OPCODE_DIF_UPDT:
+ rc = task_result_verify_dif(tsk, tsk->xfer_size - 8 * tsk->blks,
+ mismatch_expected);
+ rc = task_result_verify_dif_tags(tsk, tsk->xfer_size - 8 * tsk->blks);
+ return rc;
}
info("test with op %d passed\n", tsk->opcode);
@@ -1776,6 +1941,314 @@ uint16_t dsa_calculate_crc_t10dif(unsigned char *buffer, size_t len, int flags)
return (flags & DIF_INVERT_CRC_RESULT) ? ~crc : crc;
}
+static int task_result_verify_dif_page_fault(struct task *tsk, unsigned long xfer_size,
+ int mismatch_expected)
+{
+ struct dsa_hw_desc *hw = tsk->desc;
+ int rc = 0;
+ unsigned char *src1 = (unsigned char *)hw->src_addr;
+ unsigned char *dst1 = (unsigned char *)hw->dst_addr;
+ unsigned long i, blks;
+
+ if (tsk->comp->status == 0x16 || xfer_size == 0)
+ /* This check need to be removed for GNR-SP. Its a know bug in SPR-SP
+ * https://hsdes.intel.com/appstore/article/#/22010927356
+ * [SPR][No Fix] For DIF operations, RTL should consider 'computed transfer size'
+ * when determining overlapping buffer conditions
+ */
+ return DSA_STATUS_OK;
+
+ info("Partial DIF Src and Dest Check Ongoing\n");
+
+ if (tsk->opcode == DSA_OPCODE_DIF_INS) {
+ blks = xfer_size / dif_blk_arr[tsk->blk_idx_flg];
+ for (i = 0; i < blks; i++)
+ rc = memcmp(&src1[dif_blk_arr[tsk->blk_idx_flg] * i],
+ &dst1[(dif_blk_arr[tsk->blk_idx_flg] + 8) * i],
+ dif_blk_arr[tsk->blk_idx_flg]);
+ }
+
+ if (tsk->opcode == DSA_OPCODE_DIF_STRP) {
+ blks = xfer_size / (dif_blk_arr[tsk->blk_idx_flg] + 8);
+ for (i = 0; i < blks; i++)
+ rc = memcmp(&src1[(dif_blk_arr[tsk->blk_idx_flg] + 8) * i],
+ &dst1[dif_blk_arr[tsk->blk_idx_flg] * i],
+ dif_blk_arr[tsk->blk_idx_flg]);
+ }
+
+ if (tsk->opcode == DSA_OPCODE_DIF_UPDT) {
+ blks = xfer_size / (dif_blk_arr[tsk->blk_idx_flg] + 8);
+ for (i = 0; i < blks; i++)
+ rc = memcmp(&src1[(dif_blk_arr[tsk->blk_idx_flg] + 8) * i],
+ &dst1[(dif_blk_arr[tsk->blk_idx_flg] + 8) * i],
+ dif_blk_arr[tsk->blk_idx_flg]);
+ }
+
+ if (rc) {
+ err("dif mismatch dst1, memcmp rc %d\n", rc);
+ return -ENXIO;
+ }
+
+ return DSA_STATUS_OK;
+}
+
+int task_result_verify_dif(struct task *tsk, unsigned long xfer_size, int mismatch_expected)
+{
+ int rc;
+ unsigned long i;
+ unsigned long blks = tsk->blks;
+ unsigned long buf_size = dif_blk_arr[tsk->blk_idx_flg];
+ unsigned char *src1 = (unsigned char *)tsk->src1;
+ unsigned char *dst1 = (unsigned char *)tsk->dst1;
+
+ if (tsk->comp->status == DSA_COMP_PAGE_FAULT_NOBOF ||
+ tsk->comp->status == DSA_COMP_PAGE_FAULT_IR ||
+ tsk->comp->status == 0x83) {
+ rc = task_result_verify_dif_page_fault(tsk, tsk->comp->bytes_completed, 0);
+ info("Partial DIF Src and Dest Checking Done\n");
+ if (!rc)
+ return DSA_STATUS_OK;
+ }
+
+ /* This check need to be removed for GNR-SP. Its a know bug in SPR-SP
+ * https://hsdes.intel.com/appstore/article/#/22010927356
+ * [SPR][No Fix] For DIF operations, RTL should consider 'computed transfer size'
+ * when determining overlapping buffer conditions
+ */
+ if (tsk->comp->status == 0x16)
+ return DSA_STATUS_OK;
+
+ info("Checking Src & Dst buffers\n");
+ if (tsk->opcode == DSA_OPCODE_DIF_INS) {
+ for (i = 0; i < blks; i++)
+ rc = memcmp(&src1[buf_size * i], &dst1[(buf_size + 8) * i], buf_size);
+ }
+
+ if (tsk->opcode == DSA_OPCODE_DIF_STRP) {
+ for (i = 0; i < blks; i++)
+ rc = memcmp(&src1[(buf_size + 8) * i], &dst1[buf_size * i], buf_size);
+ }
+
+ if (tsk->opcode == DSA_OPCODE_DIF_UPDT) {
+ for (i = 0; i < blks; i++)
+ rc = memcmp(&src1[(buf_size + 8) * i], &dst1[(buf_size + 8) * i], buf_size);
+ }
+
+ if (rc) {
+ err("dif mismatch dst1, memcmp rc %d\n", rc);
+ return -ENXIO;
+ }
+
+ return DSA_STATUS_OK;
+}
+
+static int task_result_verify_dif_tags_page_fault(struct task *tsk, unsigned long xfer_size)
+{
+ struct dsa_hw_desc *hw = tsk->desc;
+ unsigned long blks;
+ unsigned long buf_size;
+ unsigned char *dst1 = (uint8_t *)hw->dst_addr;
+ unsigned char *src1 = (uint8_t *)hw->src_addr;
+ unsigned long g_count = 0;
+ unsigned long a_count = 0;
+ unsigned long r_count = 0;
+ unsigned short dif_apptag = 0;
+ unsigned long dif_reftag = 0;
+ unsigned int dif_guardtag = 0;
+ unsigned char tmp_buf;
+ unsigned char dst_tag;
+ unsigned long i;
+
+ info("Checking Partial DIF Tags\n");
+ /* This check need to be removed for GNR-SP. Its a know bug in SPR-SP
+ * https://hsdes.intel.com/appstore/article/#/22010927356
+ * [SPR][No Fix] For DIF operations, RTL should consider 'computed transfer size'
+ * when determining overlapping buffer conditions
+ */
+ if (tsk->comp->status == 0x16 || xfer_size == 0)
+ return DSA_STATUS_OK;
+
+ if (tsk->opcode != DSA_OPCODE_DIF_UPDT)
+ blks = xfer_size / dif_blk_arr[tsk->blk_idx_flg];
+ else
+ blks = xfer_size / (dif_blk_arr[tsk->blk_idx_flg] + 8);
+
+ switch (tsk->opcode) {
+ case DSA_OPCODE_DIF_INS:
+ dif_reftag = hw->ins_ref_tag_seed;
+ dif_apptag = hw->ins_app_tag_seed;
+ break;
+
+ case DSA_OPCODE_DIF_CHECK:
+ case DSA_OPCODE_DIF_STRP:
+ dif_reftag = hw->chk_ref_tag_seed;
+ dif_apptag = hw->chk_app_tag_seed;
+ break;
+
+ case DSA_OPCODE_DIF_UPDT:
+ dif_reftag = hw->dest_ref_tag_seed;
+ dif_apptag = hw->dest_app_tag_seed;
+ break;
+ }
+
+ buf_size = dif_blk_arr[tsk->blk_idx_flg];
+ for (i = 0; i < blks; i++) {
+ if (tsk->opcode == DSA_OPCODE_DIF_INS)
+ dif_guardtag = dsa_calculate_crc_t10dif((src1 + buf_size * i),
+ buf_size, 0);
+ else
+ dif_guardtag = dsa_calculate_crc_t10dif((src1 + (buf_size + 8) * i),
+ buf_size, 0);
+
+ dst_tag = dst1[buf_size + DIF_BLK_GRD_1 + (buf_size + 8) * i];
+ tmp_buf = (dif_guardtag >> 8) & 0xff;
+ if (tmp_buf != dst_tag)
+ g_count++;
+
+ dst_tag = dst1[buf_size + DIF_BLK_GRD_2 + (buf_size + 8) * i];
+ tmp_buf = dif_guardtag & 0xff;
+ if (tmp_buf != dst_tag)
+ g_count++;
+
+ dst_tag = dst1[buf_size + DIF_APP_TAG_1 + (buf_size + 8) * i];
+ tmp_buf = (dif_apptag >> 8) & 0xff;
+ if (tmp_buf != dst_tag)
+ a_count++;
+
+ dst_tag = dst1[buf_size + DIF_APP_TAG_2 + (buf_size + 8) * i];
+ tmp_buf = (dif_apptag) & 0xff;
+ if (tmp_buf != dst_tag)
+ a_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_1 + (buf_size + 8) * i];
+ tmp_buf = (dif_reftag >> 24) & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_2 + (buf_size + 8) * i];
+ tmp_buf = (dif_reftag >> 16) & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_3 + (buf_size + 8) * i];
+ tmp_buf = (dif_reftag >> 8) & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_4 + (buf_size + 8) * i];
+ tmp_buf = dif_reftag & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ if (tsk->opcode != DSA_OPCODE_DIF_UPDT)
+ dif_reftag++;
+ }
+
+ if (g_count || a_count || r_count)
+ err("Tag Errors Found g: %ld a: %ld r: %ld\n", g_count, a_count, r_count);
+ else
+ info("All Tags Validated\n", g_count, a_count, r_count);
+
+ return DSA_STATUS_OK;
+}
+
+int task_result_verify_dif_tags(struct task *tsk, unsigned long xfer_size)
+{
+ int rc;
+ unsigned long blks;
+ unsigned long buf_size;
+ unsigned char *dst1 = (unsigned char *)tsk->dst1;
+ unsigned char *src1 = (unsigned char *)tsk->src1;
+ unsigned long g_count = 0;
+ unsigned long a_count = 0;
+ unsigned long r_count = 0;
+ unsigned int dif_reftag = tsk->reftag;
+ unsigned int dif_apptag = tsk->apptag;
+ unsigned int dif_guardtag = 0;
+ unsigned char tmp_buf;
+ unsigned char dst_tag;
+ unsigned long i;
+
+ info("compsts: %x\n", tsk->comp->status);
+ if (tsk->comp->status == 0x83 ||
+ tsk->comp->status == DSA_COMP_PAGE_FAULT_NOBOF ||
+ tsk->comp->status == DSA_COMP_PAGE_FAULT_IR) {
+ rc = task_result_verify_dif_tags_page_fault(tsk, tsk->comp->bytes_completed);
+ info("Partial DIF Tags Checking Done\n");
+ if (!rc)
+ return DSA_STATUS_OK;
+ }
+
+ info("Checking All Tags\n");
+ if (tsk->opcode != DSA_OPCODE_DIF_UPDT)
+ blks = xfer_size / dif_blk_arr[tsk->blk_idx_flg];
+ else
+ blks = tsk->blks;
+
+ buf_size = dif_blk_arr[tsk->blk_idx_flg];
+ tsk->reftag = 0xABBA;
+ tsk->apptag = 0xFACE;
+
+ for (i = 0; i < blks; i++) {
+ if (tsk->opcode == DSA_OPCODE_DIF_INS)
+ dif_guardtag = dsa_calculate_crc_t10dif((src1 + (buf_size) * i),
+ buf_size, 0);
+ else
+ dif_guardtag = dsa_calculate_crc_t10dif((src1 + (buf_size + 8) * i),
+ buf_size, 0);
+
+ dst_tag = dst1[buf_size + DIF_BLK_GRD_1 + (buf_size + 8) * i];
+ tmp_buf = (dif_guardtag >> 8) & 0xff;
+ if (tmp_buf != dst_tag)
+ g_count++;
+
+ dst_tag = dst1[buf_size + DIF_BLK_GRD_2 + (buf_size + 8) * i];
+ tmp_buf = dif_guardtag & 0xff;
+ if (tmp_buf != dst_tag)
+ g_count++;
+
+ dst_tag = dst1[buf_size + DIF_APP_TAG_1 + (buf_size + 8) * i];
+ tmp_buf = (dif_apptag >> 8) & 0xff;
+ if (tmp_buf != dst_tag)
+ a_count++;
+
+ dst_tag = dst1[buf_size + DIF_APP_TAG_2 + (buf_size + 8) * i];
+ tmp_buf = (dif_apptag) & 0xff;
+ if (tmp_buf != dst_tag)
+ a_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_1 + (buf_size + 8) * i];
+ tmp_buf = (dif_reftag >> 24) & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_2 + (buf_size + 8) * i];
+ tmp_buf = (dif_reftag >> 16) & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_3 + (buf_size + 8) * i];
+ tmp_buf = (dif_reftag >> 8) & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ dst_tag = dst1[buf_size + DIF_REF_TAG_4 + (buf_size + 8) * i];
+ tmp_buf = dif_reftag & 0xff;
+ if (tmp_buf != dst_tag)
+ r_count++;
+
+ if (tsk->opcode != DSA_OPCODE_DIF_UPDT)
+ dif_reftag++;
+ }
+
+ if (g_count || a_count || r_count)
+ err("Tag Errors Found g: %ld a: %ld r: %ld\n", g_count, a_count, r_count);
+ else
+ info("All Tags Validated\n", g_count, a_count, r_count);
+
+ return DSA_STATUS_OK;
+}
+
int batch_result_verify(struct batch_task *btsk, int bof)
{
uint8_t core_stat, sub_stat;
diff --git a/test/dsa.h b/test/dsa.h
index ad86dfa..007883e 100644
--- a/test/dsa.h
+++ b/test/dsa.h
@@ -292,6 +292,12 @@ int dsa_wait_crcgen(struct dsa_context *ctx, struct task *tsk);
int dsa_crc_copy_multi_task_nodes(struct dsa_context *ctx);
int dsa_wait_crc_copy(struct dsa_context *ctx, struct task *tsk);
+int dsa_dif_check_multi_task_nodes(struct dsa_context *ctx);
+int dsa_dif_ins_multi_task_nodes(struct dsa_context *ctx);
+int dsa_dif_strp_multi_task_nodes(struct dsa_context *ctx);
+int dsa_dif_updt_multi_task_nodes(struct dsa_context *ctx);
+int dsa_wait_dif(struct dsa_context *ctx, struct task *tsk);
+
void dsa_prep_noop(struct task *tsk);
void dsa_prep_memcpy(struct task *tsk);
void dsa_reprep_memcpy(struct dsa_context *ctx, struct task *tsk);
@@ -311,6 +317,11 @@ void dsa_prep_crcgen(struct task *tsk);
void dsa_reprep_crcgen(struct dsa_context *ctx, struct task *tsk);
void dsa_prep_crc_copy(struct task *tsk);
void dsa_reprep_crc_copy(struct dsa_context *ctx, struct task *tsk);
+void dsa_prep_dif_check(struct task *tsk);
+void dsa_prep_dif_insert(struct task *tsk);
+void dsa_prep_dif_strip(struct task *tsk);
+void dsa_prep_dif_update(struct task *tsk);
+void dsa_reprep_dif(struct dsa_context *ctx, struct task *tsk);
int task_result_verify(struct task *tsk, int mismatch_expected);
int task_result_verify_task_nodes(struct dsa_context *ctx, int mismatch_expected);
@@ -323,6 +334,8 @@ int task_result_verify_cr_delta(struct task *tsk, int mismatch_expected);
int task_result_verify_ap_delta(struct task *tsk, int mismatch_expected);
int task_result_verify_crcgen(struct task *tsk, int mismatch_expected);
int task_result_verify_crc_copy(struct task *tsk, int mismatch_expected);
+int task_result_verify_dif(struct task *tsk, unsigned long xfer_size, int mismatch_expected);
+int task_result_verify_dif_tags(struct task *tsk, unsigned long xfer_size);
int batch_result_verify(struct batch_task *btsk, int bof);
int alloc_batch_task(struct dsa_context *ctx, unsigned int task_num, int num_itr);
@@ -340,6 +353,10 @@ void dsa_prep_batch_cr_delta(struct batch_task *btsk);
void dsa_prep_batch_ap_delta(struct batch_task *btsk);
void dsa_prep_batch_crcgen(struct batch_task *btsk);
void dsa_prep_batch_crc_copy(struct batch_task *btsk);
+void dsa_prep_batch_dif_check(struct batch_task *btsk);
+void dsa_prep_batch_dif_insert(struct batch_task *btsk);
+void dsa_prep_batch_dif_strip(struct batch_task *btsk);
+void dsa_prep_batch_dif_update(struct batch_task *btsk);
int dsa_wait_batch(struct batch_task *btsk);
void dsa_free(struct dsa_context *ctx);
diff --git a/test/dsa_test.c b/test/dsa_test.c
index addf7c8..13558ec 100644
--- a/test/dsa_test.c
+++ b/test/dsa_test.c
@@ -111,6 +111,22 @@ static int test_batch(struct dsa_context *ctx, size_t buf_size,
dsa_prep_batch_crc_copy(btsk_node->btsk);
break;
+ case DSA_OPCODE_DIF_CHECK:
+ dsa_prep_batch_dif_check(btsk_node->btsk);
+ break;
+
+ case DSA_OPCODE_DIF_INS:
+ dsa_prep_batch_dif_insert(btsk_node->btsk);
+ break;
+
+ case DSA_OPCODE_DIF_STRP:
+ dsa_prep_batch_dif_strip(btsk_node->btsk);
+ break;
+
+ case DSA_OPCODE_DIF_UPDT:
+ dsa_prep_batch_dif_update(btsk_node->btsk);
+ break;
+
default:
err("Unsupported op %#x\n", bopcode);
return -EINVAL;
@@ -517,6 +533,85 @@ static int test_crc(struct dsa_context *ctx, size_t buf_size,
return rc;
}
+static int test_dif(struct dsa_context *ctx, size_t buf_size,
+ int tflags, uint32_t opcode, int num_desc)
+{
+ struct task_node *tsk_node;
+ int rc = DSA_STATUS_OK;
+ int itr = num_desc, i = 0, range = 0;
+
+ info("testmemory: opcode %d len %#lx tflags %#x num_desc %ld\n",
+ opcode, buf_size, tflags, num_desc);
+
+ ctx->is_batch = 0;
+
+ if (ctx->dedicated == ACCFG_WQ_SHARED)
+ range = ctx->threshold;
+ else
+ range = ctx->wq_size - 1;
+
+ while (itr > 0 && rc == DSA_STATUS_OK) {
+ i = (itr < range) ? itr : range;
+ /* Allocate memory to all the task nodes, desc, completion record*/
+ rc = alloc_multiple_tasks(ctx, i);
+ if (rc != DSA_STATUS_OK)
+ return rc;
+
+ /* allocate memory to src and dest buffers and fill in the desc for all the nodes*/
+ tsk_node = ctx->multi_task_node;
+ while (tsk_node) {
+ tsk_node->tsk->xfer_size = buf_size;
+ tsk_node->tsk->blk_idx_flg = get_dif_blksz_flg(tsk_node->tsk->xfer_size);
+
+ rc = init_task(tsk_node->tsk, tflags, opcode, buf_size);
+ if (rc != DSA_STATUS_OK)
+ return rc;
+
+ tsk_node = tsk_node->next;
+ }
+
+ switch (opcode) {
+ case DSA_OPCODE_DIF_CHECK:
+ rc = dsa_dif_check_multi_task_nodes(ctx);
+ if (rc != DSA_STATUS_OK)
+ return rc;
+ break;
+
+ case DSA_OPCODE_DIF_INS:
+ rc = dsa_dif_ins_multi_task_nodes(ctx);
+ if (rc != DSA_STATUS_OK)
+ return rc;
+ break;
+
+ case DSA_OPCODE_DIF_STRP:
+ rc = dsa_dif_strp_multi_task_nodes(ctx);
+ if (rc != DSA_STATUS_OK)
+ return rc;
+ break;
+
+ case DSA_OPCODE_DIF_UPDT:
+ rc = dsa_dif_updt_multi_task_nodes(ctx);
+ if (rc != DSA_STATUS_OK)
+ return rc;
+ break;
+
+ default:
+ err("Unsupported op %#x\n", opcode);
+ return -EINVAL;
+ }
+
+ /* Verification of all the nodes*/
+ rc = task_result_verify_task_nodes(ctx, 0);
+ if (rc != DSA_STATUS_OK)
+ return rc;
+
+ dsa_free_task(ctx);
+ itr = itr - range;
+ }
+
+ return rc;
+}
+
int main(int argc, char *argv[])
{
struct dsa_context *dsa;
@@ -636,6 +731,15 @@ int main(int argc, char *argv[])
goto error;
break;
+ case DSA_OPCODE_DIF_CHECK:
+ case DSA_OPCODE_DIF_INS:
+ case DSA_OPCODE_DIF_STRP:
+ case DSA_OPCODE_DIF_UPDT:
+ rc = test_dif(dsa, buf_size, tflags, opcode, num_desc);
+ if (rc != DSA_STATUS_OK)
+ goto error;
+ break;
+
default:
rc = -EINVAL;
break;
diff --git a/test/prep.c b/test/prep.c
index ad4da68..56c821d 100644
--- a/test/prep.c
+++ b/test/prep.c
@@ -8,6 +8,8 @@
#include <accfg/idxd.h>
#include "dsa.h"
+unsigned int dif_arr[] = {512, 520, 4096, 4104};
+
void dsa_prep_desc_common(struct dsa_hw_desc *hw, char opcode,
uint64_t dest, uint64_t src, size_t len, unsigned long dflags)
{
@@ -482,6 +484,86 @@ void dsa_prep_batch_crc_copy(struct batch_task *btsk)
}
}
+void dsa_prep_batch_dif_check(struct batch_task *btsk)
+{
+ int i;
+ struct task *sub_task;
+
+ for (i = 0; i < btsk->task_num; i++) {
+ sub_task = &btsk->sub_tasks[i];
+ sub_task->xfer_size = btsk->sub_tasks[i].xfer_size;
+ sub_task->desc->dif_chk_flags = btsk->sub_tasks[i].blk_idx_flg;
+ dsa_prep_desc_common(sub_task->desc, sub_task->opcode,
+ (uint64_t)(sub_task->dst1), (uint64_t)(sub_task->src1),
+ sub_task->xfer_size, 0xc);
+ sub_task->desc->completion_addr = (uint64_t)(sub_task->comp);
+ sub_task->comp->status = 0;
+ sub_task->desc->chk_app_tag_seed = sub_task->apptag;
+ sub_task->desc->chk_ref_tag_seed = sub_task->reftag;
+ }
+}
+
+void dsa_prep_batch_dif_insert(struct batch_task *btsk)
+{
+ int i;
+ struct task *sub_task;
+
+ for (i = 0; i < btsk->task_num; i++) {
+ sub_task = &btsk->sub_tasks[i];
+ sub_task->xfer_size = btsk->sub_tasks[i].xfer_size;
+ sub_task->desc->dif_chk_flags = btsk->sub_tasks[i].blk_idx_flg;
+ dsa_prep_desc_common(sub_task->desc, sub_task->opcode,
+ (uint64_t)(sub_task->dst1), (uint64_t)(sub_task->src1),
+ sub_task->xfer_size, sub_task->dflags);
+ sub_task->desc->completion_addr = (uint64_t)(sub_task->comp);
+ sub_task->comp->status = 0;
+ sub_task->desc->ins_app_tag_seed = sub_task->apptag;
+ sub_task->desc->ins_ref_tag_seed = sub_task->reftag;
+ }
+}
+
+void dsa_prep_batch_dif_strip(struct batch_task *btsk)
+{
+ int i;
+ struct task *sub_task;
+
+ for (i = 0; i < btsk->task_num; i++) {
+ sub_task = &btsk->sub_tasks[i];
+ sub_task->xfer_size = btsk->sub_tasks[i].xfer_size;
+ sub_task->desc->dif_chk_flags = btsk->sub_tasks[i].blk_idx_flg;
+ dsa_prep_desc_common(sub_task->desc, sub_task->opcode,
+ (uint64_t)(sub_task->dst1), (uint64_t)(sub_task->src1),
+ sub_task->xfer_size, 0x200f);
+ sub_task->desc->completion_addr = (uint64_t)(sub_task->comp);
+ sub_task->comp->status = 0;
+ sub_task->desc->chk_app_tag_seed = sub_task->apptag;
+ sub_task->desc->chk_ref_tag_seed = sub_task->reftag;
+ }
+}
+
+void dsa_prep_batch_dif_update(struct batch_task *btsk)
+{
+ int i;
+ struct task *sub_task;
+
+ for (i = 0; i < btsk->task_num; i++) {
+ sub_task = &btsk->sub_tasks[i];
+ sub_task->xfer_size = btsk->sub_tasks[i].xfer_size;
+ sub_task->desc->dif_chk_flags = btsk->sub_tasks[i].blk_idx_flg;
+ dsa_prep_desc_common(sub_task->desc, sub_task->opcode,
+ (uint64_t)(sub_task->dst1), (uint64_t)(sub_task->src1),
+ sub_task->xfer_size, 0x200f);
+ sub_task->desc->completion_addr = (uint64_t)(sub_task->comp);
+ sub_task->comp->status = 0;
+ sub_task->desc->src_app_tag_seed = sub_task->apptag;
+ sub_task->desc->src_ref_tag_seed = sub_task->reftag;
+ sub_task->desc->dest_ref_tag_seed = sub_task->reftag;
+ sub_task->desc->dest_app_tag_seed = sub_task->apptag;
+ sub_task->desc->src_upd_flags = 0x80;
+ sub_task->desc->upd_dest_flags = 0x80;
+ }
+}
+
void dsa_prep_crc_copy(struct task *tsk)
{
info("preparing descriptor for crc copy\n");
@@ -515,6 +597,113 @@ void dsa_reprep_crc_copy(struct dsa_context *ctx, struct task *tsk)
dsa_desc_submit(ctx, hw);
}
+void dsa_prep_dif_check(struct task *tsk)
+{
+ info("preparing descriptor for dif check\n");
+
+ dsa_prep_desc_common(tsk->desc, tsk->opcode, (uint64_t)(tsk->dst1),
+ (uint64_t)(tsk->src1), tsk->xfer_size, tsk->dflags);
+ tsk->desc->completion_addr = (uint64_t)(tsk->comp);
+ tsk->comp->status = 0;
+ tsk->desc->chk_app_tag_seed = tsk->apptag;
+ tsk->desc->chk_ref_tag_seed = tsk->reftag;
+ tsk->desc->dif_chk_flags = tsk->blk_idx_flg;
+}
+
+void dsa_prep_dif_insert(struct task *tsk)
+{
+ info("preparing descriptor for dif insert\n");
+
+ dsa_prep_desc_common(tsk->desc, tsk->opcode, (uint64_t)(tsk->dst1),
+ (uint64_t)(tsk->src1), tsk->xfer_size, tsk->dflags);
+ tsk->desc->completion_addr = (uint64_t)(tsk->comp);
+ tsk->comp->status = 0;
+ tsk->desc->ins_app_tag_seed = tsk->apptag;
+ tsk->desc->ins_ref_tag_seed = tsk->reftag;
+ tsk->desc->dif_ins_flags = tsk->blk_idx_flg;
+}
+
+void dsa_prep_dif_strip(struct task *tsk)
+{
+ info("preparing descriptor for dif strip\n");
+
+ dsa_prep_desc_common(tsk->desc, tsk->opcode, (uint64_t)(tsk->dst1),
+ (uint64_t)(tsk->src1), tsk->xfer_size, tsk->dflags);
+ tsk->desc->completion_addr = (uint64_t)(tsk->comp);
+ tsk->comp->status = 0;
+ tsk->desc->chk_app_tag_seed = tsk->apptag;
+ tsk->desc->chk_ref_tag_seed = tsk->reftag;
+ tsk->desc->dif_chk_flags = tsk->blk_idx_flg;
+}
+
+void dsa_prep_dif_update(struct task *tsk)
+{
+ info("preparing descriptor for dif update\n");
+
+ dsa_prep_desc_common(tsk->desc, tsk->opcode, (uint64_t)(tsk->dst1),
+ (uint64_t)(tsk->src1), tsk->xfer_size, tsk->dflags);
+ tsk->desc->completion_addr = (uint64_t)(tsk->comp);
+ tsk->comp->status = 0;
+ tsk->desc->src_app_tag_seed = tsk->apptag;
+ tsk->desc->src_ref_tag_seed = tsk->reftag;
+ tsk->desc->dest_ref_tag_seed = tsk->reftag;
+ tsk->desc->dest_app_tag_seed = tsk->apptag;
+ tsk->desc->src_upd_flags = 0x80;
+ tsk->desc->upd_dest_flags = 0x80;
+ tsk->desc->dif_upd_flags = tsk->blk_idx_flg;
+}
+
+void dsa_reprep_dif(struct dsa_context *ctx, struct task *tsk)
+{
+ struct dsa_completion_record *compl = tsk->comp;
+ struct dsa_hw_desc *hw = tsk->desc;
+ unsigned long blks_completed = 0;
+
+ info("PF addr %#lx dir %d bc %#x\n",
+ compl->fault_addr, compl->result,
+ compl->bytes_completed);
+
+ hw->src_addr += compl->bytes_completed;
+ hw->ins_ref_tag_seed = compl->dif_ins_ref_tag;
+ if (tsk->opcode == DSA_OPCODE_DIF_INS) {
+ blks_completed = compl->bytes_completed / (dif_arr[tsk->blk_idx_flg]);
+ hw->xfer_size -= compl->bytes_completed;
+ hw->dst_addr += compl->bytes_completed + 8 * blks_completed;
+ hw->ins_app_tag_seed = compl->dif_ins_app_tag;
+ hw->ins_ref_tag_seed = compl->dif_ins_ref_tag;
+ }
+
+ if (tsk->opcode == DSA_OPCODE_DIF_STRP) {
+ blks_completed = compl->bytes_completed / (dif_arr[tsk->blk_idx_flg] + 8);
+ hw->xfer_size -= compl->bytes_completed;
+ hw->dst_addr += dif_arr[tsk->blk_idx_flg] * blks_completed;
+ hw->chk_app_tag_seed = compl->dif_chk_app_tag;
+ hw->chk_ref_tag_seed = compl->dif_chk_ref_tag;
+ }
+
+ if (tsk->opcode == DSA_OPCODE_DIF_UPDT) {
+ blks_completed = compl->bytes_completed / (dif_arr[tsk->blk_idx_flg] + 8);
+ hw->xfer_size -= compl->bytes_completed;
+ hw->dst_addr += (dif_arr[tsk->blk_idx_flg] + 8) * blks_completed;
+ hw->src_app_tag_seed = compl->dif_upd_src_app_tag;
+ hw->dest_app_tag_seed = compl->dif_upd_dest_app_tag;
+ hw->src_ref_tag_seed = compl->dif_upd_dest_ref_tag;
+ hw->dest_ref_tag_seed = compl->dif_upd_dest_ref_tag;
+ }
+ if (tsk->opcode == DSA_OPCODE_DIF_CHECK) {
+ blks_completed = compl->bytes_completed / (dif_arr[tsk->blk_idx_flg] + 8);
+ hw->xfer_size -= compl->bytes_completed;
+ hw->chk_app_tag_seed = compl->dif_chk_app_tag;
+ hw->chk_ref_tag_seed = compl->dif_chk_ref_tag;
+ }
+
+ resolve_page_fault(compl->fault_addr, compl->status);
+
+ compl->status = 0;
+
+ dsa_desc_submit(ctx, hw);
+}
+
void dsa_prep_batch(struct batch_task *btsk, unsigned long desc_flags)
{
struct task *ctsk = btsk->core_task;
--
2.27.0