Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ae1b5911 authored by Maya Erez's avatar Maya Erez Committed by Gerrit - the friendly Code Review server
Browse files

wil6210: prevent ioctl access while in reset or suspend



Accessing some of the memory of the device while the device is
resetting or suspending may cause unexpected error as the HW is still
not in a stable state. Prevent this access to guarantee successful
read/write memory operations.

Change-Id: Idbf046e21726ec8d074161f75643f34137d6ec24
Signed-off-by: default avatarAhmad Masri <amasri@codeaurora.org>
Signed-off-by: default avatarMaya Erez <merez@codeaurora.org>
Signed-off-by: default avatarLior David <liord@codeaurora.org>
parent 3fb337ee
Loading
Loading
Loading
Loading
+19 −3
Original line number Original line Diff line number Diff line
@@ -59,6 +59,7 @@ static int wil_ioc_memio_dword(struct wil6210_priv *wil, void __user *data)
	struct wil_memio io;
	struct wil_memio io;
	void __iomem *a;
	void __iomem *a;
	bool need_copy = false;
	bool need_copy = false;
	int rc;


	if (copy_from_user(&io, data, sizeof(io)))
	if (copy_from_user(&io, data, sizeof(io)))
		return -EFAULT;
		return -EFAULT;
@@ -72,6 +73,11 @@ static int wil_ioc_memio_dword(struct wil6210_priv *wil, void __user *data)
			io.op);
			io.op);
		return -EINVAL;
		return -EINVAL;
	}
	}

	rc = wil_mem_access_lock(wil);
	if (rc)
		return rc;

	/* operation */
	/* operation */
	switch (io.op & WIL_MMIO_OP_MASK) {
	switch (io.op & WIL_MMIO_OP_MASK) {
	case WIL_MMIO_READ:
	case WIL_MMIO_READ:
@@ -86,9 +92,12 @@ static int wil_ioc_memio_dword(struct wil6210_priv *wil, void __user *data)
#endif
#endif
	default:
	default:
		wil_err(wil, "Unsupported operation, op = 0x%08x\n", io.op);
		wil_err(wil, "Unsupported operation, op = 0x%08x\n", io.op);
		wil_mem_access_unlock(wil);
		return -EINVAL;
		return -EINVAL;
	}
	}


	wil_mem_access_unlock(wil);

	if (need_copy) {
	if (need_copy) {
		wil_dbg_ioctl(wil,
		wil_dbg_ioctl(wil,
			      "IO done: addr(0x%08x) val(0x%08x) op(0x%08x)\n",
			      "IO done: addr(0x%08x) val(0x%08x) op(0x%08x)\n",
@@ -134,6 +143,12 @@ static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data)
	if (!block)
	if (!block)
		return -ENOMEM;
		return -ENOMEM;


	rc = wil_mem_access_lock(wil);
	if (rc) {
		kfree(block);
		return rc;
	}

	/* operation */
	/* operation */
	switch (io.op & WIL_MMIO_OP_MASK) {
	switch (io.op & WIL_MMIO_OP_MASK) {
	case WIL_MMIO_READ:
	case WIL_MMIO_READ:
@@ -142,7 +157,7 @@ static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data)
		if (copy_to_user((void __user *)(uintptr_t)io.block,
		if (copy_to_user((void __user *)(uintptr_t)io.block,
				 block, io.size)) {
				 block, io.size)) {
			rc = -EFAULT;
			rc = -EFAULT;
			goto out_free;
			goto out_unlock;
		}
		}
		break;
		break;
#if defined(CONFIG_WIL6210_WRITE_IOCTL)
#if defined(CONFIG_WIL6210_WRITE_IOCTL)
@@ -150,7 +165,7 @@ static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data)
		if (copy_from_user(block, (void __user *)(uintptr_t)io.block,
		if (copy_from_user(block, (void __user *)(uintptr_t)io.block,
				   io.size)) {
				   io.size)) {
			rc = -EFAULT;
			rc = -EFAULT;
			goto out_free;
			goto out_unlock;
		}
		}
		wil_memcpy_toio_32(a, block, io.size);
		wil_memcpy_toio_32(a, block, io.size);
		wmb(); /* make sure write propagated to HW */
		wmb(); /* make sure write propagated to HW */
@@ -163,7 +178,8 @@ static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data)
		break;
		break;
	}
	}


out_free:
out_unlock:
	wil_mem_access_unlock(wil);
	kfree(block);
	kfree(block);
	return rc;
	return rc;
}
}