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: 119203 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp845649qgn; Fri, 17 Nov 2017 10:24:52 -0800 (PST) X-Google-Smtp-Source: AGs4zMbd6eRtVQ9bnwpvyvEu8/paZR63RcAwtkr6X0Ae/b6b4XJTkcqFbhsxq9Rgd2nSdy6Hefp4 X-Received: by 10.99.114.82 with SMTP id c18mr5930516pgn.221.1510943092082; Fri, 17 Nov 2017 10:24:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510943092; cv=none; d=google.com; s=arc-20160816; b=qm/36nLbZBehr0Hjk5vghI/gka9d8HcTuUliRX8xXKpxqw+mWqMCC1qhFPoq1SX3oK XvcUbVih7hjtJ+HmqGFZRColTQ8MgnMU7ZAesvSKO7KmSp3WDnIC6Butqz8mY5pLi6mi Rgpv0luVrHB3JQYKM9uUvMcJYH1zN59Q6ZdXg4I3nQauWhHhBqQT10QZDwqldxVWUORg zQETKC80vyb+uYr1lkFB28622Nel/K0U9Ia/QizDfIZfb01CrMPs7fAkTY6JcrpuSx6T ZvH2BYEnAtmfeu8/oapRyjiw/F4EuXKwmutxuzUkjnsNyGqFdk/M+XKj+ixFVsFUX+I5 2qHg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=TJiBhosd4G9tpeCgmcONfRfbFPWgmlbBPBrgwJO0jP0=; b=RC6TFM/Lx5t5uwMltv1NoBmBSVxOsvrnCGqqQceAq/NNBnZVem0LIn5aKjG6QLFl// riDOogh3vNN5bD/fWs9/9v5k+J+CDoJ0+D0sjr3/Z0OolwhZ3mpGED3IIJfxbP768Jdz mzces0bEb9usP5BUf9pTlAMdNeGqgsToMp1e31RIv9kbSry9VQtKN13NnTr0cFyvFYbv Mts2tJoAZXkICvmK//mDfVnAMYEn91A+sQ0NO/0BssklpT/flQJRTxPL8Tk3PNpviH/2 Yt2pPpg/5SlJjCrw6WVDlXtLgUCqQryU9elY3Yn2OkJ72DfHYGDBqS5sGrJ0OB0KT/j5 WvUw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y62si3088438pgb.383.2017.11.17.10.24.51; Fri, 17 Nov 2017 10:24:52 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760450AbdKQSYr (ORCPT + 28 others); Fri, 17 Nov 2017 13:24:47 -0500 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70]:39464 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1760299AbdKQSV5 (ORCPT ); Fri, 17 Nov 2017 13:21:57 -0500 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 Cc: linux-kernel@vger.kernel.org, catalin.marinas@arm.com, mark.rutland@arm.com, ard.biesheuvel@linaro.org, sboyd@codeaurora.org, dave.hansen@linux.intel.com, keescook@chromium.org, Will Deacon 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> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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(+) -- 2.1.4 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