Commit ce068bc7 authored by Tomas Winkler's avatar Tomas Winkler Committed by Greg Kroah-Hartman
Browse files

mei: allow map and unmap of client dma buffer only for disconnected client



Allow map and unmap of the client dma buffer only when the client is not
connected. The functions return -EPROTO if the client is already connected.
This is to fix the race when traffic may start or stop when buffer
is not available.

Cc: <stable@vger.kernel.org> #v5.11+
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Link: https://lore.kernel.org/r/20210318055959.305627-1-tomas.winkler@intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 903079a5
Loading
Loading
Loading
Loading
+7 −10
Original line number Diff line number Diff line
@@ -2286,8 +2286,8 @@ int mei_cl_dma_alloc_and_map(struct mei_cl *cl, const struct file *fp,
	if (buffer_id == 0)
		return -EINVAL;

	if (!mei_cl_is_connected(cl))
		return -ENODEV;
	if (mei_cl_is_connected(cl))
		return -EPROTO;

	if (cl->dma_mapped)
		return -EPROTO;
@@ -2327,9 +2327,7 @@ int mei_cl_dma_alloc_and_map(struct mei_cl *cl, const struct file *fp,

	mutex_unlock(&dev->device_lock);
	wait_event_timeout(cl->wait,
			   cl->dma_mapped ||
			   cl->status ||
			   !mei_cl_is_connected(cl),
			   cl->dma_mapped || cl->status,
			   mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
	mutex_lock(&dev->device_lock);

@@ -2376,8 +2374,9 @@ int mei_cl_dma_unmap(struct mei_cl *cl, const struct file *fp)
		return -EOPNOTSUPP;
	}

	if (!mei_cl_is_connected(cl))
		return -ENODEV;
	/* do not allow unmap for connected client */
	if (mei_cl_is_connected(cl))
		return -EPROTO;

	if (!cl->dma_mapped)
		return -EPROTO;
@@ -2405,9 +2404,7 @@ int mei_cl_dma_unmap(struct mei_cl *cl, const struct file *fp)

	mutex_unlock(&dev->device_lock);
	wait_event_timeout(cl->wait,
			   !cl->dma_mapped ||
			   cl->status ||
			   !mei_cl_is_connected(cl),
			   !cl->dma_mapped || cl->status,
			   mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
	mutex_lock(&dev->device_lock);