aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2006-12-21 17:23:03 -0500
committerPaul Mackerras <paulus@samba.org>2007-01-09 01:03:01 -0500
commit6aa3e1e9447134ccda8b04b91c4ba8182274a78e (patch)
treeda637c9a708b93bcacc4f4284fba5cc2190c996f /arch
parentefa06708fe77190f31bed5c3cb5da49e211240f5 (diff)
[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 <david@gibson.dropbear.id.au> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/mm/hugetlbpage.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 89c836d54809..1bb20d841080 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)
744 struct vm_area_struct *vma; 744 struct vm_area_struct *vma;
745 745
746 vma = find_vma(current->mm, addr); 746 vma = find_vma(current->mm, addr);
747 if (!vma || ((addr + len) <= vma->vm_start)) 747 if (TASK_SIZE - len >= addr &&
748 (!vma || ((addr + len) <= vma->vm_start)))
748 return 0; 749 return 0;
749 750
750 return -ENOMEM; 751 return -ENOMEM;
@@ -815,6 +816,8 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
815 return -EINVAL; 816 return -EINVAL;
816 if (len & ~HPAGE_MASK) 817 if (len & ~HPAGE_MASK)
817 return -EINVAL; 818 return -EINVAL;
819 if (len > TASK_SIZE)
820 return -ENOMEM;
818 821
819 if (!cpu_has_feature(CPU_FTR_16M_PAGE)) 822 if (!cpu_has_feature(CPU_FTR_16M_PAGE))
820 return -EINVAL; 823 return -EINVAL;
@@ -823,9 +826,6 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
823 BUG_ON((addr + len) < addr); 826 BUG_ON((addr + len) < addr);
824 827
825 if (test_thread_flag(TIF_32BIT)) { 828 if (test_thread_flag(TIF_32BIT)) {
826 /* Paranoia, caller should have dealt with this */
827 BUG_ON((addr + len) > 0x100000000UL);
828
829 curareas = current->mm->context.low_htlb_areas; 829 curareas = current->mm->context.low_htlb_areas;
830 830
831 /* First see if we can use the hint address */ 831 /* First see if we can use the hint address */