if (pud_none(*pud))
                goto no_page_table;
        if (pud_huge(*pud) && vma->vm_flags & VM_HUGETLB) {
-               BUG_ON(flags & FOLL_GET);
+               if (flags & FOLL_GET)
+                       goto out;
                page = follow_huge_pud(mm, address, pud, flags & FOLL_WRITE);
                goto out;
        }
        if (pmd_none(*pmd))
                goto no_page_table;
        if (pmd_huge(*pmd) && vma->vm_flags & VM_HUGETLB) {
-               BUG_ON(flags & FOLL_GET);
                page = follow_huge_pmd(mm, address, pmd, flags & FOLL_WRITE);
+               if (flags & FOLL_GET) {
+                       /*
+                        * Refcount on tail pages are not well-defined and
+                        * shouldn't be taken. The caller should handle a NULL
+                        * return when trying to follow tail pages.
+                        */
+                       if (PageHead(page))
+                               get_page(page);
+                       else {
+                               page = NULL;
+                               goto out;
+                       }
+               }
                goto out;
        }
        if ((flags & FOLL_NUMA) && pmd_numa(*pmd))
 
 
        *result = &pm->status;
 
-       return alloc_pages_exact_node(pm->node,
+       if (PageHuge(p))
+               return alloc_huge_page_node(page_hstate(compound_head(p)),
+                                       pm->node);
+       else
+               return alloc_pages_exact_node(pm->node,
                                GFP_HIGHUSER_MOVABLE | GFP_THISNODE, 0);
 }
 
                                !migrate_all)
                        goto put_and_set;
 
+               if (PageHuge(page)) {
+                       isolate_huge_page(page, &pagelist);
+                       goto put_and_set;
+               }
+
                err = isolate_lru_page(page);
                if (!err) {
                        list_add_tail(&page->lru, &pagelist);
                err = migrate_pages(&pagelist, new_page_node,
                                (unsigned long)pm, MIGRATE_SYNC, MR_SYSCALL);
                if (err)
-                       putback_lru_pages(&pagelist);
+                       putback_movable_pages(&pagelist);
        }
 
        up_read(&mm->mmap_sem);