Unverified Commit c0c5f5fd authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!14106 uacce: some bugfix and cleanup

Merge Pull Request from: @xiao_jiang_shui 
 
1. uacce: add error number for the unsupported mremap
Since the driver doesn't support the mremap, add an error number to
show users the fail.

2. uacce: check the qfr address before releasing the qfr
When qfr type is UACCE_QFRT_SS, qfr may be noiommu_ss_default_qfr.
The memory is global static memory and cannot be freed. Therefore,
the qfr address needs to be checked before the qfr is released.

3. uacce: add stop_queue to replace put_queue in ioctl
Since the resources of uacce_queue cannot be ensured to be fully
released before calling put_queue, directly putting the queue might
pose a slight risk.

4. uacce: add mutex for check qfr
Since the qfr operations can race in some cases, the validity checks
require locking protection.

5. crypto: hisilicon/zip - correct the wrong word in the printed information
Correct the wrong word in the printed information.

6. crypto: hisilicon/qm - fix the uacce_alloc return value check
The uacce_alloc mentions that caller needs check returned negotiated
uacce->flags. And now it will clear the bit UACCE_DEV_SVA if failed to
enable sva. So the qm need to remove uacce if 'flags' changes.

7. migration: modify dfx error type without VM driver
In the live migration scenario, when the ACC driver is not insmod
to the VM, the command to test the mailbox operation will detect
that the device has no driver loaded. However, the error reported
is the same as the abnormal parameter when testing dfx, and the
error scenario cannot be distinguished.
Therefore, this error type needs to be modified.

issue: https://gitee.com/openeuler/kernel/issues/IB9H0P 
 
Link:https://gitee.com/openeuler/kernel/pulls/14106

 

Reviewed-by: default avatarYang Shen <shenyang39@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents b05af249 3258b093
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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;
	}
+48 −25
Original line number Diff line number Diff line
@@ -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(&current->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);
		if (qfr != &noiommu_ss_default_qfr)
			kfree(qfr);
	} else if (qfr->type != UACCE_QFRT_SS) {
	} 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;
}

+1 −1
Original line number Diff line number Diff line
@@ -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);