From patchwork Tue Feb 9 06:09:03 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 44879 X-Patchwork-Delegate: benh@kernel.crashing.org Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from bilbo.ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix) with ESMTP id 43FFEB7F81 for ; Tue, 9 Feb 2010 17:09:13 +1100 (EST) Received: by ozlabs.org (Postfix) id 8B490B7CE2; Tue, 9 Feb 2010 17:09:06 +1100 (EST) Delivered-To: linuxppc-dev@ozlabs.org Received: by ozlabs.org (Postfix, from userid 1007) id 89C88B7D01; Tue, 9 Feb 2010 17:09:06 +1100 (EST) Date: Tue, 9 Feb 2010 17:09:03 +1100 From: David Gibson To: Benjamin Herrenschmidt Subject: Fix address masking bug in hpte_need_flush() Message-ID: <20100209060903.GC13335@yookeroo> Mail-Followup-To: Benjamin Herrenschmidt , Miichael Neuling , linuxppc-dev@ozlabs.org MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) Cc: linuxppc-dev@ozlabs.org, Miichael Neuling X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org 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 Index: working-2.6/arch/powerpc/mm/tlb_hash64.c =================================================================== --- working-2.6.orig/arch/powerpc/mm/tlb_hash64.c 2010-02-09 16:44:58.810336741 +1100 +++ working-2.6/arch/powerpc/mm/tlb_hash64.c 2010-02-09 16:45:58.920721138 +1100 @@ -63,15 +63,21 @@ void hpte_need_flush(struct mm_struct *m 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 for the standard page size. If we + * have a 64k page kernel, but the hardware does not + * support 64k pages, this might be different from the + * hardware page size encoded in the slice table. */ + addr &= PAGE_MASK; + } - /* Mask the address for the correct page size */ - addr &= ~((1UL << mmu_psize_defs[psize].shift) - 1); /* Build full vaddr */ if (!is_kernel_addr(addr)) {