]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
arm64/kernel: Fix range on invalidating dcache for boot page tables
authorGavin Shan <gshan@redhat.com>
Mon, 27 Apr 2020 23:57:00 +0000 (09:57 +1000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 Jun 2020 07:32:18 +0000 (09:32 +0200)
[ Upstream commit 9d2d75ede59bc1edd8561f2ee9d4702a5ea0ae30 ]

Prior to commit 8eb7e28d4c642c31 ("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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/arm64/include/asm/pgtable.h
arch/arm64/kernel/head.S
arch/arm64/kernel/vmlinux.lds.S

index 538c85e62f86d5fbd2f064a66278b917deab240e..25f56df7ed9a2190795ac139bd687697befcdf54 100644 (file)
@@ -457,6 +457,7 @@ extern pgd_t init_pg_dir[PTRS_PER_PGD];
 extern pgd_t init_pg_end[];
 extern pgd_t swapper_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 void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd);
index 57a91032b4c21ca2dc74447c10093f0d4dd0cec7..32f5ecbec0ea145a4b2feaa4f94eb88ee555740c 100644 (file)
@@ -394,13 +394,19 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
 
        /*
         * Since the page tables have been populated with non-cacheable
-        * accesses (MMU disabled), invalidate the idmap and swapper page
-        * tables again to remove any speculatively loaded cache lines.
+        * accesses (MMU disabled), invalidate those tables again to
+        * remove any speculatively loaded cache lines.
         */
+       dmb     sy
+
        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
        sub     x1, x1, x0
-       dmb     sy
        bl      __inval_dcache_area
 
        ret     x28
index 497f9675071d428bff29deb8fa009aeaa600e663..94402aaf5f5c7fbbb6f7f3908bbe885280f18936 100644 (file)
@@ -139,6 +139,7 @@ SECTIONS
 
        idmap_pg_dir = .;
        . += IDMAP_DIR_SIZE;
+       idmap_pg_end = .;
 
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
        tramp_pg_dir = .;