2012-05-24 08:33:02

by Cho KyongHo

[permalink] [raw]
Subject: mm: fix faulty initialization in vmalloc_init()

vmalloc_init() adds 'vmap_area's for early 'vm_struct's.
This patch fixes vmalloc_init() to correctly initialize
vmap_area for the given vm_struct.

Signed-off-by: KyongHo Cho <[email protected]>
---
mm/vmalloc.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 94dff88..1196c77 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1185,9 +1185,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);
}

--
1.7.1


2012-05-24 22:12:33

by Andrew Morton

[permalink] [raw]
Subject: Re: mm: fix faulty initialization in vmalloc_init()

On Thu, 24 May 2012 17:32:56 +0900
KyongHo <[email protected]> wrote:

> vmalloc_init() adds 'vmap_area's for early 'vm_struct's.
> This patch fixes vmalloc_init() to correctly initialize
> vmap_area for the given vm_struct.
>

<daily message>
Insufficient information. When fixing a bug please always always
always describe the user-visible effects of the bug. Does the kernel
instantly crash? Is it a comestic cleanliness thing which has no
effect? Something in between? I have simply no idea, and am dependent
upon you to tell me.

> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -1185,9 +1185,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;

This change is a mystery. Why do we no longer transfer ->flags?

> va->va_start = (unsigned long)tmp->addr;
> va->va_end = va->va_start + tmp->size;
> + va->vm = tmp;

OK, I can see how this might be important. But why did you find it
necessary? Why was this change actually needed?

> __insert_vmap_area(va);
> }

2012-05-25 00:24:04

by Olav Haugan

[permalink] [raw]
Subject: RE: mm: fix faulty initialization in vmalloc_init()

> -----Original Message-----
> On Thu, 24 May 2012 17:32:56 +0900
> KyongHo <[email protected]> wrote:
>
> > --- a/mm/vmalloc.c
> > +++ b/mm/vmalloc.c
> > @@ -1185,9 +1185,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;
>
> This change is a mystery. Why do we no longer transfer ->flags?

I was actually debugging the same exact issue today. This transfer of flags
actually 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.

--
Olav Haugan

Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.