diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2006-12-21 17:23:03 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-01-09 01:03:01 -0500 |
commit | 6aa3e1e9447134ccda8b04b91c4ba8182274a78e (patch) | |
tree | da637c9a708b93bcacc4f4284fba5cc2190c996f | |
parent | efa06708fe77190f31bed5c3cb5da49e211240f5 (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>
-rw-r--r-- | arch/powerpc/mm/hugetlbpage.c | 8 |
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 */ |