diff options
author | KyongHo <pullip.cho@samsung.com> | 2012-05-29 18:06:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-29 19:22:24 -0400 |
commit | dbda591d920b4c7692725b13e3f68ecb251e9080 (patch) | |
tree | 15de210e18f06b02cfcd180556a07938a3d2578b /mm | |
parent | 26c191788f18129af0eb32a358cdaea0c7479626 (diff) |
mm: fix faulty initialization in vmalloc_init()
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>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/vmalloc.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index c28b0b9e5cc0..2aad49981b57 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c | |||
@@ -1185,9 +1185,10 @@ void __init vmalloc_init(void) | |||
1185 | /* Import existing vmlist entries. */ | 1185 | /* Import existing vmlist entries. */ |
1186 | for (tmp = vmlist; tmp; tmp = tmp->next) { | 1186 | for (tmp = vmlist; tmp; tmp = tmp->next) { |
1187 | va = kzalloc(sizeof(struct vmap_area), GFP_NOWAIT); | 1187 | va = kzalloc(sizeof(struct vmap_area), GFP_NOWAIT); |
1188 | va->flags = tmp->flags | VM_VM_AREA; | 1188 | va->flags = VM_VM_AREA; |
1189 | va->va_start = (unsigned long)tmp->addr; | 1189 | va->va_start = (unsigned long)tmp->addr; |
1190 | va->va_end = va->va_start + tmp->size; | 1190 | va->va_end = va->va_start + tmp->size; |
1191 | va->vm = tmp; | ||
1191 | __insert_vmap_area(va); | 1192 | __insert_vmap_area(va); |
1192 | } | 1193 | } |
1193 | 1194 | ||