Commit 6aa3e1e9 authored by David Gibson's avatar David Gibson Committed by Paul Mackerras

[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: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent efa06708
...@@ -744,7 +744,8 @@ static int htlb_check_hinted_area(unsigned long addr, unsigned long len) ...@@ -744,7 +744,8 @@ static int htlb_check_hinted_area(unsigned long addr, unsigned long len)
struct vm_area_struct *vma; struct vm_area_struct *vma;
vma = find_vma(current->mm, addr); 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 0;
return -ENOMEM; return -ENOMEM;
...@@ -815,6 +816,8 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, ...@@ -815,6 +816,8 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
return -EINVAL; return -EINVAL;
if (len & ~HPAGE_MASK) if (len & ~HPAGE_MASK)
return -EINVAL; return -EINVAL;
if (len > TASK_SIZE)
return -ENOMEM;
if (!cpu_has_feature(CPU_FTR_16M_PAGE)) if (!cpu_has_feature(CPU_FTR_16M_PAGE))
return -EINVAL; return -EINVAL;
...@@ -823,9 +826,6 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, ...@@ -823,9 +826,6 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
BUG_ON((addr + len) < addr); BUG_ON((addr + len) < addr);
if (test_thread_flag(TIF_32BIT)) { 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; curareas = current->mm->context.low_htlb_areas;
/* First see if we can use the hint address */ /* First see if we can use the hint address */
......
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