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

From: Adrian Ng Ho Yin

Date: Wed Jul 22 2026 - 05:41:53 EST


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 <adrian.ho.yin.ng@xxxxxxxxxx>
---
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