aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2019-10-04 13:23:37 -0400
committerHelge Deller <deller@gmx.de>2019-10-14 15:44:17 -0400
commit513f7f747e1cba81f28a436911fba0b485878ebd (patch)
tree1d6d3351b0fb65e2f262645a9f5514bddad572f9 /arch/parisc
parent0703ad217ebd441dd730af71f8d9cdbf144fbc03 (diff)
parisc: Fix vmap memory leak in ioremap()/iounmap()
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 vunmap() in iounmap(). Signed-off-by: Helge Deller <deller@gmx.de> Noticed-by: Sven Schnelle <svens@stackframe.org> Cc: <stable@vger.kernel.org> # v3.16+
Diffstat (limited to 'arch/parisc')
-rw-r--r--arch/parisc/mm/ioremap.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c
index 92a9b5f12f98..f29f682352f0 100644
--- a/arch/parisc/mm/ioremap.c
+++ b/arch/parisc/mm/ioremap.c
@@ -3,7 +3,7 @@
3 * arch/parisc/mm/ioremap.c 3 * arch/parisc/mm/ioremap.c
4 * 4 *
5 * (C) Copyright 1995 1996 Linus Torvalds 5 * (C) Copyright 1995 1996 Linus Torvalds
6 * (C) Copyright 2001-2006 Helge Deller <deller@gmx.de> 6 * (C) Copyright 2001-2019 Helge Deller <deller@gmx.de>
7 * (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org> 7 * (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org>
8 */ 8 */
9 9
@@ -84,7 +84,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
84 addr = (void __iomem *) area->addr; 84 addr = (void __iomem *) area->addr;
85 if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, 85 if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
86 phys_addr, pgprot)) { 86 phys_addr, pgprot)) {
87 vfree(addr); 87 vunmap(addr);
88 return NULL; 88 return NULL;
89 } 89 }
90 90
@@ -92,9 +92,11 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
92} 92}
93EXPORT_SYMBOL(__ioremap); 93EXPORT_SYMBOL(__ioremap);
94 94
95void iounmap(const volatile void __iomem *addr) 95void iounmap(const volatile void __iomem *io_addr)
96{ 96{
97 if (addr > high_memory) 97 unsigned long addr = (unsigned long)io_addr & PAGE_MASK;
98 return vfree((void *) (PAGE_MASK & (unsigned long __force) addr)); 98
99 if (is_vmalloc_addr((void *)addr))
100 vunmap((void *)addr);
99} 101}
100EXPORT_SYMBOL(iounmap); 102EXPORT_SYMBOL(iounmap);