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

ARM: 8817/1: mm: skip cleaning of idmap page tables on LPAE capable cores

Currently, init_static_idmap() installs some page table entries to
cover the identity mapped part of the kernel image (which is only
about 160 bytes in size in a multi_v7_defconfig Thumb2 build), and
calls flush_cache_louis() to ensure that the updates are visible
to the page table walker on the same core.

When running under virtualization, flush_cache_louis() may take more
than 10 seconds to complete:

[ 0.108192] Setting up static identity map for 0x40300000 - 0x403000a0
[ 13.078127] rcu: Hierarchical SRCU implementation.

This is due to the fact that set/way ops are not virtualizable, and so
KVM may trap each one, resulting in a substantial delay.

Since only LPAE capable CPUs may execute under virtualization, and
considering that LPAE capable CPUs are guaranteed to have cache
coherent page table walkers (per the architecture), let's only
perform this cache maintenance on non-LPAE cores.

Cc: Will Deacon <will.deacon@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

authored by

Ard Biesheuvel and committed by
Russell King
9ec5cd0a bfeffd15

+3 -1
+3 -1
arch/arm/mm/idmap.c
··· 6 6 7 7 #include <asm/cputype.h> 8 8 #include <asm/idmap.h> 9 + #include <asm/hwcap.h> 9 10 #include <asm/pgalloc.h> 10 11 #include <asm/pgtable.h> 11 12 #include <asm/sections.h> ··· 111 110 __idmap_text_end, 0); 112 111 113 112 /* Flush L1 for the hardware to see this page table content */ 114 - flush_cache_louis(); 113 + if (!(elf_hwcap & HWCAP_LPAE)) 114 + flush_cache_louis(); 115 115 116 116 return 0; 117 117 }