From patchwork Tue Apr 12 08:14:40 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tero Kristo X-Patchwork-Id: 65594 Delivered-To: patch@linaro.org Received: by 10.140.93.198 with SMTP id d64csp1785420qge; Tue, 12 Apr 2016 01:16:26 -0700 (PDT) X-Received: by 10.98.86.77 with SMTP id k74mr2809089pfb.28.1460448986149; Tue, 12 Apr 2016 01:16:26 -0700 (PDT) Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id 86si8630583pfr.63.2016.04.12.01.16.26 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 12 Apr 2016 01:16:26 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) client-ip=2001:1868:205::9; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) smtp.mailfrom=linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aptTs-0006nd-Ac; Tue, 12 Apr 2016 08:15:28 +0000 Received: from comal.ext.ti.com ([198.47.26.152]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aptTc-0005NK-8p for linux-arm-kernel@lists.infradead.org; Tue, 12 Apr 2016 08:15:13 +0000 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id u3C8Egwf022839; Tue, 12 Apr 2016 03:14:42 -0500 Received: from DFLE73.ent.ti.com (dfle73.ent.ti.com [128.247.5.110]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id u3C8EgNE020362; Tue, 12 Apr 2016 03:14:42 -0500 Received: from dflp32.itg.ti.com (10.64.6.15) by DFLE73.ent.ti.com (128.247.5.110) with Microsoft SMTP Server id 14.3.224.2; Tue, 12 Apr 2016 03:14:42 -0500 Received: from sokoban.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp32.itg.ti.com (8.14.3/8.13.8) with ESMTP id u3C8EcgN022076; Tue, 12 Apr 2016 03:14:41 -0500 From: Tero Kristo To: , , , Subject: [RFC 1/1] ARM: mm: add support for specifying shareability level via cmdline Date: Tue, 12 Apr 2016 11:14:40 +0300 Message-ID: <1460448880-5677-2-git-send-email-t-kristo@ti.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1460448880-5677-1-git-send-email-t-kristo@ti.com> References: <1460448880-5677-1-git-send-email-t-kristo@ti.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160412_011512_488177_30691B79 X-CRM114-Status: GOOD ( 16.22 ) X-Spam-Score: -7.9 (-------) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-7.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [198.47.26.152 listed in list.dnswl.org] -1.0 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [198.47.26.152 listed in wl.mailspike.net] -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-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org pmd_sect_s=x can be used to specify cache coherency level for the CPU. The value is used to setup cache coherency level for specific MMU mappings. Currently kernel only supports inner shareable attribute. This feature is required at least for keystone DMA cache coherency support, where pages meant to be used by DMA must be marked as outer shareable also, so the DMA masters can snoop the maintenance messages. Signed-off-by: Tero Kristo --- arch/arm/include/asm/fixmap.h | 2 +- arch/arm/include/asm/pgtable.h | 3 +++ arch/arm/kernel/setup.c | 39 +++++++++++++++++++++++++++++++--- arch/arm/mm/dump.c | 3 +++ arch/arm/mm/mmu.c | 46 +++++++++++++++++++++++++--------------- 5 files changed, 72 insertions(+), 21 deletions(-) -- 1.7.9.5 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h index 5c17d2d..310981a 100644 --- a/arch/arm/include/asm/fixmap.h +++ b/arch/arm/include/asm/fixmap.h @@ -45,7 +45,7 @@ static const enum fixed_addresses __end_of_fixed_addresses = #define FIXMAP_PAGE_RO (FIXMAP_PAGE_NORMAL | L_PTE_RDONLY) /* Used by set_fixmap_(io|nocache), both meant for mapping a device */ -#define FIXMAP_PAGE_IO (FIXMAP_PAGE_COMMON | L_PTE_MT_DEV_SHARED | L_PTE_SHARED) +#define FIXMAP_PAGE_IO (FIXMAP_PAGE_COMMON | L_PTE_MT_DEV_SHARED | l_pte_shared) #define FIXMAP_PAGE_NOCACHE FIXMAP_PAGE_IO #define __early_set_fixmap __set_fixmap diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 348caab..e8a28aa 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -86,6 +86,9 @@ extern pgprot_t pgprot_hyp_device; extern pgprot_t pgprot_s2; extern pgprot_t pgprot_s2_device; +extern pteval_t pmd_sect_s; +extern pteval_t l_pte_shared; + #define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b)) #define PAGE_NONE _MOD_PROT(pgprot_user, L_PTE_XN | L_PTE_RDONLY | L_PTE_NONE) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 139791e..3836c9a 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -668,6 +669,8 @@ static void __init smp_build_mpidr_hash(void) } #endif +static unsigned long cpu_mm_mmu_flags; + static void __init setup_processor(void) { struct proc_info_list *list; @@ -704,6 +707,8 @@ static void __init setup_processor(void) cpu_name, read_cpuid_id(), read_cpuid_id() & 15, proc_arch[cpu_architecture()], get_cr()); + cpu_mm_mmu_flags = list->__cpu_mm_mmu_flags; + snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c", list->arch_name, ENDIANNESS); snprintf(elf_platform, ELF_PLATFORM_SIZE, "%s%c", @@ -716,9 +721,6 @@ static void __init setup_processor(void) #ifndef CONFIG_ARM_THUMB elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT); #endif -#ifdef CONFIG_MMU - init_default_cache_policy(list->__cpu_mm_mmu_flags); -#endif erratum_a15_798181_init(); elf_hwcap_fixup(); @@ -1002,6 +1004,36 @@ void __init hyp_mode_check(void) #endif } +pteval_t pmd_sect_s = PMD_SECT_S; +pteval_t l_pte_shared = L_PTE_SHARED; + +static int __init parse_mmu_setup(char *str) +{ + u32 new_val; + + if (!get_option(&str, &new_val)) + return -EINVAL; + + if (new_val < 2 || new_val > 3) { + pr_err("%s: bad value: %d\n", __func__, new_val); + return -EINVAL; + } + + new_val = _AT(pteval_t, new_val) << 8; + + pr_info("%s: setting PMD_SECT_S to %08x, old-val%08x\n", __func__, + new_val, (u32)pmd_sect_s); + + pmd_sect_s = new_val; + l_pte_shared = new_val; + + cpu_mm_mmu_flags = ~(u32)PMD_SECT_S; + cpu_mm_mmu_flags |= pmd_sect_s; + + return 0; +} +early_param("pmd_sect_s", parse_mmu_setup); + void __init setup_arch(char **cmdline_p) { const struct machine_desc *mdesc; @@ -1032,6 +1064,7 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); #ifdef CONFIG_MMU + init_default_cache_policy(cpu_mm_mmu_flags); early_paging_init(mdesc); #endif setup_dma_zone(mdesc); diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c index 9fe8e24..319412e 100644 --- a/arch/arm/mm/dump.c +++ b/arch/arm/mm/dump.c @@ -346,6 +346,9 @@ static int ptdump_init(void) struct dentry *pe; unsigned i, j; + if (l_pte_shared != L_PTE_SHARED) + pte_bits[3].val = l_pte_shared; + for (i = 0; i < ARRAY_SIZE(pg_level); i++) if (pg_level[i].bits) for (j = 0; j < pg_level[i].num; j++) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 62f4d01..4140acb 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -454,9 +454,9 @@ static void __init build_mem_type_table(void) pr_warn("Forcing write-allocate cache policy for SMP\n"); cachepolicy = CPOLICY_WRITEALLOC; } - if (!(initial_pmd_value & PMD_SECT_S)) { + if ((initial_pmd_value & PMD_SECT_S) != pmd_sect_s) { pr_warn("Forcing shared mappings for SMP\n"); - initial_pmd_value |= PMD_SECT_S; + initial_pmd_value |= pmd_sect_s; } } @@ -591,27 +591,39 @@ static void __init build_mem_type_table(void) mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; #endif + mem_types[MT_DEVICE].prot_sect &= ~PMD_SECT_S; + mem_types[MT_DEVICE].prot_sect |= pmd_sect_s; + + mem_types[MT_DEVICE].prot_pte &= ~L_PTE_SHARED; + mem_types[MT_DEVICE].prot_pte |= l_pte_shared; + + mem_types[MT_DEVICE].prot_pte_s2 &= ~L_PTE_SHARED; + mem_types[MT_DEVICE].prot_pte_s2 |= l_pte_shared; + + mem_types[MT_MEMORY_RW_SO].prot_sect &= ~PMD_SECT_S; + mem_types[MT_MEMORY_RW_SO].prot_sect |= pmd_sect_s; + /* * If the initial page tables were created with the S bit * set, then we need to do the same here for the same * reasons given in early_cachepolicy(). */ if (initial_pmd_value & PMD_SECT_S) { - user_pgprot |= L_PTE_SHARED; - kern_pgprot |= L_PTE_SHARED; - vecs_pgprot |= L_PTE_SHARED; - s2_pgprot |= L_PTE_SHARED; - mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S; - mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED; - mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S; - mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; - mem_types[MT_MEMORY_RWX].prot_sect |= PMD_SECT_S; - mem_types[MT_MEMORY_RWX].prot_pte |= L_PTE_SHARED; - mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_S; - mem_types[MT_MEMORY_RW].prot_pte |= L_PTE_SHARED; - mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED; - mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_S; - mem_types[MT_MEMORY_RWX_NONCACHED].prot_pte |= L_PTE_SHARED; + user_pgprot |= l_pte_shared; + kern_pgprot |= l_pte_shared; + vecs_pgprot |= l_pte_shared; + s2_pgprot |= l_pte_shared; + mem_types[MT_DEVICE_WC].prot_sect |= pmd_sect_s; + mem_types[MT_DEVICE_WC].prot_pte |= l_pte_shared; + mem_types[MT_DEVICE_CACHED].prot_sect |= pmd_sect_s; + mem_types[MT_DEVICE_CACHED].prot_pte |= l_pte_shared; + mem_types[MT_MEMORY_RWX].prot_sect |= pmd_sect_s; + mem_types[MT_MEMORY_RWX].prot_pte |= l_pte_shared; + mem_types[MT_MEMORY_RW].prot_sect |= pmd_sect_s; + mem_types[MT_MEMORY_RW].prot_pte |= l_pte_shared; + mem_types[MT_MEMORY_DMA_READY].prot_pte |= l_pte_shared; + mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= pmd_sect_s; + mem_types[MT_MEMORY_RWX_NONCACHED].prot_pte |= l_pte_shared; } }