aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/mm/hugetlbpage.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 53b200abb025..123f7070238a 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -436,18 +436,27 @@ static noinline int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long add
436 return 1; 436 return 1;
437} 437}
438 438
439static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end,
440 unsigned long sz)
441{
442 unsigned long __boundary = (addr + sz) & ~(sz-1);
443 return (__boundary - 1 < end - 1) ? __boundary : end;
444}
445
439int gup_hugepd(hugepd_t *hugepd, unsigned pdshift, 446int gup_hugepd(hugepd_t *hugepd, unsigned pdshift,
440 unsigned long addr, unsigned long end, 447 unsigned long addr, unsigned long end,
441 int write, struct page **pages, int *nr) 448 int write, struct page **pages, int *nr)
442{ 449{
443 pte_t *ptep; 450 pte_t *ptep;
444 unsigned long sz = 1UL << hugepd_shift(*hugepd); 451 unsigned long sz = 1UL << hugepd_shift(*hugepd);
452 unsigned long next;
445 453
446 ptep = hugepte_offset(hugepd, addr, pdshift); 454 ptep = hugepte_offset(hugepd, addr, pdshift);
447 do { 455 do {
456 next = hugepte_addr_end(addr, end, sz);
448 if (!gup_hugepte(ptep, sz, addr, end, write, pages, nr)) 457 if (!gup_hugepte(ptep, sz, addr, end, write, pages, nr))
449 return 0; 458 return 0;
450 } while (ptep++, addr += sz, addr != end); 459 } while (ptep++, addr = next, addr != end);
451 460
452 return 1; 461 return 1;
453} 462}