mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 03:24:45 +01:00
arm64: Work around convergence issue with LLD linker
LLD will occasionally error out with a '__init_end does not converge' error if INIT_IDMAP_DIR_SIZE is defined in terms of _end, as this results in a circular dependency. Counter this by dimensioning the initial IDMAP page tables based on a new boundary marker 'kimage_limit', and define it such that its value should not change as a result of the initdata segment being pushed over a 64k segment boundary due to changes in INIT_IDMAP_DIR_SIZE, provided that its value doesn't change by more than 2M between linker passes. Reported-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Link: https://lore.kernel.org/r/20250531123005.3866382-2-ardb+git@google.com Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
parent
e21560b7d3
commit
dc0a083948
2 changed files with 12 additions and 1 deletions
|
|
@ -58,7 +58,7 @@
|
|||
#define INIT_DIR_SIZE (PAGE_SIZE * (EARLY_PAGES(SWAPPER_PGTABLE_LEVELS, KIMAGE_VADDR, _end, EXTRA_PAGE) \
|
||||
+ EARLY_SEGMENT_EXTRA_PAGES))
|
||||
|
||||
#define INIT_IDMAP_DIR_PAGES (EARLY_PAGES(INIT_IDMAP_PGTABLE_LEVELS, KIMAGE_VADDR, _end, 1))
|
||||
#define INIT_IDMAP_DIR_PAGES (EARLY_PAGES(INIT_IDMAP_PGTABLE_LEVELS, KIMAGE_VADDR, kimage_limit, 1))
|
||||
#define INIT_IDMAP_DIR_SIZE ((INIT_IDMAP_DIR_PAGES + EARLY_IDMAP_EXTRA_PAGES) * PAGE_SIZE)
|
||||
|
||||
#define INIT_IDMAP_FDT_PAGES (EARLY_PAGES(INIT_IDMAP_PGTABLE_LEVELS, 0UL, UL(MAX_FDT_SIZE), 1) - 1)
|
||||
|
|
|
|||
|
|
@ -146,6 +146,17 @@ KVM_NVHE_ALIAS(kvm_protected_mode_initialized);
|
|||
_kernel_codesize = ABSOLUTE(__inittext_end - _text);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* LLD will occasionally error out with a '__init_end does not converge' error
|
||||
* if INIT_IDMAP_DIR_SIZE is defined in terms of _end, as this results in a
|
||||
* circular dependency. Counter this by dimensioning the initial IDMAP page
|
||||
* tables based on kimage_limit, which is defined such that its value should
|
||||
* not change as a result of the initdata segment being pushed over a 64k
|
||||
* segment boundary due to changes in INIT_IDMAP_DIR_SIZE, provided that its
|
||||
* value doesn't change by more than 2M between linker passes.
|
||||
*/
|
||||
kimage_limit = ALIGN(ABSOLUTE(_end + SZ_64K), SZ_2M);
|
||||
|
||||
#undef ASSERT
|
||||
|
||||
#endif /* __ARM64_KERNEL_IMAGE_VARS_H */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue