On Fri, Jun 3, 2011 at 2:37 PM, Greg Ungerer <gerg@xxxxxxxxxxxx> wrote: > Hi Bob, > > On 06/05/11 16:03, Bob Liu wrote: >> >> Currently on nommu arch mmap(),mremap() and munmap() doesn't do >> page_align() >> which isn't consist with mmu arch and cause some issues. >> >> First, some drivers' mmap() function depends on vma->vm_end - vma->start >> is >> page aligned which is true on mmu arch but not on nommu. eg: uvc camera >> driver. >> >> Second munmap() may return -EINVAL[split file] error in cases when end is >> not >> page aligned(passed into from userspace) but vma->vm_end is aligned dure >> to >> split or driver's mmap() ops. >> >> This patch add page align to fix those issues. > > This is actually causing me problems on head at the moment. > git bisected to this patch as the cause. > > When booting on a ColdFire (m68knommu) target the init process (or > there abouts at least) fails. Last console messages are: > > Â... > ÂVFS: Mounted root (romfs filesystem) readonly on device 31:0. > ÂFreeing unused kernel memory: 52k freed (0x401aa000 - 0x401b6000) > ÂUnable to mmap process text, errno 22 > Oh, bad news. I will try to reproduce it on my board. If you are free please enable debug in nommu.c and then we can see what caused the problem. Thanks! > I haven't really debugged it any further yet. But that error message > comes from fs/binfmt_flat.c, it is reporting a failed do_mmap() call. > > Reverting that this patch and no more problem. > > Regards > Greg > > > >> Changelog v1->v2: >> - added more commit message >> >> Signed-off-by: Bob Liu<lliubbo@xxxxxxxxx> >> --- >> Âmm/nommu.c |  24 ++++++++++++++---------- >> Â1 files changed, 14 insertions(+), 10 deletions(-) >> >> diff --git a/mm/nommu.c b/mm/nommu.c >> index c4c542c..3febfd9 100644 >> --- a/mm/nommu.c >> +++ b/mm/nommu.c >> @@ -1133,7 +1133,7 @@ static int do_mmap_private(struct vm_area_struct >> *vma, >>              unsigned long capabilities) >> Â{ >>    Âstruct page *pages; >> -    unsigned long total, point, n, rlen; >> +    unsigned long total, point, n; >>    Âvoid *base; >>    Âint ret, order; >> >> @@ -1157,13 +1157,12 @@ static int do_mmap_private(struct vm_area_struct >> *vma, >>         * make a private copy of the data and map that instead */ >>    Â} >> >> -    rlen = PAGE_ALIGN(len); >> >>    Â/* allocate some memory to hold the mapping >>     * - note that this may not return a page-aligned address if the >> object >>     *  we're allocating is smaller than a page >>     */ >> -    order = get_order(rlen); >> +    order = get_order(len); >>    Âkdebug("alloc order %d for %lx", order, len); >> >>    Âpages = alloc_pages(GFP_KERNEL, order); >> @@ -1173,7 +1172,7 @@ static int do_mmap_private(struct vm_area_struct >> *vma, >>    Âtotal = 1<< Âorder; >>    Âatomic_long_add(total,&mmap_pages_allocated); >> >> -    point = rlen>> ÂPAGE_SHIFT; >> +    point = len>> ÂPAGE_SHIFT; >> >>    Â/* we allocated a power-of-2 sized page set, so we may want to trim >> off >>     * the excess */ >> @@ -1195,7 +1194,7 @@ static int do_mmap_private(struct vm_area_struct >> *vma, >>    Âbase = page_address(pages); >>    Âregion->vm_flags = vma->vm_flags |= VM_MAPPED_COPY; >>    Âregion->vm_start = (unsigned long) base; >> -    region->vm_end  = region->vm_start + rlen; >> +    region->vm_end  = region->vm_start + len; >>    Âregion->vm_top  = region->vm_start + (total<< ÂPAGE_SHIFT); >> >>    Âvma->vm_start = region->vm_start; >> @@ -1211,15 +1210,15 @@ static int do_mmap_private(struct vm_area_struct >> *vma, >> >>        Âold_fs = get_fs(); >>        Âset_fs(KERNEL_DS); >> -        ret = vma->vm_file->f_op->read(vma->vm_file, base, >> rlen,&fpos); >> +        ret = vma->vm_file->f_op->read(vma->vm_file, base, >> len,&fpos); >>        Âset_fs(old_fs); >> >>        Âif (ret< Â0) >>            Âgoto error_free; >> >>        Â/* clear the last little bit */ >> -        if (ret< Ârlen) >> -            memset(base + ret, 0, rlen - ret); >> +        if (ret< Âlen) >> +            memset(base + ret, 0, len - ret); >> >>    Â} >> >> @@ -1268,6 +1267,7 @@ unsigned long do_mmap_pgoff(struct file *file, >> >>    Â/* we ignore the address hint */ >>    Âaddr = 0; >> +    len = PAGE_ALIGN(len); >> >>    Â/* we've determined that we can make the mapping, now translate >> what we >>     * now know into VMA flags */ >> @@ -1645,14 +1645,16 @@ int do_munmap(struct mm_struct *mm, unsigned long >> start, size_t len) >> Â{ >>    Âstruct vm_area_struct *vma; >>    Âstruct rb_node *rb; >> -    unsigned long end = start + len; >> +    unsigned long end; >>    Âint ret; >> >>    Âkenter(",%lx,%zx", start, len); >> >> -    if (len == 0) >> +    if ((len = PAGE_ALIGN(len)) == 0) >>        Âreturn -EINVAL; >> >> +    end = start + len; >> + >>    Â/* find the first potentially overlapping VMA */ >>    Âvma = find_vma(mm, start); >>    Âif (!vma) { >> @@ -1773,6 +1775,8 @@ unsigned long do_mremap(unsigned long addr, >>    Âstruct vm_area_struct *vma; >> >>    Â/* insanity checks first */ >> +    old_len = PAGE_ALIGN(old_len); >> +    new_len = PAGE_ALIGN(new_len); >>    Âif (old_len == 0 || new_len == 0) >>        Âreturn (unsigned long) -EINVAL; >> > > > -- > ------------------------------------------------------------------------ > Greg Ungerer Â-- ÂPrincipal Engineer    ÂEMAIL:   gerg@xxxxxxxxxxxx > SnapGear Group, McAfee           ÂPHONE:    +61 7 3435 2888 > 8 Gardner Close               FAX:     +61 7 3217 5323 > Milton, QLD, 4064, Australia        ÂWEB: http://www.SnapGear.com > -- Regards, --Bob -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxxx For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href