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

Commit 33c7ee26 authored by Jilai Wang's avatar Jilai Wang
Browse files

msm: npu: Avoid OOB while accessing registers and memory



This change is to add boundary check while accessing registers
and memory to avoid accessing invalid IO regions.

Change-Id: Ibe4f45cbff813ab2107e0f4d2c8137bf3bd0d9ce
Signed-off-by: default avatarJilai Wang <jilaiw@codeaurora.org>
parent d754300a
Loading
Loading
Loading
Loading
+69 −29
Original line number Diff line number Diff line
@@ -20,67 +20,93 @@
 * Functions - Register
 * -------------------------------------------------------------------------
 */
uint32_t npu_core_reg_read(struct npu_device *npu_dev, uint32_t off)
static uint32_t npu_reg_read(void __iomem *base, size_t size, uint32_t off)
{
	uint32_t ret = 0;
	if (!base) {
		NPU_ERR("NULL base address\n");
		return 0;
	}

	ret = readl(npu_dev->core_io.base + off);
	return ret;
	if ((off % 4) != 0) {
		NPU_ERR("offset %x is not aligned\n", off);
		return 0;
	}

void npu_core_reg_write(struct npu_device *npu_dev, uint32_t off, uint32_t val)
	if (off >= size) {
		NPU_ERR("offset exceeds io region %x:%x\n", off, size);
		return 0;
	}

	return readl_relaxed(base + off);
}

static void npu_reg_write(void __iomem *base, size_t size, uint32_t off,
	uint32_t val)
{
	writel_relaxed(val, npu_dev->core_io.base + off);
	if (!base) {
		NPU_ERR("NULL base address\n");
		return;
	}

	if ((off % 4) != 0) {
		NPU_ERR("offset %x is not aligned\n", off);
		return;
	}

	if (off >= size) {
		NPU_ERR("offset exceeds io region %x:%x\n", off, size);
		return;
	}

	writel_relaxed(val, base + off);
	__iowmb();
}

uint32_t npu_tcsr_reg_read(struct npu_device *npu_dev, uint32_t off)
uint32_t npu_core_reg_read(struct npu_device *npu_dev, uint32_t off)
{
	uint32_t ret = 0;
	return npu_reg_read(npu_dev->core_io.base, npu_dev->core_io.size, off);
}

	ret = readl_relaxed(npu_dev->tcsr_io.base + off);
	return ret;
void npu_core_reg_write(struct npu_device *npu_dev, uint32_t off, uint32_t val)
{
	npu_reg_write(npu_dev->core_io.base, npu_dev->core_io.size,
		off, val);
}

uint32_t npu_apss_shared_reg_read(struct npu_device *npu_dev, uint32_t off)
uint32_t npu_tcsr_reg_read(struct npu_device *npu_dev, uint32_t off)
{
	uint32_t ret = 0;
	return npu_reg_read(npu_dev->tcsr_io.base, npu_dev->tcsr_io.size, off);
}

	ret = readl(npu_dev->apss_shared_io.base + off);
	return ret;
uint32_t npu_apss_shared_reg_read(struct npu_device *npu_dev, uint32_t off)
{
	return npu_reg_read(npu_dev->apss_shared_io.base,
		npu_dev->apss_shared_io.size, off);
}

void npu_apss_shared_reg_write(struct npu_device *npu_dev, uint32_t off,
	uint32_t val)
{
	writel_relaxed(val, npu_dev->apss_shared_io.base + off);
	__iowmb();
	npu_reg_write(npu_dev->apss_shared_io.base,
		npu_dev->apss_shared_io.size, off, val);
}

uint32_t npu_cc_reg_read(struct npu_device *npu_dev, uint32_t off)
{
	uint32_t ret = 0;

	ret = readl_relaxed(npu_dev->cc_io.base + off);

	return ret;
	return npu_reg_read(npu_dev->cc_io.base, npu_dev->cc_io.size, off);
}

void npu_cc_reg_write(struct npu_device *npu_dev, uint32_t off,
	uint32_t val)
{
	writel_relaxed(val, npu_dev->cc_io.base + off);
	__iowmb();
	npu_reg_write(npu_dev->cc_io.base, npu_dev->cc_io.size,
		off, val);
}

uint32_t npu_qfprom_reg_read(struct npu_device *npu_dev, uint32_t off)
{
	uint32_t ret = 0;

	if (npu_dev->qfprom_io.base)
		ret = readl(npu_dev->qfprom_io.base + off);

	return ret;
	return npu_reg_read(npu_dev->qfprom_io.base,
		npu_dev->qfprom_io.size, off);
}

/* -------------------------------------------------------------------------
@@ -96,6 +122,13 @@ void npu_mem_write(struct npu_device *npu_dev, void *dst, void *src,
	uint32_t i = 0;
	uint32_t num = 0;

	if (dst_off >= npu_dev->tcm_io.size ||
		(npu_dev->tcm_io.size - dst_off) < size) {
		NPU_ERR("memory write exceeds io region %x:%x:%x\n",
			dst_off, size, npu_dev->tcm_io.size);
		return;
	}

	num = size/4;
	for (i = 0; i < num; i++) {
		writel_relaxed(src_ptr32[i], npu_dev->tcm_io.base + dst_off);
@@ -122,6 +155,13 @@ int32_t npu_mem_read(struct npu_device *npu_dev, void *src, void *dst,
	uint32_t i = 0;
	uint32_t num = 0;

	if (src_off >= npu_dev->tcm_io.size ||
		(npu_dev->tcm_io.size - src_off) < size) {
		NPU_ERR("memory read exceeds io region %x:%x:%x\n",
			src_off, size, npu_dev->tcm_io.size);
		return 0;
	}

	num = size/4;
	for (i = 0; i < num; i++) {
		out32[i] = readl_relaxed(npu_dev->tcm_io.base + src_off);