arm64: trans_pgd: clone only the linear map that exists at runtime

kexec_file_load() fails on arm64 if we have CONFIG_ARM64_VA_BITS_52 but
it runs on a !FEAT_LPA2 host (such as my loving Grace machine).

That is because trans_pgd_create_copy() uses the compile time
PAGE_OFFSET (VA 52) instead of the actual VA size (48 -- due to the lack
of LPA2). With the fifth level folded, pgd_none() is always false, so
the walk cannot skip the 15 extra PGDIR_SIZE slots, and they all alias
back to the same table: the whole kernel page table gets cloned 16
times, KASAN shadow included. Without KASAN it does not blow up, it just
wastes ~RAM/32 in page tables.

Fix it by copying the linear map that is the actual one, not the
compiled one.

Fixes: a6bbf5d4d9 ("arm64: mm: Add definitions to support 5 levels of paging")
Signed-off-by: Breno Leitao <leitao@debian.org>
Tested-by: Yury Smirnov <yurymonzon@gmail.com>
Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
Breno Leitao 2026-08-28 02:28:18 -07:00 committed by Will Deacon
parent a77644d009
commit 1537e55728

View File

@ -129,7 +129,8 @@ int machine_kexec_post_load(struct kimage *kimage)
}
/* Create a copy of the linear map */
rc = trans_pgd_create_copy(&info, &trans_pgd, PAGE_OFFSET, PAGE_END);
rc = trans_pgd_create_copy(&info, &trans_pgd,
_PAGE_OFFSET(vabits_actual), PAGE_END);
if (rc)
return rc;
kimage->arch.ttbr1 = __pa(trans_pgd);