diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c index 7abc187033b9f87a3f0d6f336d62852e612182c0..50007c7355d9d5b0cab8599a7b85e390da222389 100644 --- a/drivers/crypto/hisilicon/hpre/hpre_main.c +++ b/drivers/crypto/hisilicon/hpre/hpre_main.c @@ -1356,6 +1356,15 @@ static void hpre_disable_error_report(struct hisi_qm *qm, u32 err_type) writel(nfe_mask & (~err_type), qm->io_base + HPRE_RAS_NFE_ENB); } +static void hpre_enable_error_report(struct hisi_qm *qm) +{ + u32 nfe_mask = qm->err_info.dev_err.nfe; + u32 ce_mask = qm->err_info.dev_err.ce; + + writel(nfe_mask, qm->io_base + HPRE_RAS_NFE_ENB); + writel(ce_mask, qm->io_base + HPRE_RAS_CE_ENB); +} + static void hpre_open_axi_master_ooo(struct hisi_qm *qm) { u32 value; @@ -1383,6 +1392,8 @@ static enum acc_err_result hpre_get_err_result(struct hisi_qm *qm) return ACC_ERR_NEED_RESET; } hpre_clear_hw_err_status(qm, err_status); + /* Avoid firmware disable error report, re-enable. */ + hpre_enable_error_report(qm); } return ACC_ERR_RECOVERED; diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index 36b23e3b6c46fff98e65afb1dabc9275a6763a48..d7a7826cb016ec3e1d01b00567bc3a0a7028236d 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -4147,13 +4147,14 @@ int hisi_qm_sriov_enable(struct pci_dev *pdev, int max_vfs) goto err_put_sync; } + qm->vfs_num = num_vfs; ret = pci_enable_sriov(pdev, num_vfs); if (ret) { pci_err(pdev, "Can't enable VF!\n"); qm_clear_vft_config(qm); + qm->vfs_num = 0; goto err_put_sync; } - qm->vfs_num = num_vfs; pci_info(pdev, "VF enabled, vfs_num(=%d)!\n", num_vfs); @@ -4175,6 +4176,7 @@ EXPORT_SYMBOL_GPL(hisi_qm_sriov_enable); int hisi_qm_sriov_disable(struct pci_dev *pdev, bool is_frozen) { struct hisi_qm *qm = pci_get_drvdata(pdev); + int ret; if (pci_vfs_assigned(pdev)) { pci_err(pdev, "Failed to disable VFs as VFs are assigned!\n"); @@ -4188,11 +4190,14 @@ int hisi_qm_sriov_disable(struct pci_dev *pdev, bool is_frozen) } pci_disable_sriov(pdev); + ret = qm_clear_vft_config(qm); + if (ret) + pci_err(pdev, "Failed to clear vft config!\n"); qm->vfs_num = 0; qm_pm_put_sync(qm); - return qm_clear_vft_config(qm); + return 0; } EXPORT_SYMBOL_GPL(hisi_qm_sriov_disable); @@ -4961,6 +4966,15 @@ void hisi_qm_reset_done(struct pci_dev *pdev) } EXPORT_SYMBOL_GPL(hisi_qm_reset_done); +static irqreturn_t qm_rsvd_irq(int irq, void *data) +{ + struct hisi_qm *qm = data; + + dev_info(&qm->pdev->dev, "Reserved interrupt, ignore!\n"); + + return IRQ_HANDLED; +} + static irqreturn_t qm_abnormal_irq(int irq, void *data) { struct hisi_qm *qm = data; @@ -5253,17 +5267,14 @@ static void qm_unregister_abnormal_irq(struct hisi_qm *qm) struct pci_dev *pdev = qm->pdev; u32 irq_vector, val; - if (qm->fun_type == QM_HW_VF) - return; - - if (!qm->err_ini->err_info_init) - return; - val = qm->cap_tables.qm_cap_table[QM_ABNORMAL_IRQ].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK)) return; - irq_vector = val & QM_IRQ_VECTOR_MASK; + + if (qm->fun_type == QM_HW_VF && qm->ver < QM_HW_V3) + return; + free_irq(pci_irq_vector(pdev, irq_vector), qm); } @@ -5273,24 +5284,29 @@ static int qm_register_abnormal_irq(struct hisi_qm *qm) u32 irq_vector, val; int ret; - if (qm->fun_type == QM_HW_VF) + val = qm->cap_tables.qm_cap_table[QM_ABNORMAL_IRQ].cap_val; + if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK)) return 0; + irq_vector = val & QM_IRQ_VECTOR_MASK; - if (!qm->err_ini->err_info_init) { - dev_info(&qm->pdev->dev, "device doesnot support error init!\n"); - return 0; - } + /* For VF, this is a reserved interrupt in V3 version. */ + if (qm->fun_type == QM_HW_VF) { + if (qm->ver < QM_HW_V3) + return 0; - val = qm->cap_tables.qm_cap_table[QM_ABNORMAL_IRQ].cap_val; - if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK)) + ret = request_irq(pci_irq_vector(pdev, irq_vector), qm_rsvd_irq, + IRQF_NO_AUTOEN, qm->dev_name, qm); + if (ret) { + dev_err(&pdev->dev, "failed to request reserved irq, ret = %d!\n", ret); + return ret; + } return 0; + } INIT_WORK(&qm->rst_work, hisi_qm_controller_reset); - - irq_vector = val & QM_IRQ_VECTOR_MASK; ret = request_irq(pci_irq_vector(pdev, irq_vector), qm_abnormal_irq, 0, qm->dev_name, qm); if (ret) { - dev_err(&qm->pdev->dev, "failed to request abnormal irq, ret = %d!\n", ret); + dev_err(&pdev->dev, "failed to request abnormal irq, ret = %d!\n", ret); return ret; } @@ -5733,6 +5749,12 @@ static int hisi_qm_pci_init(struct hisi_qm *qm) pci_set_master(pdev); num_vec = qm_get_irq_num(qm); + if (!num_vec) { + dev_err(dev, "Device irq num is zero!\n"); + ret = -EINVAL; + goto err_get_pci_res; + } + num_vec = roundup_pow_of_two(num_vec); ret = pci_alloc_irq_vectors(pdev, num_vec, num_vec, PCI_IRQ_MSI); if (ret < 0) { dev_err(dev, "Failed to enable MSI vectors!\n"); diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c index 9af30716c49cf8ec738329499d54fe9e19a26eb7..dfc63e98cf486bee02de0e37cbcc26d78e2b9f3b 100644 --- a/drivers/crypto/hisilicon/sec2/sec_main.c +++ b/drivers/crypto/hisilicon/sec2/sec_main.c @@ -1065,6 +1065,15 @@ static void sec_disable_error_report(struct hisi_qm *qm, u32 err_type) writel(nfe_mask & (~err_type), qm->io_base + SEC_RAS_NFE_REG); } +static void sec_enable_error_report(struct hisi_qm *qm) +{ + u32 nfe_mask = qm->err_info.dev_err.nfe; + u32 ce_mask = qm->err_info.dev_err.ce; + + writel(nfe_mask, qm->io_base + SEC_RAS_NFE_REG); + writel(ce_mask, qm->io_base + SEC_RAS_CE_REG); +} + static void sec_open_axi_master_ooo(struct hisi_qm *qm) { u32 val; @@ -1090,6 +1099,8 @@ static enum acc_err_result sec_get_err_result(struct hisi_qm *qm) return ACC_ERR_NEED_RESET; } sec_clear_hw_err_status(qm, err_status); + /* Avoid firmware disable error report, re-enable. */ + sec_enable_error_report(qm); } return ACC_ERR_RECOVERED; diff --git a/drivers/crypto/hisilicon/trng/trng.c b/drivers/crypto/hisilicon/trng/trng.c index 8f1743a053dfcca90815df0b3d5c39d909e20def..5acd5261439c76f8c139997b22e92842cfa4e5b0 100644 --- a/drivers/crypto/hisilicon/trng/trng.c +++ b/drivers/crypto/hisilicon/trng/trng.c @@ -44,7 +44,6 @@ #define WAIT_PERIOD 20 struct hisi_trng_list { - struct mutex lock; struct list_head list; bool is_init; }; @@ -67,6 +66,7 @@ struct hisi_trng_ctx { static atomic_t trng_active_devs; static struct hisi_trng_list trng_devices; +static DEFINE_MUTEX(trng_device_lock); static void hisi_trng_set_seed(struct hisi_trng *trng, const u8 *seed) { @@ -172,7 +172,7 @@ static int hisi_trng_init(struct crypto_tfm *tfm) struct hisi_trng *trng; int ret = 0; - mutex_lock(&trng_devices.lock); + mutex_lock(&trng_device_lock); list_for_each_entry(trng, &trng_devices.list, list) { if (!trng->is_used) { trng->is_used = true; @@ -181,7 +181,7 @@ static int hisi_trng_init(struct crypto_tfm *tfm) break; } } - mutex_unlock(&trng_devices.lock); + mutex_unlock(&trng_device_lock); if (!ctx->trng) { ctx->drbg = crypto_alloc_rng("drbg_nopr_ctr_aes256", 0, 0); @@ -191,9 +191,9 @@ static int hisi_trng_init(struct crypto_tfm *tfm) return ret; } - mutex_lock(&trng_devices.lock); + mutex_lock(&trng_device_lock); if (list_empty(&trng_devices.list)) { - mutex_unlock(&trng_devices.lock); + mutex_unlock(&trng_device_lock); crypto_free_rng(ctx->drbg); return -ENODEV; } @@ -202,7 +202,7 @@ static int hisi_trng_init(struct crypto_tfm *tfm) struct hisi_trng, list); trng->ctx_num++; ctx->trng = trng; - mutex_unlock(&trng_devices.lock); + mutex_unlock(&trng_device_lock); } return ret; @@ -212,14 +212,16 @@ static void hisi_trng_exit(struct crypto_tfm *tfm) { struct hisi_trng_ctx *ctx = crypto_tfm_ctx(tfm); - mutex_lock(&trng_devices.lock); + mutex_lock(&trng_device_lock); + if (!ctx->drbg) ctx->trng->is_used = false; else crypto_free_rng(ctx->drbg); ctx->trng->ctx_num--; - mutex_unlock(&trng_devices.lock); + + mutex_unlock(&trng_device_lock); } static int hisi_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait) @@ -270,21 +272,28 @@ static struct rng_alg hisi_trng_alg = { static void hisi_trng_add_to_list(struct hisi_trng *trng) { - mutex_lock(&trng_devices.lock); + mutex_lock(&trng_device_lock); + if (!trng_devices.is_init) { + INIT_LIST_HEAD(&trng_devices.list); + trng_devices.is_init = true; + } + list_add_tail(&trng->list, &trng_devices.list); - mutex_unlock(&trng_devices.lock); + mutex_unlock(&trng_device_lock); } static int hisi_trng_del_from_list(struct hisi_trng *trng) { int ret = -EBUSY; - mutex_lock(&trng_devices.lock); + mutex_lock(&trng_device_lock); + if (!trng->ctx_num) { list_del(&trng->list); ret = 0; } - mutex_unlock(&trng_devices.lock); + + mutex_unlock(&trng_device_lock); return ret; } @@ -307,11 +316,6 @@ static int hisi_trng_probe(struct platform_device *pdev) trng->is_used = false; trng->ctx_num = 0; trng->ver = readl(trng->base + HISI_TRNG_VERSION); - if (!trng_devices.is_init) { - INIT_LIST_HEAD(&trng_devices.list); - mutex_init(&trng_devices.lock); - trng_devices.is_init = true; - } hisi_trng_add_to_list(trng); if (trng->ver != HISI_TRNG_VER_V1 && diff --git a/drivers/crypto/hisilicon/zip/dae_main.c b/drivers/crypto/hisilicon/zip/dae_main.c index 6f22e4c36e494f7500c1ac0633f8f3feeacbdc45..63e3a1e7c2fb4bbaf0bf6d90969e1248d4acd9aa 100644 --- a/drivers/crypto/hisilicon/zip/dae_main.c +++ b/drivers/crypto/hisilicon/zip/dae_main.c @@ -87,7 +87,7 @@ int hisi_dae_set_alg(struct hisi_qm *qm) if (!dae_is_support(qm)) return 0; - if (!qm->uacce) + if (!qm->uacce || qm->mode != UACCE_MODE_SVA) return 0; len = strlen(qm->uacce->algs); @@ -168,6 +168,12 @@ static void hisi_dae_disable_error_report(struct hisi_qm *qm, u32 err_type) writel(DAE_ERR_NFE_MASK & (~err_type), qm->io_base + DAE_ERR_NFE_OFFSET); } +static void hisi_dae_enable_error_report(struct hisi_qm *qm) +{ + writel(DAE_ERR_CE_MASK, qm->io_base + DAE_ERR_CE_OFFSET); + writel(DAE_ERR_NFE_MASK, qm->io_base + DAE_ERR_NFE_OFFSET); +} + static void hisi_dae_log_hw_error(struct hisi_qm *qm, u32 err_type) { const struct hisi_dae_hw_error *err = dae_hw_error; @@ -209,6 +215,8 @@ enum acc_err_result hisi_dae_get_err_result(struct hisi_qm *qm) return ACC_ERR_NEED_RESET; } hisi_dae_clear_hw_err_status(qm, err_status); + /* Avoid firmware disable error report, re-enable. */ + hisi_dae_enable_error_report(qm); return ACC_ERR_RECOVERED; } diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c index 10ddbaa02773f6a803d9ef01eb888579f98228c6..31bb0178f1bf4d902610c20663af8dc433c4da29 100644 --- a/drivers/crypto/hisilicon/zip/zip_main.c +++ b/drivers/crypto/hisilicon/zip/zip_main.c @@ -1117,6 +1117,15 @@ static void hisi_zip_disable_error_report(struct hisi_qm *qm, u32 err_type) writel(nfe_mask & (~err_type), qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB); } +static void hisi_zip_enable_error_report(struct hisi_qm *qm) +{ + u32 nfe_mask = qm->err_info.dev_err.nfe; + u32 ce_mask = qm->err_info.dev_err.ce; + + writel(nfe_mask, qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB); + writel(ce_mask, qm->io_base + HZIP_CORE_INT_RAS_CE_ENB); +} + static void hisi_zip_open_axi_master_ooo(struct hisi_qm *qm) { u32 val; @@ -1165,6 +1174,8 @@ static enum acc_err_result hisi_zip_get_err_result(struct hisi_qm *qm) zip_result = ACC_ERR_NEED_RESET; } else { hisi_zip_clear_hw_err_status(qm, err_status); + /* Avoid firmware disable error report, re-enable. */ + hisi_zip_enable_error_report(qm); } } diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c index ac1b2ec3ec1653b08fd29c15fbfd9a62d44eb055..f1d74a0894597e040178c4cc2c7b3fa469e6d160 100644 --- a/drivers/misc/uacce/uacce.c +++ b/drivers/misc/uacce/uacce.c @@ -525,7 +525,7 @@ static int uacce_alloc_dma_buffers(struct uacce_queue *q, size = vma->vm_end - start; else size = max_size; - dev_dbg(pdev, "allocate dma %ld pages\n", + dev_dbg(pdev, "allocate dma %lu pages\n", (size + PAGE_SIZE - 1) >> PAGE_SHIFT); slice[i].kaddr = dma_alloc_coherent(pdev, (size + PAGE_SIZE - 1) & PAGE_MASK, @@ -886,7 +886,7 @@ static umode_t uacce_dev_is_visible(struct kobject *kobj, return 0; if (attr == &dev_attr_isolate_strategy.attr && - (!uacce->ops->isolate_err_threshold_read && + (!uacce->ops->isolate_err_threshold_read || !uacce->ops->isolate_err_threshold_write)) return 0; @@ -955,18 +955,14 @@ static void uacce_disable_sva(struct uacce_device *uacce) struct uacce_device *uacce_alloc(struct device *parent, struct uacce_interface *interface) { + unsigned int flags = interface->flags; struct uacce_device *uacce; - unsigned int flags; int ret; - if (!parent || !interface) - return ERR_PTR(-EINVAL); - uacce = kzalloc(sizeof(struct uacce_device), GFP_KERNEL); if (!uacce) return ERR_PTR(-ENOMEM); - flags = interface->flags; flags = uacce_enable_sva(parent, flags); uacce->parent = parent;