From patchwork Fri Nov 17 18:21:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Will Deacon X-Patchwork-Id: 10063321 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 271196037E for ; Fri, 17 Nov 2017 18:34:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1DE1029F0B for ; Fri, 17 Nov 2017 18:34:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 12B7C29FE5; Fri, 17 Nov 2017 18:34:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8ABE029F0B for ; Fri, 17 Nov 2017 18:34:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=vPX/88zbzZSe7ElSCWYzV6acAymjsKyfK8nu1FP8v4o=; b=D/iRzDhDP7WNBeOoXIZT0Ho4cM eqPaVM6GywkCqCo3KLbU5O6rdbNKjSvXg6r9enZr8BxDuLQLxiU89fvlwfFCyN6KjyvjEda2ZINjp XLYCJ90dRwGeEtbT1vquh5NMYUZYq/ATV+GhXlg4UmmqL9pRVO1nZ7Uk82T8Hs6ubeIEhSZz0kKYX mQKfjjIchNLKwZGSPoPowGQAjKVQ4uq5kJQn1p477Gst7o3SAgrbyOH/bVsvstWRIg7HEQElKEwzb Ztm41W85UFT6EVknAhGJQPpLOS51DrjspQq0FQtSU3+h0M8vYk8DHSYChjzGfcxmRHWFsKT52ljD0 k5p0xxSQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1eFlTb-0001yX-Gy; Fri, 17 Nov 2017 18:34:55 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1eFlHh-0005rI-H5 for linux-arm-kernel@lists.infradead.org; Fri, 17 Nov 2017 18:22:41 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 29CB7174E; Fri, 17 Nov 2017 10:21:55 -0800 (PST) Received: from edgewater-inn.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.72.51.249]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id EF59E3F246; Fri, 17 Nov 2017 10:21:54 -0800 (PST) Received: by edgewater-inn.cambridge.arm.com (Postfix, from userid 1000) id 8DA9B1AE1382; Fri, 17 Nov 2017 18:22:03 +0000 (GMT) From: Will Deacon To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 11/18] arm64: mm: Map entry trampoline into trampoline and kernel page tables Date: Fri, 17 Nov 2017 18:21:54 +0000 Message-Id: <1510942921-12564-12-git-send-email-will.deacon@arm.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1510942921-12564-1-git-send-email-will.deacon@arm.com> References: <1510942921-12564-1-git-send-email-will.deacon@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171117_102237_680844_AF0C1D96 X-CRM114-Status: GOOD ( 13.47 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, keescook@chromium.org, ard.biesheuvel@linaro.org, catalin.marinas@arm.com, dave.hansen@linux.intel.com, sboyd@codeaurora.org, linux-kernel@vger.kernel.org, Will Deacon MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The exception entry trampoline needs to be mapped at the same virtual address in both the trampoline page table (which maps nothing else) and also the kernel page table, so that we can swizzle TTBR1_EL1 on exceptions from and return to EL0. This patch maps the trampoline at a fixed virtual address (TRAMP_VALIAS), which allows the kernel proper to be randomized with respect to the trampoline when KASLR is enabled. Signed-off-by: Will Deacon --- arch/arm64/include/asm/memory.h | 1 + arch/arm64/include/asm/pgtable.h | 1 + arch/arm64/mm/mmu.c | 48 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index f7c4d2146aed..18a3cb86ef17 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -70,6 +70,7 @@ #define PAGE_OFFSET (UL(0xffffffffffffffff) - \ (UL(1) << (VA_BITS - 1)) + 1) #define KIMAGE_VADDR (MODULES_END) +#define TRAMP_VALIAS (KIMAGE_VADDR) #define MODULES_END (MODULES_VADDR + MODULES_VSIZE) #define MODULES_VADDR (VA_START + KASAN_SHADOW_SIZE) #define MODULES_VSIZE (SZ_128M) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index b46e54c2399b..2f3b58a1d434 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -667,6 +667,7 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm, extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern pgd_t idmap_pg_dir[PTRS_PER_PGD]; +extern pgd_t tramp_pg_dir[PTRS_PER_PGD]; /* * Encode and decode a swap entry: diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index a75858267b6d..5ce5cb1249da 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -528,6 +528,51 @@ early_param("rodata", parse_rodata); #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 DEFINE_STATIC_KEY_TRUE(__unmap_kernel_at_el0); EXPORT_SYMBOL_GPL(__unmap_kernel_at_el0); + +static void __init add_tramp_vma(void) +{ + extern char __entry_tramp_text_start[], __entry_tramp_text_end[]; + static struct vm_struct vmlinux_tramp; + unsigned long size = (unsigned long)__entry_tramp_text_end - + (unsigned long)__entry_tramp_text_start; + + vmlinux_tramp = (struct vm_struct) { + .addr = (void *)TRAMP_VALIAS, + .phys_addr = __pa_symbol(__entry_tramp_text_start), + .size = size + PAGE_SIZE, + .flags = VM_MAP, + .caller = __builtin_return_address(0), + + }; + + vm_area_add_early(&vmlinux_tramp); +} + +static int __init map_entry_trampoline(void) +{ + extern char __entry_tramp_text_start[], __entry_tramp_text_end[]; + + pgprot_t prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC; + phys_addr_t size = (unsigned long)__entry_tramp_text_end - + (unsigned long)__entry_tramp_text_start; + phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start); + + /* The trampoline is always mapped and can therefore be global */ + pgprot_val(prot) &= ~PTE_NG; + + /* Map only the text into the trampoline page table */ + memset((char *)tramp_pg_dir, 0, PGD_SIZE); + __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, size, prot, + pgd_pgtable_alloc, 0); + + /* ...as well as the kernel page table */ + __create_pgd_mapping(init_mm.pgd, pa_start, TRAMP_VALIAS, size, prot, + pgd_pgtable_alloc, 0); + return 0; +} +core_initcall(map_entry_trampoline); +#else +static void __init add_tramp_vma(void) {} #endif /* @@ -559,6 +604,9 @@ static void __init map_kernel(pgd_t *pgd) &vmlinux_initdata, 0, VM_NO_GUARD); map_kernel_segment(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0); + /* Add a VMA for the trampoline page, which will be mapped later on */ + add_tramp_vma(); + if (!pgd_val(*pgd_offset_raw(pgd, FIXADDR_START))) { /* * The fixmap falls in a separate pgd to the kernel, and doesn't