From patchwork Thu Apr 6 16:03:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Jon Medhurst (Tixy)" X-Patchwork-Id: 9667779 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 2EA67601EB for ; Thu, 6 Apr 2017 16:03:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 872BA28581 for ; Thu, 6 Apr 2017 16:03:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7C1CC2858C; Thu, 6 Apr 2017 16:03:47 +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=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=ham 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 DEAD128581 for ; Thu, 6 Apr 2017 16:03:46 +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:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Mime-Version:References:In-Reply-To: Date:To:From:Subject:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=f1fATP6GoZYYcPkLGhhzCvQLbnXMfP09wQBsq/dA2IA=; b=GbklrnDh8ShPqG tijmq5bq2uqzk5ucyuV+hb/0xb5G67EmPXoriGK82GPrzZzra1KbKVDLdjDOM5UuMtik4it7aLCy4 zFkYDs8v8EqPBpUUUeqImC3Xg/8xEkds21fGE5851EbF6wMnOa/lcmuwDlwKb4QttMqWZeIayEzfu NHsDHVusAzPBtddtdkndFQjU1VT5bqdKcL60QE56K1dBOE7LSxQyopfq0tECzvEHkZqCQA91WrZqc v80y9eDTo1oVEJOM1ojlQtmvM/bYxuTgPeMtCNJ2BgQYXILSTCoU+aJf72xRZ6prA5LPxYYwrLXEH bwtUNSu2r3bk6+lvoCjA==; 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 1cw9sv-0000q1-JH; Thu, 06 Apr 2017 16:03:45 +0000 Received: from mail-wr0-x231.google.com ([2a00:1450:400c:c0c::231]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cw9sq-0000Wg-B3 for linux-arm-kernel@lists.infradead.org; Thu, 06 Apr 2017 16:03:43 +0000 Received: by mail-wr0-x231.google.com with SMTP id w11so63371342wrc.3 for ; Thu, 06 Apr 2017 09:03:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=message-id:subject:from:to:cc:date:in-reply-to:references :mime-version:content-transfer-encoding; bh=8BykaK8P0EMr/2dHDNIQwqxZQXJimKqpHzJ9M1YcpwM=; b=TBmh5jNO4ohUNrqbcbjPtqsCihb5tFQkaqpvg1/0/mN/F6EVjpLNifk72NeM/47fch jZCF1zcUmFM3dy3immWKE2EyQuHTKhVgFT4hjoPEYOO+jnby1wBfsNPWs1vH/CGIcYdu zfgcVFN5G92mB85Rb6q2aRDV6hV8dB1jHQlUE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:subject:from:to:cc:date:in-reply-to :references:mime-version:content-transfer-encoding; bh=8BykaK8P0EMr/2dHDNIQwqxZQXJimKqpHzJ9M1YcpwM=; b=C3KuxSESt6cHBqQl3TUuzv4iu4eqxOt1fkmxUxyKnmoB+vwVKr42D77OwGT+Ab1n8F 1QnJFBNHE2ouB/vII2z6SnjsXSjSUkjB4xQh432DjbvsWCvOslzfl/YNHAsDKL7IpDSi tajefaYBBdhn3sGZR71Xr4z9Jk8VtY8xKtAcJMG5ADE08yVB+Nq/huJroXpqjGpM8iGe zimsd4hm+9reN2r+/Cuz1HZnRry+Ob4WvHYg8m7n/5J+oanFLW2U7NOxFFSph3EeTCyr JJRlVL0AV11Ao4deubIansR5ertV5DkVcEEvjurs0JAtNQOgL0Wk41ENmCWYcUDC+4Ar koXg== X-Gm-Message-State: AFeK/H0kI4wUyOHAvYUkLMlXgj+ZJc57fAigQ4zHgz7w/7OmqSIkGO20zwcIHqU9AVQG6DmP X-Received: by 10.223.169.70 with SMTP id u64mr29538583wrc.187.1491494596514; Thu, 06 Apr 2017 09:03:16 -0700 (PDT) Received: from linaro1 (82-69-122-217.dsl.in-addr.zen.co.uk. [82.69.122.217]) by smtp.gmail.com with ESMTPSA id m7sm26961382wmi.34.2017.04.06.09.03.15 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 06 Apr 2017 09:03:15 -0700 (PDT) Message-ID: <1491494594.2950.7.camel@linaro.org> Subject: [PATCH v4] arm: Fix memory attribute inconsistencies when using fixmap From: "Jon Medhurst (Tixy)" To: Ard Biesheuvel , Russell King - ARM Linux Date: Thu, 06 Apr 2017 17:03:14 +0100 In-Reply-To: References: <1491291087-17450-1-git-send-email-ard.biesheuvel@linaro.org> <20170405224245.GA17774@n2100.armlinux.org.uk> <1491486403.2950.3.camel@linaro.org> X-Mailer: Evolution 3.22.6-1 Mime-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170406_090340_578192_F3DD9D19 X-CRM114-Status: GOOD ( 18.84 ) 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: Vladimir Murzin , afzal mohammed , "linux-arm-kernel@lists.infradead.org" , Stefan Agner 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 To cope with the variety in ARM architectures and configurations, the pagetable attributes for kernel memory are generated at runtime to match the system the kernel finds itself on. This calculated value is stored in pgprot_kernel. However, when early fixmap support was added for ARM (commit a5f4c561b3b1) the attributes used for mappings were hard coded because pgprot_kernel is not set up early enough. Unfortunately, when fixmap is used after early boot this means the memory being mapped can have different attributes to existing mappings, potentially leading to unpredictable behaviour. A specific problem also exists due to the hard coded values not include the 'shareable' attribute which means on systems where this matters (e.g. those with multiple CPU clusters) the cache contents for a memory location can become inconsistent between CPUs. To resolve these issues we change fixmap to use the same memory attributes (from pgprot_kernel) that the rest of the kernel uses. To enable this we need to refactor the initialisation code so build_mem_type_table() is called early enough. Note, that relies on early param parsing for memory type overrides passed via the kernel command line, so we need to make sure this call is still after parse_early_params(). Fixes: a5f4c561b3b1 ("ARM: 8415/1: early fixmap support for earlycon") Cc: # v4.3+ Signed-off-by: Jon Medhurst [ardb: keep early_fixmap_init() before param parsing, for earlycon] Signed-off-by: Ard Biesheuvel Tested-by: afzal mohammed --- v4: - Drop declaration of early_mm_init() from arch/arm/include/asm/mmu.h and make early_paging_init() static. Ard's v3: - Unfortunately, I failed to spot an issue with earlycon when testing Tixy's v2. Earlycon depends on fixmap, but only for device mappings, which are not affected by this change. So instead, preserve the calls to early_fixmap_init() and early_ioremap_init() in their original locations, and only move build_mem_type_table() to the earliest possible moment in boot, which is right after early param parsing (which may set cachepolicy/nocache/nowb variables) arch/arm/include/asm/fixmap.h | 2 +- arch/arm/kernel/setup.c | 4 ++-- arch/arm/mm/mmu.c | 16 +++++++++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h index 5c17d2dec777..8f967d1373f6 100644 --- a/arch/arm/include/asm/fixmap.h +++ b/arch/arm/include/asm/fixmap.h @@ -41,7 +41,7 @@ static const enum fixed_addresses __end_of_fixed_addresses = #define FIXMAP_PAGE_COMMON (L_PTE_YOUNG | L_PTE_PRESENT | L_PTE_XN | L_PTE_DIRTY) -#define FIXMAP_PAGE_NORMAL (FIXMAP_PAGE_COMMON | L_PTE_MT_WRITEBACK) +#define FIXMAP_PAGE_NORMAL (pgprot_kernel | L_PTE_XN) #define FIXMAP_PAGE_RO (FIXMAP_PAGE_NORMAL | L_PTE_RDONLY) /* Used by set_fixmap_(io|nocache), both meant for mapping a device */ diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index f4e54503afa9..32e1a9513dc7 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -80,7 +80,7 @@ __setup("fpe=", fpe_setup); extern void init_default_cache_policy(unsigned long); extern void paging_init(const struct machine_desc *desc); -extern void early_paging_init(const struct machine_desc *); +extern void early_mm_init(const struct machine_desc *); extern void adjust_lowmem_bounds(void); extern enum reboot_mode reboot_mode; extern void setup_dma_zone(const struct machine_desc *desc); @@ -1088,7 +1088,7 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); #ifdef CONFIG_MMU - early_paging_init(mdesc); + early_mm_init(mdesc); #endif setup_dma_zone(mdesc); xen_early_init(); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 4e016d7f37b3..347cca965783 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -414,6 +414,11 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot) FIXADDR_END); BUG_ON(idx >= __end_of_fixed_addresses); + /* we only support device mappings until pgprot_kernel has been set */ + if (WARN_ON(pgprot_val(prot) != pgprot_val(FIXMAP_PAGE_IO) && + pgprot_val(pgprot_kernel) == 0)) + return; + if (pgprot_val(prot)) set_pte_at(NULL, vaddr, pte, pfn_pte(phys >> PAGE_SHIFT, prot)); @@ -1492,7 +1497,7 @@ pgtables_remap lpae_pgtables_remap_asm; * early_paging_init() recreates boot time page table setup, allowing machines * to switch over to a high (>4G) address space on LPAE systems */ -void __init early_paging_init(const struct machine_desc *mdesc) +static void __init early_paging_init(const struct machine_desc *mdesc) { pgtables_remap *lpae_pgtables_remap; unsigned long pa_pgd; @@ -1560,7 +1565,7 @@ void __init early_paging_init(const struct machine_desc *mdesc) #else -void __init early_paging_init(const struct machine_desc *mdesc) +static void __init early_paging_init(const struct machine_desc *mdesc) { long long offset; @@ -1616,7 +1621,6 @@ void __init paging_init(const struct machine_desc *mdesc) { void *zero_page; - build_mem_type_table(); prepare_page_table(); map_lowmem(); memblock_set_current_limit(arm_lowmem_limit); @@ -1636,3 +1640,9 @@ void __init paging_init(const struct machine_desc *mdesc) empty_zero_page = virt_to_page(zero_page); __flush_dcache_page(NULL, empty_zero_page); } + +void __init early_mm_init(const struct machine_desc *mdesc) +{ + build_mem_type_table(); + early_paging_init(mdesc); +}