arm64/kernel: Fix range on invalidating dcache for boot page tables

Prior to commit 8eb7e28d4c ("arm64/mm: move runtime pgds to
rodata"), idmap_pgd_dir, tramp_pg_dir, reserved_ttbr0, swapper_pg_dir,
and init_pg_dir were contiguous at the end of the kernel image. The
maintenance at the end of __create_page_tables assumed these were
contiguous, and affected everything from the start of idmap_pg_dir
to the end of init_pg_dir.

That commit moved all but init_pg_dir into the .rodata section, with
other data placed between idmap_pg_dir and init_pg_dir, but did not
update the maintenance. Hence the maintenance is performed on much
more data than necessary (but as the bootloader previously made this
clean to the PoC there is no functional problem).

As we only alter idmap_pg_dir, and init_pg_dir, we only need to perform
maintenance for these. As the other dirs are in .rodata, the bootloader
will have initialised them as expected and cleaned them to the PoC. The
kernel will initialize them as necessary after enabling the MMU.

This patch reworks the maintenance to only cover the idmap_pg_dir and
init_pg_dir to avoid this unnecessary work.

Signed-off-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Link: https://lore.kernel.org/r/20200427235700.112220-1-gshan@redhat.com
Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
Gavin Shan 2020-04-28 09:57:00 +10:00 committed by Will Deacon
parent cfa7ede20f
commit 9d2d75ede5
3 changed files with 11 additions and 3 deletions

View File

@ -457,6 +457,7 @@ extern pgd_t init_pg_dir[PTRS_PER_PGD];
extern pgd_t init_pg_end[]; extern pgd_t init_pg_end[];
extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
extern pgd_t idmap_pg_dir[PTRS_PER_PGD]; extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
extern pgd_t idmap_pg_end[];
extern pgd_t tramp_pg_dir[PTRS_PER_PGD]; extern pgd_t tramp_pg_dir[PTRS_PER_PGD];
extern void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd); extern void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd);

View File

@ -393,13 +393,19 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
/* /*
* Since the page tables have been populated with non-cacheable * Since the page tables have been populated with non-cacheable
* accesses (MMU disabled), invalidate the idmap and swapper page * accesses (MMU disabled), invalidate those tables again to
* tables again to remove any speculatively loaded cache lines. * remove any speculatively loaded cache lines.
*/ */
dmb sy
adrp x0, idmap_pg_dir adrp x0, idmap_pg_dir
adrp x1, idmap_pg_end
sub x1, x1, x0
bl __inval_dcache_area
adrp x0, init_pg_dir
adrp x1, init_pg_end adrp x1, init_pg_end
sub x1, x1, x0 sub x1, x1, x0
dmb sy
bl __inval_dcache_area bl __inval_dcache_area
ret x28 ret x28

View File

@ -133,6 +133,7 @@ SECTIONS
idmap_pg_dir = .; idmap_pg_dir = .;
. += IDMAP_DIR_SIZE; . += IDMAP_DIR_SIZE;
idmap_pg_end = .;
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
tramp_pg_dir = .; tramp_pg_dir = .;