diff mbox series

arm: mach-imx: Fix speculative instruction prefetch issue

Message ID 1613874427-17961-1-git-send-email-ye.li@nxp.com
State Changes Requested
Delegated to: Stefano Babic
Headers show
Series arm: mach-imx: Fix speculative instruction prefetch issue | expand

Commit Message

Ye Li Feb. 21, 2021, 2:27 a.m. UTC
Default ARM32 MMU setting in u-boot sets XN bit to entire 4GB space no
matter which DCACHE option is used, and set domain permission to manager.
This causes MMU ignores the access check and XN bit, so speculative
instruction can fetch from entire space.

This patch sets the DDR, ROM, OCRAM without XN bit, and set domain to client
to enable the XN and access check. So speculative instruction fetch can only
happens on these 3 regions to avoid prefetch from peripherals and invalid
regions.

Signed-off-by: Ye Li <ye.li@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/mach-imx/cache.c | 49 ++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 42 insertions(+), 7 deletions(-)

Comments

Stefano Babic May 2, 2021, 10:55 a.m. UTC | #1
Hi Ye,

this patch is quite old and it looks like it was forgotten - I apply it 
and runs CI, but it breaks most arm board. So I have to drop it.

Best regards,
Stefano Babic

On 21.02.21 03:27, Ye Li wrote:
> Default ARM32 MMU setting in u-boot sets XN bit to entire 4GB space no
> matter which DCACHE option is used, and set domain permission to manager.
> This causes MMU ignores the access check and XN bit, so speculative
> instruction can fetch from entire space.
> 
> This patch sets the DDR, ROM, OCRAM without XN bit, and set domain to client
> to enable the XN and access check. So speculative instruction fetch can only
> happens on these 3 regions to avoid prefetch from peripherals and invalid
> regions.
> 
> Signed-off-by: Ye Li <ye.li@nxp.com>
> Reviewed-by: Peng Fan <peng.fan@nxp.com>
> ---
>   arch/arm/mach-imx/cache.c | 49 ++++++++++++++++++++++++++++++++++++++++-------
>   1 file changed, 42 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/cache.c b/arch/arm/mach-imx/cache.c
> index 4e3b49a..8486c2d 100644
> --- a/arch/arm/mach-imx/cache.c
> +++ b/arch/arm/mach-imx/cache.c
> @@ -10,6 +10,10 @@
>   #include <asm/pl310.h>
>   #include <asm/io.h>
>   #include <asm/mach-imx/sys_proto.h>
> +#include <asm/global_data.h>
> +#include <log.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
>   
>   static void enable_ca7_smp(void)
>   {
> @@ -40,13 +44,13 @@ static void enable_ca7_smp(void)
>   }
>   
>   #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
> +
> +#define ARMV7_DOMAIN_CLIENT	1
> +#define ARMV7_DOMAIN_MASK	(0x3 << 0)
> +#define IMX_ARMV7_DCACHE_OPTION (DCACHE_DEFAULT_OPTION & ~TTB_SECT_XN_MASK)
> +
>   void enable_caches(void)
>   {
> -#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
> -	enum dcache_option option = DCACHE_WRITETHROUGH;
> -#else
> -	enum dcache_option option = DCACHE_WRITEBACK;
> -#endif
>   	/* Avoid random hang when download by usb */
>   	invalidate_dcache_all();
>   
> @@ -59,11 +63,42 @@ void enable_caches(void)
>   	/* Enable caching on OCRAM and ROM */
>   	mmu_set_region_dcache_behaviour(ROMCP_ARB_BASE_ADDR,
>   					ROMCP_ARB_END_ADDR,
> -					option);
> +					IMX_ARMV7_DCACHE_OPTION);
>   	mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR,
>   					IRAM_SIZE,
> -					option);
> +					IMX_ARMV7_DCACHE_OPTION);
> +}
> +
> +void dram_bank_mmu_setup(int bank)
> +{
> +	struct bd_info *bd = gd->bd;
> +	int	i;
> +
> +	/* bd->bi_dram is available only after relocation */
> +	if ((gd->flags & GD_FLG_RELOC) == 0)
> +		return;
> +
> +	debug("%s: bank: %d\n", __func__, bank);
> +	for (i = bd->bi_dram[bank].start >> MMU_SECTION_SHIFT;
> +	     i < (bd->bi_dram[bank].start >> MMU_SECTION_SHIFT) +
> +		 (bd->bi_dram[bank].size >> MMU_SECTION_SHIFT);
> +	     i++)
> +		set_section_dcache(i, IMX_ARMV7_DCACHE_OPTION);
>   }
> +
> +void arm_init_domains(void)
> +{
> +	u32 reg;
> +
> +	reg = get_dacr();
> +	/*
> +	* Set domain to client to do access and XN check
> +	*/
> +	reg &= ~ARMV7_DOMAIN_MASK;
> +	reg |= ARMV7_DOMAIN_CLIENT;
> +	set_dacr(reg);
> +}
> +
>   #else
>   void enable_caches(void)
>   {
>
diff mbox series

Patch

diff --git a/arch/arm/mach-imx/cache.c b/arch/arm/mach-imx/cache.c
index 4e3b49a..8486c2d 100644
--- a/arch/arm/mach-imx/cache.c
+++ b/arch/arm/mach-imx/cache.c
@@ -10,6 +10,10 @@ 
 #include <asm/pl310.h>
 #include <asm/io.h>
 #include <asm/mach-imx/sys_proto.h>
+#include <asm/global_data.h>
+#include <log.h>
+
+DECLARE_GLOBAL_DATA_PTR;
 
 static void enable_ca7_smp(void)
 {
@@ -40,13 +44,13 @@  static void enable_ca7_smp(void)
 }
 
 #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
+
+#define ARMV7_DOMAIN_CLIENT	1
+#define ARMV7_DOMAIN_MASK	(0x3 << 0)
+#define IMX_ARMV7_DCACHE_OPTION (DCACHE_DEFAULT_OPTION & ~TTB_SECT_XN_MASK)
+
 void enable_caches(void)
 {
-#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
-	enum dcache_option option = DCACHE_WRITETHROUGH;
-#else
-	enum dcache_option option = DCACHE_WRITEBACK;
-#endif
 	/* Avoid random hang when download by usb */
 	invalidate_dcache_all();
 
@@ -59,11 +63,42 @@  void enable_caches(void)
 	/* Enable caching on OCRAM and ROM */
 	mmu_set_region_dcache_behaviour(ROMCP_ARB_BASE_ADDR,
 					ROMCP_ARB_END_ADDR,
-					option);
+					IMX_ARMV7_DCACHE_OPTION);
 	mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR,
 					IRAM_SIZE,
-					option);
+					IMX_ARMV7_DCACHE_OPTION);
+}
+
+void dram_bank_mmu_setup(int bank)
+{
+	struct bd_info *bd = gd->bd;
+	int	i;
+
+	/* bd->bi_dram is available only after relocation */
+	if ((gd->flags & GD_FLG_RELOC) == 0)
+		return;
+
+	debug("%s: bank: %d\n", __func__, bank);
+	for (i = bd->bi_dram[bank].start >> MMU_SECTION_SHIFT;
+	     i < (bd->bi_dram[bank].start >> MMU_SECTION_SHIFT) +
+		 (bd->bi_dram[bank].size >> MMU_SECTION_SHIFT);
+	     i++)
+		set_section_dcache(i, IMX_ARMV7_DCACHE_OPTION);
 }
+
+void arm_init_domains(void)
+{
+	u32 reg;
+
+	reg = get_dacr();
+	/*
+	* Set domain to client to do access and XN check
+	*/
+	reg &= ~ARMV7_DOMAIN_MASK;
+	reg |= ARMV7_DOMAIN_CLIENT;
+	set_dacr(reg);
+}
+
 #else
 void enable_caches(void)
 {