powerpc: Fix address masking bug in hpte_need_flush()

Previous thread: [CIFS] Don't cache timestamps on utimes due to coarse granularity by Linux Kernel Mailing List on Wednesday, February 10, 2010 - 9:00 am. (1 message)

Next thread: [S390] qdio: continue polling for buffer state ERROR by Linux Kernel Mailing List on Wednesday, February 10, 2010 - 9:00 am. (1 message)
From: Linux Kernel Mailing List
Date: Wednesday, February 10, 2010 - 9:00 am

Gitweb:     http://git.kernel.org/linus/77058e1adcc439151db41f2b84e4867a88113cd8
Commit:     77058e1adcc439151db41f2b84e4867a88113cd8
Parent:     ac73fddfc523bf3c3525d16356b44527c44fae6d
Author:     David Gibson <david@gibson.dropbear.id.au>
AuthorDate: Mon Feb 8 20:09:03 2010 +0000
Committer:  Benjamin Herrenschmidt <benh@kernel.crashing.org>
CommitDate: Wed Feb 10 13:58:06 2010 +1100

    powerpc: Fix address masking bug in hpte_need_flush()
    
    Commit f71dc176aa06359681c30ba6877ffccab6fba3a6 'Make
    hpte_need_flush() correctly mask for multiple page sizes' introduced
    bug, which is triggered when a kernel with a 64k base page size is run
    on a system whose hardware does not 64k hash PTEs.  In this case, we
    emulate 64k pages with multiple 4k hash PTEs, however in
    hpte_need_flush() we incorrectly only mask the hardware page size from
    the address, instead of the logical page size.  This causes things to
    go wrong when we later attempt to iterate through the hardware
    subpages of the logical page.
    
    This patch corrects the error.  It has been tested on pSeries bare
    metal by Michael Neuling.
    
    Signed-off-by: David Gibson <dwg@au1.ibm.com>
    Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/mm/tlb_hash64.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/mm/tlb_hash64.c b/arch/powerpc/mm/tlb_hash64.c
index 282d930..1ec0657 100644
--- a/arch/powerpc/mm/tlb_hash64.c
+++ b/arch/powerpc/mm/tlb_hash64.c
@@ -63,15 +63,21 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
 	if (huge) {
 #ifdef CONFIG_HUGETLB_PAGE
 		psize = get_slice_psize(mm, addr);
+		/* Mask the address for the correct page size */
+		addr &= ~((1UL << mmu_psize_defs[psize].shift) - 1);
 #else
 		BUG();
 		psize = pte_pagesize_index(mm, addr, pte); /* shutup gcc */
 #endif
-	} else
+	} else {
 		psize = pte_pagesize_index(mm, addr, pte);
+		/* Mask the address ...
Previous thread: [CIFS] Don't cache timestamps on utimes due to coarse granularity by Linux Kernel Mailing List on Wednesday, February 10, 2010 - 9:00 am. (1 message)

Next thread: [S390] qdio: continue polling for buffer state ERROR by Linux Kernel Mailing List on Wednesday, February 10, 2010 - 9:00 am. (1 message)