Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Nicolas Pitre and committed by
Russell King
e4067855 b62655f4

+10 -4
+10 -4
arch/arm/mm/idmap.c
··· 92 92 (long long)idmap_start, (long long)idmap_end); 93 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 98 return 0; 96 99 } 97 100 early_initcall(init_static_idmap); ··· 106 103 */ 107 104 void setup_mm_for_reboot(void) 108 105 { 109 - /* Clean and invalidate L1. */ 110 - flush_cache_all(); 111 - 112 106 /* Switch to the identity mapping. */ 113 107 cpu_switch_mm(idmap_pgd, &init_mm); 114 108 115 - /* Flush the TLB. */ 109 + #ifdef CONFIG_CPU_HAS_ASID 110 + /* 111 + * We don't have a clean ASID for the identity mapping, which 112 + * may clash with virtual addresses of the previous page tables 113 + * and therefore potentially in the TLB. 114 + */ 116 115 local_flush_tlb_all(); 116 + #endif 117 117 }