]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
powerpc/fsl: Force coherent memory on e500mc derivatives
authorScott Wood <scottwood@freescale.com>
Sat, 18 Jul 2015 19:24:58 +0000 (14:24 -0500)
committerScott Wood <scottwood@freescale.com>
Sat, 8 Aug 2015 04:00:01 +0000 (23:00 -0500)
In CoreNet systems it is not allowed to mix M and non-M mappings to the
same memory, and coherent DMA accesses are considered to be M mappings
for this purpose.  Ignoring this has been observed to cause hard
lockups in non-SMP kernels on e6500.

Furthermore, e6500 implements the LRAT (logical to real address table)
which allows KVM guests to control the WIMGE bits.  This means that
KVM cannot force the M bit on the way it usually does, so the guest had
better set it itself.

Signed-off-by: Scott Wood <scottwood@freescale.com>
arch/powerpc/include/asm/pte-common.h
arch/powerpc/kernel/exceptions-64e.S
arch/powerpc/kernel/fsl_booke_entry_mapping.S
arch/powerpc/mm/fsl_booke_mmu.c

index b7c8d079c121e8fe6bea35eaad0eeeee206d4404..71537a319fc828474f71fd1855ed127b30d0cce5 100644 (file)
@@ -109,7 +109,8 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
  * the processor might need it for DMA coherency.
  */
 #define _PAGE_BASE_NC  (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_PSIZE)
-#if defined(CONFIG_SMP) || defined(CONFIG_PPC_STD_MMU)
+#if defined(CONFIG_SMP) || defined(CONFIG_PPC_STD_MMU) || \
+       defined(CONFIG_PPC_E500MC)
 #define _PAGE_BASE     (_PAGE_BASE_NC | _PAGE_COHERENT)
 #else
 #define _PAGE_BASE     (_PAGE_BASE_NC)
index 3e68d1c69718541578a7b875551ed203b2d9d49d..f3bd5e747ed84013be78206ab510a93a271ca604 100644 (file)
@@ -1313,11 +1313,14 @@ skpinv: addi    r6,r6,1                         /* Increment */
        sync
        isync
 
-/* The mapping only needs to be cache-coherent on SMP */
-#ifdef CONFIG_SMP
-#define M_IF_SMP       MAS2_M
+/*
+ * The mapping only needs to be cache-coherent on SMP, except on
+ * Freescale e500mc derivatives where it's also needed for coherent DMA.
+ */
+#if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC)
+#define M_IF_NEEDED    MAS2_M
 #else
-#define M_IF_SMP       0
+#define M_IF_NEEDED    0
 #endif
 
 /* 6. Setup KERNELBASE mapping in TLB[0]
@@ -1332,7 +1335,7 @@ skpinv:   addi    r6,r6,1                         /* Increment */
        ori     r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_1GB))@l
        mtspr   SPRN_MAS1,r6
 
-       LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET | M_IF_SMP)
+       LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET | M_IF_NEEDED)
        mtspr   SPRN_MAS2,r6
 
        rlwinm  r5,r5,0,0,25
index f22e7e44fbf321e9df8140ef55cb73e0b72142b0..83dd0f6776b3e61bba5f7786db49a4e3df1b2f1b 100644 (file)
@@ -152,11 +152,14 @@ skpinv:   addi    r6,r6,1                         /* Increment */
        tlbivax 0,r9
        TLBSYNC
 
-/* The mapping only needs to be cache-coherent on SMP */
-#ifdef CONFIG_SMP
-#define M_IF_SMP       MAS2_M
+/*
+ * The mapping only needs to be cache-coherent on SMP, except on
+ * Freescale e500mc derivatives where it's also needed for coherent DMA.
+ */
+#if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC)
+#define M_IF_NEEDED    MAS2_M
 #else
-#define M_IF_SMP       0
+#define M_IF_NEEDED    0
 #endif
 
 #if defined(ENTRY_MAPPING_BOOT_SETUP)
@@ -167,8 +170,8 @@ skpinv:     addi    r6,r6,1                         /* Increment */
        lis     r6,(MAS1_VALID|MAS1_IPROT)@h
        ori     r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l
        mtspr   SPRN_MAS1,r6
-       lis     r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h
-       ori     r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l
+       lis     r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_NEEDED)@h
+       ori     r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_NEEDED)@l
        mtspr   SPRN_MAS2,r6
        mtspr   SPRN_MAS3,r8
        tlbwe
index 9c90e66cffb6daadb3400f5e30650fc3a03721bc..354ba3c09ef3e940cb53267d78632eb24bc3d6b7 100644 (file)
@@ -112,7 +112,7 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
 
        tsize = __ilog2(size) - 10;
 
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC)
        if ((flags & _PAGE_NO_CACHE) == 0)
                flags |= _PAGE_COHERENT;
 #endif