From: David Gibson Date: Thu, 21 Dec 2006 22:23:03 +0000 (+1100) Subject: [POWERPC] Fix bogus BUG_ON() in in hugetlb_get_unmapped_area() X-Git-Tag: v2.6.20-rc5~35^2~17 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6aa3e1e9447134ccda8b04b91c4ba8182274a78e;p=linux-2.6 [POWERPC] Fix bogus BUG_ON() in in hugetlb_get_unmapped_area() The powerpc specific version of hugetlb_get_unmapped_area() makes some unwarranted assumptions about what checks have been made to its parameters by its callers. This will lead to a BUG_ON() if a 32-bit process attempts to make a hugepage mapping which extends above TASK_SIZE (4GB). I'm not sure if these assumptions came about because they were valid with earlier versions of the get_unmapped_area() path, or if it was always broken. Nonetheless this patch fixes the logic, and removes the crash. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 89c836d548..1bb20d8410 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -744,7 +744,8 @@ static int htlb_check_hinted_area(unsigned long addr, unsigned long len) struct vm_area_struct *vma; vma = find_vma(current->mm, addr); - if (!vma || ((addr + len) <= vma->vm_start)) + if (TASK_SIZE - len >= addr && + (!vma || ((addr + len) <= vma->vm_start))) return 0; return -ENOMEM; @@ -815,6 +816,8 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, return -EINVAL; if (len & ~HPAGE_MASK) return -EINVAL; + if (len > TASK_SIZE) + return -ENOMEM; if (!cpu_has_feature(CPU_FTR_16M_PAGE)) return -EINVAL; @@ -823,9 +826,6 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, BUG_ON((addr + len) < addr); if (test_thread_flag(TIF_32BIT)) { - /* Paranoia, caller should have dealt with this */ - BUG_ON((addr + len) > 0x100000000UL); - curareas = current->mm->context.low_htlb_areas; /* First see if we can use the hint address */