From 3434c9f80e6a2918c9c7623898102518025312b1 Mon Sep 17 00:00:00 2001 From: tao zeng Date: Tue, 6 Nov 2018 14:02:57 +0800 Subject: [PATCH] mm: clear MMU mapping for secure os memory [1/1] PD#SWPL-1631 Problem: If Cortex A73 accessed memory near secure memory range, an SError may occur due to prefetch of A73 core. Solution: Add clear mmu property for arm platform Verify: W400 Change-Id: I2e396f77772aeea231d0bf5f38a81440117ecdd6 Signed-off-by: tao zeng --- arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts | 1 + arch/arm/boot/dts/amlogic/mesong12b.dtsi | 1 + mm/cma.c | 32 +++++++++++++++++++++++---- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts b/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts index 866769b..3913614 100644 --- a/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts +++ b/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts @@ -68,6 +68,7 @@ size = <0x400000>; alignment = <0x400000>; alloc-ranges = <0x05000000 0x400000>; + clear-map; }; secos_reserved:linux,secos { diff --git a/arch/arm/boot/dts/amlogic/mesong12b.dtsi b/arch/arm/boot/dts/amlogic/mesong12b.dtsi index 0037257..09fceff 100644 --- a/arch/arm/boot/dts/amlogic/mesong12b.dtsi +++ b/arch/arm/boot/dts/amlogic/mesong12b.dtsi @@ -249,6 +249,7 @@ in_base_func = <0x82000020>; out_base_func = <0x82000021>; reserve_mem_size = <0x00300000>; + clear_range = <0x05100000 0x200000>; }; securitykey { diff --git a/mm/cma.c b/mm/cma.c index 86b45e4..23d978d 100644 --- a/mm/cma.c +++ b/mm/cma.c @@ -53,6 +53,7 @@ void cma_init_clear(struct cma *cma, bool clear) cma->clear_map = clear; } +#ifdef CONFIG_ARM64 static int clear_cma_pagemap2(struct cma *cma) { pgd_t *pgd; @@ -64,8 +65,8 @@ static int clear_cma_pagemap2(struct cma *cma) addr = (unsigned long)pfn_to_kaddr(cma->base_pfn); end = addr + cma->count * PAGE_SIZE; mm = &init_mm; - pgd = pgd_offset(mm, addr); - for (; addr < end; addr += PMD_SIZE) { + for (; addr < end; addr += SECTION_SIZE) { + pgd = pgd_offset(mm, addr); if (pgd_none(*pgd) || pgd_bad(*pgd)) break; @@ -77,14 +78,25 @@ static int clear_cma_pagemap2(struct cma *cma) if (pmd_none(*pmd)) break; + pr_debug("%s, addr:%lx, pgd:%p %llx, pmd:%p %llx\n", + __func__, addr, pgd, pgd_val(*pgd), pmd, pmd_val(*pmd)); pmd_clear(pmd); } return 0; } +#endif int setup_cma_full_pagemap(struct cma *cma) { +#ifdef CONFIG_ARM + /* + * arm already create level 3 mmu mapping for lowmem cma. + * And if high mem cma, there is no mapping. So nothing to + * do for arch arm. + */ + return 0; +#elif defined(CONFIG_ARM64) struct vm_area_struct vma = {}; unsigned long addr, size; int ret; @@ -102,6 +114,9 @@ int setup_cma_full_pagemap(struct cma *cma) pr_info("%s, remap pte failed:%d, cma:%lx\n", __func__, ret, cma->base_pfn); return 0; +#else + #error "NOT supported ARCH" +#endif } int cma_mmu_op(struct page *page, int count, bool set) @@ -113,14 +128,14 @@ int cma_mmu_op(struct page *page, int count, bool set) unsigned long addr, end; struct mm_struct *mm; - if (!page) + if (!page || PageHighMem(page)) return -EINVAL; addr = (unsigned long)page_address(page); end = addr + count * PAGE_SIZE; mm = &init_mm; - pgd = pgd_offset(mm, addr); for (; addr < end; addr += PAGE_SIZE) { + pgd = pgd_offset(mm, addr); if (pgd_none(*pgd) || pgd_bad(*pgd)) break; @@ -138,6 +153,15 @@ int cma_mmu_op(struct page *page, int count, bool set) else pte_clear(mm, addr, pte); pte_unmap(pte); + #ifdef CONFIG_ARM + pr_debug("%s, add:%lx, pgd:%p %x, pmd:%p %x, pte:%p %x\n", + __func__, addr, pgd, (int)pgd_val(*pgd), + pmd, (int)pmd_val(*pmd), pte, (int)pte_val(*pte)); + #elif defined(CONFIG_ARM64) + pr_debug("%s, add:%lx, pgd:%p %llx, pmd:%p %llx, pte:%p %llx\n", + __func__, addr, pgd, pgd_val(*pgd), + pmd, pmd_val(*pmd), pte, pte_val(*pte)); + #endif page++; } return 0; -- 2.7.4