diff options
-rw-r--r-- | arch/powerpc/mm/hugetlbpage.c | 11 |
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 | ||
439 | static 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 | |||
439 | int gup_hugepd(hugepd_t *hugepd, unsigned pdshift, | 446 | int 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 | } |