powerpc/mm: Make hpte_need_flush() correctly mask for multiple page sizes
authorDavid Gibson <david@gibson.dropbear.id.au>
Mon, 26 Oct 2009 19:24:31 +0000 (19:24 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Fri, 30 Oct 2009 06:20:57 +0000 (17:20 +1100)
Currently, hpte_need_flush() only correctly flushes the given address
for normal pages.  Callers for hugepages are required to mask the
address themselves.

But hpte_need_flush() already looks up the page sizes for its own
reasons, so this is a rather silly imposition on the callers.  This
patch alters it to mask based on the pagesize it has looked up itself,
and removes the awkward masking code in the hugepage caller.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/mm/hugetlbpage.c
arch/powerpc/mm/tlb_hash64.c

index 90df6ffe3a43140fcbfcb5ceaa312fdb7c642319..3d542a9732ae7ec2c5057e495eabb968814715c7 100644 (file)
@@ -445,11 +445,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
                 * necessary anymore if we make hpte_need_flush() get the
                 * page size from the slices
                 */
-               unsigned int psize = get_slice_psize(mm, addr);
-               unsigned int shift = mmu_psize_to_shift(psize);
-               unsigned long sz = ((1UL) << shift);
-               struct hstate *hstate = size_to_hstate(sz);
-               pte_update(mm, addr & hstate->mask, ptep, ~0UL, 1);
+               pte_update(mm, addr, ptep, ~0UL, 1);
        }
        *ptep = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
 }
index 2b2f35f6985e561aaacf2ef515e654d0ba1985b4..282d9306361f58f3ba3443648f73dd6955a75fd4 100644 (file)
@@ -53,11 +53,6 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
 
        i = batch->index;
 
-       /* We mask the address for the base page size. Huge pages will
-        * have applied their own masking already
-        */
-       addr &= PAGE_MASK;
-
        /* Get page size (maybe move back to caller).
         *
         * NOTE: when using special 64K mappings in 4K environment like
@@ -75,6 +70,9 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
        } else
                psize = pte_pagesize_index(mm, addr, pte);
 
+       /* Mask the address for the correct page size */
+       addr &= ~((1UL << mmu_psize_defs[psize].shift) - 1);
+
        /* Build full vaddr */
        if (!is_kernel_addr(addr)) {
                ssize = user_segment_size(addr);