From c6fb8488265dd9b28aa4da9f38de1ae629fcfdde Mon Sep 17 00:00:00 2001 From: David Brazdil Date: Mon, 6 Dec 2021 11:03:06 +0000 Subject: [PATCH] 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 (cherry picked from commit 395d0451237fb14d801591d0a42c2abaa6641d03) Signed-off-by: Mostafa Saleh --- arch/arm64/kvm/hyp/nvhe/setup.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c index 6f8b2b5c1320..13312c484fc3 100644 --- a/arch/arm64/kvm/hyp/nvhe/setup.c +++ b/arch/arm64/kvm/hyp/nvhe/setup.c @@ -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;