Skip to content

Commit

Permalink
arm64: head: create a temporary FDT mapping in the initial ID map
Browse files Browse the repository at this point in the history
We need to access the DT very early to get at the command line and the
KASLR seed, which currently means we rely on some hacks to call into the
kernel before really calling into the kernel, which is undesirable.

So instead, let's create a mapping for the FDT in the initial ID map,
which is feasible now that it has been extended to cover more than a
single page or block, and can be updated in place to remap other output
addresses.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20220624150651.1358849-15-ardb@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
  • Loading branch information
Ard Biesheuvel authored and Will Deacon committed Jun 24, 2022
1 parent d7bea55 commit f70b3a2
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 3 deletions.
6 changes: 4 additions & 2 deletions arch/arm64/include/asm/kernel-pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#ifndef __ASM_KERNEL_PGTABLE_H
#define __ASM_KERNEL_PGTABLE_H

#include <asm/boot.h>
#include <asm/pgtable-hwdef.h>
#include <asm/sparsemem.h>

Expand Down Expand Up @@ -88,10 +89,11 @@

/* the initial ID map may need two extra pages if it needs to be extended */
#if VA_BITS < 48
#define INIT_IDMAP_DIR_SIZE (INIT_DIR_SIZE + (2 * PAGE_SIZE))
#define INIT_IDMAP_DIR_SIZE ((INIT_IDMAP_DIR_PAGES + 2) * PAGE_SIZE)
#else
#define INIT_IDMAP_DIR_SIZE INIT_DIR_SIZE
#define INIT_IDMAP_DIR_SIZE (INIT_IDMAP_DIR_PAGES * PAGE_SIZE)
#endif
#define INIT_IDMAP_DIR_PAGES EARLY_PAGES(KIMAGE_VADDR, _end + MAX_FDT_SIZE + SWAPPER_BLOCK_SIZE)

/* Initial memory map size */
#if ARM64_KERNEL_USES_PMD_MAPS
Expand Down
14 changes: 13 additions & 1 deletion arch/arm64/kernel/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
*
* Register Scope Purpose
* x21 primary_entry() .. start_kernel() FDT pointer passed at boot in x0
* x22 create_idmap() .. start_kernel() ID map VA of the DT blob
* x23 primary_entry() .. start_kernel() physical misalignment/KASLR offset
* x28 clear_page_tables() callee preserved temp register
* x19/x20 __primary_switch() callee preserved temp registers
Expand Down Expand Up @@ -348,7 +349,7 @@ SYM_FUNC_START_LOCAL(create_idmap)
#endif
adrp x0, init_idmap_pg_dir
adrp x3, _text
adrp x6, _end
adrp x6, _end + MAX_FDT_SIZE + SWAPPER_BLOCK_SIZE
mov x7, SWAPPER_RX_MMUFLAGS

map_memory x0, x1, x3, x6, x7, x3, IDMAP_PGD_ORDER, x10, x11, x12, x13, x14, EXTRA_SHIFT
Expand All @@ -362,6 +363,17 @@ SYM_FUNC_START_LOCAL(create_idmap)
mov x6, #SWAPPER_BLOCK_SHIFT
bl remap_region

/* Remap the FDT after the kernel image */
adrp x1, _text
adrp x22, _end + SWAPPER_BLOCK_SIZE
bic x2, x22, #SWAPPER_BLOCK_SIZE - 1
bfi x22, x21, #0, #SWAPPER_BLOCK_SHIFT // remapped FDT address
add x3, x2, #MAX_FDT_SIZE + SWAPPER_BLOCK_SIZE
bic x4, x21, #SWAPPER_BLOCK_SIZE - 1
mov x5, SWAPPER_RW_MMUFLAGS
mov x6, #SWAPPER_BLOCK_SHIFT
bl remap_region

/*
* Since the page tables have been populated with non-cacheable
* accesses (MMU disabled), invalidate those tables again to
Expand Down

0 comments on commit f70b3a2

Please sign in to comment.