aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2007-03-20 23:26:06 +0100
committerAdrian Bunk <bunk@stusta.de>2007-03-20 23:26:06 +0100
commit521c8225cc9cb09c7cfe626ee12afe8cc76e9ed5 (patch)
tree7f9e2a2b4693363fdeb960218bc2b3cebe8242b1 /arch
parentf2654bc1df0c27d3be0167fddae403515e80dc9b (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.c29
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);