From patchwork Mon Nov 28 04:07:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuriy Kolerov X-Patchwork-Id: 699846 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3tRtSV0nZxz9t15 for ; Mon, 28 Nov 2016 15:07:53 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1cBDEN-00059G-6B; Mon, 28 Nov 2016 04:07:51 +0000 Received: from us01smtprelay-2.synopsys.com ([198.182.47.9] helo=smtprelay.synopsys.com) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1cBDEK-00057Z-Tt for linux-snps-arc@lists.infradead.org; Mon, 28 Nov 2016 04:07:50 +0000 Received: from mailhost.synopsys.com (mailhost2.synopsys.com [10.13.184.66]) by smtprelay.synopsys.com (Postfix) with ESMTP id C3A1A24E0694; Sun, 27 Nov 2016 20:07:23 -0800 (PST) Received: from mailhost.synopsys.com (localhost [127.0.0.1]) by mailhost.synopsys.com (Postfix) with ESMTP id 89F4BE72; Sun, 27 Nov 2016 20:07:23 -0800 (PST) Received: from ykolerov-vm.internal.synopsys.com (ykolerov-840g3.internal.synopsys.com [10.225.2.18]) by mailhost.synopsys.com (Postfix) with ESMTP id 2B919E60; Sun, 27 Nov 2016 20:07:21 -0800 (PST) From: Yuriy Kolerov To: linux-snps-arc@lists.infradead.org Subject: [PATCH] ARC: mm: PAE40: Cast pfn to pte_t in pfn_pte() macro Date: Mon, 28 Nov 2016 07:07:17 +0300 Message-Id: <1480306037-15415-1-git-send-email-yuriy.kolerov@synopsys.com> X-Mailer: git-send-email 2.7.4 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161127_200749_048354_6F29EB7A X-CRM114-Status: UNSURE ( 8.26 ) X-CRM114-Notice: Please train this message. X-Spam-Score: -3.3 (---) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-3.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [198.182.47.9 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [198.182.47.9 listed in wl.mailspike.net] -1.4 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-BeenThere: linux-snps-arc@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Linux on Synopsys ARC Processors List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Vineet.Gupta1@synopsys.com, Alexey.Brodkin@synopsys.com, linux-kernel@vger.kernel.org, Yuriy Kolerov MIME-Version: 1.0 Sender: "linux-snps-arc" Errors-To: linux-snps-arc-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Originally pfn_pte(pfn, prot) macro had this definition: __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) The value of pfn (Page Frame Number) is shifted to the left to get the value of pte (Page Table Entry). Usually a 4-byte value is passed to this macro as value of pfn. However if Linux is configured with support of PAE40 then value of pte has 8-byte type because it must contain additional 8 bits of the physical address. Thus if value of pfn represents a physical page frame above of 4GB boundary then shifting of pfn to the left by PAGE_SHIFT wipes most significant bits of the 40-bit physical address. As a result all physical addresses above of 4GB boundary in systems with PAE40 are mapped to virtual address incorrectly. An error may occur when the kernel tries to unmap such bad pages: [ECR ]: 0x00050100 => Invalid Read @ 0x41414144 by insn @ 0x801644c6 [EFA ]: 0x41414144 [BLINK ]: unmap_page_range+0x134/0x700 [ERET ]: unmap_page_range+0x17a/0x700 [STAT32]: 0x8008021e : IE K BTA: 0x801644c6 SP: 0x901a5e84 FP: 0x5ff35de8 LPS: 0x8026462c LPE: 0x80264630 LPC: 0x00000000 r00: 0x8fcc4fc0 r01: 0x2fe68000 r02: 0x41414140 r03: 0x2c05c000 r04: 0x2fe6a000 r05: 0x0009ffff r06: 0x901b6898 r07: 0x2fe68000 r08: 0x00000001 r09: 0x804a807c r10: 0x0000067e r11: 0xffffffff r12: 0x80164480 Stack Trace: unmap_page_range+0x17a/0x700 unmap_vmas+0x46/0x64 do_munmap+0x210/0x450 SyS_munmap+0x2c/0x50 EV_Trap+0xfc/0x100 So the value of pfn must be casted to pte_t before shifting to ensure that 40-bit address will not be truncated: __pte(((pte_t) (pfn) << PAGE_SHIFT) | pgprot_val(prot)) Signed-off-by: Yuriy Kolerov --- arch/arc/include/asm/pgtable.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h index 89eeb37..77bc51c 100644 --- a/arch/arc/include/asm/pgtable.h +++ b/arch/arc/include/asm/pgtable.h @@ -280,7 +280,8 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep) #define pte_page(pte) pfn_to_page(pte_pfn(pte)) #define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot) -#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) +#define pfn_pte(pfn, prot) \ + __pte(((pte_t) (pfn) << PAGE_SHIFT) | pgprot_val(prot)) /* Don't use virt_to_pfn for macros below: could cause truncations for PAE40*/ #define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)