Commit 4d1906f4 authored by Zhiqi Song's avatar Zhiqi Song Committed by JiangShui
Browse files

crypto: hisilicon/sec2 - save capability registers in probe process

driver inclusion
category: bugfix
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: default avatarZhiqi Song <songzhiqi1@huawei.com>
Signed-off-by: default avatarJiangShui Yang <yangjiangshui@h-partners.com>
parent f6b0ab94
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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);
+7 −2
Original line number Diff line number Diff line
@@ -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));
+28 −7
Original line number Diff line number Diff line
@@ -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;
}
@@ -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");