[PATCH] ARM: setup_mm_for_reboot(): use flush_cache_louis()
Will Deacon
will.deacon at arm.com
Thu Nov 8 11:26:13 EST 2012
On Wed, Nov 07, 2012 at 08:10:49PM +0000, Nicolas Pitre wrote:
> Here's my latest version. I made the tlb flush conditional. Please
> review again before I add your ACK.
Ok.
> ---- >8
> From: Nicolas Pitre <nicolas.pitre at linaro.org>
> Subject: [PATCH] ARM: 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 at linaro.org>
>
> diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
> index ab88ed4f8e..99db769307 100644
> --- a/arch/arm/mm/idmap.c
> +++ b/arch/arm/mm/idmap.c
> @@ -92,6 +92,9 @@ static int __init init_static_idmap(void)
> (long long)idmap_start, (long long)idmap_end);
> identity_mapping_add(idmap_pgd, idmap_start, idmap_end);
>
> + /* Flush L1 for the hardware to see this page table content */
> + flush_cache_louis();
> +
> return 0;
> }
> early_initcall(init_static_idmap);
> @@ -103,12 +106,15 @@ early_initcall(init_static_idmap);
> */
> void setup_mm_for_reboot(void)
> {
> - /* Clean and invalidate L1. */
> - flush_cache_all();
> -
> /* Switch to the identity mapping. */
> cpu_switch_mm(idmap_pgd, &init_mm);
>
> - /* Flush the TLB. */
> +#ifdef CONFIG_CPU_HAS_ASID
> + /*
> + * We don't have a clean ASID for the identity mapping, which
> + * may clash with virtual addresses of the previous page tables
> + * and therefore potentially in the TLB.
> + */
> local_flush_tlb_all();
> +#endif
I checked all of the switch_mm implementations and it looks like
!CONFIG_CPU_HAS_ASID implies the TLB flush in all cases, so this looks fine
to me.
Acked-by: Will Deacon <will.deacon at arm.com>
Cheers,
Will
More information about the linux-arm-kernel
mailing list