aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm/hugetlbpage.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/mm/hugetlbpage.c')
-rw-r--r--arch/powerpc/mm/hugetlbpage.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 54131b877da..b51bb28c054 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -549,6 +549,17 @@ fail:
549 return addr; 549 return addr;
550} 550}
551 551
552static int htlb_check_hinted_area(unsigned long addr, unsigned long len)
553{
554 struct vm_area_struct *vma;
555
556 vma = find_vma(current->mm, addr);
557 if (!vma || ((addr + len) <= vma->vm_start))
558 return 0;
559
560 return -ENOMEM;
561}
562
552static unsigned long htlb_get_low_area(unsigned long len, u16 segmask) 563static unsigned long htlb_get_low_area(unsigned long len, u16 segmask)
553{ 564{
554 unsigned long addr = 0; 565 unsigned long addr = 0;
@@ -618,15 +629,28 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
618 if (!cpu_has_feature(CPU_FTR_16M_PAGE)) 629 if (!cpu_has_feature(CPU_FTR_16M_PAGE))
619 return -EINVAL; 630 return -EINVAL;
620 631
632 /* Paranoia, caller should have dealt with this */
633 BUG_ON((addr + len) < addr);
634
621 if (test_thread_flag(TIF_32BIT)) { 635 if (test_thread_flag(TIF_32BIT)) {
636 /* Paranoia, caller should have dealt with this */
637 BUG_ON((addr + len) > 0x100000000UL);
638
622 curareas = current->mm->context.low_htlb_areas; 639 curareas = current->mm->context.low_htlb_areas;
623 640
624 /* First see if we can do the mapping in the existing 641 /* First see if we can use the hint address */
625 * low areas */ 642 if (addr && (htlb_check_hinted_area(addr, len) == 0)) {
643 areamask = LOW_ESID_MASK(addr, len);
644 if (open_low_hpage_areas(current->mm, areamask) == 0)
645 return addr;
646 }
647
648 /* Next see if we can map in the existing low areas */
626 addr = htlb_get_low_area(len, curareas); 649 addr = htlb_get_low_area(len, curareas);
627 if (addr != -ENOMEM) 650 if (addr != -ENOMEM)
628 return addr; 651 return addr;
629 652
653 /* Finally go looking for areas to open */
630 lastshift = 0; 654 lastshift = 0;
631 for (areamask = LOW_ESID_MASK(0x100000000UL-len, len); 655 for (areamask = LOW_ESID_MASK(0x100000000UL-len, len);
632 ! lastshift; areamask >>=1) { 656 ! lastshift; areamask >>=1) {
@@ -641,12 +665,22 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
641 } else { 665 } else {
642 curareas = current->mm->context.high_htlb_areas; 666 curareas = current->mm->context.high_htlb_areas;
643 667
644 /* First see if we can do the mapping in the existing 668 /* First see if we can use the hint address */
645 * high areas */ 669 /* We discourage 64-bit processes from doing hugepage
670 * mappings below 4GB (must use MAP_FIXED) */
671 if ((addr >= 0x100000000UL)
672 && (htlb_check_hinted_area(addr, len) == 0)) {
673 areamask = HTLB_AREA_MASK(addr, len);
674 if (open_high_hpage_areas(current->mm, areamask) == 0)
675 return addr;
676 }
677
678 /* Next see if we can map in the existing high areas */
646 addr = htlb_get_high_area(len, curareas); 679 addr = htlb_get_high_area(len, curareas);
647 if (addr != -ENOMEM) 680 if (addr != -ENOMEM)
648 return addr; 681 return addr;
649 682
683 /* Finally go looking for areas to open */
650 lastshift = 0; 684 lastshift = 0;
651 for (areamask = HTLB_AREA_MASK(TASK_SIZE_USER64-len, len); 685 for (areamask = HTLB_AREA_MASK(TASK_SIZE_USER64-len, len);
652 ! lastshift; areamask >>=1) { 686 ! lastshift; areamask >>=1) {