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 <[email protected]>
Tested-by: Yury Smirnov <[email protected]>
Signed-off-by: Will Deacon <[email protected]>
This commit is contained in:
Breno Leitao authored and Will Deacon committed 2026-09-03 13:01:15 +00:00
1 parent a77644d009
commit 1537e55728
1 file changed
+2 -1
+2 -1
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);