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 | } |
