.section ".text.head", "ax"
 
 #ifdef CONFIG_SMP
+diag_reg_offset:
+       .word   g_diag_reg - .
+
+       .macro  set_diag_reg
+       adr     r0, diag_reg_offset
+       ldr     r1, [r0]
+       add     r1, r1, r0              @ r1 = physical &g_diag_reg
+       ldr     r0, [r1]
+       mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
+       .endm
+
 ENTRY(v7_secondary_startup)
        bl      v7_invalidate_l1
+       set_diag_reg
        b       secondary_startup
 ENDPROC(v7_secondary_startup)
 #endif
 
 
 #include <linux/init.h>
 #include <linux/smp.h>
+#include <asm/cacheflush.h>
 #include <asm/page.h>
 #include <asm/smp_scu.h>
 #include <asm/mach/map.h>
 
 #define SCU_STANDBY_ENABLE     (1 << 5)
 
+u32 g_diag_reg;
 static void __iomem *scu_base;
 
 static struct map_desc scu_io_desc __initdata = {
 static void __init imx_smp_prepare_cpus(unsigned int max_cpus)
 {
        imx_smp_prepare();
+
+       /*
+        * The diagnostic register holds the errata bits.  Mostly bootloader
+        * does not bring up secondary cores, so that when errata bits are set
+        * in bootloader, they are set only for boot cpu.  But on a SMP
+        * configuration, it should be equally done on every single core.
+        * Read the register from boot cpu here, and will replicate it into
+        * secondary cores when booting them.
+        */
+       asm("mrc p15, 0, %0, c15, c0, 1" : "=r" (g_diag_reg) : : "cc");
+       __cpuc_flush_dcache_area(&g_diag_reg, sizeof(g_diag_reg));
+       outer_clean_range(__pa(&g_diag_reg), __pa(&g_diag_reg + 1));
 }
 
 struct smp_operations  imx_smp_ops __initdata = {