From: JiangShui Yang yangjiangshui@h-partners.com
Misc fixes for Kunpeng accelerator drivers!
Kai Ye (1): crypto: hisilicon/sec - misc cleanups
Wenkai Lin (3): crypto: hisilicon/sec - remove unused parameter crypto: hisilicon/sec - fix for resource leak crypto: hisilicon/qm - add a function to set qm algs
Zhiqi Song (4): crypto: hisilicon/qm - save capability registers in qm init process crypto: hisilicon/hpre - save capability registers in probe process crypto: hisilicon/sec2 - save capability registers in probe process crypto: hisilicon/zip - save capability registers in probe process
drivers/crypto/hisilicon/hpre/hpre_main.c | 68 ++++++------- drivers/crypto/hisilicon/qm.c | 72 ++++++++++++-- drivers/crypto/hisilicon/sec2/sec.h | 7 ++ drivers/crypto/hisilicon/sec2/sec_crypto.c | 89 +++++++++-------- drivers/crypto/hisilicon/sec2/sec_main.c | 105 ++++++++++----------- drivers/crypto/hisilicon/zip/zip_main.c | 104 ++++++++++---------- include/linux/hisi_acc_qm.h | 12 +++ 7 files changed, 254 insertions(+), 203 deletions(-)
From: Kai Ye yekai13@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7BANJ CVE: NA
----------------------------------------------------------------------
some misc cleanups, include main and crypto file.
Signed-off-by: Kai Ye yekai13@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- drivers/crypto/hisilicon/sec2/sec_crypto.c | 63 ++++++++++------------ drivers/crypto/hisilicon/sec2/sec_main.c | 33 +++++++----- 2 files changed, 47 insertions(+), 49 deletions(-)
diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c index b2f8df547e01..92c4bb0a1111 100644 --- a/drivers/crypto/hisilicon/sec2/sec_crypto.c +++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c @@ -115,7 +115,7 @@ struct sec_aead { };
/* Get an en/de-cipher queue cyclically to balance load over queues of TFM */ -static inline int sec_alloc_queue_id(struct sec_ctx *ctx, struct sec_req *req) +static inline u32 sec_alloc_queue_id(struct sec_ctx *ctx, struct sec_req *req) { if (req->c_req.encrypt) return (u32)atomic_inc_return(&ctx->enc_qcyclic) % @@ -846,8 +846,6 @@ static int sec_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key, case SEC_CALG_SM4: ret = sec_skcipher_aes_sm4_setkey(c_ctx, keylen, c_mode); break; - default: - return -EINVAL; }
if (ret) { @@ -866,27 +864,6 @@ static int sec_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key, return 0; }
-#define GEN_SEC_SETKEY_FUNC(name, c_alg, c_mode) \ -static int sec_setkey_##name(struct crypto_skcipher *tfm, const u8 *key,\ - u32 keylen) \ -{ \ - return sec_skcipher_setkey(tfm, key, keylen, c_alg, c_mode); \ -} - -GEN_SEC_SETKEY_FUNC(aes_ecb, SEC_CALG_AES, SEC_CMODE_ECB) -GEN_SEC_SETKEY_FUNC(aes_cbc, SEC_CALG_AES, SEC_CMODE_CBC) -GEN_SEC_SETKEY_FUNC(aes_xts, SEC_CALG_AES, SEC_CMODE_XTS) -GEN_SEC_SETKEY_FUNC(aes_ofb, SEC_CALG_AES, SEC_CMODE_OFB) -GEN_SEC_SETKEY_FUNC(aes_cfb, SEC_CALG_AES, SEC_CMODE_CFB) -GEN_SEC_SETKEY_FUNC(aes_ctr, SEC_CALG_AES, SEC_CMODE_CTR) -GEN_SEC_SETKEY_FUNC(3des_ecb, SEC_CALG_3DES, SEC_CMODE_ECB) -GEN_SEC_SETKEY_FUNC(3des_cbc, SEC_CALG_3DES, SEC_CMODE_CBC) -GEN_SEC_SETKEY_FUNC(sm4_xts, SEC_CALG_SM4, SEC_CMODE_XTS) -GEN_SEC_SETKEY_FUNC(sm4_cbc, SEC_CALG_SM4, SEC_CMODE_CBC) -GEN_SEC_SETKEY_FUNC(sm4_ofb, SEC_CALG_SM4, SEC_CMODE_OFB) -GEN_SEC_SETKEY_FUNC(sm4_cfb, SEC_CALG_SM4, SEC_CMODE_CFB) -GEN_SEC_SETKEY_FUNC(sm4_ctr, SEC_CALG_SM4, SEC_CMODE_CTR) - static int sec_cipher_pbuf_map(struct sec_ctx *ctx, struct sec_req *req, struct scatterlist *src) { @@ -1368,7 +1345,7 @@ static int sec_skcipher_bd_fill_v3(struct sec_ctx *ctx, struct sec_req *req) sec_sqe3->bd_param = cpu_to_le32(bd_param);
sec_sqe3->c_len_ivin |= cpu_to_le32(c_req->c_len); - sec_sqe3->tag = cpu_to_le64(req); + sec_sqe3->tag = cpu_to_le64((unsigned long)(uintptr_t)req);
return 0; } @@ -2093,7 +2070,7 @@ static int sec_skcipher_soft_crypto(struct sec_ctx *ctx,
skcipher_request_set_sync_tfm(subreq, c_ctx->fbtfm);
- /* software need sync mode to do crypto */ + /* Software need sync mode to do crypto */ skcipher_request_set_callback(subreq, sreq->base.flags, NULL, NULL); skcipher_request_set_crypt(subreq, sreq->src, sreq->dst, @@ -2146,8 +2123,29 @@ static int sec_skcipher_decrypt(struct skcipher_request *sk_req) return sec_skcipher_crypto(sk_req, false); }
-#define SEC_SKCIPHER_GEN_ALG(sec_cra_name, sec_set_key, sec_min_key_size, \ - sec_max_key_size, ctx_init, ctx_exit, blk_size, iv_size)\ +#define GEN_SEC_SETKEY_FUNC(name, c_alg, c_mode) \ +static int sec_setkey_##name(struct crypto_skcipher *tfm, \ + const u8 *key, u32 keylen) \ +{ \ + return sec_skcipher_setkey(tfm, key, keylen, c_alg, c_mode); \ +} + +GEN_SEC_SETKEY_FUNC(aes_ecb, SEC_CALG_AES, SEC_CMODE_ECB) +GEN_SEC_SETKEY_FUNC(aes_cbc, SEC_CALG_AES, SEC_CMODE_CBC) +GEN_SEC_SETKEY_FUNC(aes_xts, SEC_CALG_AES, SEC_CMODE_XTS) +GEN_SEC_SETKEY_FUNC(aes_ofb, SEC_CALG_AES, SEC_CMODE_OFB) +GEN_SEC_SETKEY_FUNC(aes_cfb, SEC_CALG_AES, SEC_CMODE_CFB) +GEN_SEC_SETKEY_FUNC(aes_ctr, SEC_CALG_AES, SEC_CMODE_CTR) +GEN_SEC_SETKEY_FUNC(3des_ecb, SEC_CALG_3DES, SEC_CMODE_ECB) +GEN_SEC_SETKEY_FUNC(3des_cbc, SEC_CALG_3DES, SEC_CMODE_CBC) +GEN_SEC_SETKEY_FUNC(sm4_xts, SEC_CALG_SM4, SEC_CMODE_XTS) +GEN_SEC_SETKEY_FUNC(sm4_cbc, SEC_CALG_SM4, SEC_CMODE_CBC) +GEN_SEC_SETKEY_FUNC(sm4_ofb, SEC_CALG_SM4, SEC_CMODE_OFB) +GEN_SEC_SETKEY_FUNC(sm4_cfb, SEC_CALG_SM4, SEC_CMODE_CFB) +GEN_SEC_SETKEY_FUNC(sm4_ctr, SEC_CALG_SM4, SEC_CMODE_CTR) + +#define SEC_SKCIPHER_ALG(sec_cra_name, sec_set_key, \ + sec_min_key_size, sec_max_key_size, blk_size, iv_size)\ {\ .base = {\ .cra_name = sec_cra_name,\ @@ -2159,8 +2157,8 @@ static int sec_skcipher_decrypt(struct skcipher_request *sk_req) .cra_ctxsize = sizeof(struct sec_ctx),\ .cra_module = THIS_MODULE,\ },\ - .init = ctx_init,\ - .exit = ctx_exit,\ + .init = sec_skcipher_ctx_init,\ + .exit = sec_skcipher_ctx_exit,\ .setkey = sec_set_key,\ .decrypt = sec_skcipher_decrypt,\ .encrypt = sec_skcipher_encrypt,\ @@ -2169,11 +2167,6 @@ static int sec_skcipher_decrypt(struct skcipher_request *sk_req) .ivsize = iv_size,\ }
-#define SEC_SKCIPHER_ALG(name, key_func, min_key_size, \ - max_key_size, blk_size, iv_size) \ - SEC_SKCIPHER_GEN_ALG(name, key_func, min_key_size, max_key_size, \ - sec_skcipher_ctx_init, sec_skcipher_ctx_exit, blk_size, iv_size) - static struct sec_skcipher sec_skciphers[] = { { .alg_msk = BIT(0), diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c index c9140bccc9cf..d550bafdbf37 100644 --- a/drivers/crypto/hisilicon/sec2/sec_main.c +++ b/drivers/crypto/hisilicon/sec2/sec_main.c @@ -189,59 +189,59 @@ static const struct sec_dev_alg sec_dev_algs[] = { { static const struct sec_hw_error sec_hw_errors[] = { { .int_msk = BIT(0), - .msg = "sec_axi_rresp_err_rint" + .msg = "sec_axi_rresp_err_rint", }, { .int_msk = BIT(1), - .msg = "sec_axi_bresp_err_rint" + .msg = "sec_axi_bresp_err_rint", }, { .int_msk = BIT(2), - .msg = "sec_ecc_2bit_err_rint" + .msg = "sec_ecc_2bit_err_rint", }, { .int_msk = BIT(3), - .msg = "sec_ecc_1bit_err_rint" + .msg = "sec_ecc_1bit_err_rint", }, { .int_msk = BIT(4), - .msg = "sec_req_trng_timeout_rint" + .msg = "sec_req_trng_timeout_rint", }, { .int_msk = BIT(5), - .msg = "sec_fsm_hbeat_rint" + .msg = "sec_fsm_hbeat_rint", }, { .int_msk = BIT(6), - .msg = "sec_channel_req_rng_timeout_rint" + .msg = "sec_channel_req_rng_timeout_rint", }, { .int_msk = BIT(7), - .msg = "sec_bd_err_rint" + .msg = "sec_bd_err_rint", }, { .int_msk = BIT(8), - .msg = "sec_chain_buff_err_rint" + .msg = "sec_chain_buff_err_rint", }, { .int_msk = BIT(14), - .msg = "sec_no_secure_access" + .msg = "sec_no_secure_access", }, { .int_msk = BIT(15), - .msg = "sec_wrapping_key_auth_err" + .msg = "sec_wrapping_key_auth_err", }, { .int_msk = BIT(16), - .msg = "sec_km_key_crc_fail" + .msg = "sec_km_key_crc_fail", }, { .int_msk = BIT(17), - .msg = "sec_axi_poison_err" + .msg = "sec_axi_poison_err", }, { .int_msk = BIT(18), - .msg = "sec_sva_err" + .msg = "sec_sva_err", }, {} }; @@ -282,6 +282,11 @@ static const struct debugfs_reg32 sec_dfx_regs[] = { {"SEC_BD_SAA6 ", 0x301C38}, {"SEC_BD_SAA7 ", 0x301C3C}, {"SEC_BD_SAA8 ", 0x301C40}, + {"SEC_RAS_CE_ENABLE ", 0x301050}, + {"SEC_RAS_FE_ENABLE ", 0x301054}, + {"SEC_RAS_NFE_ENABLE ", 0x301058}, + {"SEC_REQ_TRNG_TIME_TH ", 0x30112C}, + {"SEC_CHANNEL_RNG_REQ_THLD ", 0x302110}, };
/* define the SEC's dfx regs region and region length */
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7BANJ CVE: NA
----------------------------------------------------------------------
Unused parameter of static functions should be removed.
Signed-off-by: Wenkai Lin linwenkai6@hisilicon.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- drivers/crypto/hisilicon/sec2/sec_crypto.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c index 92c4bb0a1111..9ff1c8d771d8 100644 --- a/drivers/crypto/hisilicon/sec2/sec_crypto.c +++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c @@ -482,8 +482,7 @@ static void sec_alg_resource_free(struct sec_ctx *ctx, sec_free_mac_resource(dev, qp_ctx->res); }
-static int sec_alloc_qp_ctx_resource(struct hisi_qm *qm, struct sec_ctx *ctx, - struct sec_qp_ctx *qp_ctx) +static int sec_alloc_qp_ctx_resource(struct sec_ctx *ctx, struct sec_qp_ctx *qp_ctx) { u16 q_depth = qp_ctx->qp->sq_depth; struct device *dev = ctx->dev; @@ -538,8 +537,7 @@ static void sec_free_qp_ctx_resource(struct sec_ctx *ctx, struct sec_qp_ctx *qp_ kfree(qp_ctx->req_list); }
-static int sec_create_qp_ctx(struct hisi_qm *qm, struct sec_ctx *ctx, - int qp_ctx_id, int alg_type) +static int sec_create_qp_ctx(struct sec_ctx *ctx, int qp_ctx_id) { struct sec_qp_ctx *qp_ctx; struct hisi_qp *qp; @@ -558,7 +556,7 @@ static int sec_create_qp_ctx(struct hisi_qm *qm, struct sec_ctx *ctx, idr_init(&qp_ctx->req_idr); INIT_LIST_HEAD(&qp_ctx->backlog);
- ret = sec_alloc_qp_ctx_resource(qm, ctx, qp_ctx); + ret = sec_alloc_qp_ctx_resource(ctx, qp_ctx); if (ret) goto err_destroy_idr;
@@ -611,7 +609,7 @@ static int sec_ctx_base_init(struct sec_ctx *ctx) }
for (i = 0; i < sec->ctx_q_num; i++) { - ret = sec_create_qp_ctx(&sec->qm, ctx, i, 0); + ret = sec_create_qp_ctx(ctx, i); if (ret) goto err_sec_release_qp_ctx; } @@ -747,9 +745,7 @@ static void sec_skcipher_uninit(struct crypto_skcipher *tfm) sec_ctx_base_uninit(ctx); }
-static int sec_skcipher_3des_setkey(struct crypto_skcipher *tfm, const u8 *key, - const u32 keylen, - const enum sec_cmode c_mode) +static int sec_skcipher_3des_setkey(struct crypto_skcipher *tfm, const u8 *key, const u32 keylen) { struct sec_ctx *ctx = crypto_skcipher_ctx(tfm); struct sec_cipher_ctx *c_ctx = &ctx->c_ctx; @@ -840,7 +836,7 @@ static int sec_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
switch (c_alg) { case SEC_CALG_3DES: - ret = sec_skcipher_3des_setkey(tfm, key, keylen, c_mode); + ret = sec_skcipher_3des_setkey(tfm, key, keylen); break; case SEC_CALG_AES: case SEC_CALG_SM4:
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7BANJ CVE: NA
----------------------------------------------------------------------
The hisi_acc_sg_buf_unmap function is not executed before return ret, causing resource leakage.
Signed-off-by: Wenkai Lin linwenkai6@hisilicon.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- drivers/crypto/hisilicon/sec2/sec_crypto.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c index 9ff1c8d771d8..27db9fa65ddf 100644 --- a/drivers/crypto/hisilicon/sec2/sec_crypto.c +++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c @@ -984,6 +984,7 @@ static int sec_cipher_map(struct sec_ctx *ctx, struct sec_req *req, ret = sec_aead_mac_init(a_req); if (unlikely(ret)) { dev_err(dev, "fail to init mac data for ICV!\n"); + hisi_acc_sg_buf_unmap(dev, src, req->in); return ret; } }
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7BANJ CVE: NA
----------------------------------------------------------------------
Extract a public function to set qm algs and remove the similar code for setting qm algs in each module.
Signed-off-by: Hao Fang fanghao11@huawei.com Signed-off-by: Wenkai Lin linwenkai6@hisilicon.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- drivers/crypto/hisilicon/hpre/hpre_main.c | 42 ++----------------- drivers/crypto/hisilicon/qm.c | 29 ++++++++++++++ drivers/crypto/hisilicon/sec2/sec_main.c | 47 ++++------------------ drivers/crypto/hisilicon/zip/zip_main.c | 49 ++++------------------- include/linux/hisi_acc_qm.h | 7 ++++ 5 files changed, 55 insertions(+), 119 deletions(-)
diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c index 4d99bfd90fa1..804b125d9c79 100644 --- a/drivers/crypto/hisilicon/hpre/hpre_main.c +++ b/drivers/crypto/hisilicon/hpre/hpre_main.c @@ -117,8 +117,6 @@ #define HPRE_DFX_COMMON2_LEN 0xE #define HPRE_DFX_CORE_LEN 0x43
-#define HPRE_DEV_ALG_MAX_LEN 256 - static const char hpre_name[] = "hisi_hpre"; static struct dentry *hpre_debugfs_root; static const struct pci_device_id hpre_dev_ids[] = { @@ -134,12 +132,7 @@ struct hpre_hw_error { const char *msg; };
-struct hpre_dev_alg { - u32 alg_msk; - const char *alg; -}; - -static const struct hpre_dev_alg hpre_dev_algs[] = { +static const struct qm_dev_alg hpre_dev_algs[] = { { .alg_msk = BIT(0), .alg = "rsa\n" @@ -358,35 +351,6 @@ bool hpre_check_alg_support(struct hisi_qm *qm, u32 alg) return false; }
-static int hpre_set_qm_algs(struct hisi_qm *qm) -{ - struct device *dev = &qm->pdev->dev; - char *algs, *ptr; - u32 alg_msk; - int i; - - if (!qm->use_uacce) - return 0; - - algs = devm_kzalloc(dev, HPRE_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); - if (!algs) - return -ENOMEM; - - alg_msk = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_DEV_ALG_BITMAP_CAP, qm->cap_ver); - - for (i = 0; i < ARRAY_SIZE(hpre_dev_algs); i++) - if (alg_msk & hpre_dev_algs[i].alg_msk) - strcat(algs, hpre_dev_algs[i].alg); - - ptr = strrchr(algs, '\n'); - if (ptr) - *ptr = '\0'; - - qm->uacce->algs = algs; - - return 0; -} - static int hpre_diff_regs_show(struct seq_file *s, void *unused) { struct hisi_qm *qm = s->private; @@ -1137,6 +1101,7 @@ static void hpre_debugfs_exit(struct hisi_qm *qm)
static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) { + u64 alg_msk; int ret;
if (pdev->revision == QM_HW_V1) { @@ -1167,7 +1132,8 @@ static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) return ret; }
- ret = hpre_set_qm_algs(qm); + alg_msk = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_DEV_ALG_BITMAP_CAP, qm->cap_ver); + ret = hisi_qm_set_algs(qm, alg_msk, hpre_dev_algs, ARRAY_SIZE(hpre_dev_algs)); if (ret) { pci_err(pdev, "Failed to set hpre algs!\n"); hisi_qm_uninit(qm); diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index 443d1edc0de6..2abca4fa687c 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -226,6 +226,7 @@ #define QM_QOS_MIN_CIR_B 100 #define QM_QOS_MAX_CIR_U 6 #define QM_AUTOSUSPEND_DELAY 3000 +#define QM_DEV_ALG_MAX_LEN 256
#define QM_MK_CQC_DW3_V1(hop_num, pg_sz, buf_sz, cqe_sz) \ (((hop_num) << QM_CQ_HOP_NUM_SHIFT) | \ @@ -781,6 +782,34 @@ static void qm_get_xqc_depth(struct hisi_qm *qm, u16 *low_bits, *high_bits = (depth >> QM_XQ_DEPTH_SHIFT) & QM_XQ_DEPTH_MASK; }
+int hisi_qm_set_algs(struct hisi_qm *qm, u64 alg_msk, const struct qm_dev_alg *dev_algs, + u32 dev_algs_size) +{ + struct device *dev = &qm->pdev->dev; + char *algs, *ptr; + int i; + + if (!qm->use_uacce) + return 0; + + algs = devm_kzalloc(dev, QM_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); + if (!algs) + return -ENOMEM; + + for (i = 0; i < dev_algs_size; i++) + if (alg_msk & dev_algs[i].alg_msk) + strcat(algs, dev_algs[i].alg); + + ptr = strrchr(algs, '\n'); + if (ptr) + *ptr = '\0'; + + qm->uacce->algs = algs; + + return 0; +} +EXPORT_SYMBOL_GPL(hisi_qm_set_algs); + static u32 qm_get_irq_num(struct hisi_qm *qm) { if (qm->fun_type == QM_HW_PF) diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c index d550bafdbf37..91775f56edb9 100644 --- a/drivers/crypto/hisilicon/sec2/sec_main.c +++ b/drivers/crypto/hisilicon/sec2/sec_main.c @@ -121,7 +121,6 @@ GENMASK_ULL(42, 25)) #define SEC_AEAD_BITMAP (GENMASK_ULL(7, 6) | GENMASK_ULL(18, 17) | \ GENMASK_ULL(45, 43)) -#define SEC_DEV_ALG_MAX_LEN 256
struct sec_hw_error { u32 int_msk; @@ -133,11 +132,6 @@ struct sec_dfx_item { u32 offset; };
-struct sec_dev_alg { - u64 alg_msk; - const char *algs; -}; - static const char sec_name[] = "hisi_sec2"; static struct dentry *sec_debugfs_root;
@@ -174,15 +168,15 @@ static const struct hisi_qm_cap_info sec_basic_info[] = { {SEC_CORE4_ALG_BITMAP_HIGH, 0x3170, 0, GENMASK(31, 0), 0x3FFF, 0x3FFF, 0x3FFF}, };
-static const struct sec_dev_alg sec_dev_algs[] = { { +static const struct qm_dev_alg sec_dev_algs[] = { { .alg_msk = SEC_CIPHER_BITMAP, - .algs = "cipher\n", + .alg = "cipher\n", }, { .alg_msk = SEC_DIGEST_BITMAP, - .algs = "digest\n", + .alg = "digest\n", }, { .alg_msk = SEC_AEAD_BITMAP, - .algs = "aead\n", + .alg = "aead\n", }, };
@@ -1083,37 +1077,9 @@ static int sec_pf_probe_init(struct sec_dev *sec) return ret; }
-static int sec_set_qm_algs(struct hisi_qm *qm) -{ - struct device *dev = &qm->pdev->dev; - char *algs, *ptr; - u64 alg_mask; - int i; - - if (!qm->use_uacce) - return 0; - - algs = devm_kzalloc(dev, SEC_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); - if (!algs) - return -ENOMEM; - - alg_mask = sec_get_alg_bitmap(qm, SEC_DEV_ALG_BITMAP_HIGH, SEC_DEV_ALG_BITMAP_LOW); - - for (i = 0; i < ARRAY_SIZE(sec_dev_algs); i++) - if (alg_mask & sec_dev_algs[i].alg_msk) - strcat(algs, sec_dev_algs[i].algs); - - ptr = strrchr(algs, '\n'); - if (ptr) - *ptr = '\0'; - - qm->uacce->algs = algs; - - return 0; -} - static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) { + u64 alg_msk; int ret;
qm->pdev = pdev; @@ -1148,7 +1114,8 @@ static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) return ret; }
- ret = sec_set_qm_algs(qm); + alg_msk = sec_get_alg_bitmap(qm, SEC_DEV_ALG_BITMAP_HIGH, SEC_DEV_ALG_BITMAP_LOW); + ret = hisi_qm_set_algs(qm, alg_msk, sec_dev_algs, ARRAY_SIZE(sec_dev_algs)); if (ret) { pci_err(qm->pdev, "Failed to set sec algs!\n"); hisi_qm_uninit(qm); diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c index 1b873118d636..5cd8b870f300 100644 --- a/drivers/crypto/hisilicon/zip/zip_main.c +++ b/drivers/crypto/hisilicon/zip/zip_main.c @@ -74,7 +74,6 @@ #define HZIP_AXI_SHUTDOWN_ENABLE BIT(14) #define HZIP_WR_PORT BIT(11)
-#define HZIP_DEV_ALG_MAX_LEN 256 #define HZIP_ALG_ZLIB_BIT GENMASK(1, 0) #define HZIP_ALG_GZIP_BIT GENMASK(3, 2) #define HZIP_ALG_DEFLATE_BIT GENMASK(5, 4) @@ -120,23 +119,18 @@ struct zip_dfx_item { u32 offset; };
-struct zip_dev_alg { - u32 alg_msk; - const char *algs; -}; - -static const struct zip_dev_alg zip_dev_algs[] = { { +static const struct qm_dev_alg zip_dev_algs[] = { { .alg_msk = HZIP_ALG_ZLIB_BIT, - .algs = "zlib\n", + .alg = "zlib\n", }, { .alg_msk = HZIP_ALG_GZIP_BIT, - .algs = "gzip\n", + .alg = "gzip\n", }, { .alg_msk = HZIP_ALG_DEFLATE_BIT, - .algs = "deflate\n", + .alg = "deflate\n", }, { .alg_msk = HZIP_ALG_LZ77_BIT, - .algs = "lz77_zstd\n", + .alg = "lz77_zstd\n", }, };
@@ -417,35 +411,6 @@ bool hisi_zip_alg_support(struct hisi_qm *qm, u32 alg) return false; }
-static int hisi_zip_set_qm_algs(struct hisi_qm *qm) -{ - struct device *dev = &qm->pdev->dev; - char *algs, *ptr; - u32 alg_mask; - int i; - - if (!qm->use_uacce) - return 0; - - algs = devm_kzalloc(dev, HZIP_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); - if (!algs) - return -ENOMEM; - - alg_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DEV_ALG_BITMAP, qm->cap_ver); - - for (i = 0; i < ARRAY_SIZE(zip_dev_algs); i++) - if (alg_mask & zip_dev_algs[i].alg_msk) - strcat(algs, zip_dev_algs[i].algs); - - ptr = strrchr(algs, '\n'); - if (ptr) - *ptr = '\0'; - - qm->uacce->algs = algs; - - return 0; -} - static void hisi_zip_open_sva_prefetch(struct hisi_qm *qm) { u32 val; @@ -1128,6 +1093,7 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)
static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) { + u64 alg_msk; int ret;
qm->pdev = pdev; @@ -1163,7 +1129,8 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) return ret; }
- ret = hisi_zip_set_qm_algs(qm); + alg_msk = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DEV_ALG_BITMAP, qm->cap_ver); + ret = hisi_qm_set_algs(qm, alg_msk, zip_dev_algs, ARRAY_SIZE(zip_dev_algs)); if (ret) { pci_err(qm->pdev, "Failed to set zip algs!\n"); hisi_qm_uninit(qm); diff --git a/include/linux/hisi_acc_qm.h b/include/linux/hisi_acc_qm.h index b434e4f6111c..1efc2821b7b9 100644 --- a/include/linux/hisi_acc_qm.h +++ b/include/linux/hisi_acc_qm.h @@ -163,6 +163,11 @@ enum qm_cap_bits { QM_SUPPORT_RPM, };
+struct qm_dev_alg { + u64 alg_msk; + const char *alg; +}; + enum qm_dev_fail_state { STOP_QUEUE_FAIL = 1, ALLOC_CTX_FAIL, @@ -556,4 +561,6 @@ void hisi_qm_regs_dump(struct seq_file *s, struct debugfs_regset32 *regset); u32 hisi_qm_get_hw_info(struct hisi_qm *qm, const struct hisi_qm_cap_info *info_table, u32 index, bool is_read); +int hisi_qm_set_algs(struct hisi_qm *qm, u64 alg_msk, const struct qm_dev_alg *dev_algs, + u32 dev_algs_size); #endif
From: Zhiqi Song songzhiqi1@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7BANJ CVE: NA
----------------------------------------------------------------------
We find that in the reset scenario, if the reset failed and the MSE is disabled, the value of capability registers will became invalid. When we remove the device under this situation, the unregister process will read the related irq vector from the capability register directly with the mask. Then we will get an invalid value which is out of range and can not be used to get the right irq number by pci_irq_vector(). This will cause the following call trace:
| Call trace: | pci_irq_vector+0xfc/0x140 | hisi_qm_uninit+0x278/0x3b0 [hisi_qm] | hpre_remove+0x16c/0x1c0 [hisi_hpre] | pci_device_remove+0x6c/0x264 | device_release_driver_internal+0x1ec/0x3e0 | device_release_driver+0x3c/0x60 | pci_stop_bus_device+0xfc/0x22c | pci_stop_and_remove_bus_device+0x38/0x70 | pci_iov_remove_virtfn+0x108/0x1c0 | sriov_disable+0x7c/0x1e4 | pci_disable_sriov+0x4c/0x6c | hisi_qm_sriov_disable+0x90/0x160 [hisi_qm] | hpre_remove+0x1a8/0x1c0 [hisi_hpre] | pci_device_remove+0x6c/0x264 | device_release_driver_internal+0x1ec/0x3e0 | driver_detach+0x168/0x2d0 | bus_remove_driver+0xc0/0x230 | driver_unregister+0x58/0xdc | pci_unregister_driver+0x40/0x220 | hpre_exit+0x34/0x64 [hisi_hpre] | __arm64_sys_delete_module+0x374/0x620 [...]
| Call trace: | free_msi_irqs+0x25c/0x300 | pci_disable_msi+0x19c/0x264 | pci_free_irq_vectors+0x4c/0x70 | hisi_qm_pci_uninit+0x44/0x90 [hisi_qm] | hisi_qm_uninit+0x28c/0x3b0 [hisi_qm] | hpre_remove+0x16c/0x1c0 [hisi_hpre] | pci_device_remove+0x6c/0x264 [...] So we pre-store the valid value of the capability register to a global array in qm init process, and read the register value from this array when we need it. This ensures we can always get valid values.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- drivers/crypto/hisilicon/qm.c | 43 ++++++++++++++++++++++++++++------- include/linux/hisi_acc_qm.h | 5 ++++ 2 files changed, 40 insertions(+), 8 deletions(-)
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index 2abca4fa687c..df6679ea0b0f 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -306,6 +306,13 @@ enum qm_basic_type { QM_VF_IRQ_NUM_CAP, };
+enum qm_irq_type_caps_idx { + QM_EQ_IRQ_TYPE_CAP_IDX, + QM_AEQ_IRQ_TYPE_CAP_IDX, + QM_ABN_IRQ_TYPE_CAP_IDX, + QM_PF2VF_IRQ_TYPE_CAP_IDX +}; + static const struct hisi_qm_cap_info qm_cap_info_comm[] = { {QM_SUPPORT_DB_ISOLATION, 0x30, 0, BIT(0), 0x0, 0x0, 0x0}, {QM_SUPPORT_FUNC_QOS, 0x3100, 0, BIT(8), 0x0, 0x0, 0x1}, @@ -335,6 +342,13 @@ static const struct hisi_qm_cap_info qm_basic_info[] = { {QM_VF_IRQ_NUM_CAP, 0x311c, 0, GENMASK(15, 0), 0x1, 0x2, 0x3}, };
+static struct hisi_qm_cap_record qm_irq_type_caps[] = { + {QM_EQ_IRQ_TYPE_CAP, 0x10000}, + {QM_AEQ_IRQ_TYPE_CAP, 0x10001}, + {QM_ABN_IRQ_TYPE_CAP, 0x10003}, + {QM_PF2VF_IRQ_TYPE_CAP, 0x10002}, +}; + struct qm_mailbox { __le16 w0; __le16 queue_num; @@ -5102,7 +5116,7 @@ static void qm_unregister_abnormal_irq(struct hisi_qm *qm) if (qm->fun_type == QM_HW_VF) return;
- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_ABN_IRQ_TYPE_CAP, qm->cap_ver); + val = qm_irq_type_caps[QM_ABN_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK)) return;
@@ -5119,7 +5133,7 @@ static int qm_register_abnormal_irq(struct hisi_qm *qm) if (qm->fun_type == QM_HW_VF) return 0;
- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_ABN_IRQ_TYPE_CAP, qm->cap_ver); + val = qm_irq_type_caps[QM_ABN_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK)) return 0;
@@ -5136,7 +5150,7 @@ static void qm_unregister_mb_cmd_irq(struct hisi_qm *qm) struct pci_dev *pdev = qm->pdev; u32 irq_vector, val;
- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_PF2VF_IRQ_TYPE_CAP, qm->cap_ver); + val = qm_irq_type_caps[QM_PF2VF_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) return;
@@ -5150,7 +5164,7 @@ static int qm_register_mb_cmd_irq(struct hisi_qm *qm) u32 irq_vector, val; int ret;
- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_PF2VF_IRQ_TYPE_CAP, qm->cap_ver); + val = qm_irq_type_caps[QM_PF2VF_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) return 0;
@@ -5167,7 +5181,7 @@ static void qm_unregister_aeq_irq(struct hisi_qm *qm) struct pci_dev *pdev = qm->pdev; u32 irq_vector, val;
- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_AEQ_IRQ_TYPE_CAP, qm->cap_ver); + val = qm_irq_type_caps[QM_AEQ_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) return;
@@ -5181,7 +5195,7 @@ static int qm_register_aeq_irq(struct hisi_qm *qm) u32 irq_vector, val; int ret;
- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_AEQ_IRQ_TYPE_CAP, qm->cap_ver); + val = qm_irq_type_caps[QM_AEQ_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) return 0;
@@ -5199,7 +5213,7 @@ static void qm_unregister_eq_irq(struct hisi_qm *qm) struct pci_dev *pdev = qm->pdev; u32 irq_vector, val;
- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_EQ_IRQ_TYPE_CAP, qm->cap_ver); + val = qm_irq_type_caps[QM_EQ_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) return;
@@ -5213,7 +5227,7 @@ static int qm_register_eq_irq(struct hisi_qm *qm) u32 irq_vector, val; int ret;
- val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_EQ_IRQ_TYPE_CAP, qm->cap_ver); + val = qm_irq_type_caps[QM_EQ_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) return 0;
@@ -5300,6 +5314,16 @@ static int qm_get_qp_num(struct hisi_qm *qm) return 0; }
+static void qm_pre_store_irq_type_caps(struct hisi_qm *qm) +{ + int i, size; + + size = ARRAY_SIZE(qm_irq_type_caps); + for (i = 0; i < size; i++) + qm_irq_type_caps[i].cap_val = hisi_qm_get_hw_info(qm, qm_basic_info, + qm_irq_type_caps[i].type, qm->cap_ver); +} + static void qm_get_hw_caps(struct hisi_qm *qm) { const struct hisi_qm_cap_info *cap_info = qm->fun_type == QM_HW_PF ? @@ -5331,6 +5355,9 @@ static void qm_get_hw_caps(struct hisi_qm *qm) if (val) set_bit(cap_info[i].type, &qm->caps); } + + /* Fetch and save the value of irq type related capability registers */ + qm_pre_store_irq_type_caps(qm); }
static int qm_get_pci_res(struct hisi_qm *qm) diff --git a/include/linux/hisi_acc_qm.h b/include/linux/hisi_acc_qm.h index 1efc2821b7b9..9b4528ecb610 100644 --- a/include/linux/hisi_acc_qm.h +++ b/include/linux/hisi_acc_qm.h @@ -287,6 +287,11 @@ struct hisi_qm_cap_info { u32 v3_val; };
+struct hisi_qm_cap_record { + u32 type; + u32 cap_val; +}; + struct hisi_qm_list { struct mutex lock; struct list_head list;
From: Zhiqi Song songzhiqi1@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7BANJ CVE: NA
----------------------------------------------------------------------
Pre-store the valid value of hpre alg support related capability register to a global array in hpre_qm_init(), which will be called by hpre_probe(). It can reduce the number of capability register queries and avoid obtaining incorrect values in abnormal scenarios, such as reset failed and the memory space disabled.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- drivers/crypto/hisilicon/hpre/hpre_main.c | 28 +++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c index 804b125d9c79..3a81569f3e70 100644 --- a/drivers/crypto/hisilicon/hpre/hpre_main.c +++ b/drivers/crypto/hisilicon/hpre/hpre_main.c @@ -225,6 +225,16 @@ static const struct hisi_qm_cap_info hpre_basic_info[] = { {HPRE_CORE10_ALG_BITMAP_CAP, 0x3170, 0, GENMASK(31, 0), 0x0, 0x10, 0x10} };
+enum hpre_cap_reg_record_idx { + HPRE_DRV_ALG_BITMAP_CAP_IDX, + HPRE_DEV_ALG_BITMAP_CAP_IDX, +}; + +static struct hisi_qm_cap_record hpre_cap_reg_record[] = { + {HPRE_DRV_ALG_BITMAP_CAP, 0x27}, + {HPRE_DEV_ALG_BITMAP_CAP, 0x7F}, +}; + static const struct hpre_hw_error hpre_hw_errors[] = { { .int_msk = BIT(0), @@ -344,7 +354,7 @@ bool hpre_check_alg_support(struct hisi_qm *qm, u32 alg) { u32 cap_val;
- cap_val = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_DRV_ALG_BITMAP_CAP, qm->cap_ver); + cap_val = hpre_cap_reg_record[HPRE_DRV_ALG_BITMAP_CAP_IDX].cap_val; if (alg & cap_val) return true;
@@ -1099,6 +1109,17 @@ static void hpre_debugfs_exit(struct hisi_qm *qm) debugfs_remove_recursive(qm->debug.debug_root); }
+static void hpre_pre_store_cap_reg(struct hisi_qm *qm) +{ + int i, size; + + size = ARRAY_SIZE(hpre_cap_reg_record); + for (i = 0; i < size; i++) { + hpre_cap_reg_record[i].cap_val = hisi_qm_get_hw_info(qm, hpre_basic_info, + hpre_cap_reg_record[i].type, qm->cap_ver); + } +} + static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) { u64 alg_msk; @@ -1132,7 +1153,10 @@ static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) return ret; }
- alg_msk = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_DEV_ALG_BITMAP_CAP, qm->cap_ver); + /* Fetch and save the value of capability registers */ + hpre_pre_store_cap_reg(qm); + + alg_msk = hpre_cap_reg_record[HPRE_DEV_ALG_BITMAP_CAP_IDX].cap_val; ret = hisi_qm_set_algs(qm, alg_msk, hpre_dev_algs, ARRAY_SIZE(hpre_dev_algs)); if (ret) { pci_err(pdev, "Failed to set hpre algs!\n");
From: Zhiqi Song songzhiqi1@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7BANJ CVE: NA
----------------------------------------------------------------------
Pre-store the valid value of the sec alg support related capability register to a global array in sec_qm_init(), which will be called by sec_probe(). It can reduce the number of capability register queries and avoid obtaining incorrect values in abnormal scenarios, such as reset failed and the memory space disabled.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- drivers/crypto/hisilicon/sec2/sec.h | 7 +++++ drivers/crypto/hisilicon/sec2/sec_crypto.c | 9 ++++-- drivers/crypto/hisilicon/sec2/sec_main.c | 35 +++++++++++++++++----- 3 files changed, 42 insertions(+), 9 deletions(-)
diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h index 9fa6e2a6f9a6..6857d6d9a386 100644 --- a/drivers/crypto/hisilicon/sec2/sec.h +++ b/drivers/crypto/hisilicon/sec2/sec.h @@ -219,6 +219,13 @@ enum sec_cap_type { SEC_CORE4_ALG_BITMAP_HIGH, };
+enum sec_cap_reg_record_idx { + SEC_DRV_ALG_BITMAP_LOW_IDX, + SEC_DRV_ALG_BITMAP_HIGH_IDX, + SEC_DEV_ALG_BITMAP_LOW_IDX, + SEC_DEV_ALG_BITMAP_HIGH_IDX, +}; + void sec_destroy_qps(struct hisi_qp **qps, int qp_num); struct hisi_qp **sec_create_qps(void); int sec_register_to_crypto(struct hisi_qm *qm); diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c index 27db9fa65ddf..43a3c7245505 100644 --- a/drivers/crypto/hisilicon/sec2/sec_crypto.c +++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c @@ -2535,9 +2535,11 @@ static int sec_register_aead(u64 alg_mask)
int sec_register_to_crypto(struct hisi_qm *qm) { - u64 alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH, SEC_DRV_ALG_BITMAP_LOW); + u64 alg_mask; int ret;
+ alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH_IDX, + SEC_DRV_ALG_BITMAP_LOW_IDX); ret = sec_register_skcipher(alg_mask); if (ret) return ret; @@ -2551,7 +2553,10 @@ int sec_register_to_crypto(struct hisi_qm *qm)
void sec_unregister_from_crypto(struct hisi_qm *qm) { - u64 alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH, SEC_DRV_ALG_BITMAP_LOW); + u64 alg_mask; + + alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH_IDX, + SEC_DRV_ALG_BITMAP_LOW_IDX);
sec_unregister_aead(alg_mask, ARRAY_SIZE(sec_aeads)); sec_unregister_skcipher(alg_mask, ARRAY_SIZE(sec_skciphers)); diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c index 91775f56edb9..784416c0c559 100644 --- a/drivers/crypto/hisilicon/sec2/sec_main.c +++ b/drivers/crypto/hisilicon/sec2/sec_main.c @@ -168,6 +168,13 @@ static const struct hisi_qm_cap_info sec_basic_info[] = { {SEC_CORE4_ALG_BITMAP_HIGH, 0x3170, 0, GENMASK(31, 0), 0x3FFF, 0x3FFF, 0x3FFF}, };
+static struct hisi_qm_cap_record sec_cap_reg_record[] = { + {SEC_DRV_ALG_BITMAP_LOW, 0x187F0FF}, + {SEC_DRV_ALG_BITMAP_HIGH, 0x395C}, + {SEC_DEV_ALG_BITMAP_LOW, 0xFFFFFFFF}, + {SEC_DEV_ALG_BITMAP_HIGH, 0x3FFF}, +}; + static const struct qm_dev_alg sec_dev_algs[] = { { .alg_msk = SEC_CIPHER_BITMAP, .alg = "cipher\n", @@ -394,8 +401,8 @@ u64 sec_get_alg_bitmap(struct hisi_qm *qm, u32 high, u32 low) { u32 cap_val_h, cap_val_l;
- cap_val_h = hisi_qm_get_hw_info(qm, sec_basic_info, high, qm->cap_ver); - cap_val_l = hisi_qm_get_hw_info(qm, sec_basic_info, low, qm->cap_ver); + cap_val_h = sec_cap_reg_record[high].cap_val; + cap_val_l = sec_cap_reg_record[low].cap_val;
return ((u64)cap_val_h << SEC_ALG_BITMAP_SHIFT) | (u64)cap_val_l; } @@ -1030,13 +1037,13 @@ static void sec_err_info_init(struct hisi_qm *qm) err_info->nfe = hisi_qm_get_hw_info(qm, sec_basic_info, SEC_QM_NFE_MASK_CAP, qm->cap_ver); err_info->ecc_2bits_mask = SEC_CORE_INT_STATUS_M_ECC; err_info->qm_shutdown_mask = hisi_qm_get_hw_info(qm, sec_basic_info, - SEC_QM_OOO_SHUTDOWN_MASK_CAP, qm->cap_ver); + SEC_QM_OOO_SHUTDOWN_MASK_CAP, qm->cap_ver); err_info->dev_shutdown_mask = hisi_qm_get_hw_info(qm, sec_basic_info, - SEC_OOO_SHUTDOWN_MASK_CAP, qm->cap_ver); + SEC_OOO_SHUTDOWN_MASK_CAP, qm->cap_ver); err_info->qm_reset_mask = hisi_qm_get_hw_info(qm, sec_basic_info, - SEC_QM_RESET_MASK_CAP, qm->cap_ver); + SEC_QM_RESET_MASK_CAP, qm->cap_ver); err_info->dev_reset_mask = hisi_qm_get_hw_info(qm, sec_basic_info, - SEC_RESET_MASK_CAP, qm->cap_ver); + SEC_RESET_MASK_CAP, qm->cap_ver); err_info->msi_wr_port = BIT(0); err_info->acpi_rst = "SRST"; } @@ -1077,6 +1084,17 @@ static int sec_pf_probe_init(struct sec_dev *sec) return ret; }
+static void sec_pre_store_cap_reg(struct hisi_qm *qm) +{ + int i, size; + + size = ARRAY_SIZE(sec_cap_reg_record); + for (i = 0; i < size; i++) { + sec_cap_reg_record[i].cap_val = hisi_qm_get_hw_info(qm, sec_basic_info, + sec_cap_reg_record[i].type, qm->cap_ver); + } +} + static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) { u64 alg_msk; @@ -1114,7 +1132,10 @@ static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) return ret; }
- alg_msk = sec_get_alg_bitmap(qm, SEC_DEV_ALG_BITMAP_HIGH, SEC_DEV_ALG_BITMAP_LOW); + /* Fetch and save the value of capability registers */ + sec_pre_store_cap_reg(qm); + + alg_msk = sec_get_alg_bitmap(qm, SEC_DEV_ALG_BITMAP_HIGH_IDX, SEC_DEV_ALG_BITMAP_LOW_IDX); ret = hisi_qm_set_algs(qm, alg_msk, sec_dev_algs, ARRAY_SIZE(sec_dev_algs)); if (ret) { pci_err(qm->pdev, "Failed to set sec algs!\n");
From: Zhiqi Song songzhiqi1@huawei.com
driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7BANJ CVE: NA
----------------------------------------------------------------------
Pre-store the valid value of the zip alg support related capability register to a global array in hisi_zip_qm_init(), which will be called by hisi_zip_probe(). It can reduce the number of capability register queries and avoid obtaining incorrect values in abnormal scenarios, such as reset failed and the memory space disabled.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- drivers/crypto/hisilicon/zip/zip_main.c | 57 +++++++++++++++++++------ 1 file changed, 44 insertions(+), 13 deletions(-)
diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c index 5cd8b870f300..1099c16f5555 100644 --- a/drivers/crypto/hisilicon/zip/zip_main.c +++ b/drivers/crypto/hisilicon/zip/zip_main.c @@ -241,6 +241,26 @@ static struct hisi_qm_cap_info zip_basic_cap_info[] = { {ZIP_CAP_MAX, 0x317c, 0, GENMASK(0, 0), 0x0, 0x0, 0x0} };
+enum zip_cap_reg_record_idx { + ZIP_CORE_NUM_CAP_IDX, + ZIP_CLUSTER_COMP_NUM_CAP_IDX, + ZIP_CLUSTER_DECOMP_NUM_CAP_IDX, + ZIP_DECOMP_ENABLE_BITMAP_IDX, + ZIP_COMP_ENABLE_BITMAP_IDX, + ZIP_DRV_ALG_BITMAP_IDX, + ZIP_DEV_ALG_BITMAP_IDX, +}; + +static struct hisi_qm_cap_record zip_cap_reg_record[] = { + {ZIP_CORE_NUM_CAP, 0x5}, + {ZIP_CLUSTER_COMP_NUM_CAP, 0x2}, + {ZIP_CLUSTER_DECOMP_NUM_CAP, 0x3}, + {ZIP_DECOMP_ENABLE_BITMAP, 0x1C}, + {ZIP_COMP_ENABLE_BITMAP, 0x3}, + {ZIP_DRV_ALG_BITMAP, 0xF}, + {ZIP_DEV_ALG_BITMAP, 0xFF}, +}; + enum { HZIP_COMP_CORE0, HZIP_COMP_CORE1, @@ -404,7 +424,7 @@ bool hisi_zip_alg_support(struct hisi_qm *qm, u32 alg) { u32 cap_val;
- cap_val = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DRV_ALG_BITMAP, qm->cap_ver); + cap_val = zip_cap_reg_record[ZIP_DRV_ALG_BITMAP_IDX].cap_val; if ((alg & cap_val) == alg) return true;
@@ -507,10 +527,8 @@ static int hisi_zip_set_user_domain_and_cache(struct hisi_qm *qm) }
/* let's open all compression/decompression cores */ - dcomp_bm = hisi_qm_get_hw_info(qm, zip_basic_cap_info, - ZIP_DECOMP_ENABLE_BITMAP, qm->cap_ver); - comp_bm = hisi_qm_get_hw_info(qm, zip_basic_cap_info, - ZIP_COMP_ENABLE_BITMAP, qm->cap_ver); + dcomp_bm = zip_cap_reg_record[ZIP_DECOMP_ENABLE_BITMAP_IDX].cap_val; + comp_bm = zip_cap_reg_record[ZIP_COMP_ENABLE_BITMAP_IDX].cap_val; writel(HZIP_DECOMP_CHECK_ENABLE | dcomp_bm | comp_bm, base + HZIP_CLOCK_GATE_CTRL);
/* enable sqc,cqc writeback */ @@ -737,9 +755,8 @@ static int hisi_zip_core_debug_init(struct hisi_qm *qm) char buf[HZIP_BUF_SIZE]; int i;
- zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver); - zip_comp_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CLUSTER_COMP_NUM_CAP, - qm->cap_ver); + zip_core_num = zip_cap_reg_record[ZIP_CORE_NUM_CAP_IDX].cap_val; + zip_comp_core_num = zip_cap_reg_record[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val;
for (i = 0; i < zip_core_num; i++) { if (i < zip_comp_core_num) @@ -881,7 +898,7 @@ static int hisi_zip_show_last_regs_init(struct hisi_qm *qm) u32 zip_core_num; int i, j, idx;
- zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver); + zip_core_num = zip_cap_reg_record[ZIP_CORE_NUM_CAP_IDX].cap_val;
debug->last_words = kcalloc(core_dfx_regs_num * zip_core_num + com_dfx_regs_num, sizeof(unsigned int), GFP_KERNEL); @@ -937,9 +954,9 @@ static void hisi_zip_show_last_dfx_regs(struct hisi_qm *qm) hzip_com_dfx_regs[i].name, debug->last_words[i], val); }
- zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver); - zip_comp_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CLUSTER_COMP_NUM_CAP, - qm->cap_ver); + zip_core_num = zip_cap_reg_record[ZIP_CORE_NUM_CAP_IDX].cap_val; + zip_comp_core_num = zip_cap_reg_record[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val; + for (i = 0; i < zip_core_num; i++) { if (i < zip_comp_core_num) scnprintf(buf, sizeof(buf), "Comp_core-%d", i); @@ -1091,6 +1108,17 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip) return ret; }
+static void zip_pre_store_cap_reg(struct hisi_qm *qm) +{ + int i, size; + + size = ARRAY_SIZE(zip_cap_reg_record); + for (i = 0; i < size; i++) { + zip_cap_reg_record[i].cap_val = hisi_qm_get_hw_info(qm, zip_basic_cap_info, + zip_cap_reg_record[i].type, qm->cap_ver); + } +} + static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) { u64 alg_msk; @@ -1129,7 +1157,10 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) return ret; }
- alg_msk = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DEV_ALG_BITMAP, qm->cap_ver); + /* Fetch and save the value of capability registers */ + zip_pre_store_cap_reg(qm); + + alg_msk = zip_cap_reg_record[ZIP_DEV_ALG_BITMAP_IDX].cap_val; ret = hisi_qm_set_algs(qm, alg_msk, zip_dev_algs, ARRAY_SIZE(zip_dev_algs)); if (ret) { pci_err(qm->pdev, "Failed to set zip algs!\n");