summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSvyatoslav Pankratov <svyatoslav.pankratov@intel.com>2025-06-04 16:59:56 +0100
committerHerbert Xu <herbert@gondor.apana.org.au>2025-06-13 17:26:17 +0800
commit254923ca8715f623704378266815b6d14eb26194 (patch)
tree286a2c4b688a305a12f2127c0f9f4c9b176951ad
parent53669ff591d4deb2d80eed4c07593ad0c0b45899 (diff)
crypto: qat - fix state restore for banks with exceptions
Change the logic in the restore function to properly handle bank exceptions. The check for exceptions in the saved state should be performed before conducting any other ringstat register checks. If a bank was saved with an exception, the ringstat will have the appropriate rp_halt/rp_exception bits set, causing the driver to exit the restore process with an error. Instead, the restore routine should first check the ringexpstat register, and if any exception was raised, it should stop further checks and return without any error. In other words, if a ring pair is in an exception state at the source, it should be restored the same way at the destination but without raising an error. Even though this approach might lead to losing the exception state during migration, the driver will log the exception from the saved state during the restore process. Signed-off-by: Svyatoslav Pankratov <svyatoslav.pankratov@intel.com> Fixes: bbfdde7d195f ("crypto: qat - add bank save and restore flows") Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c b/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c
index 0406cb09c5bb..14d0fdd66a4b 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c
@@ -581,6 +581,28 @@ static int bank_state_restore(struct adf_hw_csr_ops *ops, void __iomem *base,
ops->write_csr_int_srcsel_w_val(base, bank, state->iaintflagsrcsel0);
ops->write_csr_exp_int_en(base, bank, state->ringexpintenable);
ops->write_csr_int_col_ctl(base, bank, state->iaintcolctl);
+
+ /*
+ * Verify whether any exceptions were raised during the bank save process.
+ * If exceptions occurred, the status and exception registers cannot
+ * be directly restored. Consequently, further restoration is not
+ * feasible, and the current state of the ring should be maintained.
+ */
+ val = state->ringexpstat;
+ if (val) {
+ pr_info("QAT: Bank %u state not fully restored due to exception in saved state (%#x)\n",
+ bank, val);
+ return 0;
+ }
+
+ /* Ensure that the restoration process completed without exceptions */
+ tmp_val = ops->read_csr_exp_stat(base, bank);
+ if (tmp_val) {
+ pr_err("QAT: Bank %u restored with exception: %#x\n",
+ bank, tmp_val);
+ return -EFAULT;
+ }
+
ops->write_csr_ring_srv_arb_en(base, bank, state->ringsrvarben);
/* Check that all ring statuses match the saved state. */
@@ -614,13 +636,6 @@ static int bank_state_restore(struct adf_hw_csr_ops *ops, void __iomem *base,
if (ret)
return ret;
- tmp_val = ops->read_csr_exp_stat(base, bank);
- val = state->ringexpstat;
- if (tmp_val && !val) {
- pr_err("QAT: Bank was restored with exception: 0x%x\n", val);
- return -EINVAL;
- }
-
return 0;
}