ANDROID: KVM: arm64: Initialize pkvm_pgtable.mm_ops earlier

The `init` callback of an IOMMU driver is called just before
`finalize_host_mappings` so that EL2 mappings created by drivers are
subsequently unmapped from host stage-2. However, at this point hyp has
already switched to the buddy allocator, having reserved pages allocated
by the early allocator, but `pkvm_pgtable.mm_ops` have not been switched
to buddy allocator callbacks. As a result, pages allocated for EL2
mappings of the IOMMU driver are allocated by the obsoleted early
allocator and remain treated as free by the buddy allocator. This likely
leads to a corruption in the free page lists and a later hyp panic.

Move the initialization of `pkvm_pgtable.mm_ops` before
`finalize_host_mappings` and the call to IOMMU's `init`.

Test: run a VM
Test: adb shell cmd jobscheduler run -f android 5132250
Bug: 190463801
Bug: 209004831
Change-Id: I1f6e00bca087d889b0cad4bd43d044895e37006c
Signed-off-by: David Brazdil <dbrazdil@google.com>
(cherry picked from commit 395d045123)
Signed-off-by: Mostafa Saleh <smostafa@google.com>
This commit is contained in:
David Brazdil
2021-12-06 11:03:06 +00:00
committed by Mostafa Saleh
parent b2ba2c2eb4
commit c6fb848826

View File

@@ -336,13 +336,6 @@ void __noreturn __pkvm_init_finalise(void)
if (ret)
goto out;
if (kvm_iommu_ops.init) {
ret = kvm_iommu_ops.init();
if (ret)
goto out;
}
pkvm_pgtable_mm_ops = (struct kvm_pgtable_mm_ops) {
.zalloc_page = hyp_zalloc_hyp_page,
.phys_to_virt = hyp_phys_to_virt,
@@ -353,6 +346,12 @@ void __noreturn __pkvm_init_finalise(void)
};
pkvm_pgtable.mm_ops = &pkvm_pgtable_mm_ops;
if (kvm_iommu_ops.init) {
ret = kvm_iommu_ops.init();
if (ret)
goto out;
}
ret = fix_host_ownership();
if (ret)
goto out;