[PATCH v2 RESEND v2 3/5] firmware: stratix10-svc: fix list corruption in stratix10_svc_free_memory

Adrian Ng Ho Yin <[email protected]>
Newsgroups org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel
Message-ID <728586aafb602977ff0c5f6e21322530bbb75c12.1786520346.git.adrian.ho.yin.ng@altera.com>
When no matching buffer is found, the fallthrough path calls
list_del(&svc_data_mem), corrupting the list head. Replace it with
dev_warn() to report the spurious free address.

hile here, refactor the loop to use an inverted condition with continue
to reduce nesting. Add braces in svc_pa_to_va() for consistency, and fix
a stale "physical address" comment to "address" since paddr is not
strictly a physical address.

Fixes: 5a0793ac66ac ("firmware: stratix10-svc: fix a missing check on list iterator")
Signed-off-by: Adrian Ng Ho Yin <[email protected]>
---
 drivers/firmware/stratix10-svc.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c
index 00e134e663c8..20ab90a4584f 100644
--- a/drivers/firmware/stratix10-svc.c
+++ b/drivers/firmware/stratix10-svc.c
@@ -318,11 +318,12 @@ static void *svc_pa_to_va(unsigned long addr)
 
 	pr_debug("claim back P-addr=0x%016x\n", (unsigned int)addr);
 	guard(mutex)(&svc_mem_lock);
-	list_for_each_entry(pmem, &svc_data_mem, node)
+	list_for_each_entry(pmem, &svc_data_mem, node) {
 		if (pmem->paddr == addr)
 			return pmem->vaddr;
+	}
 
-	/* physical address is not found */
+	/* address is not found */
 	return NULL;
 }
 
@@ -1880,19 +1881,23 @@ EXPORT_SYMBOL_GPL(stratix10_svc_allocate_memory);
  */
 void stratix10_svc_free_memory(struct stratix10_svc_chan *chan, void *kaddr)
 {
+	struct stratix10_svc_controller *ctrl = chan->ctrl;
 	struct stratix10_svc_data_mem *pmem;
+
 	guard(mutex)(&svc_mem_lock);
 
-	list_for_each_entry(pmem, &svc_data_mem, node)
-		if (pmem->vaddr == kaddr) {
-			gen_pool_free(chan->ctrl->genpool,
-				       (unsigned long)kaddr, pmem->size);
-			pmem->vaddr = NULL;
-			list_del(&pmem->node);
-			return;
-		}
+	list_for_each_entry(pmem, &svc_data_mem, node) {
+		if (pmem->vaddr != kaddr)
+			continue;
+
+		gen_pool_free(chan->ctrl->genpool,
+			      (unsigned long)kaddr, pmem->size);
+		pmem->vaddr = NULL;
+		list_del(&pmem->node);
+		return;
+	}
 
-	list_del(&svc_data_mem);
+	dev_warn(ctrl->dev, "free of unknown buffer %p\n", kaddr);
 }
 EXPORT_SYMBOL_GPL(stratix10_svc_free_memory);
 
-- 
2.49.GIT
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.