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

Commit 8b10b1d5 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: npu: Avoid OOB while accessing registers and memory"

parents bd262581 09cc344e
Loading
Loading
Loading
Loading
+65 −18
Original line number Diff line number Diff line
@@ -29,43 +29,76 @@
 * 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) {
		pr_err("NULL base address\n");
		return 0;
	}

	ret = readl(npu_dev->core_io.base + off);
	return ret;
	if ((off % 4) != 0) {
		pr_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) {
		pr_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) {
		pr_err("NULL base address\n");
		return;
	}

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

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

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

uint32_t npu_bwmon_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(npu_dev->bwmon_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_bwmon_reg_read(struct npu_device *npu_dev, uint32_t off)
{
	return npu_reg_read(npu_dev->bwmon_io.base, npu_dev->bwmon_io.size,
		off);
}

void npu_bwmon_reg_write(struct npu_device *npu_dev, uint32_t off,
	uint32_t val)
{
	writel_relaxed(val, npu_dev->bwmon_io.base + off);
	__iowmb();
	npu_reg_write(npu_dev->bwmon_io.base, npu_dev->bwmon_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);
}

/* -------------------------------------------------------------------------
@@ -81,6 +114,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) {
		pr_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);
@@ -107,6 +147,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) {
		pr_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);
+2 −12
Original line number Diff line number Diff line
@@ -436,7 +436,8 @@ static void npu_destroy_wq(struct npu_host_ctx *host_ctx)
static struct workqueue_struct *npu_create_wq(struct npu_host_ctx *host_ctx,
	const char *name)
{
	struct workqueue_struct *wq = create_workqueue(name);
	struct workqueue_struct *wq =
		alloc_workqueue(name, WQ_HIGHPRI | WQ_UNBOUND, 0);

	INIT_WORK(&host_ctx->irq_work, host_irq_wq);
	INIT_DELAYED_WORK(&host_ctx->fw_deinit_work, fw_deinit_wq);
@@ -579,17 +580,6 @@ static struct npu_network *alloc_network(struct npu_host_ctx *ctx,

	WARN_ON(!mutex_is_locked(&ctx->lock));

	for (i = 0; i < MAX_LOADED_NETWORK; i++) {
		if ((network->id != 0) &&
			(network->client != client)) {
			pr_err("NPU is used by other client now\n");
			return NULL;
		}

		network++;
	}

	network = ctx->networks;
	for (i = 0; i < MAX_LOADED_NETWORK; i++) {
		if (network->id == 0)
			break;