aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorNicolas Pitre <nicolas.pitre@linaro.org>2012-11-08 13:46:07 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-11-13 06:47:41 -0500
commite40678559fdf3f56ce9a349365fbf39e1f63ecc0 (patch)
treebf17297c143e5aa6f55f73bd44d703a4f3817686 /arch
parentb62655f4c6f3e4d21934eee14ac2ac5cd479c97c (diff)
ARM: 7573/1: idmap: use flush_cache_louis() and flush TLBs only when necessary
Flushing the cache is needed for the hardware to see the idmap table and therefore can be done at init time. On ARMv7 it is not necessary to flush L2 so flush_cache_louis() is used here instead. There is no point flushing the cache in setup_mm_for_reboot() as the caller should, and already is, taking care of this. If switching the memory map requires a cache flush, then cpu_switch_mm() already includes that operation. What is not done by cpu_switch_mm() on ASID capable CPUs is TLB flushing as the whole point of the ASID is to tag the TLBs and avoid flushing them on a context switch. Since we don't have a clean ASID for the identity mapping, we need to flush the TLB explicitly in that case. Otherwise this is already performed by cpu_switch_mm(). Signed-off-by: Nicolas Pitre <nico@linaro.org> Acked-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mm/idmap.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index ab88ed4f8e08..99db769307ec 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -92,6 +92,9 @@ static int __init init_static_idmap(void)
92 (long long)idmap_start, (long long)idmap_end); 92 (long long)idmap_start, (long long)idmap_end);
93 identity_mapping_add(idmap_pgd, idmap_start, idmap_end); 93 identity_mapping_add(idmap_pgd, idmap_start, idmap_end);
94 94
95 /* Flush L1 for the hardware to see this page table content */
96 flush_cache_louis();
97
95 return 0; 98 return 0;
96} 99}
97early_initcall(init_static_idmap); 100early_initcall(init_static_idmap);
@@ -103,12 +106,15 @@ early_initcall(init_static_idmap);
103 */ 106 */
104void setup_mm_for_reboot(void) 107void setup_mm_for_reboot(void)
105{ 108{
106 /* Clean and invalidate L1. */
107 flush_cache_all();
108
109 /* Switch to the identity mapping. */ 109 /* Switch to the identity mapping. */
110 cpu_switch_mm(idmap_pgd, &init_mm); 110 cpu_switch_mm(idmap_pgd, &init_mm);
111 111
112 /* Flush the TLB. */ 112#ifdef CONFIG_CPU_HAS_ASID
113 /*
114 * We don't have a clean ASID for the identity mapping, which
115 * may clash with virtual addresses of the previous page tables
116 * and therefore potentially in the TLB.
117 */
113 local_flush_tlb_all(); 118 local_flush_tlb_all();
119#endif
114} 120}