ANDROID: KVM: arm64: Check PGD alignment when creating a pVM

Martijn reported a hypervisor crash when providing pKVM with an
undersized PGD allocation. Indeed, although the size of the PGD
allocation at EL2 is not under host control, a smaller host-side
allocation can lead to providing pKVM with a misaligned PGD, which will
cause the guest stage-2 init to fail in a bad way. Specifically,
guest_s2_zalloc_pages_exact() expects a successful allocation from
hyp_alloc_pages(), which can only happen if the pool has been pre-filled
with a physically aligned high-order page.

In order to guarantee allocation success in this path, check the
host-provided PGD alignment early on.

Bug: 443668075
Change-Id: I170963edc5721cf368a506bcdc4b2d0cdb462f78
Fixes: a1ec5c70d3 ("KVM: arm64: Add infrastructure to create and track pKVM instances at EL2")
Reported-by: Martijn Bogaard <martijnbogaard@google.com>
Signed-off-by: Quentin Perret <qperret@google.com>
(cherry picked from commit 749cf1743eb22eff1851c68a533147e1af97a9bf)
Signed-off-by: Lee Jones <joneslee@google.com>
This commit is contained in:
Quentin Perret
2025-09-16 08:02:46 +00:00
committed by Lee Jones
parent 8c67d4274c
commit adc27a4336
2 changed files with 3 additions and 1 deletions
+1 -1
View File
@@ -218,7 +218,7 @@ static void *guest_s2_zalloc_pages_exact(size_t size)
{
void *addr = hyp_alloc_pages(&current_vm->pool, get_order(size));
WARN_ON(size != (PAGE_SIZE << get_order(size)));
WARN_ON(!addr || size != (PAGE_SIZE << get_order(size)));
hyp_split_page(hyp_virt_to_page(addr));
return addr;
+2
View File
@@ -857,6 +857,8 @@ int __pkvm_init_vm(struct kvm *host_kvm, unsigned long pgd_hva)
ret = -EINVAL;
pgd_size = kvm_pgtable_stage2_pgd_size(host_mmu.arch.mmu.vtcr);
if (!IS_ALIGNED(pgd_hva, pgd_size))
goto err_free_last_ran;
pgd = map_donated_memory_noclear(pgd_hva, pgd_size);
if (!pgd)
goto err_free_last_ran;