[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210609223503.2649114-6-elder@linaro.org>
Date: Wed, 9 Jun 2021 17:34:57 -0500
From: Alex Elder <elder@...aro.org>
To: davem@...emloft.net, kuba@...nel.org
Cc: bjorn.andersson@...aro.org, evgreen@...omium.org,
cpratapa@...eaurora.org, subashab@...eaurora.org, elder@...nel.org,
netdev@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH net-next 05/11] net: ipa: separate region range check from other validation
The only thing done by ipa_mem_valid_one() that requires hardware
access is the check for whether all regions fit within the size of
IPA local memory specified by an IPA register.
Introduce ipa_mem_size_valid() to implement this verification and
stop doing so in ipa_mem_valid_one(). Call the new function from
ipa_mem_config() (which is also the caller of ipa_mem_valid()).
Signed-off-by: Alex Elder <elder@...aro.org>
---
drivers/net/ipa/ipa_mem.c | 29 ++++++++++++++++++++++++++---
1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ipa/ipa_mem.c b/drivers/net/ipa/ipa_mem.c
index 62e1b8280d982..f245e1a60a44b 100644
--- a/drivers/net/ipa/ipa_mem.c
+++ b/drivers/net/ipa/ipa_mem.c
@@ -115,9 +115,6 @@ static bool ipa_mem_valid_one(struct ipa *ipa, const struct ipa_mem *mem)
else if (mem->offset < mem->canary_count * sizeof(__le32))
dev_err(dev, "region %u offset too small for %hu canaries\n",
mem_id, mem->canary_count);
- else if (mem->offset + mem->size > ipa->mem_size)
- dev_err(dev, "region %u ends beyond memory limit (0x%08x)\n",
- mem_id, ipa->mem_size);
else if (mem_id == IPA_MEM_END_MARKER && mem->size)
dev_err(dev, "non-zero end marker region size\n");
else
@@ -151,6 +148,28 @@ static bool ipa_mem_valid(struct ipa *ipa)
return true;
}
+/* Do all memory regions fit within the IPA local memory? */
+static bool ipa_mem_size_valid(struct ipa *ipa)
+{
+ struct device *dev = &ipa->pdev->dev;
+ u32 limit = ipa->mem_size;
+ enum ipa_mem_id mem_id;
+
+ for (mem_id = 0; mem_id < ipa->mem_count; mem_id++) {
+ const struct ipa_mem *mem = &ipa->mem[mem_id];
+
+ if (mem->offset + mem->size <= limit)
+ continue;
+
+ dev_err(dev, "region %u ends beyond memory limit (0x%08x)\n",
+ mem_id, limit);
+
+ return false;
+ }
+
+ return true;
+}
+
/**
* ipa_mem_config() - Configure IPA shared memory
* @ipa: IPA pointer
@@ -184,6 +203,10 @@ int ipa_mem_config(struct ipa *ipa)
mem_size);
}
+ /* We know our memory size; make sure regions are all in range */
+ if (!ipa_mem_size_valid(ipa))
+ return -EINVAL;
+
/* Prealloc DMA memory for zeroing regions */
virt = dma_alloc_coherent(dev, IPA_MEM_MAX, &addr, GFP_KERNEL);
if (!virt)
--
2.27.0
Powered by blists - more mailing lists