From: Yongji Xie Date: Fri, 20 May 2016 23:57:41 +0000 (-0700) Subject: mm: fix incorrect pfn passed to untrack_pfn() in remap_pfn_range() X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=d5957d2fc232a689543bdbed1a5ff8002f0e9843;p=linux-beck.git mm: fix incorrect pfn passed to untrack_pfn() in remap_pfn_range() We use generic hooks in remap_pfn_range() to help archs to track pfnmap regions. The code is something like: int remap_pfn_range() { ... track_pfn_remap(vma, &prot, pfn, addr, PAGE_ALIGN(size)); ... pfn -= addr >> PAGE_SHIFT; ... untrack_pfn(vma, pfn, PAGE_ALIGN(size)); ... } Here we can easily find the pfn is changed but not recovered before untrack_pfn() is called. That's incorrect. There are no known runtime effects - this is from inspection. Signed-off-by: Yongji Xie Cc: Kirill A. Shutemov Cc: Jerome Marchand Cc: Ingo Molnar Cc: Vlastimil Babka Cc: Dave Hansen Cc: Dan Williams Cc: Matthew Wilcox Cc: Andrea Arcangeli Cc: Michal Hocko Cc: Andy Lutomirski Cc: David Hildenbrand Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/mm/memory.c b/mm/memory.c index 07493e34ab7e..007c72ad03f6 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1744,6 +1744,7 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, unsigned long next; unsigned long end = addr + PAGE_ALIGN(size); struct mm_struct *mm = vma->vm_mm; + unsigned long remap_pfn = pfn; int err; /* @@ -1770,7 +1771,7 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, vma->vm_pgoff = pfn; } - err = track_pfn_remap(vma, &prot, pfn, addr, PAGE_ALIGN(size)); + err = track_pfn_remap(vma, &prot, remap_pfn, addr, PAGE_ALIGN(size)); if (err) return -EINVAL; @@ -1789,7 +1790,7 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, } while (pgd++, addr = next, addr != end); if (err) - untrack_pfn(vma, pfn, PAGE_ALIGN(size)); + untrack_pfn(vma, remap_pfn, PAGE_ALIGN(size)); return err; }