Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: hisilicon/qm - invalidate queues in use

Before the device reset, although the driver has set the queue
status to intercept doorbells sent by the task process, the reset
thread is isolated from the user-mode task process, so the task process
may still send doorbells. Therefore, before the reset, the queue is
directly invalidated, and the device directly discards the doorbells
sent by the process.

Signed-off-by: Weili Qian <qianweili@huawei.com>
Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Weili Qian and committed by
Herbert Xu
85acd1b2 5ce9891e

+40 -13
+40 -13
drivers/crypto/hisilicon/qm.c
··· 45 45 46 46 #define QM_SQ_TYPE_MASK GENMASK(3, 0) 47 47 #define QM_SQ_TAIL_IDX(sqc) ((le16_to_cpu((sqc).w11) >> 6) & 0x1) 48 + #define QM_SQC_DISABLE_QP (1U << 6) 49 + #define QM_XQC_RANDOM_DATA 0xaaaa 48 50 49 51 /* cqc shift */ 50 52 #define QM_CQ_HOP_NUM_SHIFT 0 ··· 3196 3194 3197 3195 qm_init_eq_aeq_status(qm); 3198 3196 3197 + /* Before starting the dev, clear the memory and then configure to device using. */ 3198 + memset(qm->qdma.va, 0, qm->qdma.size); 3199 + 3199 3200 ret = qm_eq_ctx_cfg(qm); 3200 3201 if (ret) { 3201 3202 dev_err(dev, "Set eqc failed!\n"); ··· 3210 3205 3211 3206 static int __hisi_qm_start(struct hisi_qm *qm) 3212 3207 { 3208 + struct device *dev = &qm->pdev->dev; 3213 3209 int ret; 3214 3210 3215 - WARN_ON(!qm->qdma.va); 3211 + if (!qm->qdma.va) { 3212 + dev_err(dev, "qm qdma is NULL!\n"); 3213 + return -EINVAL; 3214 + } 3216 3215 3217 3216 if (qm->fun_type == QM_HW_PF) { 3218 3217 ret = hisi_qm_set_vft(qm, 0, qm->qp_base, qm->qp_num); ··· 3290 3281 for (i = 0; i < qm->qp_num; i++) { 3291 3282 qp = &qm->qp_array[i]; 3292 3283 if (atomic_read(&qp->qp_status.flags) == QP_STOP && 3293 - qp->is_resetting == true) { 3284 + qp->is_resetting == true && qp->is_in_kernel == true) { 3294 3285 ret = qm_start_qp_nolock(qp, 0); 3295 3286 if (ret < 0) { 3296 3287 dev_err(dev, "Failed to start qp%d!\n", i); ··· 3322 3313 } 3323 3314 3324 3315 /** 3325 - * qm_clear_queues() - Clear all queues memory in a qm. 3326 - * @qm: The qm in which the queues will be cleared. 3316 + * qm_invalid_queues() - invalid all queues in use. 3317 + * @qm: The qm in which the queues will be invalidated. 3327 3318 * 3328 - * This function clears all queues memory in a qm. Reset of accelerator can 3329 - * use this to clear queues. 3319 + * This function invalid all queues in use. If the doorbell command is sent 3320 + * to device in user space after the device is reset, the device discards 3321 + * the doorbell command. 3330 3322 */ 3331 - static void qm_clear_queues(struct hisi_qm *qm) 3323 + static void qm_invalid_queues(struct hisi_qm *qm) 3332 3324 { 3333 3325 struct hisi_qp *qp; 3326 + struct qm_sqc *sqc; 3327 + struct qm_cqc *cqc; 3334 3328 int i; 3329 + 3330 + /* 3331 + * Normal stop queues is no longer used and does not need to be 3332 + * invalid queues. 3333 + */ 3334 + if (qm->status.stop_reason == QM_NORMAL) 3335 + return; 3336 + 3337 + if (qm->status.stop_reason == QM_DOWN) 3338 + hisi_qm_cache_wb(qm); 3335 3339 3336 3340 for (i = 0; i < qm->qp_num; i++) { 3337 3341 qp = &qm->qp_array[i]; 3338 - if (qp->is_in_kernel && qp->is_resetting) 3342 + if (!qp->is_resetting) 3343 + continue; 3344 + 3345 + /* Modify random data and set sqc close bit to invalid queue. */ 3346 + sqc = qm->sqc + i; 3347 + cqc = qm->cqc + i; 3348 + sqc->w8 = cpu_to_le16(QM_XQC_RANDOM_DATA); 3349 + sqc->w13 = cpu_to_le16(QM_SQC_DISABLE_QP); 3350 + cqc->w8 = cpu_to_le16(QM_XQC_RANDOM_DATA); 3351 + if (qp->is_in_kernel) 3339 3352 memset(qp->qdma.va, 0, qp->qdma.size); 3340 3353 } 3341 - 3342 - memset(qm->qdma.va, 0, qm->qdma.size); 3343 3354 } 3344 3355 3345 3356 /** ··· 3416 3387 } 3417 3388 } 3418 3389 3419 - qm_clear_queues(qm); 3390 + qm_invalid_queues(qm); 3420 3391 qm->status.stop_reason = QM_NORMAL; 3421 3392 3422 3393 err_unlock: ··· 4814 4785 ret = hisi_qm_stop(qm, QM_DOWN); 4815 4786 if (ret) 4816 4787 dev_err(&pdev->dev, "Fail to stop qm in shutdown!\n"); 4817 - 4818 - hisi_qm_cache_wb(qm); 4819 4788 } 4820 4789 EXPORT_SYMBOL_GPL(hisi_qm_dev_shutdown); 4821 4790