diff options
author | David S. Miller <davem@davemloft.net> | 2007-03-20 23:26:06 +0100 |
---|---|---|
committer | Adrian Bunk <bunk@stusta.de> | 2007-03-20 23:26:06 +0100 |
commit | 521c8225cc9cb09c7cfe626ee12afe8cc76e9ed5 (patch) | |
tree | 7f9e2a2b4693363fdeb960218bc2b3cebe8242b1 /arch | |
parent | f2654bc1df0c27d3be0167fddae403515e80dc9b (diff) |
[SPARC64]: Add missing HPAGE_MASK masks on address parameters.
These pte loops all assume the passed in address is HPAGE
aligned, make sure that is actually true.
[ This also includes other hugepage bug fixes for sparc64
that occurred between 2.6.16 to 2.6.20 ]
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sparc64/mm/hugetlbpage.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c index 625cbb336a2..19eeea7a0a2 100644 --- a/arch/sparc64/mm/hugetlbpage.c +++ b/arch/sparc64/mm/hugetlbpage.c @@ -29,14 +29,19 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) pmd_t *pmd; pte_t *pte = NULL; + /* We must align the address, because our caller will run + * set_huge_pte_at() on whatever we return, which writes out + * all of the sub-ptes for the hugepage range. So we have + * to give it the first such sub-pte. + */ + addr &= HPAGE_MASK; + pgd = pgd_offset(mm, addr); - if (pgd) { - pud = pud_offset(pgd, addr); - if (pud) { - pmd = pmd_alloc(mm, pud, addr); - if (pmd) - pte = pte_alloc_map(mm, pmd, addr); - } + pud = pud_alloc(mm, pgd, addr); + if (pud) { + pmd = pmd_alloc(mm, pud, addr); + if (pmd) + pte = pte_alloc_map(mm, pmd, addr); } return pte; } @@ -48,12 +53,14 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) pmd_t *pmd; pte_t *pte = NULL; + addr &= HPAGE_MASK; + pgd = pgd_offset(mm, addr); - if (pgd) { + if (!pgd_none(*pgd)) { pud = pud_offset(pgd, addr); - if (pud) { + if (!pud_none(*pud)) { pmd = pmd_offset(pud, addr); - if (pmd) + if (!pmd_none(*pmd)) pte = pte_offset_map(pmd, addr); } } @@ -67,6 +74,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, { int i; + addr &= HPAGE_MASK; for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { set_pte_at(mm, addr, ptep, entry); ptep++; @@ -82,6 +90,7 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, int i; entry = *ptep; + addr &= HPAGE_MASK; for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { pte_clear(mm, addr, ptep); |