Commit 5b90073d authored by Weili Qian's avatar Weili Qian Committed by Herbert Xu

crypto: hisilicon/qm - alloc buffer to set and get xqc

If the temporarily applied memory is used to set or get the xqc
information, the driver releases the memory immediately after the
hardware mailbox operation time exceeds the driver waiting time.
However, the hardware does not cancel the operation, so the hardware
may write data to released memory.

Therefore, when the driver is bound to a device, the driver reserves
memory for the xqc configuration. The subsequent xqc configuration
uses the reserved memory to prevent hardware from accessing the
released memory.
Signed-off-by: default avatarWeili Qian <qianweili@huawei.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 8405ec8e
......@@ -137,8 +137,8 @@ static void dump_show(struct hisi_qm *qm, void *info,
static int qm_sqc_dump(struct hisi_qm *qm, char *s, char *name)
{
struct device *dev = &qm->pdev->dev;
struct qm_sqc *sqc, *sqc_curr;
dma_addr_t sqc_dma;
struct qm_sqc *sqc_curr;
struct qm_sqc sqc;
u32 qp_id;
int ret;
......@@ -151,35 +151,29 @@ static int qm_sqc_dump(struct hisi_qm *qm, char *s, char *name)
return -EINVAL;
}
sqc = hisi_qm_ctx_alloc(qm, sizeof(*sqc), &sqc_dma);
if (IS_ERR(sqc))
return PTR_ERR(sqc);
ret = qm_set_and_get_xqc(qm, QM_MB_CMD_SQC, &sqc, qp_id, 1);
if (!ret) {
dump_show(qm, &sqc, sizeof(struct qm_sqc), name);
ret = hisi_qm_mb(qm, QM_MB_CMD_SQC, sqc_dma, qp_id, 1);
if (ret) {
down_read(&qm->qps_lock);
if (qm->sqc) {
sqc_curr = qm->sqc + qp_id;
return 0;
}
dump_show(qm, sqc_curr, sizeof(*sqc), "SOFT SQC");
}
up_read(&qm->qps_lock);
down_read(&qm->qps_lock);
if (qm->sqc) {
sqc_curr = qm->sqc + qp_id;
goto free_ctx;
dump_show(qm, sqc_curr, sizeof(*sqc_curr), "SOFT SQC");
}
up_read(&qm->qps_lock);
dump_show(qm, sqc, sizeof(*sqc), name);
free_ctx:
hisi_qm_ctx_free(qm, sizeof(*sqc), sqc, &sqc_dma);
return 0;
}
static int qm_cqc_dump(struct hisi_qm *qm, char *s, char *name)
{
struct device *dev = &qm->pdev->dev;
struct qm_cqc *cqc, *cqc_curr;
dma_addr_t cqc_dma;
struct qm_cqc *cqc_curr;
struct qm_cqc cqc;
u32 qp_id;
int ret;
......@@ -192,34 +186,29 @@ static int qm_cqc_dump(struct hisi_qm *qm, char *s, char *name)
return -EINVAL;
}
cqc = hisi_qm_ctx_alloc(qm, sizeof(*cqc), &cqc_dma);
if (IS_ERR(cqc))
return PTR_ERR(cqc);
ret = qm_set_and_get_xqc(qm, QM_MB_CMD_CQC, &cqc, qp_id, 1);
if (!ret) {
dump_show(qm, &cqc, sizeof(struct qm_cqc), name);
ret = hisi_qm_mb(qm, QM_MB_CMD_CQC, cqc_dma, qp_id, 1);
if (ret) {
down_read(&qm->qps_lock);
if (qm->cqc) {
cqc_curr = qm->cqc + qp_id;
return 0;
}
dump_show(qm, cqc_curr, sizeof(*cqc), "SOFT CQC");
}
up_read(&qm->qps_lock);
down_read(&qm->qps_lock);
if (qm->cqc) {
cqc_curr = qm->cqc + qp_id;
goto free_ctx;
dump_show(qm, cqc_curr, sizeof(*cqc_curr), "SOFT CQC");
}
up_read(&qm->qps_lock);
dump_show(qm, cqc, sizeof(*cqc), name);
free_ctx:
hisi_qm_ctx_free(qm, sizeof(*cqc), cqc, &cqc_dma);
return 0;
}
static int qm_eqc_aeqc_dump(struct hisi_qm *qm, char *s, char *name)
{
struct device *dev = &qm->pdev->dev;
dma_addr_t xeqc_dma;
struct qm_aeqc aeqc;
struct qm_eqc eqc;
size_t size;
void *xeqc;
int ret;
......@@ -233,23 +222,19 @@ static int qm_eqc_aeqc_dump(struct hisi_qm *qm, char *s, char *name)
if (!strcmp(name, "EQC")) {
cmd = QM_MB_CMD_EQC;
size = sizeof(struct qm_eqc);
xeqc = &eqc;
} else {
cmd = QM_MB_CMD_AEQC;
size = sizeof(struct qm_aeqc);
xeqc = &aeqc;
}
xeqc = hisi_qm_ctx_alloc(qm, size, &xeqc_dma);
if (IS_ERR(xeqc))
return PTR_ERR(xeqc);
ret = hisi_qm_mb(qm, cmd, xeqc_dma, 0, 1);
ret = qm_set_and_get_xqc(qm, cmd, xeqc, 0, 1);
if (ret)
goto err_free_ctx;
return ret;
dump_show(qm, xeqc, size, name);
err_free_ctx:
hisi_qm_ctx_free(qm, size, xeqc, &xeqc_dma);
return ret;
}
......
This diff is collapsed.
......@@ -76,10 +76,7 @@ static const char * const qm_s[] = {
"init", "start", "close", "stop",
};
void *hisi_qm_ctx_alloc(struct hisi_qm *qm, size_t ctx_size,
dma_addr_t *dma_addr);
void hisi_qm_ctx_free(struct hisi_qm *qm, size_t ctx_size,
const void *ctx_addr, dma_addr_t *dma_addr);
int qm_set_and_get_xqc(struct hisi_qm *qm, u8 cmd, void *xqc, u32 qp_id, bool op);
void hisi_qm_show_last_dfx_regs(struct hisi_qm *qm);
void hisi_qm_set_algqos_init(struct hisi_qm *qm);
......
......@@ -292,6 +292,18 @@ struct qm_err_isolate {
struct list_head qm_hw_errs;
};
struct qm_rsv_buf {
struct qm_sqc *sqc;
struct qm_cqc *cqc;
struct qm_eqc *eqc;
struct qm_aeqc *aeqc;
dma_addr_t sqc_dma;
dma_addr_t cqc_dma;
dma_addr_t eqc_dma;
dma_addr_t aeqc_dma;
struct qm_dma qcdma;
};
struct hisi_qm {
enum qm_hw_ver ver;
enum qm_fun_type fun_type;
......@@ -324,6 +336,7 @@ struct hisi_qm {
dma_addr_t cqc_dma;
dma_addr_t eqe_dma;
dma_addr_t aeqe_dma;
struct qm_rsv_buf xqc_buf;
struct hisi_qm_status status;
const struct hisi_qm_err_ini *err_ini;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment