From f452e8f092b3e500ac955e44b7a3f1680d62d8f7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 Sep 2024 16:26:27 -0600 Subject: [PATCH] sandbox: Implement reference counting for address mapping An address may be mapped twice and unmapped twice. Delete the mapping only when the last user unmaps it. Fix a missing comment while here. Signed-off-by: Simon Glass --- arch/sandbox/cpu/cpu.c | 14 ++++++++++---- arch/sandbox/include/asm/state.h | 3 +++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index 3e1c0dd583..51ce40e7f0 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -111,6 +111,7 @@ void *phys_to_virt(phys_addr_t paddr) if (mentry->tag == paddr) { log_debug("Used map from %lx to %p\n", (ulong)paddr, mentry->ptr); + mentry->refcnt++; return mentry->ptr; } } @@ -200,10 +201,12 @@ void unmap_physmem(const void *ptr, unsigned long flags) mentry = find_tag(ptr); if (mentry) { - list_del(&mentry->sibling_node); - log_debug("Removed map from %p to %lx\n", ptr, - (ulong)mentry->tag); - free(mentry); + if (!--mentry->refcnt) { + list_del(&mentry->sibling_node); + log_debug("Removed map from %p to %lx\n", ptr, + (ulong)mentry->tag); + free(mentry); + } } else { log_warning("Address not mapped: %p\n", ptr); } @@ -235,11 +238,14 @@ phys_addr_t map_to_sysmem(const void *ptr) } mentry->tag = state->next_tag++; mentry->ptr = (void *)ptr; + mentry->refcnt = 0; list_add_tail(&mentry->sibling_node, &state->mapmem_head); log_debug("Added map from %p to %lx\n", ptr, (ulong)mentry->tag); } + mentry->refcnt++; + /* * Return the tag as the address to use. A later call to map_sysmem() * will return ptr diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 6b50473ed4..e7dc01759e 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -53,10 +53,13 @@ struct sandbox_wdt_info { * be returned, just as it would for a normal sandbox address. * * @tag: Address tag (a value which U-Boot uses to refer to the address) + * @refcnt: Number of references to this tag * @ptr: Associated pointer for that tag + * @sibling_node: Next node */ struct sandbox_mapmem_entry { ulong tag; + uint refcnt; void *ptr; struct list_head sibling_node; }; -- 2.39.5