Commit dde27822 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] hugetlbpage msync() fix

From: David Gibson <david@gibson.dropbear.id.au>

Currently, calling msync() on a hugepage area will cause the kernel to blow
up with a bad_page() (at least on ppc64, but I think the problem will exist
on other archs too).  The msync path attempts to walk pagetables which may
not be there, or may have an unusual layout for hugepages.

Lucikly we shouldn't need to do anything for an msync on hugetlbfs beyond
flushing the cache, so this patch should be sufficient to fix the problem.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0af0d788
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/mman.h> #include <linux/mman.h>
#include <linux/hugetlb.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
...@@ -106,6 +107,13 @@ static int filemap_sync(struct vm_area_struct * vma, unsigned long address, ...@@ -106,6 +107,13 @@ static int filemap_sync(struct vm_area_struct * vma, unsigned long address,
dir = pgd_offset(vma->vm_mm, address); dir = pgd_offset(vma->vm_mm, address);
flush_cache_range(vma, address, end); flush_cache_range(vma, address, end);
/* For hugepages we can't go walking the page table normally,
* but that's ok, hugetlbfs is memory based, so we don't need
* to do anything more on an msync() */
if (is_vm_hugetlb_page(vma))
goto out;
if (address >= end) if (address >= end)
BUG(); BUG();
do { do {
...@@ -118,7 +126,7 @@ static int filemap_sync(struct vm_area_struct * vma, unsigned long address, ...@@ -118,7 +126,7 @@ static int filemap_sync(struct vm_area_struct * vma, unsigned long address,
* dirty bits. * dirty bits.
*/ */
flush_tlb_range(vma, end - size, end); flush_tlb_range(vma, end - size, end);
out:
spin_unlock(&vma->vm_mm->page_table_lock); spin_unlock(&vma->vm_mm->page_table_lock);
return error; return error;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment