secmon: clear mmu mapping of cma before a73 run [1/1]
authorTao Zeng <tao.zeng@amlogic.com>
Tue, 14 May 2019 10:18:09 +0000 (18:18 +0800)
committerNick Xie <nick@khadas.com>
Mon, 5 Aug 2019 06:33:30 +0000 (14:33 +0800)
PD#SWPL-8082

Problem:
Very low ratio(0.3%) of SError can be seen when do auto-reboot
test on g12b platfrom.

Solution:
Clear mmu mapping of secmon cma before a73 run

Verify:
w400

Change-Id: Idacfaea29dea2eff86304c7071a560c76654a5c3
Signed-off-by: Tao Zeng <tao.zeng@amlogic.com>
drivers/amlogic/secmon/secmon.c
include/linux/amlogic/secmon.h
mm/cma.c

index 624c8e3..36ce744 100644 (file)
@@ -62,7 +62,6 @@ static int secmon_probe(struct platform_device *pdev)
        int ret;
        int mem_size;
        struct page *page;
-       unsigned int clear[2] = {};
 
        if (!of_property_read_u32(np, "in_base_func", &id))
                phy_in_base = get_sharemem_info(id);
@@ -82,11 +81,6 @@ static int secmon_probe(struct platform_device *pdev)
                return ret;
        }
 
-       if (of_property_read_u32_array(np, "clear_range", clear, 2))
-               pr_info("can't fine clear_range\n");
-       else
-               pr_info("clear_range:%x %x\n", clear[0], clear[1]);
-
        page = dma_alloc_from_contiguous(&pdev->dev, mem_size >> PAGE_SHIFT, 0);
        if (!page) {
                pr_err("alloc page failed, ret:%p\n", page);
@@ -104,13 +98,6 @@ static int secmon_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
-       if (clear[0]) {
-               struct page *page = phys_to_page(clear[0]);
-               int cnt = clear[1] / PAGE_SIZE;
-
-               cma_mmu_op(page, cnt, 0);
-       }
-
        if (pfn_valid(__phys_to_pfn(phy_out_base)))
                sharemem_out_base = (void __iomem *)
                                __phys_to_virt(phy_out_base);
@@ -130,6 +117,28 @@ static int secmon_probe(struct platform_device *pdev)
        return ret;
 }
 
+void __init secmon_clear_cma_mmu(void)
+{
+       struct device_node *np;
+       unsigned int clear[2] = {};
+
+       np = of_find_node_by_name(NULL, "secmon");
+       if (!np)
+               return;
+
+       if (of_property_read_u32_array(np, "clear_range", clear, 2))
+               pr_info("can't fine clear_range\n");
+       else
+               pr_info("clear_range:%x %x\n", clear[0], clear[1]);
+
+       if (clear[0]) {
+               struct page *page = phys_to_page(clear[0]);
+               int cnt = clear[1] / PAGE_SIZE;
+
+               cma_mmu_op(page, cnt, 0);
+       }
+}
+
 static const struct of_device_id secmon_dt_match[] = {
        { .compatible = "amlogic, secmon" },
        { /* sentinel */ },
index 07bc94a..2003ac2 100644 (file)
@@ -25,5 +25,6 @@ long get_secmon_phy_output_base(void);
 
 void sharemem_mutex_lock(void);
 void sharemem_mutex_unlock(void);
+void secmon_clear_cma_mmu(void);
 
 #endif
index b59c2da..3311330 100644 (file)
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -39,6 +39,7 @@
 #ifdef CONFIG_AMLOGIC_CMA
 #include <asm/pgtable.h>
 #include <linux/amlogic/aml_cma.h>
+#include <linux/amlogic/secmon.h>
 #endif /* CONFIG_AMLOGIC_CMA */
 
 #include "cma.h"
@@ -281,10 +282,22 @@ static int __init cma_init_reserved_areas(void)
                if (ret)
                        return ret;
        }
-
+#ifdef CONFIG_AMLOGIC_SEC
+       /*
+        * A73 cache speculate prefetch may cause SError when boot.
+        * because it may prefetch cache line in secure memory range
+        * which have already reserved by bootloader. So we must
+        * clear mmu of secmon range before A73 core boot up
+        */
+       secmon_clear_cma_mmu();
+#endif
        return 0;
 }
+#ifdef CONFIG_AMLOGIC_CMA
+early_initcall(cma_init_reserved_areas);
+#else
 core_initcall(cma_init_reserved_areas);
+#endif
 
 /**
  * cma_init_reserved_mem() - create custom contiguous area from reserved memory