diff options
author | Scott Wood <scottwood@freescale.com> | 2015-07-18 15:24:58 -0400 |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2015-08-08 00:00:01 -0400 |
commit | c60232029aee84f69da0e74aa6f6d249edbbc80b (patch) | |
tree | f56c5b4928f84e47a308a8d4adf664d0d34e4839 /arch/powerpc | |
parent | 0d61f0b3e222b588480e2ad1e85bb2ea57561c4b (diff) |
powerpc/fsl: Force coherent memory on e500mc derivatives
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>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/pte-common.h | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/exceptions-64e.S | 13 | ||||
-rw-r--r-- | arch/powerpc/kernel/fsl_booke_entry_mapping.S | 15 | ||||
-rw-r--r-- | arch/powerpc/mm/fsl_booke_mmu.c | 2 |
4 files changed, 20 insertions, 13 deletions
diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h index b7c8d079c121..71537a319fc8 100644 --- a/arch/powerpc/include/asm/pte-common.h +++ b/arch/powerpc/include/asm/pte-common.h | |||
@@ -109,7 +109,8 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void); | |||
109 | * the processor might need it for DMA coherency. | 109 | * the processor might need it for DMA coherency. |
110 | */ | 110 | */ |
111 | #define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_PSIZE) | 111 | #define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_PSIZE) |
112 | #if defined(CONFIG_SMP) || defined(CONFIG_PPC_STD_MMU) | 112 | #if defined(CONFIG_SMP) || defined(CONFIG_PPC_STD_MMU) || \ |
113 | defined(CONFIG_PPC_E500MC) | ||
113 | #define _PAGE_BASE (_PAGE_BASE_NC | _PAGE_COHERENT) | 114 | #define _PAGE_BASE (_PAGE_BASE_NC | _PAGE_COHERENT) |
114 | #else | 115 | #else |
115 | #define _PAGE_BASE (_PAGE_BASE_NC) | 116 | #define _PAGE_BASE (_PAGE_BASE_NC) |
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index 3e68d1c69718..f3bd5e747ed8 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S | |||
@@ -1313,11 +1313,14 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
1313 | sync | 1313 | sync |
1314 | isync | 1314 | isync |
1315 | 1315 | ||
1316 | /* The mapping only needs to be cache-coherent on SMP */ | 1316 | /* |
1317 | #ifdef CONFIG_SMP | 1317 | * The mapping only needs to be cache-coherent on SMP, except on |
1318 | #define M_IF_SMP MAS2_M | 1318 | * Freescale e500mc derivatives where it's also needed for coherent DMA. |
1319 | */ | ||
1320 | #if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC) | ||
1321 | #define M_IF_NEEDED MAS2_M | ||
1319 | #else | 1322 | #else |
1320 | #define M_IF_SMP 0 | 1323 | #define M_IF_NEEDED 0 |
1321 | #endif | 1324 | #endif |
1322 | 1325 | ||
1323 | /* 6. Setup KERNELBASE mapping in TLB[0] | 1326 | /* 6. Setup KERNELBASE mapping in TLB[0] |
@@ -1332,7 +1335,7 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
1332 | ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_1GB))@l | 1335 | ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_1GB))@l |
1333 | mtspr SPRN_MAS1,r6 | 1336 | mtspr SPRN_MAS1,r6 |
1334 | 1337 | ||
1335 | LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET | M_IF_SMP) | 1338 | LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET | M_IF_NEEDED) |
1336 | mtspr SPRN_MAS2,r6 | 1339 | mtspr SPRN_MAS2,r6 |
1337 | 1340 | ||
1338 | rlwinm r5,r5,0,0,25 | 1341 | rlwinm r5,r5,0,0,25 |
diff --git a/arch/powerpc/kernel/fsl_booke_entry_mapping.S b/arch/powerpc/kernel/fsl_booke_entry_mapping.S index f22e7e44fbf3..83dd0f6776b3 100644 --- a/arch/powerpc/kernel/fsl_booke_entry_mapping.S +++ b/arch/powerpc/kernel/fsl_booke_entry_mapping.S | |||
@@ -152,11 +152,14 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
152 | tlbivax 0,r9 | 152 | tlbivax 0,r9 |
153 | TLBSYNC | 153 | TLBSYNC |
154 | 154 | ||
155 | /* The mapping only needs to be cache-coherent on SMP */ | 155 | /* |
156 | #ifdef CONFIG_SMP | 156 | * The mapping only needs to be cache-coherent on SMP, except on |
157 | #define M_IF_SMP MAS2_M | 157 | * Freescale e500mc derivatives where it's also needed for coherent DMA. |
158 | */ | ||
159 | #if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC) | ||
160 | #define M_IF_NEEDED MAS2_M | ||
158 | #else | 161 | #else |
159 | #define M_IF_SMP 0 | 162 | #define M_IF_NEEDED 0 |
160 | #endif | 163 | #endif |
161 | 164 | ||
162 | #if defined(ENTRY_MAPPING_BOOT_SETUP) | 165 | #if defined(ENTRY_MAPPING_BOOT_SETUP) |
@@ -167,8 +170,8 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
167 | lis r6,(MAS1_VALID|MAS1_IPROT)@h | 170 | lis r6,(MAS1_VALID|MAS1_IPROT)@h |
168 | ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l | 171 | ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l |
169 | mtspr SPRN_MAS1,r6 | 172 | mtspr SPRN_MAS1,r6 |
170 | lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h | 173 | lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_NEEDED)@h |
171 | ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l | 174 | ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_NEEDED)@l |
172 | mtspr SPRN_MAS2,r6 | 175 | mtspr SPRN_MAS2,r6 |
173 | mtspr SPRN_MAS3,r8 | 176 | mtspr SPRN_MAS3,r8 |
174 | tlbwe | 177 | tlbwe |
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index 9c90e66cffb6..354ba3c09ef3 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c | |||
@@ -112,7 +112,7 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys, | |||
112 | 112 | ||
113 | tsize = __ilog2(size) - 10; | 113 | tsize = __ilog2(size) - 10; |
114 | 114 | ||
115 | #ifdef CONFIG_SMP | 115 | #if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC) |
116 | if ((flags & _PAGE_NO_CACHE) == 0) | 116 | if ((flags & _PAGE_NO_CACHE) == 0) |
117 | flags |= _PAGE_COHERENT; | 117 | flags |= _PAGE_COHERENT; |
118 | #endif | 118 | #endif |