diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index f5d9ff496005f226b4727437a90dbb82dabdb46a..b3bd4aece611eba5ae99752a701857587d043f4a 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -2786,6 +2786,7 @@ static int qm_alloc_uacce(struct hisi_qm *qm) struct uacce_interface interface = {0}; struct pci_dev *pdev = qm->pdev; struct uacce_device *uacce; + u32 flags; int ret; ret = strscpy(interface.name, dev_driver_string(&pdev->dev), @@ -2804,11 +2805,18 @@ static int qm_alloc_uacce(struct hisi_qm *qm) } interface.ops = &uacce_qm_ops; + flags = interface.flags; uacce = uacce_alloc(&pdev->dev, &interface); if (IS_ERR(uacce)) { pci_err(pdev, "fail to alloc uacce device\n!"); return PTR_ERR(uacce); } + if (flags != interface.flags) { + pci_err(pdev, "fail to enable sva\n!"); + uacce_remove(uacce); + return -EINVAL; + } + qm->uacce = uacce; qm_uacce_base_init(qm); diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c b/drivers/crypto/hisilicon/zip/zip_crypto.c index 7327f8f29b013811c702ecab7baf9e5670eab88a..5cf72bbc311fc9741bd231d0b57e5723c3ede34a 100644 --- a/drivers/crypto/hisilicon/zip/zip_crypto.c +++ b/drivers/crypto/hisilicon/zip/zip_crypto.c @@ -236,7 +236,7 @@ static int hisi_zip_do_work(struct hisi_zip_qp_ctx *qp_ctx, &req->dma_dst); if (IS_ERR(req->hw_dst)) { ret = PTR_ERR(req->hw_dst); - dev_err(dev, "failed to map the dst buffer to hw slg (%d)!\n", + dev_err(dev, "failed to map the dst buffer to hw sgl (%d)!\n", ret); goto err_unmap_input; } diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c index 6e142a04b08031c78a38cb8b9b536ebb085fb2a4..f324877ebc1fbd1b8fe7f2eeac96b8165d9942bc 100644 --- a/drivers/misc/uacce/uacce.c +++ b/drivers/misc/uacce/uacce.c @@ -47,22 +47,28 @@ static int uacce_start_queue(struct uacce_queue *q) return 0; } -static int uacce_put_queue(struct uacce_queue *q) +static int uacce_stop_queue(struct uacce_queue *q) { struct uacce_device *uacce = q->uacce; if ((q->state == UACCE_Q_STARTED) && uacce->ops->stop_queue) uacce->ops->stop_queue(q); - if ((q->state == UACCE_Q_INIT || q->state == UACCE_Q_STARTED) && - uacce->ops->put_queue) - uacce->ops->put_queue(q); - q->state = UACCE_Q_ZOMBIE; return 0; } +static void uacce_put_queue(struct uacce_queue *q) +{ + struct uacce_device *uacce = q->uacce; + + uacce_stop_queue(q); + + if (uacce->ops->put_queue) + uacce->ops->put_queue(q); +} + static long uacce_cmd_share_qfr(struct uacce_queue *src, int fd) { struct device *dev = &src->uacce->dev; @@ -222,7 +228,7 @@ static long uacce_fops_unl_ioctl(struct file *filep, ret = uacce_start_queue(q); break; case UACCE_CMD_PUT_Q: - ret = uacce_put_queue(q); + ret = uacce_stop_queue(q); break; case UACCE_CMD_SHARE_SVAS: ret = uacce_cmd_share_qfr(q, (int)arg); @@ -360,40 +366,53 @@ static void uacce_vma_close(struct vm_area_struct *vma) struct uacce_queue *q = vma->vm_private_data; struct uacce_qfile_region *qfr = NULL; struct uacce_device *uacce = q->uacce; - struct device *dev = &q->uacce->dev; if (vma->vm_pgoff >= UACCE_MAX_REGION) return; - qfr = q->qfrs[vma->vm_pgoff]; - if (!qfr) { - dev_err(dev, "qfr NULL, type %lu!\n", vma->vm_pgoff); - return; - } - - if (qfr->type == UACCE_QFRT_SS && + if (vma->vm_pgoff == UACCE_QFRT_SS && atomic_read(¤t->active_mm->mm_users) > 0) { /* * uacce_vma_close() and uacce_remove() may be executed concurrently. * To avoid accessing the same address at the same time, takes the uacce->mutex. */ mutex_lock(&uacce->mutex); + mutex_lock(&q->mutex); + qfr = q->qfrs[vma->vm_pgoff]; + if (!qfr) { + mutex_lock(&q->mutex); + mutex_unlock(&uacce->mutex); + return; + } if ((q->state == UACCE_Q_STARTED) && uacce->ops->stop_queue) uacce->ops->stop_queue(q); uacce_free_dma_buffers(q); q->qfrs[vma->vm_pgoff] = NULL; + mutex_unlock(&q->mutex); mutex_unlock(&uacce->mutex); - kfree(qfr); - } else if (qfr->type != UACCE_QFRT_SS) { + if (qfr != &noiommu_ss_default_qfr) + kfree(qfr); + } else if (vma->vm_pgoff != UACCE_QFRT_SS) { mutex_lock(&q->mutex); + qfr = q->qfrs[vma->vm_pgoff]; + if (!qfr) { + mutex_unlock(&q->mutex); + return; + } q->qfrs[vma->vm_pgoff] = NULL; mutex_unlock(&q->mutex); kfree(qfr); } } +static int uacce_vma_mremap(struct vm_area_struct *area) +{ + return -EPERM; +} + static const struct vm_operations_struct uacce_vm_ops = { .close = uacce_vma_close, + .mremap = uacce_vma_mremap, }; static int get_sort_base(struct uacce_dma_slice *list, int low, int high, @@ -615,24 +634,28 @@ static int uacce_fops_mmap(struct file *filep, struct vm_area_struct *vma) else return -EINVAL; - if (q->qfrs[type]) - return -EEXIST; - - qfr = kzalloc(sizeof(*qfr), GFP_KERNEL); - if (!qfr) - return -ENOMEM; - vm_flags_set(vma, VM_DONTCOPY | VM_DONTEXPAND | VM_WIPEONFORK); vma->vm_ops = &uacce_vm_ops; vma->vm_private_data = q; - qfr->type = type; mutex_lock(&q->mutex); + if (q->qfrs[type]) { + mutex_unlock(&q->mutex); + return -EEXIST; + } + + qfr = kzalloc(sizeof(*qfr), GFP_KERNEL); + if (!qfr) { + ret = -ENOMEM; + goto out_with_lock; + } + if (!uacce_queue_is_valid(q)) { ret = -ENXIO; goto out_with_lock; } + qfr->type = type; q->qfrs[type] = qfr; switch (type) { @@ -664,9 +687,9 @@ static int uacce_fops_mmap(struct file *filep, struct vm_area_struct *vma) return ret; out_with_lock: + q->qfrs[type] = NULL; mutex_unlock(&q->mutex); kfree(qfr); - q->qfrs[type] = NULL; return ret; } diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c index 0a35894301052ddeb5cf89ccd5998a6080c32515..c8b60d1384e4f4e5cbee57341ba13c28d8e6ed95 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c @@ -1523,7 +1523,7 @@ static ssize_t acc_vf_debug_write(struct file *filp, const char __user *buffer, case MB_TEST: ret = acc_vf_debug_test(hisi_acc_vdev); if (ret) - return -EINVAL; + return -EAGAIN; break; case MIG_DATA_DUMP: acc_vf_dev_data_dump(hisi_acc_vdev);