All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] parisc: Fix vmap memory leak in ioremap()/iounmap()
@ 2019-09-09 13:38 Helge Deller
  2019-09-30  6:20 ` Jeroen Roovers
  0 siblings, 1 reply; 6+ messages in thread
From: Helge Deller @ 2019-09-09 13:38 UTC (permalink / raw)
  To: linux-parisc, James Bottomley, John David Anglin; +Cc: Sven Schnelle

Sven noticed that calling ioremap() and iounmap() multiple times leads
to a vmap memory leak:
	vmap allocation for size 4198400 failed:
	use vmalloc=<size> to increase size

It seems we missed calling remove_vm_area() for ioummap().

Signed-off-by: Helge Deller <deller@gmx.de>
Noticed-by: Sven Schnelle <svens@stackframe.org>
Cc: <stable@vger.kernel.org>

diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c
index 92a9b5f12f98..bcfa98aa134c 100644
--- a/arch/parisc/mm/ioremap.c
+++ b/arch/parisc/mm/ioremap.c
@@ -3,13 +3,14 @@
  * arch/parisc/mm/ioremap.c
  *
  * (C) Copyright 1995 1996 Linus Torvalds
- * (C) Copyright 2001-2006 Helge Deller <deller@gmx.de>
+ * (C) Copyright 2001-2019 Helge Deller <deller@gmx.de>
  * (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org>
  */

 #include <linux/vmalloc.h>
 #include <linux/errno.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 #include <asm/pgalloc.h>

@@ -84,7 +85,8 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
 	addr = (void __iomem *) area->addr;
 	if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
 			       phys_addr, pgprot)) {
-		vfree(addr);
+		remove_vm_area((void __force *)addr);
+		kfree(area);
 		return NULL;
 	}

@@ -94,7 +96,24 @@ EXPORT_SYMBOL(__ioremap);

 void iounmap(const volatile void __iomem *addr)
 {
-	if (addr > high_memory)
-		return vfree((void *) (PAGE_MASK & (unsigned long __force) addr));
+	struct vm_struct *p, *o;
+
+	if (addr <= high_memory)
+		return;
+
+	addr = (volatile void __iomem *)
+		(PAGE_MASK & (unsigned long __force)addr);
+
+	p = find_vm_area((void __force *)addr);
+	if (!p) {
+		printk(KERN_ERR "iounmap: bad address %p\n", addr);
+		dump_stack();
+		return;
+	}
+
+	/* Finally remove it */
+	o = remove_vm_area((void __force *)addr);
+	BUG_ON(p != o || o == NULL);
+	kfree(p);
 }
 EXPORT_SYMBOL(iounmap);

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-10-11 19:17 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-09-09 13:38 [PATCH] parisc: Fix vmap memory leak in ioremap()/iounmap() Helge Deller
2019-09-30  6:20 ` Jeroen Roovers
2019-09-30  6:35   ` Carlo Pisani
2019-10-02 15:38   ` Helge Deller
2019-10-04 17:23     ` [PATCH v2] " Helge Deller
2019-10-11 19:17     ` pATA Promise Technologies PDC20265 (datasheet) Carlo Pisani

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.