aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyongHo <pullip.cho@samsung.com>2012-05-29 15:06:49 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-06-17 11:23:13 -0700
commitc201beec4842674cd4773771931d25c9a5d45d66 (patch)
tree338e5e02fc63fd3cadfcdd4f273a02bd49c96e6d
parent5c2d31dda012797578d012425a785d58e14d2053 (diff)
downloadkernel_samsung_smdk4412-c201beec4842674cd4773771931d25c9a5d45d66.zip
kernel_samsung_smdk4412-c201beec4842674cd4773771931d25c9a5d45d66.tar.gz
kernel_samsung_smdk4412-c201beec4842674cd4773771931d25c9a5d45d66.tar.bz2
mm: fix faulty initialization in vmalloc_init()
commit dbda591d920b4c7692725b13e3f68ecb251e9080 upstream. The transfer of ->flags causes some of the static mapping virtual addresses to be prematurely freed (before the mapping is removed) because VM_LAZY_FREE gets "set" if tmp->flags has VM_IOREMAP set. This might cause subsequent vmalloc/ioremap calls to fail because it might allocate one of the freed virtual address ranges that aren't unmapped. va->flags has different types of flags from tmp->flags. If a region with VM_IOREMAP set is registered with vm_area_add_early(), it will be removed by __purge_vmap_area_lazy(). Fix vmalloc_init() to correctly initialize vmap_area for the given vm_struct. Also initialise va->vm. If it is not set, find_vm_area() for the early vm regions will always fail. Signed-off-by: KyongHo Cho <pullip.cho@samsung.com> Cc: "Olav Haugan" <ohaugan@codeaurora.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--mm/vmalloc.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 3e927cc..bdb7004 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1174,9 +1174,10 @@ void __init vmalloc_init(void)
/* Import existing vmlist entries. */
for (tmp = vmlist; tmp; tmp = tmp->next) {
va = kzalloc(sizeof(struct vmap_area), GFP_NOWAIT);
- va->flags = tmp->flags | VM_VM_AREA;
+ va->flags = VM_VM_AREA;
va->va_start = (unsigned long)tmp->addr;
va->va_end = va->va_start + tmp->size;
+ va->vm = tmp;
__insert_vmap_area(va);
}