diff mbox

[v3] arm: ioremap: Fix static vm area boundary check.

Message ID 1400232920-25079-1-git-send-email-Li.Xiubo@freescale.com (mailing list archive)
State New, archived
Headers show

Commit Message

Xiubo Li May 16, 2014, 9:35 a.m. UTC
For each vmalloc area, there is one guard page at the end of it.
so the vm->size = PAGE_ALIGN(offset + request size) + guard page size.

Signed-off-by: Richard Lee <superlibj8301@gmail.com>
Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
Cc: Nicolas Pitre <nico@linaro.org>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
---
 arch/arm/mm/ioremap.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

Comments

Nicolas Pitre May 16, 2014, 6:11 p.m. UTC | #1
On Fri, 16 May 2014, Xiubo Li wrote:

> For each vmalloc area, there is one guard page at the end of it.
> so the vm->size = PAGE_ALIGN(offset + request size) + guard page size.

Nope.  There is no guard page for statically created vmalloc areas.


> Signed-off-by: Richard Lee <superlibj8301@gmail.com>
> Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
> Cc: Nicolas Pitre <nico@linaro.org>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
> ---
>  arch/arm/mm/ioremap.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
> index be69333..758e8f7 100644
> --- a/arch/arm/mm/ioremap.c
> +++ b/arch/arm/mm/ioremap.c
> @@ -49,14 +49,18 @@ static struct static_vm *find_static_vm_paddr(phys_addr_t paddr,
>  	struct vm_struct *vm;
>  
>  	list_for_each_entry(svm, &static_vmlist, list) {
> +		phys_addr_t paddr_end, phys_addr_end;
> +
>  		vm = &svm->vm;
>  		if (!(vm->flags & VM_ARM_STATIC_MAPPING))
>  			continue;
>  		if ((vm->flags & VM_ARM_MTYPE_MASK) != VM_ARM_MTYPE(mtype))
>  			continue;
>  
> -		if (vm->phys_addr > paddr ||
> -			paddr + size - 1 > vm->phys_addr + vm->size - 1)
> +		/* The PAGE_SIZE here is vmalloc area's guard page */
> +		phys_addr_end = vm->phys_addr + vm->size - PAGE_SIZE - 1;
> +		paddr_end = paddr + size - 1;
> +		if (vm->phys_addr > paddr || paddr_end > phys_addr_end)
>  			continue;
>  
>  		return svm;
> -- 
> 1.8.4
>
Xiubo Li May 19, 2014, 2:49 a.m. UTC | #2
> > For each vmalloc area, there is one guard page at the end of it.
> > so the vm->size = PAGE_ALIGN(offset + request size) + guard page size.
> 
> Nope.  There is no guard page for statically created vmalloc areas.
> 

Yes, you are right, I'm thinking why the static area has no guard page?

Thanks very much,

BRs
Xiubo


> 
> > Signed-off-by: Richard Lee <superlibj8301@gmail.com>
> > Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com>
> > Cc: Nicolas Pitre <nico@linaro.org>
> > Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
> > ---
> >  arch/arm/mm/ioremap.c | 8 ++++++--
> >  1 file changed, 6 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
> > index be69333..758e8f7 100644
> > --- a/arch/arm/mm/ioremap.c
> > +++ b/arch/arm/mm/ioremap.c
> > @@ -49,14 +49,18 @@ static struct static_vm
> *find_static_vm_paddr(phys_addr_t paddr,
> >  	struct vm_struct *vm;
> >
> >  	list_for_each_entry(svm, &static_vmlist, list) {
> > +		phys_addr_t paddr_end, phys_addr_end;
> > +
> >  		vm = &svm->vm;
> >  		if (!(vm->flags & VM_ARM_STATIC_MAPPING))
> >  			continue;
> >  		if ((vm->flags & VM_ARM_MTYPE_MASK) != VM_ARM_MTYPE(mtype))
> >  			continue;
> >
> > -		if (vm->phys_addr > paddr ||
> > -			paddr + size - 1 > vm->phys_addr + vm->size - 1)
> > +		/* The PAGE_SIZE here is vmalloc area's guard page */
> > +		phys_addr_end = vm->phys_addr + vm->size - PAGE_SIZE - 1;
> > +		paddr_end = paddr + size - 1;
> > +		if (vm->phys_addr > paddr || paddr_end > phys_addr_end)
> >  			continue;
> >
> >  		return svm;
> > --
> > 1.8.4
> >
Nicolas Pitre May 20, 2014, 3:13 a.m. UTC | #3
On Mon, 19 May 2014, Li.Xiubo@freescale.com wrote:

> > > For each vmalloc area, there is one guard page at the end of it.
> > > so the vm->size = PAGE_ALIGN(offset + request size) + guard page size.
> > 
> > Nope.  There is no guard page for statically created vmalloc areas.
> > 
> 
> Yes, you are right, I'm thinking why the static area has no guard page?

The virtual addresses being used are provided by the static mapping 
descriptions themselves.  Sometimes those mappings are large and 
contiguous, covering multiple peripherals at once with a single TLB, 
etc.  There is simply no room for a guard page, or no guard page at all 
between different areas covered by a single section mapping (1MB worth 
of mapping from a single page table entry).

All this to say that trying to enforce a guard page in those cases is 
likely to throw away all the performance advantage and conplexify 
things.


Nicolas
diff mbox

Patch

diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index be69333..758e8f7 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -49,14 +49,18 @@  static struct static_vm *find_static_vm_paddr(phys_addr_t paddr,
 	struct vm_struct *vm;
 
 	list_for_each_entry(svm, &static_vmlist, list) {
+		phys_addr_t paddr_end, phys_addr_end;
+
 		vm = &svm->vm;
 		if (!(vm->flags & VM_ARM_STATIC_MAPPING))
 			continue;
 		if ((vm->flags & VM_ARM_MTYPE_MASK) != VM_ARM_MTYPE(mtype))
 			continue;
 
-		if (vm->phys_addr > paddr ||
-			paddr + size - 1 > vm->phys_addr + vm->size - 1)
+		/* The PAGE_SIZE here is vmalloc area's guard page */
+		phys_addr_end = vm->phys_addr + vm->size - PAGE_SIZE - 1;
+		paddr_end = paddr + size - 1;
+		if (vm->phys_addr > paddr || paddr_end > phys_addr_end)
 			continue;
 
 		return svm;