aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Medhurst <tixy@linaro.org>2012-07-18 19:05:15 +0100
committerJon Medhurst <tixy@linaro.org>2012-07-18 19:05:15 +0100
commitf8dd49dc88778b6484b201e7dbceb0d06474dc66 (patch)
treee56c603d200745d10ec1accf58c2d7bef1fbec0b
parent2d4e3b16f288d63a8fb21ee14fcece92f3548f55 (diff)
parent04730d7db446199a142a093224399d99c908d872 (diff)
downloadkernel-f8dd49dc88778b6484b201e7dbceb0d06474dc66.tar.gz
Merge branch 'tracking-armlt-misc-fixes' into integration-linux-vexpressHEADmasterintegration-linux-vexpress
-rw-r--r--arch/arm/mach-realview/hotplug.c2
-rw-r--r--arch/arm/mach-vexpress/hotplug.c2
-rw-r--r--arch/arm/mm/fault.c13
-rw-r--r--arch/arm/mm/proc-v7-2level.S4
-rw-r--r--arch/arm/mm/proc-v7-3level.S4
5 files changed, 19 insertions, 6 deletions
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
index 57d9efb..77b23fa 100644
--- a/arch/arm/mach-realview/hotplug.c
+++ b/arch/arm/mach-realview/hotplug.c
@@ -99,7 +99,7 @@ int platform_cpu_kill(unsigned int cpu)
*
* Called with IRQs disabled
*/
-void platform_cpu_die(unsigned int cpu)
+void __cpuinit platform_cpu_die(unsigned int cpu)
{
int spurious = 0;
diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c
index c504a72..b0a3f7d 100644
--- a/arch/arm/mach-vexpress/hotplug.c
+++ b/arch/arm/mach-vexpress/hotplug.c
@@ -94,7 +94,7 @@ int platform_cpu_kill(unsigned int cpu)
*
* Called with IRQs disabled
*/
-void platform_cpu_die(unsigned int cpu)
+void __cpuinit platform_cpu_die(unsigned int cpu)
{
int spurious = 0;
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index c3bd834..44df364 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -445,8 +445,16 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
if (pud_none(*pud_k))
goto bad_area;
- if (!pud_present(*pud))
+ if (!pud_present(*pud)) {
set_pud(pud, *pud_k);
+ /*
+ * There is a small window during free_pgtables() where the
+ * user *pud entry is 0 but the TLB has not been invalidated
+ * and we get a level 2 (pmd) translation fault caused by the
+ * intermediate TLB caching of the old level 1 (pud) entry.
+ */
+ flush_tlb_kernel_page(addr);
+ }
pmd = pmd_offset(pud, addr);
pmd_k = pmd_offset(pud_k, addr);
@@ -469,8 +477,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
#endif
if (pmd_none(pmd_k[index]))
goto bad_area;
+ if (!pmd_present(pmd[index]))
+ copy_pmd(pmd, pmd_k);
- copy_pmd(pmd, pmd_k);
return 0;
bad_area:
diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S
index 42ac069..e3f2ba9 100644
--- a/arch/arm/mm/proc-v7-2level.S
+++ b/arch/arm/mm/proc-v7-2level.S
@@ -101,7 +101,9 @@ ENTRY(cpu_v7_set_pte_ext)
ARM( str r3, [r0, #2048]! )
THUMB( add r0, r0, #2048 )
THUMB( str r3, [r0] )
- mcr p15, 0, r0, c7, c10, 1 @ flush_pte
+ mrc p15, 0, r3, c0, c1, 7 @ read ID_MMFR3
+ tst r3, #0xf << 20 @ check the coherent walk bits
+ mcreq p15, 0, r0, c7, c10, 1 @ clean D-cache to PoU
#endif
mov pc, lr
ENDPROC(cpu_v7_set_pte_ext)
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 8de0f1d..6b30605 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -70,7 +70,9 @@ ENTRY(cpu_v7_set_pte_ext)
tst r3, #1 << (55 - 32) @ L_PTE_DIRTY
orreq r2, #L_PTE_RDONLY
1: strd r2, r3, [r0]
- mcr p15, 0, r0, c7, c10, 1 @ flush_pte
+ mrc p15, 0, r3, c0, c1, 7 @ read ID_MMFR3
+ tst r3, #0xf << 20 @ check the coherent walk bits
+ mcreq p15, 0, r0, c7, c10, 1 @ clean D-cache to PoU
#endif
mov pc, lr
ENDPROC(cpu_v7_set_pte_ext)